ROOTPWA
pwa2000/libpp/particle.cc
Go to the documentation of this file.
1 #include <sstream>
2 
3 #include "massDep.h"
4 #include "matrix.h"
5 
6 #include "event.h"
7 #include "particle.h"
8 
9 
10 using namespace std;
11 
12 
13 #define MAXPRECISION(val) setprecision(numeric_limits<double>::digits10 + 1) << val
14 
15 
17 int decay::_decay_debug = 0;
18 
19 
21  : particleData(),
22  _lambda (0),
23  _charge (0),
24  _p (fourVec(0, threeVec(0,0,0))),
25  _decay (NULL),
26  _index (0),
27  _inRestFrame(0),
28  _massDep (NULL)
29 {
30  if (_particle_debug)
31  cout << "in particle(" << this << ")::particle()" << endl;
32 }
33 
34 
36  : particleData(p)
37 {
38  if (_particle_debug)
39  cout << "in particle(" << this << ")::particle(const particle& part("
40  << &p << ")=" << p.Name() << ")" << endl;
41  _lambda = p._lambda;
42  _charge = p._charge;
43  _p = p._p;
44  if (p._decay)
45  _decay = new decay(*(p._decay));
46  else
47  _decay = NULL;
48  _index = p._index;
51  if (p._massDep)
52  _massDep = p._massDep->clone();
53  else
54  _massDep = NULL;
55 }
56 
57 
59  const int charge)
60  : particleData(data),
61  _lambda (0),
62  _charge (charge),
63  _p (fourVec(0, threeVec(0,0,0))),
64  _decay (NULL),
65  _index (0),
66  _inRestFrame(0),
67  _massDep (NULL)
68 {
69  if (_particle_debug)
70  cout << "in particle(" << this << ")::particle(const particleData& data("
71  << &data << ")=" << data.Name() << ", int c)" << endl;
72 }
73 
74 
76 {
77  if (_particle_debug)
78  cout << "in particle((" << this << ")=" << Name() << ")::~particle()" << endl;
79  delete _decay;
80  delete _massDep;
81 }
82 
83 
84 particle&
86 {
87  if (_particle_debug)
88  cout << "in particle(" << this << ")::operator=(const particle& particle("
89  << &p << ")=" << p.Name() << ")" << endl;
90  if (this != &p) {
92  _charge = p._charge;
93  _p = p._p;
94  _index = p._index;
95  _lambda = p._lambda;
98  delete _decay;
99  if (p._decay)
100  _decay = new decay(*(p._decay));
101  else
102  _decay = NULL;
103  delete _massDep;
104  if (p._massDep) {
105  _massDep = p._massDep->clone();
106  } else
107  _massDep = NULL;
108  }
109  return *this;
110 }
111 
112 
113 particle&
115 {
116  _p *= L;
117  if (_decay)
118  *_decay *= L;
119  return *this;
120 }
121 
122 
123 particle
125  const particle& p)
126 {
127  particle part = p;
128  part._p *= L;
129  return part;
130 }
131 
132 
133 particle&
134 particle::setCharge(const int charge)
135 {
136  _charge = charge;
137  return *this;
138 }
139 
140 
141 particle&
143 {
144  _p = p4;
145  return *this;
146 }
147 
148 
149 particle&
151 {
152  _p = fourVec(sqrt(p3.lenSq() + Mass() * Mass()), p3);
153  return *this;
154 }
155 
156 
157 particle&
158 particle::Index(const int i)
159 {
160  _index = i;
161  return *this;
162 }
163 
164 
165 particle&
167 {
168  if (_decay)
169  delete _decay;
170  _decay = new decay(d);
171  return *this;
172 }
173 
174 
175 particle&
177 {
178  _massDep = md;
179  return *this;
180 }
181 
182 
183 fourVec*
185  const int debug)
186 {
187  fourVec* ret = NULL;
188  if ( (Name() == part->Name())
189  && (Charge() == part->Charge())
190  && (Index() == part->Index())) {
191  if (debug)
192  cout << "found particle " << part->Name() << part->Charge() << "[" << part->Index()
193  << "]" << endl << "returning fourVec:" << ret << endl;
194  ret = new fourVec(_p);
195  } else if (_decay) {
196  if (debug)
197  cout << "I'm a " << Name() << Charge() << "[" << Index() << "]" << endl
198  << "not a " << part->Name() << part->Charge() << "[" << part->Index() << "]" << endl
199  << "checking my children..." << endl;
200  ret = _decay->get4P(part, debug);
201  }
202  return ret;
203 }
204 
205 
206 list<int>&
208 {
209  if (_helicities.size() == 0)
210  for (int lam = -J(); lam <= J(); lam += 2)
211  _helicities.push_back(lam);
212  return(_helicities);
213 }
214 
215 
216 particle&
217 particle::addHelicity(const int lam)
218 {
219  _helicities.push_back(lam);
220  return *this;
221 }
222 
223 
224 int
225 particle::is(const string& name) const
226 {
227  if (Name() == name)
228  return 1;
229  else
230  return 0;
231 }
232 
233 
234 fourVec
236 {
237  fourVec ret;
238  if (_decay) {
239  if (debug) {
240  cout << "put " << Name() << Charge() << "[" << Index () << "]"
241  << " into helicity frame:" << endl << "momentum: ";
242  _p.print ();
243  }
244 
245  // i should be in my parents rest frame when this is called
246  // so this->_p.get3P() should be a breakup momentum
247  ret = _p;
248 
249  fourVec tempP = _p;
250 
251  // make y perpendicular to z_old and p
252  const threeVec normal = threeVec(0, 0, 1) / tempP.V();
254  rotation R;
255  T.set(R.set(normal.phi(), normal.theta() - M_PI / 2, -M_PI / 2));
256  lorentzTransform L = T;
257  tempP *= T;
258 
259  // make z_new parallel to p
260  T.set(R.set(0, signof(tempP.x()) * tempP.theta(), 0));
261  matrix<double> X(4, 4);
262  X = T * L;
263  L = lorentzTransform(X);
264  tempP *= T;
265 
266  // boost into p rest frame
267  T.set(tempP);
268  X = T * L;
269  L = lorentzTransform(X);
270  tempP *= T;
271 
272  _decay->setupFrames(L, debug);
273  _inRestFrame = 1;
274  } else {
275  if (debug)
276  cout << "found stable particle " << Name() << Charge() << "[" << Index() << "]" << endl;
277  ret = _p;
278  }
279  return ret;
280 }
281 
282 
283 double
284 particle::q() const
285 {
286  list<particle>::const_iterator child = _decay->_children.begin();
287 
288  if (_inRestFrame)
289  return ~(child->get3P());
290  else {
291  assert(_decay->_children.size() == 2);
292  const particle& child1 = *child;
293  ++child;
294  const particle& child2 = *child;
295  const double Msq = _p.lenSq();
296  const double m1sq = child1.get4P().lenSq();
297  const double m2sq = child2.get4P().lenSq();
298  const double lam = lambda(Msq, m1sq, m2sq);
299  return sqrt(fabs(lam / (4 * Msq)));
300  }
301 }
302 
303 
304 double
306 {
307  list<particle>::const_iterator child = _decay->_children.begin();
308 
309  assert(_decay->_children.size() == 2);
310  const particle& child1 = *child;
311  child++;
312  const particle& child2 = *child;
313  const double Msq = Mass() * Mass();
316  const double m1sq = child1.get4P().lenSq();
317  const double m2sq = child2.get4P().lenSq();
318  // const double m1sq = child1.Mass() * child1.Mass();
319  // const double m2sq = child2.Mass() * child2.Mass();
320  const double lam = lambda(Msq, m1sq, m2sq);
321  return sqrt(fabs(lam / (4 * Msq))); // the fabs is probably wrong
322 }
323 
324 
325 string
326 particle::sprint(const string& space) const
327 {
328  stringstream s;
329  s << Name() << chargetos(Charge()) << "[" << _index << "]";
330  if (_decay) {
331  s << space << "{";
332  for (list<particle>::const_iterator i = _decay->_children.begin();
333  i != _decay->_children.end(); ++i)
334  s << space << i->sprint(space);
335  s << space << _decay->L() << space << _decay->S() << space << "}";
336  }
337  return s.str();
338 }
339 
340 
341 complex<double>
343 {
344  const double m0 = Mass();
345  const double Gamma0 = Width();
346  const double q = this->q();
347  const double q0 = this->q0();
348  const double m = ~(get4P());
349  const int l = _decay->L();
350  const double GammaV = Gamma0 * (m0 / m) * (q / q0) * (pow (F (l, q), 2) / pow (F (l, q0), 2));
351  const complex<double> i = complex < double >(0, 1);
352  const complex<double> ret = (m0 * Gamma0) / (m0 * m0 - m * m - i * m0 * GammaV);
353  return ret;
354 }
355 
356 
357 complex<double>
359  const int debug)
360 {
361  complex<double> a, bw;
362  if (Stable())
363  a = 1;
364  else {
365  bw = _massDep->val(*this);
366  if (debug) {
367  ptab();
368  cout << "calculate decay amplitude for " << Name() << Charge() << "[" << Index() << "] "
369  << "{bw=" << MAXPRECISION(bw) << "}" << endl;
370  }
371  a = _decay->amp(J(), lambda, debug) * bw;
372  }
373  if (debug) {
374  ptab();
375  cout << Name() << " decay amp = " << a << endl;
376  }
377  return a;
378 }
379 
380 
381 void
383 {
385  ptab();
386  cout << "charge: " << _charge << "\tid: " << _index << endl;
387  ptab();
388  cout << "momentum: ";
389  _p.print();
390  if (_decay) {
391  addtab();
392  cout << "mass dependance: ";
393  _massDep->print();
394  cout << endl;
395  _decay->print();
396  subtab();
397  }
398 }
399 
400 
401 void
403 {
405  ptab();
406  cout << "charge: " << _charge << "\tid: " << _index << endl;
407  ptab();
408  cout << "momentum: ";
409  _p.print();
410  if (_decay) {
411  addtab();
412  _decay->printFrames();
413  subtab();
414  }
415 }
416 
417 
418 
419 
421  : _l(0),
422  _s(0)
423 {
424 }
425 
426 
427 void
428 decay::_init(const list<particle>& children,
429  const int l,
430  const int s,
431  const double mass)
432 {
433  _children = children;
434  _l = l;
435  _s = s;
436  _mass = mass;
437 }
438 
439 
441 {
442  if (_decay_debug)
443  cout << "in decay(" << this << ")::decay(const decay& d)" << endl;
444  _init(d._children, d._l, d._s, d._mass);
445 }
446 
447 
449 {
450  if (_decay_debug)
451  cout << "in decay(" << this << ")::~decay()" << endl;
452 }
453 
454 
455 decay&
457 {
458  _children.push_back(p);
459  return *this;
460 }
461 
462 
463 decay&
464 decay::setL(const int l)
465 {
466  _l = l;
467  return *this;
468 }
469 
470 
471 decay&
472 decay::setS(const int s)
473 {
474  _s = s;
475  return *this;
476 }
477 
478 
479 decay&
481 {
482  list<particle>::const_iterator child = _children.begin();
483  int spin = 0;
484  int numNonZero = 0;
485  while (child != _children.end()) {
486  if (child->J() != 0) {
487  spin += child->J();
488  numNonZero++;
489  }
490  child++;
491  }
492  if (numNonZero > 1) {
493  cerr << "final state spin is undetermined in decay: " << endl;
494  print();
495  exit(1);
496  }
497  _s = spin;
498  return *this;
499 }
500 
501 
502 decay&
504 {
505  if (_decay_debug)
506  cout << "in decay(" << this << ")::operator=(const decay& d)" << endl;
507  _init(d._children, d._l, d._s, d._mass);
508  return *this;
509 }
510 
511 
512 decay&
514 {
515  for (list<particle>::iterator i = _children.begin(); i != _children.end(); ++i)
516  *i *= L;
517  return *this;
518 }
519 
520 
521 fourVec*
523  const int debug)
524 {
525  if (debug)
526  cout << "looking for " << part->Name() << endl;
527  list<particle>::iterator child = _children.begin();
528  fourVec* p = NULL;
529  while (child != _children.end()) {
530  if (debug)
531  cout << "checking against " << child->Name() << endl;
532  p = child->get4P(part, debug);
533  if (p != NULL) {
534  if (debug)
535  cout << "found it! " << child->Name() << " == " << part->Name() << endl;
536  break;
537  }
538  ++child;
539  }
540  return p;
541 }
542 
543 
544 fourVec
546  const int debug)
547 {
548  fourVec p;
549  for (list<particle>::iterator i = _children.begin(); i != _children.end(); ++i) {
550  fourVec v;
551  if (i->Stable()) {
552  if (debug)
553  cout << "Found stable particle " << i->Name() << endl;
554  v = e.getPartPFinal(i->Name(), i->Charge(), i->Index(), debug);
555  } else {
556  if (debug)
557  cout << "Found unstable particle " << i->Name() << endl
558  << "Calling fill for " << i->Name() << endl;
559  v = i->Decay()->fill(e, debug);
560  }
561  if (debug) {
562  cout << "Setting p of " << i->Name() << " to:"<< endl;
563  v.print();
564  }
565  i->set4P(v);
566  p += v;
567  }
568  return p;
569 }
570 
571 
572 decay&
574  const int debug)
575 {
576  // boost children into correct frame
577  list<particle>::iterator child = _children.begin();
578  while (child != _children.end() ) {
579  if (debug) {
580  cout << "boosting child (" << child->Name() << ") into correct frame" << endl
581  << "p before: " << endl;
582  child->get4P().print();
583  }
584  *child *= T;
585  if (debug) {
586  cout << "p after: " << endl;
587  child->get4P().print();
588  }
589  ++child;
590  }
591 
592  // setup decay for children
593  fourVec p(0, threeVec(0, 0, 0));
594  child = _children.begin();
595  while (child != _children.end() ) {
596  p += child->setupFrames(debug);
597  ++child;
598  }
599  _mass = ~p;
600 
601  if (debug) {
602  child = _children.begin();
603  cout << "decay mass: " << _mass << endl
604  << "decay analyzer: " << child->Name() << child->Charge() << "[" << child->Index() << "]"
605  << endl << "decay angles: theta: " << child->get3P().theta() << " "
606  << "phi: " << child->get3P().phi() << endl;
607  }
608 
609  return *this;
610 }
611 
612 
613 complex<double>
614 decay::expt_amp(const double b,
615  const double t,
616  const int debug)
617 {
618  assert(b >= 0);
619 
620  list<particle>::iterator child = _children.begin();
621  particle& child1 = *child;
622  ++child;
623  particle& child2 = *child;
624  const int s1 = child1.J();
625  const int s2 = child2.J();
626  const list<int> helicities1 = child1.helicities();
627  const list<int> helicities2 = child2.helicities();
628  //const particle& analyzer = child1;
629 
630  addtab();
631  if (debug) {
632  ptab();
633  cout << "My children are: " << child1.Name() << " and " << child2.Name() << endl;
634  ptab();
635  cout << "My childrens spins are: " << s1 << " and " << s2 << endl;
636  ptab();
637  cout << "child1's helicity list is " << helicities1.size() << " elements long" << endl;
638  ptab();
639  cout << "child1's helicities are: ";
640  list<int>::const_iterator i = helicities1.begin();
641  while (i != helicities1.end()) {
642  cout << *i << " ";
643  ++i;
644  }
645  cout << endl;
646  ptab();
647  cout << "child2's helicity list is " << helicities2.size() << " elements long" << endl;
648  ptab();
649  cout << "child2's helicities are: ";
650  i = helicities2.begin();
651  while (i != helicities2.end()) {
652  cout << *i << " ";
653  ++i;
654  }
655  cout << endl;
656  }
657 
658  // calculate my amplitude
659  complex<double> amp = 0;
660  list<int>::const_iterator lambda1 = helicities1.begin();
661  while (lambda1 != helicities1.end()) {
662  list<int>::const_iterator lambda2 = helicities2.begin();
663  while (lambda2 != helicities2.end()) {
664  if (debug) {
665  ptab();
666  cout << "lambda1: " << *lambda1 << " lambda2: " << *lambda2 << endl;
667  cout << "exp(-" << b << "|" << t << "|)" << endl;
668  }
669  complex<double> a = complex<double>(exp(-(b / 2.0) * fabs(t)), 0.0);
670  if (debug) {
671  ptab();
672  cout << "a = " << a << endl;
673  ptab();
674  cout << "calculating amp for " << child1.Name() << endl;
675  }
676  a *= child1.decayAmp(*lambda1, debug);
677  if (debug) {
678  ptab();
679  cout << "a *= child1.decayAmp = " << a << endl;
680  ptab();
681  cout << "calculating amp for " << child2.Name() << endl;
682  }
683  a *= child2.decayAmp(*lambda2, debug);
684  if (debug) {
685  ptab();
686  cout << "a *= child2.decayAmp = " << a << endl;
687  ptab();
688  cout << "PLUS" << endl;
689  }
690  amp += a;
691  if (debug) {
692  ptab();
693  cout << "amp += a = " << amp << endl;
694  }
695  ++lambda2;
696  }
697  ++lambda1;
698  }
699  subtab();
700  return amp;
701 }
702 
703 
704 complex<double>
705 decay::amp(const int j,
706  const int m,
707  const int debug)
708 {
709  assert(j >= 0);
710  assert(m <= j);
711 
712  list<particle>::iterator child = _children.begin();
713  particle& child1 = *child;
714  ++child;
715  particle& child2 = *child;
716  const int s1 = child1.J();
717  const int s2 = child2.J();
718  const list<int> helicities1 = child1.helicities();
719  const list<int> helicities2 = child2.helicities();
720  const particle& analyzer = child1;
721 
722  addtab();
723  if (debug) {
724  ptab();
725  cout << "My children are: " << child1.Name() << " and " << child2.Name() << endl;
726  ptab();
727  cout << "My childrens spins are: " << s1 << " and " << s2 << endl;
728  ptab();
729  cout << "child1's helicity list is " << helicities1.size() << " elements long" << endl;
730  ptab();
731  cout << "child1's helicities are: ";
732  list<int>::const_iterator i = helicities1.begin();
733  while (i != helicities1.end()) {
734  cout << *i << " ";
735  ++i;
736  }
737  cout << endl;
738  ptab();
739  cout << "child2's helicity list is " << helicities2.size() << " elements long" << endl;
740  ptab();
741  cout << "child2's helicities are: ";
742  i = helicities2.begin();
743  while (i != helicities2.end()) {
744  cout << *i << " ";
745  ++i;
746  }
747  cout << endl;
748  }
749 
750  // calculate my amplitude
751  complex<double> amp = 0;
752  list<int>::const_iterator lambda1 = helicities1.begin();
753  while (lambda1 != helicities1.end()) {
754  list<int>::const_iterator lambda2 = helicities2.begin();
755  while (lambda2 != helicities2.end()) {
756  const int lambda = *lambda1 - *lambda2;
757  if (abs(lambda) <= j) {
758  if (debug) {
759  ptab();
760  cout << "lambda1: " << *lambda1 << " lambda2: " << *lambda2 << endl;
761  }
762  double phi = 0;
763  double theta = 0;
764  if (_children.size() == 2) {
765  phi = analyzer.get3P().phi();
766  theta = analyzer.get3P().theta();
767  } else if (_children.size() == 3) {
768  // omega case, use normal to decay plane
769  const threeVec normal = child1.get3P() / child2.get3P();
770  phi = normal.phi();
771  theta = normal.theta();
772  }
773  const double tildeFactor = tilde(_l);
774  const complex<double> df = conj(D(phi, theta, 0, j, m, lambda));
775  const double CGcoefficient1 = clebsch(_l, _s, j, 0, lambda, lambda);
776  const double CGcoefficient2 = clebsch(s1, s2, _s, *lambda1, -*lambda2, lambda);
777  double barrierFactor = 1;
778  double lambdaFactor = 1;
779  if (_children.size() == 2) {
780  barrierFactor = F(_l, ~(analyzer.get3P()));
781  lambdaFactor = 1;
782  } else if (_children.size() == 3) {
783  // omega case
784  // instead of barrier factor use lambda factor
785  particle piZero, piPlus, piMinus;
786  child = _children.begin();
787  while (child != _children.end()) {
788  if (child->is("pi0"))
789  piZero = *child;
790  else if (child->is("pi")) {
791  switch (child->Charge()) {
792  case -1:
793  piMinus = *child;
794  break;
795  case 1:
796  piPlus = *child;
797  break;
798  default:
799  cerr << "bad child for omega: "
800  << child->Name() << endl;
801  }
802  } else {
803  cerr << "bad child for omega: "
804  << child->Name() << endl;
805  }
806  ++child;
807  }
808  if (debug) {
809  ptab();
810  cout << "calculate sqrt(lambda)" << endl;
811  ptab();
812  cout << "P_pi+: " << piPlus.get3P() << endl;
813  ptab();
814  cout << "P_pi-: " << piMinus.get3P() << endl;
815  ptab();
816  cout << "| P_pi+ X P_pi- |: " << (piPlus.get3P() / piMinus.get3P()).len() << endl;
817  ptab();
818  cout << "M(pi^+ pi^- pi^0): " << _mass << endl;
819  ptab();
820  cout << "M(pi^-): " << piMinus.get4P().lenSq() << endl;
821  ptab();
822  cout << "numerator: " << (piPlus.get3P() / piMinus.get3P()).len() << endl;
823  ptab();
824  cout << "denominator: "
825  << sqrt(3.0 / 4.0) * (pow(_mass / 3.0, 2.0) - piMinus.get4P().lenSq()) << endl;
826  }
827  lambdaFactor = (piPlus.get3P() / piMinus.get3P()).len()
828  / (sqrt(3.0 / 4.0) * (pow(_mass / 3.0, 2.0) - piMinus.get4P().lenSq()));
829  barrierFactor = 1;
830  }
831 
832  if (debug) {
833  ptab();
834  cout << "tilde(" << _l << "){=" << MAXPRECISION(tildeFactor) << "}"
835  << "D[" << j << ", " << m << ", " << lambda << "]"
836  << "(" << phi << ", " << theta << ", 0){=" << MAXPRECISION(df) << "}"
837  << "( " << _l << " 0 " << _s << " " << lambda
838  << " | " << j << " " << lambda << " ){=" << MAXPRECISION(CGcoefficient1) << "}"
839  << "( " << s1 << " " << *lambda1 << " " << s2 << " " << -*lambda2
840  << " | " << _s << " " << lambda << " ){=" << MAXPRECISION(CGcoefficient2) << "}"
841  << "F_" << _l << "(" << ~(analyzer.get3P()) << "){=" << MAXPRECISION(barrierFactor)
842  << "}sqrt(lambda)" << "{=" << MAXPRECISION(lambdaFactor) << "}"
843  << "Delta(" << _mass << ")"
844  << endl;
845  }
846  complex<double> a = tildeFactor * df * CGcoefficient1 * CGcoefficient2
847  * barrierFactor * lambdaFactor;
848  if (debug) {
849  ptab();
850  cout << "a = " << MAXPRECISION(a) << endl;
851  ptab();
852  cout << "calculating amp for " << child1.Name() << endl;
853  }
854  a *= child1.decayAmp(*lambda1, debug);
855  if (debug) {
856  ptab();
857  cout << "a *= child1.decayAmp = " << a << endl;
858  ptab();
859  cout << "calculating amp for " << child2.Name() << endl;
860  }
861  a *= child2.decayAmp(*lambda2, debug);
862  if (debug) {
863  ptab();
864  cout << "a *= child2.decayAmp = " << a << endl;
865  ptab();
866  cout << "PLUS" << endl;
867  }
868  amp += a;
869  if (debug) {
870  ptab();
871  cout << "amp += a = " << amp << endl;
872  }
873  }
874  ++lambda2;
875  }
876  ++lambda1;
877  }
878  subtab();
879  return amp;
880 }
881 
882 
883 void
885 {
886  ptab();
887  cout << "children : {" << endl;
888  for (list<particle>::const_iterator i = _children.begin(); i != _children.end(); ++i)
889  i->print();
890  ptab();
891  cout << "L: " << _l << " S: " << _s << endl;
892  ptab();
893  cout << "}" << endl;
894 }
895 
896 
897 void
899 {
900  ptab();
901  cout << "i have " << _childrenInFrames.size() << " children." << endl;
902  ptab();
903  cout << "children in decay frame : {" << endl;
904  for (list<particle>::const_iterator i = _children.begin(); i != _children.end(); ++i)
905  i->printFrames();
906  ptab();
907  cout << "L: " << _l << " S: " << _s << endl;
908  ptab();
909  cout << "}" << endl;
910 }