evtgen is hosted by Hepforge, IPPP Durham
EvtGen  2.0.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
EvtPartWave.cpp
Go to the documentation of this file.
1 
2 /***********************************************************************
3 * Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4 * *
5 * This file is part of EvtGen. *
6 * *
7 * EvtGen 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 * EvtGen 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 EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19 ***********************************************************************/
20 
22 
24 #include "EvtGenBase/EvtConst.hh"
25 #include "EvtGenBase/EvtGenKine.hh"
26 #include "EvtGenBase/EvtId.hh"
27 #include "EvtGenBase/EvtKine.hh"
28 #include "EvtGenBase/EvtPDL.hh"
30 #include "EvtGenBase/EvtPatches.hh"
31 #include "EvtGenBase/EvtReport.hh"
34 
35 #include <algorithm>
36 #include <stdlib.h>
37 #include <string>
38 using std::endl;
39 
40 std::string EvtPartWave::getName()
41 {
42  return "PARTWAVE";
43 }
44 
46 {
47  return new EvtPartWave;
48 }
49 
51 {
52  checkNDaug( 2 );
53 
54  //find out how many states each particle have
58 
59  if ( verbose() ) {
60  EvtGenReport( EVTGEN_INFO, "EvtGen" )
61  << "_nA,_nB,_nC:" << _nA << "," << _nB << "," << _nC << endl;
62  }
63 
64  //find out what 2 times the spin is
68 
69  if ( verbose() ) {
70  EvtGenReport( EVTGEN_INFO, "EvtGen" )
71  << "_JA2,_JB2,_JC2:" << _JA2 << "," << _JB2 << "," << _JC2 << endl;
72  }
73 
74  //allocate memory
75  int* _lambdaA2 = new int[_nA];
76  int* _lambdaB2 = new int[_nB];
77  int* _lambdaC2 = new int[_nC];
78 
79  EvtComplexPtr* _HBC = new EvtComplexPtr[_nB];
80  int ib, ic;
81  for ( ib = 0; ib < _nB; ib++ ) {
82  _HBC[ib] = new EvtComplex[_nC];
83  }
84 
85  int i;
86  //find the allowed helicities (actually 2*times the helicity!)
87 
88  fillHelicity( _lambdaA2, _nA, _JA2 );
89  fillHelicity( _lambdaB2, _nB, _JB2 );
90  fillHelicity( _lambdaC2, _nC, _JC2 );
91 
92  if ( verbose() ) {
93  EvtGenReport( EVTGEN_INFO, "EvtGen" )
94  << "Helicity states of particle A:" << endl;
95  for ( i = 0; i < _nA; i++ ) {
96  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << _lambdaA2[i] << endl;
97  }
98 
99  EvtGenReport( EVTGEN_INFO, "EvtGen" )
100  << "Helicity states of particle B:" << endl;
101  for ( i = 0; i < _nB; i++ ) {
102  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << _lambdaB2[i] << endl;
103  }
104 
105  EvtGenReport( EVTGEN_INFO, "EvtGen" )
106  << "Helicity states of particle C:" << endl;
107  for ( i = 0; i < _nC; i++ ) {
108  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << _lambdaC2[i] << endl;
109  }
110 
111  EvtGenReport( EVTGEN_INFO, "EvtGen" )
112  << "Will now figure out the valid (M_LS) states:" << endl;
113  }
114 
115  int Lmin = std::max( _JA2 - _JB2 - _JC2,
116  std::max( _JB2 - _JA2 - _JC2, _JC2 - _JA2 - _JB2 ) );
117  if ( Lmin < 0 )
118  Lmin = 0;
119  //int Lmin=_JA2-_JB2-_JC2;
120  int Lmax = _JA2 + _JB2 + _JC2;
121 
122  int L;
123 
124  int _nPartialWaveAmp = 0;
125 
126  int _nL[50];
127  int _nS[50];
128 
129  for ( L = Lmin; L <= Lmax; L += 2 ) {
130  int Smin = abs( L - _JA2 );
131  if ( Smin < abs( _JB2 - _JC2 ) )
132  Smin = abs( _JB2 - _JC2 );
133  int Smax = L + _JA2;
134  if ( Smax > abs( _JB2 + _JC2 ) )
135  Smax = abs( _JB2 + _JC2 );
136  int S;
137  for ( S = Smin; S <= Smax; S += 2 ) {
138  _nL[_nPartialWaveAmp] = L;
139  _nS[_nPartialWaveAmp] = S;
140 
141  _nPartialWaveAmp++;
142  if ( verbose() ) {
143  EvtGenReport( EVTGEN_INFO, "EvtGen" )
144  << "M[" << L << "][" << S << "]" << endl;
145  }
146  }
147  }
148 
149  checkNArg( _nPartialWaveAmp * 2 );
150 
151  int argcounter = 0;
152 
153  EvtComplex _M[50];
154 
155  double partampsqtot = 0.0;
156 
157  for ( i = 0; i < _nPartialWaveAmp; i++ ) {
158  _M[i] = getArg( argcounter ) *
159  exp( EvtComplex( 0.0, getArg( argcounter + 1 ) ) );
160  ;
161  argcounter += 2;
162  partampsqtot += abs2( _M[i] );
163  if ( verbose() ) {
164  EvtGenReport( EVTGEN_INFO, "EvtGen" )
165  << "M[" << _nL[i] << "][" << _nS[i] << "]=" << _M[i] << endl;
166  }
167  }
168 
169  //Now calculate the helicity amplitudes
170 
171  double helampsqtot = 0.0;
172 
173  for ( ib = 0; ib < _nB; ib++ ) {
174  for ( ic = 0; ic < _nC; ic++ ) {
175  _HBC[ib][ic] = 0.0;
176  if ( abs( _lambdaB2[ib] - _lambdaC2[ic] ) <= _JA2 ) {
177  for ( i = 0; i < _nPartialWaveAmp; i++ ) {
178  int L = _nL[i];
179  int S = _nS[i];
180  int lambda2 = _lambdaB2[ib];
181  int lambda3 = _lambdaC2[ic];
182  int s1 = _JA2;
183  int s2 = _JB2;
184  int s3 = _JC2;
185  int m1 = lambda2 - lambda3;
186  EvtCGCoefSingle c1( s2, s3 );
187  EvtCGCoefSingle c2( L, S );
188 
189  if ( verbose() ) {
190  EvtGenReport( EVTGEN_INFO, "EvtGen" )
191  << "s2,lambda2:" << s2 << " " << lambda2 << endl;
192  }
193  //fkw changes to satisfy KCC
194  double fkwTmp = ( L + 1.0 ) / ( s1 + 1.0 );
195 
196  if ( S >= abs( m1 ) ) {
197  EvtComplex tmp = sqrt( fkwTmp ) *
198  c1.coef( S, m1, s2, s3, lambda2,
199  -lambda3 ) *
200  c2.coef( s1, m1, L, S, 0, m1 ) * _M[i];
201  _HBC[ib][ic] += tmp;
202  }
203  }
204  if ( verbose() ) {
205  EvtGenReport( EVTGEN_INFO, "EvtGen" )
206  << "_HBC[" << ib << "][" << ic << "]=" << _HBC[ib][ic]
207  << endl;
208  }
209  }
210  helampsqtot += abs2( _HBC[ib][ic] );
211  }
212  }
213 
214  if ( fabs( helampsqtot - partampsqtot ) / ( helampsqtot + partampsqtot ) >
215  1e-6 ) {
216  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
217  << "In EvtPartWave for decay " << EvtPDL::name( getParentId() )
218  << " -> " << EvtPDL::name( getDaug( 0 ) ) << " "
219  << EvtPDL::name( getDaug( 1 ) ) << std::endl;
220  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "With arguments: " << std::endl;
221  for ( i = 0; i * 2 < getNArg(); i++ ) {
222  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
223  << "M(" << _nL[i] << "," << _nS[i]
224  << ")="
225  // <<getArg(2*i)<<" "<<getArg(2*i+1)<<std::endl;
226  << _M[i] << std::endl;
227  }
228  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
229  << "The total probability in the partwave basis is: " << partampsqtot
230  << std::endl;
231  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
232  << "The total probability in the helamp basis is: " << helampsqtot
233  << std::endl;
234  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
235  << "Most likely this is because the specified partwave amplitudes "
236  << std::endl;
237  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
238  << "project onto unphysical helicities of photons or neutrinos. "
239  << std::endl;
240  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
241  << "Seriously consider if your specified amplitudes are correct. "
242  << std::endl;
243  }
244 
245  _evalHelAmp = std::make_unique<EvtEvalHelAmp>( getParentId(), getDaug( 0 ),
246  getDaug( 1 ), _HBC );
247 }
248 
250 {
251  double maxprob = _evalHelAmp->probMax();
252 
253  if ( verbose() ) {
254  EvtGenReport( EVTGEN_INFO, "EvtGen" )
255  << "Calculated probmax" << maxprob << endl;
256  }
257 
258  setProbMax( maxprob );
259 }
260 
262 {
263  //first generate simple phase space
265 
266  _evalHelAmp->evalAmp( p, _amp2 );
267 
268  return;
269 }
270 
271 void EvtPartWave::fillHelicity( int* lambda2, int n, int J2 )
272 {
273  int i;
274 
275  //photon is special case!
276  if ( n == 2 && J2 == 2 ) {
277  lambda2[0] = 2;
278  lambda2[1] = -2;
279  return;
280  }
281 
282  assert( n == J2 + 1 );
283 
284  for ( i = 0; i < n; i++ ) {
285  lambda2[i] = n - i * 2 - 1;
286  }
287 
288  return;
289 }
void init() override
Definition: EvtPartWave.cpp:50
static std::string name(EvtId i)
Definition: EvtPDL.cpp:382
EvtDecayBase * clone() override
Definition: EvtPartWave.cpp:45
void decay(EvtParticle *p) override
double getArg(unsigned int j)
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
std::unique_ptr< EvtEvalHelAmp > _evalHelAmp
Definition: EvtPartWave.hh:49
void fillHelicity(int *lambda2, int n, int J2)
double abs2(const EvtComplex &c)
Definition: EvtComplex.hh:209
static int getSpinStates(spintype stype)
Definition: EvtSpinType.cpp:57
std::string getName() override
Definition: EvtPartWave.cpp:40
EvtId * getDaugs()
Definition: EvtDecayBase.hh:66
void setProbMax(double prbmx)
EvtId getParentId() const
Definition: EvtDecayBase.hh:61
double initializePhaseSpace(unsigned int numdaughter, EvtId *daughters, bool forceResetMasses=false, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
void initProbMax() override
void checkNDaug(int d1, int d2=-1)
double coef(int J, int M, int j1, int j2, int m1, int m2)
void checkNArg(int a1, int a2=-1, int a3=-1, int a4=-1)
double abs(const EvtComplex &c)
Definition: EvtComplex.hh:201
static int getSpin2(spintype stype)
Definition: EvtSpinType.cpp:26
int getNDaug() const
Definition: EvtDecayBase.hh:65
EvtComplex exp(const EvtComplex &c)
Definition: EvtComplex.hh:240
int verbose() const
Definition: EvtDecayBase.hh:82
EvtAmp _amp2
Definition: EvtDecayAmp.hh:73
int getNArg() const
Definition: EvtDecayBase.hh:68
EvtId getDaug(int i) const
Definition: EvtDecayBase.hh:67