EvtGen 2.2.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
Loading...
Searching...
No Matches
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"
25#include "EvtGenBase/EvtId.hh"
26#include "EvtGenBase/EvtPDL.hh"
31
32#include <stdlib.h>
33using std::endl;
34
36{
37 //deallocate memory
38 delete[] m_lambdaA2;
39 delete[] m_lambdaB2;
40 delete[] m_lambdaC2;
41
42 int ia, ib, ic;
43 for ( ib = 0; ib < m_nB; ib++ ) {
44 delete[] m_HBC[ib];
45 }
46
47 delete[] m_HBC;
48
49 for ( ia = 0; ia < m_nA; ia++ ) {
50 delete[] m_RA[ia];
51 }
52 delete[] m_RA;
53
54 for ( ib = 0; ib < m_nB; ib++ ) {
55 delete[] m_RB[ib];
56 }
57 delete[] m_RB;
58
59 for ( ic = 0; ic < m_nC; ic++ ) {
60 delete[] m_RC[ic];
61 }
62 delete[] m_RC;
63
64 for ( ia = 0; ia < m_nA; ia++ ) {
65 for ( ib = 0; ib < m_nB; ib++ ) {
66 delete[] m_amp[ia][ib];
67 delete[] m_amp1[ia][ib];
68 delete[] m_amp3[ia][ib];
69 }
70 delete[] m_amp[ia];
71 delete[] m_amp1[ia];
72 delete[] m_amp3[ia];
73 }
74
75 delete[] m_amp;
76 delete[] m_amp1;
77 delete[] m_amp3;
78}
79
82{
86
87 //find out how many states each particle have
91
92 //find out what 2 times the spin is
96
97 //allocate memory
98 m_lambdaA2 = new int[m_nA];
99 m_lambdaB2 = new int[m_nB];
100 m_lambdaC2 = new int[m_nC];
101
102 m_HBC = new EvtComplexPtr[m_nB];
103 int ia, ib, ic;
104 for ( ib = 0; ib < m_nB; ib++ ) {
105 m_HBC[ib] = new EvtComplex[m_nC];
106 }
107
108 m_RA = new EvtComplexPtr[m_nA];
109 for ( ia = 0; ia < m_nA; ia++ ) {
110 m_RA[ia] = new EvtComplex[m_nA];
111 }
112 m_RB = new EvtComplexPtr[m_nB];
113 for ( ib = 0; ib < m_nB; ib++ ) {
114 m_RB[ib] = new EvtComplex[m_nB];
115 }
116 m_RC = new EvtComplexPtr[m_nC];
117 for ( ic = 0; ic < m_nC; ic++ ) {
118 m_RC[ic] = new EvtComplex[m_nC];
119 }
120
124 for ( ia = 0; ia < m_nA; ia++ ) {
125 m_amp[ia] = new EvtComplexPtr[m_nB];
126 m_amp1[ia] = new EvtComplexPtr[m_nB];
127 m_amp3[ia] = new EvtComplexPtr[m_nB];
128 for ( ib = 0; ib < m_nB; ib++ ) {
129 m_amp[ia][ib] = new EvtComplex[m_nC];
130 m_amp1[ia][ib] = new EvtComplex[m_nC];
131 m_amp3[ia][ib] = new EvtComplex[m_nC];
132 }
133 }
134
135 //find the allowed helicities (actually 2*times the helicity!)
136
140
141 for ( ib = 0; ib < m_nB; ib++ ) {
142 for ( ic = 0; ic < m_nC; ic++ ) {
143 m_HBC[ib][ic] = HBC[ib][ic];
144 }
145 }
146}
147
149{
150 double c = 1.0 / sqrt( 4 * EvtConst::pi / ( m_JA2 + 1 ) );
151
152 int ia, ib, ic;
153
154 double theta;
155 int itheta;
156
157 double maxprob = 0.0;
158
159 for ( itheta = -10; itheta <= 10; itheta++ ) {
160 theta = acos( 0.099999 * itheta );
161 for ( ia = 0; ia < m_nA; ia++ ) {
162 double prob = 0.0;
163 for ( ib = 0; ib < m_nB; ib++ ) {
164 for ( ic = 0; ic < m_nC; ic++ ) {
165 m_amp[ia][ib][ic] = 0.0;
166 if ( abs( m_lambdaB2[ib] - m_lambdaC2[ic] ) <= m_JA2 ) {
167 m_amp[ia][ib][ic] =
168 c * m_HBC[ib][ic] *
170 m_lambdaB2[ib] - m_lambdaC2[ic],
171 theta );
172 prob += real( m_amp[ia][ib][ic] *
173 conj( m_amp[ia][ib][ic] ) );
174 }
175 }
176 }
177
178 prob *= sqrt( 1.0 * m_nA );
179
180 if ( prob > maxprob )
181 maxprob = prob;
182 }
183 }
184
185 return maxprob;
186}
187
189{
190 //find theta and phi of the first daughter
191
192 EvtVector4R pB = p->getDaug( 0 )->getP4();
193
194 double theta = acos( pB.get( 3 ) / pB.d3mag() );
195 double phi = atan2( pB.get( 2 ), pB.get( 1 ) );
196
197 double c = sqrt( ( m_JA2 + 1 ) / ( 4 * EvtConst::pi ) );
198
199 int ia, ib, ic;
200
201 double prob1 = 0.0;
202
203 for ( ia = 0; ia < m_nA; ia++ ) {
204 for ( ib = 0; ib < m_nB; ib++ ) {
205 for ( ic = 0; ic < m_nC; ic++ ) {
206 m_amp[ia][ib][ic] = 0.0;
207 if ( abs( m_lambdaB2[ib] - m_lambdaC2[ic] ) <= m_JA2 ) {
208 double dfun = EvtdFunction::d( m_JA2, m_lambdaA2[ia],
209 m_lambdaB2[ib] - m_lambdaC2[ic],
210 theta );
211
212 m_amp[ia][ib][ic] =
213 c * m_HBC[ib][ic] *
214 exp( EvtComplex( 0.0,
215 phi * 0.5 *
216 ( m_lambdaA2[ia] - m_lambdaB2[ib] +
217 m_lambdaC2[ic] ) ) ) *
218 dfun;
219 }
220 prob1 += real( m_amp[ia][ib][ic] * conj( m_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 < m_nA; ia++ ) {
232 for ( ib = 0; ib < m_nB; ib++ ) {
233 for ( ic = 0; ic < m_nC; ic++ ) {
234 prob2 += real( m_amp[ia][ib][ic] * conj( m_amp[ia][ib][ic] ) );
235 if ( m_nA == 1 ) {
236 if ( m_nB == 1 ) {
237 if ( m_nC == 1 ) {
238 amp.vertex( m_amp[ia][ib][ic] );
239 } else {
240 amp.vertex( ic, m_amp[ia][ib][ic] );
241 }
242 } else {
243 if ( m_nC == 1 ) {
244 amp.vertex( ib, m_amp[ia][ib][ic] );
245 } else {
246 amp.vertex( ib, ic, m_amp[ia][ib][ic] );
247 }
248 }
249 } else {
250 if ( m_nB == 1 ) {
251 if ( m_nC == 1 ) {
252 amp.vertex( ia, m_amp[ia][ib][ic] );
253 } else {
254 amp.vertex( ia, ic, m_amp[ia][ib][ic] );
255 }
256 } else {
257 if ( m_nC == 1 ) {
258 amp.vertex( ia, ib, m_amp[ia][ib][ic] );
259 } else {
260 amp.vertex( ia, ib, ic, m_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
277void 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 ( m_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 == m_nA );
331
332 for ( i = 0; i < n; i++ ) {
333 for ( j = 0; j < n; j++ ) {
334 m_RA[i][j] = R.get( i, j );
335 }
336 }
337
338 }
339
340 break;
341
342 default:
343 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
344 << "Spin2(m_JA2)=" << m_JA2 << " not supported!" << endl;
345 ::abort();
346 }
347
348 switch ( m_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
363 p->getDaug( 0 )->rotateToHelicityBasis( phi, theta, -phi );
364
365 n = R.getDim();
366
367 assert( n == m_nB );
368
369 for ( i = 0; i < n; i++ ) {
370 for ( j = 0; j < n; j++ ) {
371 m_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(m_JB2)=" << m_JB2 << " not supported!" << endl;
382 ::abort();
383 }
384
385 switch ( m_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 == m_nC );
405
406 for ( i = 0; i < n; i++ ) {
407 for ( j = 0; j < n; j++ ) {
408 m_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(m_JC2)=" << m_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 < m_nA; ia++ ) {
430 for ( ib = 0; ib < m_nB; ib++ ) {
431 for ( ic = 0; ic < m_nC; ic++ ) {
432 temp = 0;
433 for ( i = 0; i < m_nC; i++ ) {
434 temp += m_RC[i][ic] * m_amp[ia][ib][i];
435 }
436 m_amp1[ia][ib][ic] = temp;
437 }
438 }
439 }
440
441 for ( ia = 0; ia < m_nA; ia++ ) {
442 for ( ic = 0; ic < m_nC; ic++ ) {
443 for ( ib = 0; ib < m_nB; ib++ ) {
444 temp = 0;
445 for ( i = 0; i < m_nB; i++ ) {
446 temp += m_RB[i][ib] * m_amp1[ia][i][ic];
447 }
448 m_amp3[ia][ib][ic] = temp;
449 }
450 }
451 }
452
453 for ( ib = 0; ib < m_nB; ib++ ) {
454 for ( ic = 0; ic < m_nC; ic++ ) {
455 for ( ia = 0; ia < m_nA; ia++ ) {
456 temp = 0;
457 for ( i = 0; i < m_nA; i++ ) {
458 temp += m_RA[i][ia] * m_amp3[i][ib][ic];
459 }
460 m_amp[ia][ib][ic] = temp;
461 }
462 }
463 }
464}
EvtComplex conj(const EvtComplex &c)
double real(const EvtComplex &c)
EvtComplex exp(const EvtComplex &c)
EvtComplex * EvtComplexPtr
Definition EvtComplex.hh:78
double abs(const EvtComplex &c)
EvtComplexPtr * EvtComplexPtrPtr
Definition EvtComplex.hh:79
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=nullptr)
Definition EvtReport.cpp:32
@ EVTGEN_INFO
Definition EvtReport.hh:52
@ EVTGEN_ERROR
Definition EvtReport.hh:49
void vertex(const EvtComplex &amp)
Definition EvtAmp.cpp:453
static const double pi
Definition EvtConst.hh:26
EvtComplexPtrPtr m_RC
void applyRotationMatrices()
EvtComplexPtrPtr m_RB
EvtComplexPtrPtrPtr m_amp1
void fillHelicity(int *lambda2, int n, int J2, EvtId id)
EvtEvalHelAmp(EvtId idA, EvtId idB, EvtId idC, EvtComplexPtrPtr HBC)
EvtComplexPtrPtrPtr m_amp3
void evalAmp(EvtParticle *p, EvtAmp &amp)
EvtComplexPtrPtrPtr m_amp
EvtComplexPtrPtr m_RA
EvtComplexPtrPtr m_HBC
virtual ~EvtEvalHelAmp()
void setUpRotationMatrices(EvtParticle *p, double theta, double phi)
Definition EvtId.hh:27
static EvtSpinType::spintype getSpinType(EvtId i)
Definition EvtPDL.cpp:371
static int getStdHep(EvtId id)
Definition EvtPDL.cpp:356
const EvtVector4R & getP4() const
virtual EvtSpinDensity rotateToHelicityBasis() const =0
EvtParticle * getDaug(const int i)
const EvtComplex & get(int i, int j) const
static int getSpin2(spintype stype)
static int getSpinStates(spintype stype)
double get(int i) const
double d3mag() const
static double d(int j, int m1, int m2, double theta)