ROOTPWA
isobarHelicityAmplitude.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 helicity 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 isobarHelicityAmplitude::_debug = false;
54 
55 
56 isobarHelicityAmplitude::isobarHelicityAmplitude()
57  : isobarAmplitude()
58 { }
59 
60 
62  : isobarAmplitude(decay)
63 { }
64 
65 
67 { }
68 
69 
70 TLorentzRotation
71 isobarHelicityAmplitude::hfTransform(const TLorentzVector& daughterLv)
72 {
73  TLorentzVector daughter = daughterLv;
74  const TVector3 zAxisParent(0, 0, 1); // take z-axis as defined in parent frame
75  const TVector3 yHfAxis = zAxisParent.Cross(daughter.Vect()); // y-axis of helicity frame
76  // rotate so that yHfAxis becomes parallel to y-axis and zHfAxis ends up in (x, z)-plane
77  TRotation rot1;
78  rot1.RotateZ(piHalf - yHfAxis.Phi());
79  rot1.RotateX(yHfAxis.Theta() - piHalf);
80  daughter *= rot1;
81  // rotate about yHfAxis so that daughter momentum is along z-axis
82  TRotation rot2;
83  rot2.RotateY(-signum(daughter.X()) * daughter.Theta());
84  daughter *= rot2;
85  // boost to daughter RF
86  rot1.Transform(rot2);
87  TLorentzRotation hfTransform(rot1);
88  hfTransform.Boost(-daughter.BoostVector());
89  return hfTransform;
90 }
91 
92 
93 void
95 {
96  // calculate Lorentz-vectors of all isobars
97  _decay->calcIsobarLzVec();
98  // modify event for testing purposes
99  if (_doSpaceInversion) {
101  // recalculate Lorentz-vectors of all isobars
102  _decay->calcIsobarLzVec();
103  }
104  if (_doReflection) {
105  reflectDecay();
106  // recalculate Lorentz-vectors of all isobars
107  _decay->calcIsobarLzVec();
108  }
109  // calculate Lorentz-transformations into the correct frames for the
110  // daughters in the decay vertices
111  // 1) transform daughters of all decay vertices into Gottfried-Jackson frame
112  const TLorentzVector& beamLv = _decay->productionVertex()->referenceLzVec();
113  const TLorentzVector& XLv = _decay->XParticle()->lzVec();
114  const TLorentzRotation gjTrans = gjTransform(beamLv, XLv);
115  for (unsigned int i = 0; i < _decay->nmbDecayVertices(); ++i) {
116  const isobarDecayVertexPtr& vertex = _decay->isobarDecayVertices()[i];
117  if (_debug)
118  printDebug << "transforming outgoing particles of vertex " << *vertex
119  << " into " << vertex->parent()->name() << " Gottfried-Jackson RF" << endl;
120  vertex->transformOutParticles(gjTrans);
121  }
122  // 2) transform daughters of isobar decay vertices to the respective helicity frames
123  for (unsigned int i = 1; i < _decay->nmbDecayVertices(); ++i) { // exclude X-decay vertex
124  const isobarDecayVertexPtr& vertex = _decay->isobarDecayVertices()[i];
125  if (_debug)
126  printDebug << "transforming all child particles of vertex " << *vertex
127  << " into " << vertex->parent()->name() << " helicity RF" << endl;
128  const TLorentzRotation hfTrans = hfTransform(vertex->parent()->lzVec());
129  // get all particles downstream of this vertex
130  decayTopologyGraphType subGraph = _decay->dfsSubGraph(vertex);
131  decayTopologyGraphType::edgeIterator iEd, iEdEnd;
132  for (tie(iEd, iEdEnd) = subGraph.edges(); iEd != iEdEnd; ++iEd) {
133  const particlePtr& part = subGraph.particle(*iEd);
134  if (_debug)
135  cout << " transforming " << part->name() << " into "
136  << vertex->parent()->name() << " helicity RF" << endl;
137  part->transform(hfTrans);
138  }
139  }
140 }
141 
142 
143 // assumes that daughters were transformed into parent RF
144 complex<double>
146  const bool topVertex) const
147 {
148  if (_debug)
149  printDebug << "calculating two-body decay amplitude in helicity formalism for "
150  << *vertex << endl;
151 
152  const particlePtr& parent = vertex->parent();
153  const particlePtr& daughter1 = vertex->daughter1();
154  const particlePtr& daughter2 = vertex->daughter2();
155 
156  // calculate Clebsch-Gordan coefficient for L-S coupling
157  const int L = vertex->L();
158  const int S = vertex->S();
159  const int J = parent->J();
160  const int lambda1 = daughter1->spinProj();
161  const int lambda2 = daughter2->spinProj();
162  const int lambda = lambda1 - lambda2;
163  const double lsClebsch = clebschGordanCoeff<double>(L, 0, S, lambda, J, lambda, _debug);
164  if (lsClebsch == 0)
165  return 0;
166 
167  // calculate Clebsch-Gordan coefficient for S-S coupling
168  const int s1 = daughter1->J();
169  const int s2 = daughter2->J();
170  const double ssClebsch = clebschGordanCoeff<double>(s1, lambda1, s2, -lambda2, S, lambda, _debug);
171  if (ssClebsch == 0)
172  return 0;
173 
174  // calculate D-function
175  const int Lambda = parent->spinProj();
176  const int P = parent->P();
177  const int refl = parent->reflectivity();
178  const double phi = daughter1->lzVec().Phi(); // use daughter1 as analyzer
179  const double theta = daughter1->lzVec().Theta();
180  complex<double> DFunc;
181  if (topVertex and _useReflectivityBasis)
182  DFunc = DFunctionReflConj<complex<double> >(J, Lambda, lambda, P, refl, phi, theta, 0, _debug);
183  else
184  DFunc = DFunctionConj<complex<double> >(J, Lambda, lambda, phi, theta, 0, _debug);
185 
186  // calulate barrier factor
187  const double q = daughter1->lzVec().Vect().Mag();
188  const double bf = barrierFactor(L, q, _debug);
189 
190  // calculate Breit-Wigner
191  const complex<double> bw = vertex->massDepAmplitude();
192 
193  // calculate normalization factor
194  const double norm = angMomNormFactor(L, _debug);
195 
196  // calculate decay amplitude
197  complex<double> amp = norm * DFunc * lsClebsch * ssClebsch * bf * bw;
198 
199  if (_debug)
200  printDebug << "two-body decay amplitude = " << maxPrecisionDouble(amp) << endl;
201  return amp;
202 }