ROOTPWA
pwacomponent.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------
2 // File and Version Information:
3 // $Id$
4 //
5 // Description:
6 // Implementation of class pwacomponent
7 // see pwacomponent.h for details
8 //
9 //
10 // Author List:
11 // Sebastian Neubert TUM (original author)
12 //
13 //
14 //-----------------------------------------------------------
15 
16 // This Class' Header ------------------
17 #include "pwacomponent.h"
18 
19 // C/C++ Headers ----------------------
20 #include <algorithm>
21 #include <iostream>
22 
23 // Collaborating Class Headers --------
24 #include "TF1.h"
25 
26 // Class Member definitions -----------
27 
28 using namespace std;
29 
30 
31 
33  : _C(ch._C),_ps(ch._ps){
34  //if(ch._sqrtps!=NULL)_sqrtps=(TGraph*)ch._sqrtps->Clone();
35  //else _sqrtps=NULL;
36 }
37 
38 
39 
40 
42  double m0, double gamma,
43  const map<string,pwachannel >& channels)
44  : _name(name), _m0(m0), _m02(m0*m0),_m0min(0),_m0max(5000),_gamma(gamma),_gammamin(0),_gammamax(1000),_fixm(false),_fixgamma(false), _constWidth(false),_channels(channels)
45 {
46  // fill vector with channel for random access
47  map<string,pwachannel >::iterator it=_channels.begin();
48  while(it!=_channels.end()){
49  _vchannels.push_back(&(it->second)); // carefull this is dangerous
50  // refactor to vector only use as soon as possible!
51  _channelname.push_back(it->first);
52  ++it;
53  }
54 }
55 
56 
57 
58 
59 void
61  map<string,pwachannel >::iterator it=_channels.begin();
62  unsigned int counter=0;
63  while(it!=_channels.end()){
64  it->second.setCoupling(complex<double>(par[counter],par[counter+1]));
65  counter+=2;
66  ++it;
67  }
68 }
69 void
71  map<string,pwachannel >::iterator it=_channels.begin();
72  unsigned int counter=0;
73  while(it!=_channels.end()){
74  par[counter]=it->second.C().real();
75  par[counter+1]=it->second.C().imag();
76  counter+=2;
77  ++it;
78  }
79 }
80 
81 
82 complex<double>
83 rpwa::pwacomponent::val(double m) const {
84  // calculate dynamic width:
85  // loop over decay channels
86  double gamma=0;
87  std::map<std::string,pwachannel >::const_iterator it=_channels.begin();
88  double n=(double)numChannels();
89  //cout << "NChannels : " << n << endl;
90  double ps=1;
91  if(!_constWidth){
92  ps=0; // no not forget to reset phase space here!
93  while(it!=_channels.end()){
94  double myps=1.;
95  if(it->second.ps()!=NULL){
96  double ps0=it->second.ps(_m0);
97  myps=(it->second.ps(m))/ps0;
98  }
99  ps+=myps;
100  ++it;
101  }
102  ps/=n;
103  }
104  gamma=_gamma*ps;
105 
106  //std::cerr << m << " " << gamma/_gamma << std::endl;
107  //std::cerr << _name <<" compval=" <<gamma*_m0/complex<double>(m*m-_m02,gamma*_m0) << std::endl;
108  return _gamma*_m0/complex<double>(_m02-m*m,-gamma*_m0);
109 }
110 
111 
112 double
113 lambda(const double a,
114  const double b,
115  const double c)
116 {
117  return a * a + b * b + c * c - 2.0 * (a * b + b * c + c * a);
118 }
119 
120 
121 complex<double>
122 q(const double M,
123  const double m1,
124  const double m2)
125 {
126  double lam = lambda(M * M, m1 * m1, m2 * m2);
127  complex<double> ret;
128  if (lam < 0)
129  return complex<double>(0.0, 0.0);
130  return complex<double>(sqrt(lam / (4 * M * M)), 0.0 );
131 }
132 
133 complex<double>
134 rpwa::pwabkg::val(double m) const {
135  m-=_m0; // shift baseline mass
136  // calculate breakup momentum
137  complex<double> p;
138  if(m<_m1+_m2)return complex<double>(1,0);
139  p=q(m,_m1,_m2);
140  //std::cerr << _name <<" val=" << exp(-_gamma*p) << std::endl;
141  return exp(-_gamma*p.real()*p.real());
142 }
143 
144 
145 vector<string>
147  vector<string> wl;
148  for(unsigned int i=0;i<n();++i){
149  const map<string,pwachannel >& channellist=_comp[i]->channels();
150  map<string,pwachannel >::const_iterator it=channellist.begin();
151  while(it!=channellist.end()){
152  if(find(wl.begin(),wl.end(),it->first)==wl.end())
153  wl.push_back(it->first);
154  ++it;
155  }
156  }
157  return wl;
158 }
159 
160 
161 void
163  _phasespace=fPS;
164  // check if there are free parameters in the phase space that should be fitted
165  unsigned int nparPS=_phasespace->GetNpar();
166  // loop over parameters and check limits
167  // remember which parameters to let float
168  _freePSpar.clear();
169  for(unsigned int i=0;i<nparPS;++i){
170  double min,max;
171  _phasespace->GetParLimits(i,min,max);
172  if(min!=max){
173  _freePSpar.push_back(i);
174  cout << "PS parameter "<< i << " floating in ["
175  << min << "," << max << "]" << endl;
176  }
177  }// end loop over parameters
178  _numpar+=_freePSpar.size();
179 }
180 
181 
182 // performs mapping from the index of a wave in wavelist() to the components and channels that couple to this wave
183 void
185  vector<string> wlist=wavelist();
186  for(unsigned int i=0; i<wlist.size();++i){
187  // check which components this waves belongs to and which channel they are
188  _compChannel.push_back(getCompChannel(wlist[i]));
189  }
190 }
191 
192 
193 
194 double
195 rpwa::pwacompset::getFreePSPar(unsigned int i) const {
196  if(i<_freePSpar.size())
197  return _phasespace->GetParameter(_freePSpar[i]);
198  else return 0;
199 }
200 
201 
202 void
203 rpwa::pwacompset::getFreePSLimits(unsigned int i, double& lower, double& upper) const {
204  if(i<_freePSpar.size()){
205  _phasespace->GetParLimits(_freePSpar[i],lower,upper);
206  }
207 }
208 
209 void
210 rpwa::pwacompset::setPar(const double* par){ // set parameters
211  unsigned int parcount=0;
212  // components
213  for(unsigned int i=0;i<n();++i){
214  _comp[i]->setPar(par[parcount],par[parcount+1]);
215  parcount+=2;
216  _comp[i]->setCouplings(&par[parcount]);
217  parcount+=_comp[i]->numChannels()*2; // RE and Im for each channel
218  } // end loop over components
219  // phase space
220  unsigned int nfreepar=_freePSpar.size();
221  for(unsigned int ipar=0;ipar<nfreepar;++ipar){
222  _phasespace->SetParameter(_freePSpar[ipar],par[parcount]);
223  ++parcount;
224  }
225 }
226 
227 
228 void
229 rpwa::pwacompset::getPar(double* par){ // return parameters
230  unsigned int parcount=0;
231  // components
232  for(unsigned int i=0;i<n();++i){
233  par[parcount]=_comp[i]->m0();
234  par[parcount+1]=_comp[i]->gamma();
235  parcount+=2;
236  _comp[i]->getCouplings(&par[parcount]);
237  parcount+=_comp[i]->numChannels()*2; // RE and Im for each channel
238  }
239  // phase space
240  unsigned int nfreepar=_freePSpar.size();
241  for(unsigned int ipar=0;ipar<nfreepar;++ipar){
242  par[parcount]=_phasespace->GetParameter(_freePSpar[ipar]);
243  ++parcount;
244  }
245 }
246 
247 double
248 rpwa::pwacompset::ps(double m){return _phasespace->Eval(m);}
249 
250 double
251 rpwa::pwacompset::intensity(const std::string& wave, double m){
252  // loop over all components and pick up those that contribute to this channel
253  complex<double> rho(0,0);
254  for(unsigned int ic=0;ic<n();++ic){
255  if(_comp[ic]->channels().count(wave)==0)continue;
256  else {
257  rho+=_comp[ic]->val(m)*_comp[ic]->channels().find(wave)->second.C()*sqrt(_comp[ic]->channels().find(wave)->second.ps(m));
258  }
259 
260  }
261  return norm(rho)*_phasespace->Eval(m);
262 }
263 
264 double
265 rpwa::pwacompset::phase(const std::string& wave, double m){
266  // loop over all components and pick up those that contribute to this channel
267  complex<double> rho(0,0);
268  for(unsigned int ic=0;ic<n();++ic){
269  if(_comp[ic]->channels().count(wave)==0)continue;
270  else {
271  rho+=_comp[ic]->val(m)*_comp[ic]->channels().find(wave)->second.C();
272  }
273 
274  }
275  return arg(rho);
276 }
277 
278 
279 double
280 rpwa::pwacompset::phase(const std::string& wave1,
281  const std::string& wave2,
282  double m){
283  return arg(overlap(wave1,wave2,m));
284 }
285 
286 std::complex<double>
287 rpwa::pwacompset::overlap(const std::string& wave1,
288  const std::string& wave2,
289  double m){
290  // loop over all components and pick up those that contribute to this channel
291  complex<double> rho1(0,0);
292  complex<double> rho2(0,0);
293 
294  for(unsigned int ic=0;ic<n();++ic){
295  if(_comp[ic]->channels().count(wave1)!=0){
296  rho1+=_comp[ic]->val(m)*_comp[ic]->channels().find(wave1)->second.C()*sqrt(_comp[ic]->channels().find(wave1)->second.ps(m));
297  }
298  if(_comp[ic]->channels().count(wave2)!=0){
299  rho2+=_comp[ic]->val(m)*_comp[ic]->channels().find(wave2)->second.C()*sqrt(_comp[ic]->channels().find(wave2)->second.ps(m));
300  }
301  }
302  return rho1*conj(rho2)*_phasespace->Eval(m);
303 }
304 
305 std::complex<double>
306 rpwa::pwacompset::overlap(unsigned int wave1,
307  unsigned int wave2,
308  double m){
309  // loop over all components and pick up those that contribute to this channels
310  complex<double> rho1(0,0);
311  complex<double> rho2(0,0);
312 
313  // get entry from mapping
314  vector<pair<unsigned int, unsigned int> > cc1=_compChannel[wave1];
315  vector<pair<unsigned int, unsigned int> > cc2=_compChannel[wave2];
316  unsigned int nc1=cc1.size();
317  unsigned int nc2=cc2.size();
318 
319  for(unsigned int ic1=0;ic1<nc1;++ic1){
320  unsigned int icomp=cc1[ic1].first;
321  unsigned int ichan=cc1[ic1].second;
322  rho1+=_comp[icomp]->val(m)*_comp[icomp]->getChannel(ichan).CsqrtPS(m);
323  }
324  for(unsigned int ic2=0;ic2<nc2;++ic2){
325  unsigned int icomp=cc2[ic2].first;
326  unsigned int ichan=cc2[ic2].second;
327  rho2+=_comp[icomp]->val(m)*_comp[icomp]->getChannel(ichan).CsqrtPS(m);
328  }
329  return rho1*conj(rho2)*_phasespace->Eval(m);
330 }
331 
332 
333 std::vector<std::pair<unsigned int,unsigned int> >
334 rpwa::pwacompset::getCompChannel(const std::string& wave) const {
335  cerr << "Channel-mapping for wave " << wave << endl;
336  std::vector<std::pair<unsigned int,unsigned int> > result;
337  for(unsigned int ic=0;ic<n();++ic){
338  // loop over channels of component and see if wave is there
339  unsigned int nch=_comp[ic]->numChannels();
340  for(unsigned int ich=0;ich<nch;++ich){
341  if(_comp[ic]->getChannelName(ich)==wave){
342  result.push_back(pair<unsigned int,unsigned int>(ic,ich));
343  cerr << " comp("<<ic<<"): " << _comp[ic]->name() << " ch:"<<ich<<endl;
344  }
345  } // end loop over channels
346  } // end loop over components
347  return result;
348 }
349 
350 std::ostream& rpwa::operator<< (std::ostream& o,const rpwa::pwacomponent& c){
351  o << c.name() << endl
352  << "Mass= " << c.m0() << " Width="<< c.gamma() << " ConstWidth="<< c. constWidth() << endl
353  << "Decay modes: " << endl;
354  std::map<std::string,pwachannel >::const_iterator it=c.channels().begin();
355  while(it!=c.channels().end()){
356  o << it->first << " C=" << it->second.C() << endl;
357  ++it;
358  }
359 
360  return o;
361 }
362 
363 
364 
365 
366 
367 
368 std::ostream& rpwa::operator<< (std::ostream& out,const rpwa::pwacompset& cs){
369  for(unsigned int i=0;i<cs.n();++i){
370  const rpwa::pwacomponent& c =*cs[i];
371  out << c << endl;
372  }
373  return out;
374 }