ROOTPWA
isobarCanonicalAmplitude.cc
Go to the documentation of this file.
1 
2 //
3 // Copyright 2010
4 //
5 // This file is part of rootpwa
6 //
7 // rootpwa is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // rootpwa is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with rootpwa. If not, see <http://www.gnu.org/licenses/>.
19 //
21 //-------------------------------------------------------------------------
22 // File and Version Information:
23 // $Rev:: $: revision of last commit
24 // $Author:: $: author of last commit
25 // $Date:: $: date of last commit
26 //
27 // Description:
28 // general isobar decay amplitude in caninical formalism
29 //
30 //
31 // Author List:
32 // Boris Grube TUM (original author)
33 //
34 //
35 //-------------------------------------------------------------------------
36 
37 
38 #include <algorithm>
39 
40 #include "TLorentzRotation.h"
41 #include "TMath.h"
42 
43 #include "spinUtils.hpp"
44 #include "dFunction.hpp"
46 
47 
48 using namespace std;
49 using namespace boost;
50 using namespace rpwa;
51 
52 
53 bool isobarCanonicalAmplitude::_debug = false;
54 
55 
56 isobarCanonicalAmplitude::isobarCanonicalAmplitude()
57  : isobarAmplitude()
58 { }
59 
60 
62  : isobarAmplitude(decay)
63 { }
64 
65 
67 { }
68 
69 
70 void
72 {
73  // calculate Lorentz-vectors of all isobars
74  _decay->calcIsobarLzVec();
75  // modify event for testing purposes
76  if (_doSpaceInversion) {
78  // recalculate Lorentz-vectors of all isobars
79  _decay->calcIsobarLzVec();
80  }
81  if (_doReflection) {
82  reflectDecay();
83  // recalculate Lorentz-vectors of all isobars
84  _decay->calcIsobarLzVec();
85  }
86  // calculate Lorentz-transformations into the correct frames for the
87  // daughters in the decay vertices
88  // 1) transform daughters of all decay vertices into Gottfried-Jackson frame
89  const TLorentzVector& beamLv = _decay->productionVertex()->referenceLzVec();
90  const TLorentzVector& XLv = _decay->XParticle()->lzVec();
91  const TLorentzRotation gjTrans = gjTransform(beamLv, XLv);
92  for (unsigned int i = 0; i < _decay->nmbDecayVertices(); ++i) {
93  const isobarDecayVertexPtr& vertex = _decay->isobarDecayVertices()[i];
94  if (_debug)
95  printDebug << "transforming outgoing particles of vertex " << *vertex
96  << " into " << vertex->parent()->name() << " Gottfried-Jackson RF" << endl;
97  vertex->transformOutParticles(gjTrans);
98  }
99  // 2) transform daughters of isobar decay vertices to the respective rest frames
100  for (unsigned int i = 1; i < _decay->nmbDecayVertices(); ++i) { // exclude X-decay vertex
101  const isobarDecayVertexPtr& vertex = _decay->isobarDecayVertices()[i];
102  if (_debug)
103  printDebug << "transforming all child particles of vertex " << *vertex
104  << " into " << vertex->parent()->name() << " daughter RF" << endl;
105  // coordinate system does not change so this is just a simple Lorentz=boost
106  const TVector3 rfBoost = -vertex->parent()->lzVec().BoostVector();
107  // get all particles downstream of this vertex
108  decayTopologyGraphType subGraph = _decay->dfsSubGraph(vertex);
109  decayTopologyGraphType::edgeIterator iEd, iEdEnd;
110  for (tie(iEd, iEdEnd) = subGraph.edges(); iEd != iEdEnd; ++iEd) {
111  const particlePtr& part = subGraph.particle(*iEd);
112  if (_debug)
113  cout << " transforming " << part->name() << " into "
114  << vertex->parent()->name() << " RF" << endl;
115  part->transform(rfBoost);
116  }
117  }
118 }
119 
120 
121 // assumes that daughters were transformed into parent RF
122 complex<double>
124  const bool topVertex) const
125 {
126  if (_debug)
127  printDebug << "calculating two-body decay amplitude in canonical formalism "
128  << "for " << *vertex << endl;
129 
130  const particlePtr& parent = vertex->parent();
131  const particlePtr& daughter1 = vertex->daughter1();
132  const particlePtr& daughter2 = vertex->daughter2();
133 
134  // calculate Clebsch-Gordan coefficient for S-S coupling
135  const int s1 = daughter1->J();
136  const int m1 = daughter1->spinProj();
137  const int s2 = daughter2->J();
138  const int m2 = daughter2->spinProj();
139  const int S = vertex->S();
140  const int mS = m1 + m2;
141  const double ssClebsch = clebschGordanCoeff<double>(s1, m1, s2, m2, S, mS, _debug);
142  if (ssClebsch == 0)
143  return 0;
144 
145  // calulate barrier factor
146  const int L = vertex->L();
147  const double q = daughter1->lzVec().Vect().Mag();
148  const double bf = barrierFactor(L, q, _debug);
149 
150  // calculate Breit-Wigner
151  const complex<double> bw = vertex->massDepAmplitude();
152 
153  // calculate normalization factor
154  const double norm = sqrt(fourPi); // this factor comes from the fact that the (PWA2000)
155  // helicity amplitude lacks a factor of 1 / sqrt(4 pi)
156 
157  // sum over all possible spin projections of L
158  const int J = parent->J();
159  const int M = parent->spinProj();
160  const int P = parent->P();
161  const int refl = parent->reflectivity();
162  const double phi = daughter1->lzVec().Phi(); // use daughter1 as analyzer
163  const double theta = daughter1->lzVec().Theta();
164  complex<double> amp = 0;
165  for (int mL = -L; mL <= L; mL += 2) {
166  // calculate Clebsch-Gordan coefficient for L-S coupling
167  double LSClebsch;
168  if (_useReflectivityBasis and topVertex) {
169  // symmetrize L-S coupling term
170  const int reflFactor = reflectivityFactor(J, P, M, refl);
171  if (M == 0) {
172  if (reflFactor == +1)
173  LSClebsch = 0;
174  else
175  LSClebsch = clebschGordanCoeff<double>(L, mL, S, mS, J, 0, _debug);
176  } else {
177  LSClebsch = 1 / rpwa::sqrt(2)
178  * ( clebschGordanCoeff<double>(L, mL, S, mS, J, +M, _debug)
179  - reflFactor * clebschGordanCoeff<double>(L, mL, S, mS, J, -M, _debug));
180  }
181  } else
182  LSClebsch = clebschGordanCoeff<double>(L, mL, S, mS, J, M, _debug);
183  if (LSClebsch == 0)
184  continue;
185  // multiply spherical harmonic
186  amp += LSClebsch * sphericalHarmonic<complex<double> >(L, mL, theta, phi, _debug);
187  }
188 
189  // calculate decay amplitude
190  amp *= norm * ssClebsch * bf * bw;
191 
192  if (_debug)
193  printDebug << "two-body decay amplitude = " << maxPrecisionDouble(amp) << endl;
194  return amp;
195 }