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.
EvtEvalHelAmp.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 
23 #include "EvtGenBase/EvtAmp.hh"
24 #include "EvtGenBase/EvtConst.hh"
25 #include "EvtGenBase/EvtId.hh"
26 #include "EvtGenBase/EvtPDL.hh"
28 #include "EvtGenBase/EvtPatches.hh"
29 #include "EvtGenBase/EvtReport.hh"
32 
33 #include <stdlib.h>
34 using std::endl;
35 
37 {
38  //deallocate memory
39  delete[] _lambdaA2;
40  delete[] _lambdaB2;
41  delete[] _lambdaC2;
42 
43  int ia, ib, ic;
44  for ( ib = 0; ib < _nB; ib++ ) {
45  delete[] _HBC[ib];
46  }
47 
48  delete[] _HBC;
49 
50  for ( ia = 0; ia < _nA; ia++ ) {
51  delete[] _RA[ia];
52  }
53  delete[] _RA;
54 
55  for ( ib = 0; ib < _nB; ib++ ) {
56  delete[] _RB[ib];
57  }
58  delete[] _RB;
59 
60  for ( ic = 0; ic < _nC; ic++ ) {
61  delete[] _RC[ic];
62  }
63  delete[] _RC;
64 
65  for ( ia = 0; ia < _nA; ia++ ) {
66  for ( ib = 0; ib < _nB; ib++ ) {
67  delete[] _amp[ia][ib];
68  delete[] _amp1[ia][ib];
69  delete[] _amp3[ia][ib];
70  }
71  delete[] _amp[ia];
72  delete[] _amp1[ia];
73  delete[] _amp3[ia];
74  }
75 
76  delete[] _amp;
77  delete[] _amp1;
78  delete[] _amp3;
79 }
80 
82  EvtComplexPtrPtr HBC )
83 {
87 
88  //find out how many states each particle have
92 
93  //find out what 2 times the spin is
94  _JA2 = EvtSpinType::getSpin2( typeA );
95  _JB2 = EvtSpinType::getSpin2( typeB );
96  _JC2 = EvtSpinType::getSpin2( typeC );
97 
98  //allocate memory
99  _lambdaA2 = new int[_nA];
100  _lambdaB2 = new int[_nB];
101  _lambdaC2 = new int[_nC];
102 
103  _HBC = new EvtComplexPtr[_nB];
104  int ia, ib, ic;
105  for ( ib = 0; ib < _nB; ib++ ) {
106  _HBC[ib] = new EvtComplex[_nC];
107  }
108 
109  _RA = new EvtComplexPtr[_nA];
110  for ( ia = 0; ia < _nA; ia++ ) {
111  _RA[ia] = new EvtComplex[_nA];
112  }
113  _RB = new EvtComplexPtr[_nB];
114  for ( ib = 0; ib < _nB; ib++ ) {
115  _RB[ib] = new EvtComplex[_nB];
116  }
117  _RC = new EvtComplexPtr[_nC];
118  for ( ic = 0; ic < _nC; ic++ ) {
119  _RC[ic] = new EvtComplex[_nC];
120  }
121 
122  _amp = new EvtComplexPtrPtr[_nA];
123  _amp1 = new EvtComplexPtrPtr[_nA];
124  _amp3 = new EvtComplexPtrPtr[_nA];
125  for ( ia = 0; ia < _nA; ia++ ) {
126  _amp[ia] = new EvtComplexPtr[_nB];
127  _amp1[ia] = new EvtComplexPtr[_nB];
128  _amp3[ia] = new EvtComplexPtr[_nB];
129  for ( ib = 0; ib < _nB; ib++ ) {
130  _amp[ia][ib] = new EvtComplex[_nC];
131  _amp1[ia][ib] = new EvtComplex[_nC];
132  _amp3[ia][ib] = new EvtComplex[_nC];
133  }
134  }
135 
136  //find the allowed helicities (actually 2*times the helicity!)
137 
138  fillHelicity( _lambdaA2, _nA, _JA2, idA );
139  fillHelicity( _lambdaB2, _nB, _JB2, idB );
140  fillHelicity( _lambdaC2, _nC, _JC2, idC );
141 
142  for ( ib = 0; ib < _nB; ib++ ) {
143  for ( ic = 0; ic < _nC; ic++ ) {
144  _HBC[ib][ic] = HBC[ib][ic];
145  }
146  }
147 }
148 
150 {
151  double c = 1.0 / sqrt( 4 * EvtConst::pi / ( _JA2 + 1 ) );
152 
153  int ia, ib, ic;
154 
155  double theta;
156  int itheta;
157 
158  double maxprob = 0.0;
159 
160  for ( itheta = -10; itheta <= 10; itheta++ ) {
161  theta = acos( 0.099999 * itheta );
162  for ( ia = 0; ia < _nA; ia++ ) {
163  double prob = 0.0;
164  for ( ib = 0; ib < _nB; ib++ ) {
165  for ( ic = 0; ic < _nC; ic++ ) {
166  _amp[ia][ib][ic] = 0.0;
167  if ( abs( _lambdaB2[ib] - _lambdaC2[ic] ) <= _JA2 ) {
168  _amp[ia][ib][ic] = c * _HBC[ib][ic] *
170  _lambdaB2[ib] -
171  _lambdaC2[ic],
172  theta );
173  prob += real( _amp[ia][ib][ic] *
174  conj( _amp[ia][ib][ic] ) );
175  }
176  }
177  }
178 
179  prob *= sqrt( 1.0 * _nA );
180 
181  if ( prob > maxprob )
182  maxprob = prob;
183  }
184  }
185 
186  return maxprob;
187 }
188 
190 {
191  //find theta and phi of the first daughter
192 
193  EvtVector4R pB = p->getDaug( 0 )->getP4();
194 
195  double theta = acos( pB.get( 3 ) / pB.d3mag() );
196  double phi = atan2( pB.get( 2 ), pB.get( 1 ) );
197 
198  double c = sqrt( ( _JA2 + 1 ) / ( 4 * EvtConst::pi ) );
199 
200  int ia, ib, ic;
201 
202  double prob1 = 0.0;
203 
204  for ( ia = 0; ia < _nA; ia++ ) {
205  for ( ib = 0; ib < _nB; ib++ ) {
206  for ( ic = 0; ic < _nC; ic++ ) {
207  _amp[ia][ib][ic] = 0.0;
208  if ( abs( _lambdaB2[ib] - _lambdaC2[ic] ) <= _JA2 ) {
209  double dfun = EvtdFunction::d( _JA2, _lambdaA2[ia],
210  _lambdaB2[ib] - _lambdaC2[ic],
211  theta );
212 
213  _amp[ia][ib][ic] =
214  c * _HBC[ib][ic] *
215  exp( EvtComplex( 0.0, phi * 0.5 *
216  ( _lambdaA2[ia] - _lambdaB2[ib] +
217  _lambdaC2[ic] ) ) ) *
218  dfun;
219  }
220  prob1 += real( _amp[ia][ib][ic] * conj( _amp[ia][ib][ic] ) );
221  }
222  }
223  }
224 
225  setUpRotationMatrices( p, theta, phi );
226 
228 
229  double prob2 = 0.0;
230 
231  for ( ia = 0; ia < _nA; ia++ ) {
232  for ( ib = 0; ib < _nB; ib++ ) {
233  for ( ic = 0; ic < _nC; ic++ ) {
234  prob2 += real( _amp[ia][ib][ic] * conj( _amp[ia][ib][ic] ) );
235  if ( _nA == 1 ) {
236  if ( _nB == 1 ) {
237  if ( _nC == 1 ) {
238  amp.vertex( _amp[ia][ib][ic] );
239  } else {
240  amp.vertex( ic, _amp[ia][ib][ic] );
241  }
242  } else {
243  if ( _nC == 1 ) {
244  amp.vertex( ib, _amp[ia][ib][ic] );
245  } else {
246  amp.vertex( ib, ic, _amp[ia][ib][ic] );
247  }
248  }
249  } else {
250  if ( _nB == 1 ) {
251  if ( _nC == 1 ) {
252  amp.vertex( ia, _amp[ia][ib][ic] );
253  } else {
254  amp.vertex( ia, ic, _amp[ia][ib][ic] );
255  }
256  } else {
257  if ( _nC == 1 ) {
258  amp.vertex( ia, ib, _amp[ia][ib][ic] );
259  } else {
260  amp.vertex( ia, ib, ic, _amp[ia][ib][ic] );
261  }
262  }
263  }
264  }
265  }
266  }
267 
268  if ( fabs( prob1 - prob2 ) > 0.000001 * prob1 ) {
269  EvtGenReport( EVTGEN_INFO, "EvtGen" )
270  << "prob1,prob2:" << prob1 << " " << prob2 << endl;
271  ::abort();
272  }
273 
274  return;
275 }
276 
277 void EvtEvalHelAmp::fillHelicity( int* lambda2, int n, int J2, EvtId id )
278 {
279  int i;
280 
281  //photon is special case!
282  if ( n == 2 && J2 == 2 ) {
283  lambda2[0] = 2;
284  lambda2[1] = -2;
285  return;
286  }
287 
288  //and so is the neutrino!
289  if ( n == 1 && J2 == 1 ) {
290  if ( EvtPDL::getStdHep( id ) > 0 ) {
291  //particle i.e. lefthanded
292  lambda2[0] = -1;
293  } else {
294  //anti particle i.e. righthanded
295  lambda2[0] = 1;
296  }
297  return;
298  }
299 
300  assert( n == J2 + 1 );
301 
302  for ( i = 0; i < n; i++ ) {
303  lambda2[i] = n - i * 2 - 1;
304  }
305 
306  return;
307 }
308 
310  double phi )
311 {
312  switch ( _JA2 ) {
313  case 0:
314  case 1:
315  case 2:
316  case 3:
317  case 4:
318  case 5:
319  case 6:
320  case 7:
321  case 8:
322 
323  {
325 
326  int i, j, n;
327 
328  n = R.getDim();
329 
330  assert( n == _nA );
331 
332  for ( i = 0; i < n; i++ ) {
333  for ( j = 0; j < n; j++ ) {
334  _RA[i][j] = R.get( i, j );
335  }
336  }
337 
338  }
339 
340  break;
341 
342  default:
343  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
344  << "Spin2(_JA2)=" << _JA2 << " not supported!" << endl;
345  ::abort();
346  }
347 
348  switch ( _JB2 ) {
349  case 0:
350  case 1:
351  case 2:
352  case 3:
353  case 4:
354  case 5:
355  case 6:
356  case 7:
357  case 8:
358 
359  {
360  int i, j, n;
361 
362  EvtSpinDensity R =
363  p->getDaug( 0 )->rotateToHelicityBasis( phi, theta, -phi );
364 
365  n = R.getDim();
366 
367  assert( n == _nB );
368 
369  for ( i = 0; i < n; i++ ) {
370  for ( j = 0; j < n; j++ ) {
371  _RB[i][j] = conj( R.get( i, j ) );
372  }
373  }
374 
375  }
376 
377  break;
378 
379  default:
380  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
381  << "Spin2(_JB2)=" << _JB2 << " not supported!" << endl;
382  ::abort();
383  }
384 
385  switch ( _JC2 ) {
386  case 0:
387  case 1:
388  case 2:
389  case 3:
390  case 4:
391  case 5:
392  case 6:
393  case 7:
394  case 8:
395 
396  {
397  int i, j, n;
398 
400  phi, EvtConst::pi + theta, phi - EvtConst::pi );
401 
402  n = R.getDim();
403 
404  assert( n == _nC );
405 
406  for ( i = 0; i < n; i++ ) {
407  for ( j = 0; j < n; j++ ) {
408  _RC[i][j] = conj( R.get( i, j ) );
409  }
410  }
411 
412  }
413 
414  break;
415 
416  default:
417  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
418  << "Spin2(_JC2)=" << _JC2 << " not supported!" << endl;
419  ::abort();
420  }
421 }
422 
424 {
425  int ia, ib, ic, i;
426 
427  EvtComplex temp;
428 
429  for ( ia = 0; ia < _nA; ia++ ) {
430  for ( ib = 0; ib < _nB; ib++ ) {
431  for ( ic = 0; ic < _nC; ic++ ) {
432  temp = 0;
433  for ( i = 0; i < _nC; i++ ) {
434  temp += _RC[i][ic] * _amp[ia][ib][i];
435  }
436  _amp1[ia][ib][ic] = temp;
437  }
438  }
439  }
440 
441  for ( ia = 0; ia < _nA; ia++ ) {
442  for ( ic = 0; ic < _nC; ic++ ) {
443  for ( ib = 0; ib < _nB; ib++ ) {
444  temp = 0;
445  for ( i = 0; i < _nB; i++ ) {
446  temp += _RB[i][ib] * _amp1[ia][i][ic];
447  }
448  _amp3[ia][ib][ic] = temp;
449  }
450  }
451  }
452 
453  for ( ib = 0; ib < _nB; ib++ ) {
454  for ( ic = 0; ic < _nC; ic++ ) {
455  for ( ia = 0; ia < _nA; ia++ ) {
456  temp = 0;
457  for ( i = 0; i < _nA; i++ ) {
458  temp += _RA[i][ia] * _amp3[i][ib][ic];
459  }
460  _amp[ia][ib][ic] = temp;
461  }
462  }
463  }
464 }
void fillHelicity(int *lambda2, int n, int J2, EvtId id)
EvtComplexPtrPtr _HBC
virtual ~EvtEvalHelAmp()
EvtComplexPtrPtrPtr _amp1
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
EvtComplexPtrPtr _RB
EvtComplexPtrPtrPtr _amp
Evt3Rank3C conj(const Evt3Rank3C &t2)
Definition: Evt3Rank3C.cpp:172
const EvtComplex & get(int i, int j) const
EvtEvalHelAmp(EvtId idA, EvtId idB, EvtId idC, EvtComplexPtrPtr HBC)
static int getSpinStates(spintype stype)
Definition: EvtSpinType.cpp:57
Definition: EvtId.hh:27
void vertex(const EvtComplex &amp)
Definition: EvtAmp.cpp:454
static const double pi
Definition: EvtConst.hh:26
EvtComplexPtrPtr _RA
double get(int i) const
Definition: EvtVector4R.hh:162
EvtComplexPtrPtr _RC
virtual EvtSpinDensity rotateToHelicityBasis() const =0
Definition: EvtAmp.hh:30
double abs(const EvtComplex &c)
Definition: EvtComplex.hh:201
const EvtVector4R & getP4() const
void evalAmp(EvtParticle *p, EvtAmp &amp)
int getDim() const
EvtComplexPtrPtrPtr _amp3
static int getSpin2(spintype stype)
Definition: EvtSpinType.cpp:26
double d3mag() const
EvtComplex exp(const EvtComplex &c)
Definition: EvtComplex.hh:240
EvtParticle * getDaug(int i)
Definition: EvtParticle.cpp:91
void setUpRotationMatrices(EvtParticle *p, double theta, double phi)
static double d(int j, int m1, int m2, double theta)
void applyRotationMatrices()
double real(const EvtComplex &c)
Definition: EvtComplex.hh:230
static int getStdHep(EvtId id)
Definition: EvtPDL.cpp:362