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
EvtParticle.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
27#include "EvtGenBase/EvtId.hh"
30#include "EvtGenBase/EvtPDL.hh"
44
45#include <sys/stat.h>
46
47#include <iostream>
48#include <math.h>
49#include <stdio.h>
50#include <stdlib.h>
51
52using std::endl;
53
58
60{
61 m_ndaug = 0;
62 m_parent = nullptr;
63 m_channel = -10;
64 m_t = 0.0;
65 m_genlifetime = 1;
66 m_first = 1;
67 m_isInit = false;
68 m_validP4 = false;
69 m_isDecayed = false;
70 m_decayProb = nullptr;
71 m_intAttributes.clear();
72 m_dblAttributes.clear();
73 // m_mix=false;
74}
75
77{
78 m_first = 0;
79}
84
86{
87 m_channel = i;
88}
89
91{
92 return m_parent;
93}
94
95void EvtParticle::setLifetime( double tau )
96{
97 m_t = tau;
98}
99
101{
102 if ( m_genlifetime ) {
103 m_t = -log( EvtRandom::Flat() ) * EvtPDL::getctau( getId() );
104 }
105}
106
108{
109 return m_t;
110}
111
113{
114 node->m_daug[node->m_ndaug++] = this;
115 m_ndaug = 0;
116 m_parent = node;
117}
118
120{
121 return m_first;
122}
123
125{
126 return m_id;
127}
128
130{
131 return EvtPDL::getStdHep( m_id );
132}
133
138
143
145{
146 return m_p;
147}
148
150{
151 return m_channel;
152}
153
155{
156 return m_ndaug;
157}
158
159double EvtParticle::mass() const
160{
161 return m_p.mass();
162}
163
168
170{
171 if ( getSpinStates() != 3 ) {
172 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
173 << "Error in EvtParticle::setVectorSpinDensity" << endl;
174 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
175 << "spin_states:" << getSpinStates() << endl;
176 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
177 << "particle:" << EvtPDL::name( m_id ).c_str() << endl;
178 ::abort();
179 }
180
181 EvtSpinDensity rho;
182
183 //Set helicity +1 and -1 to 1.
184 rho.setDiag( getSpinStates() );
185 rho.set( 1, 1, EvtComplex( 0.0, 0.0 ) );
186
188}
189
191{
193
194 assert( R.getDim() == rho.getDim() );
195
196 int n = rho.getDim();
197
198 m_rhoForward.setDim( n );
199
200 int i, j, k, l;
201
202 for ( i = 0; i < n; i++ ) {
203 for ( j = 0; j < n; j++ ) {
204 EvtComplex tmp = 0.0;
205 for ( k = 0; k < n; k++ ) {
206 for ( l = 0; l < n; l++ ) {
207 tmp += R.get( l, i ) * rho.get( l, k ) *
208 conj( R.get( k, j ) );
209 }
210 }
211 m_rhoForward.set( i, j, tmp );
212 }
213 }
214}
215
217 double alpha, double beta,
218 double gamma )
219{
220 EvtSpinDensity R = rotateToHelicityBasis( alpha, beta, gamma );
221
222 assert( R.getDim() == rho.getDim() );
223
224 int n = rho.getDim();
225
226 m_rhoForward.setDim( n );
227
228 int i, j, k, l;
229
230 for ( i = 0; i < n; i++ ) {
231 for ( j = 0; j < n; j++ ) {
232 EvtComplex tmp = 0.0;
233 for ( k = 0; k < n; k++ ) {
234 for ( l = 0; l < n; l++ ) {
235 tmp += R.get( l, i ) * rho.get( l, k ) *
236 conj( R.get( k, j ) );
237 }
238 }
239 m_rhoForward.set( i, j, tmp );
240 }
241 }
242}
243
244void EvtParticle::initDecay( bool useMinMass )
245{
246 EvtParticle* p = this;
247 // carefull - the parent mass might be fixed in stone..
248 EvtParticle* par = p->getParent();
249 double parMass = -1.;
250 if ( par ) {
251 if ( par->hasValidP4() )
252 parMass = par->mass();
253 for ( size_t i = 0; i < par->getNDaug(); i++ ) {
254 EvtParticle* tDaug = par->getDaug( i );
255 if ( p != tDaug )
256 parMass -= EvtPDL::getMinMass( tDaug->getId() );
257 }
258 }
259
260 if ( m_isInit ) {
261 //we have already been here - just reroll the masses!
262 if ( m_ndaug > 0 ) {
263 for ( size_t ii = 0; ii < m_ndaug; ii++ ) {
264 if ( m_ndaug == 1 ||
265 EvtPDL::getWidth( p->getDaug( ii )->getId() ) > 0.0000001 )
266 p->getDaug( ii )->initDecay( useMinMass );
267 else
268 p->getDaug( ii )->setMass(
269 EvtPDL::getMeanMass( p->getDaug( ii )->getId() ) );
270 }
271 }
272
273 EvtId* dauId = nullptr;
274 double* dauMasses = nullptr;
275 if ( m_ndaug > 0 ) {
276 dauId = new EvtId[m_ndaug];
277 dauMasses = new double[m_ndaug];
278 for ( size_t j = 0; j < m_ndaug; j++ ) {
279 dauId[j] = p->getDaug( j )->getId();
280 dauMasses[j] = p->getDaug( j )->mass();
281 }
282 }
283 EvtId* parId = nullptr;
284 EvtId* othDauId = nullptr;
285 EvtParticle* tempPar = p->getParent();
286 if ( tempPar ) {
287 parId = new EvtId( tempPar->getId() );
288 if ( tempPar->getNDaug() == 2 ) {
289 if ( tempPar->getDaug( 0 ) == this )
290 othDauId = new EvtId( tempPar->getDaug( 1 )->getId() );
291 else
292 othDauId = new EvtId( tempPar->getDaug( 0 )->getId() );
293 }
294 }
295 if ( p->getParent() && m_validP4 == false ) {
296 if ( !useMinMass ) {
297 p->setMass( EvtPDL::getRandMass( p->getId(), parId, m_ndaug,
298 dauId, othDauId, parMass,
299 dauMasses ) );
300 } else
301 p->setMass( EvtPDL::getMinMass( p->getId() ) );
302 }
303 if ( parId )
304 delete parId;
305 if ( othDauId )
306 delete othDauId;
307 if ( dauId )
308 delete[] dauId;
309 if ( dauMasses )
310 delete[] dauMasses;
311 return;
312 }
313
314 //Will include effects of mixing here
315 //added by Lange Jan4,2000
316 static const EvtId BS0 = EvtPDL::getId( "B_s0" );
317 static const EvtId BSB = EvtPDL::getId( "anti-B_s0" );
318 static const EvtId BD0 = EvtPDL::getId( "B0" );
319 static const EvtId BDB = EvtPDL::getId( "anti-B0" );
320 static const EvtId D0 = EvtPDL::getId( "D0" );
321 static const EvtId D0B = EvtPDL::getId( "anti-D0" );
322 static const EvtId U4S = EvtPDL::getId( "Upsilon(4S)" );
323 static const EvtIdSet borUps{ BS0, BSB, BD0, BDB, U4S };
324
325 //only makes sense if there is no parent particle which is a B or an Upsilon
326 bool hasBorUps = false;
327 if ( getParent() && borUps.contains( getParent()->getId() ) )
328 hasBorUps = true;
329 // if ( (getNDaug()==0)&&(getParent()==0) && (getId()==BS0||getId()==BSB||getId()==BD0||getId()==BDB)){
330 EvtId thisId = getId();
331 // remove D0 mixing for now.
332 // if ( (getNDaug()==0 && !hasBorUps) && (thisId==BS0||thisId==BSB||thisId==BD0||thisId==BDB||thisId==D0||thisId==D0B)){
333 if ( ( getNDaug() == 0 && !hasBorUps ) &&
334 ( thisId == BS0 || thisId == BSB || thisId == BD0 || thisId == BDB ) ) {
335 double t;
336 int mix;
338 setLifetime( t );
339
340 if ( mix ) {
341 EvtScalarParticle* scalar_part;
342
343 scalar_part = new EvtScalarParticle;
344 if ( getId() == BS0 ) {
345 EvtVector4R p_init( EvtPDL::getMass( BSB ), 0.0, 0.0, 0.0 );
346 scalar_part->init( EvtPDL::chargeConj( getId() ), p_init );
347 } else if ( getId() == BSB ) {
348 EvtVector4R p_init( EvtPDL::getMass( BS0 ), 0.0, 0.0, 0.0 );
349 scalar_part->init( EvtPDL::chargeConj( getId() ), p_init );
350 } else if ( getId() == BD0 ) {
351 EvtVector4R p_init( EvtPDL::getMass( BDB ), 0.0, 0.0, 0.0 );
352 scalar_part->init( EvtPDL::chargeConj( getId() ), p_init );
353 } else if ( getId() == BDB ) {
354 EvtVector4R p_init( EvtPDL::getMass( BD0 ), 0.0, 0.0, 0.0 );
355 scalar_part->init( EvtPDL::chargeConj( getId() ), p_init );
356 } else if ( getId() == D0 ) {
357 EvtVector4R p_init( EvtPDL::getMass( D0B ), 0.0, 0.0, 0.0 );
358 scalar_part->init( EvtPDL::chargeConj( getId() ), p_init );
359 } else if ( getId() == D0B ) {
360 EvtVector4R p_init( EvtPDL::getMass( D0 ), 0.0, 0.0, 0.0 );
361 scalar_part->init( EvtPDL::chargeConj( getId() ), p_init );
362 }
363
364 scalar_part->setLifetime( 0 );
365 scalar_part->setDiagonalSpinDensity();
366
367 insertDaugPtr( 0, scalar_part );
368
369 m_ndaug = 1;
370 m_isInit = true;
371 p = scalar_part;
372 p->initDecay( useMinMass );
373 return;
374 }
375 }
376
377 EvtDecayBase* decayer;
379
380 if ( decayer ) {
381 p->makeDaughters( decayer->nRealDaughters(), decayer->getDaugs() );
382 //then loop over the daughters and init their decay
383 for ( size_t i = 0; i < p->getNDaug(); i++ ) {
384 // std::cout << EvtPDL::name(p->getDaug(i)->getId()) << " " << i << " " << p->getDaug(i)->getSpinType() << " " << EvtPDL::name(p->getId()) << std::endl;
385 if ( EvtPDL::getWidth( p->getDaug( i )->getId() ) > 0.0000001 )
386 p->getDaug( i )->initDecay( useMinMass );
387 else
388 p->getDaug( i )->setMass(
389 EvtPDL::getMeanMass( p->getDaug( i )->getId() ) );
390 }
391 }
392
393 int j;
394 EvtId* dauId = nullptr;
395 double* dauMasses = nullptr;
396 int nDaugT = p->getNDaug();
397 if ( nDaugT > 0 ) {
398 dauId = new EvtId[nDaugT];
399 dauMasses = new double[nDaugT];
400 for ( j = 0; j < nDaugT; j++ ) {
401 dauId[j] = p->getDaug( j )->getId();
402 dauMasses[j] = p->getDaug( j )->mass();
403 }
404 }
405
406 EvtId* parId = nullptr;
407 EvtId* othDauId = nullptr;
408 EvtParticle* tempPar = p->getParent();
409 if ( tempPar ) {
410 parId = new EvtId( tempPar->getId() );
411 if ( tempPar->getNDaug() == 2 ) {
412 if ( tempPar->getDaug( 0 ) == this )
413 othDauId = new EvtId( tempPar->getDaug( 1 )->getId() );
414 else
415 othDauId = new EvtId( tempPar->getDaug( 0 )->getId() );
416 }
417 }
418 if ( p->getParent() && p->hasValidP4() == false ) {
419 if ( !useMinMass ) {
420 p->setMass( EvtPDL::getRandMass( p->getId(), parId, p->getNDaug(),
421 dauId, othDauId, parMass,
422 dauMasses ) );
423 } else {
424 p->setMass( EvtPDL::getMinMass( p->getId() ) );
425 }
426 }
427 if ( parId )
428 delete parId;
429 if ( othDauId )
430 delete othDauId;
431 if ( dauId )
432 delete[] dauId;
433 if ( dauMasses )
434 delete[] dauMasses;
435 m_isInit = true;
436}
437
439{
440 //P is particle to decay, typically 'this' but sometime
441 //modified by mixing
442 EvtParticle* p = this;
443 //Did it mix?
444 //if ( p->getMixed() ) {
445 //should take C(p) - this should only
446 //happen the first time we call decay for this
447 //particle
448 //p->takeCConj();
449 // p->setUnMixed();
450 //}
451
452 EvtDecayBase* decayer;
454 // if ( decayer ) {
455 // EvtGenReport(EVTGEN_INFO,"EvtGen") << "calling decay for " << EvtPDL::name(p->getId()) << " " << p->mass() << " " << p->getP4() << " " << p->getNDaug() << " " << p << endl;
456 // EvtGenReport(EVTGEN_INFO,"EvtGen") << "NDaug= " << decayer->getNDaug() << endl;
457 // int ti;
458 // for ( ti=0; ti<decayer->getNDaug(); ti++)
459 // EvtGenReport(EVTGEN_INFO,"EvtGen") << "Daug " << ti << " " << EvtPDL::name(decayer->getDaug(ti)) << endl;
460 // }
461 //if (p->m_ndaug>0) {
462 // EvtGenReport(EVTGEN_INFO,"EvtGen") <<"Is decaying particle with daughters!!!!!"<<endl;
463 // ::abort();
464 //return;
465 //call initdecay first - April 29,2002 - Lange
466 //}
467
468 //if there are already daughters, then this step is already done!
469 // figure out the masses
470 bool massTreeOK( true );
471 if ( m_ndaug == 0 ) {
472 massTreeOK = generateMassTree();
473 }
474
475 if ( massTreeOK == false ) {
476 EvtGenReport( EVTGEN_INFO, "EvtGen" )
477 << "Could not decay " << EvtPDL::name( p->getId() ) << " with mass "
478 << p->mass() << " to decay channel number " << m_channel << endl;
479 m_isDecayed = false;
480 return;
481 }
482
483 static const EvtId BS0 = EvtPDL::getId( "B_s0" );
484 static const EvtId BSB = EvtPDL::getId( "anti-B_s0" );
485 static const EvtId BD0 = EvtPDL::getId( "B0" );
486 static const EvtId BDB = EvtPDL::getId( "anti-B0" );
487 // static EvtId D0=EvtPDL::getId("D0");
488 // static EvtId D0B=EvtPDL::getId("anti-D0");
489
490 EvtId thisId = getId();
491 // remove D0 mixing for now..
492 // if ( m_ndaug==1 && (thisId==BS0||thisId==BSB||thisId==BD0||thisId==BDB||thisId==D0||thisId==D0B) ) {
493 if ( m_ndaug == 1 &&
494 ( thisId == BS0 || thisId == BSB || thisId == BD0 || thisId == BDB ) ) {
495 p = p->getDaug( 0 );
497 }
498 //now we have accepted a set of masses - time
499 if ( decayer != nullptr ) {
500 decayer->makeDecay( p );
501 } else {
503 }
504
505 m_isDecayed = true;
506 return;
507}
508
510{
511 bool isOK( true );
512
513 double massProb = 1.;
514 double ranNum = 2.;
515 int counter = 0;
516 EvtParticle* p = this;
517 while ( massProb < ranNum ) {
518 //check it out the first time.
519 p->initDecay();
520 massProb = p->compMassProb();
521 ranNum = EvtRandom::Flat();
522 counter++;
523
524 if ( counter > 10000 ) {
525 if ( counter == 10001 ) {
526 EvtGenReport( EVTGEN_INFO, "EvtGen" )
527 << "Too many iterations to determine the mass tree. Parent mass= "
528 << p->mass() << " " << massProb << endl;
529 p->printTree();
530 EvtGenReport( EVTGEN_INFO, "EvtGen" )
531 << "will take next combo with non-zero likelihood\n";
532 }
533 if ( massProb > 0. )
534 massProb = 2.0;
535 if ( counter > 20000 ) {
536 // one last try - take the minimum masses
537 p->initDecay( true );
538 p->printTree();
539 massProb = p->compMassProb();
540 if ( massProb > 0. ) {
541 massProb = 2.0;
542 EvtGenReport( EVTGEN_INFO, "EvtGen" )
543 << "Taking the minimum mass of all particles in the chain\n";
544 } else {
545 EvtGenReport( EVTGEN_INFO, "EvtGen" )
546 << "Sorry, no luck finding a valid set of masses. This may be a pathological combo\n";
547 isOK = false;
548 break;
549 }
550 }
551 }
552 }
553
554 return isOK;
555}
556
558{
559 EvtParticle* p = this;
560 double mass = p->mass();
561 double parMass = 0.;
562 if ( p->getParent() ) {
563 parMass = p->getParent()->mass();
564 }
565
566 int nDaug = p->getNDaug();
567 double* dMasses = nullptr;
568
569 int i;
570 if ( nDaug > 0 ) {
571 dMasses = new double[nDaug];
572 for ( i = 0; i < nDaug; i++ )
573 dMasses[i] = p->getDaug( i )->mass();
574 }
575
576 double temp = 1.0;
577 temp = EvtPDL::getMassProb( p->getId(), mass, parMass, nDaug, dMasses );
578
579 //If the particle already has a mass, we dont need to include
580 //it in the probability calculation
581 if ( ( !p->getParent() || m_validP4 ) && temp > 0.0 )
582 temp = 1.;
583
584 delete[] dMasses;
585 for ( i = 0; i < nDaug; i++ ) {
586 temp *= p->getDaug( i )->compMassProb();
587 }
588 return temp;
589}
590
591void EvtParticle::deleteDaughters( bool keepChannel )
592{
593 for ( size_t i = 0; i < m_ndaug; i++ ) {
594 m_daug[i]->deleteTree();
595 }
596
597 m_ndaug = 0;
598 if ( !keepChannel )
599 m_channel = -10;
600 m_first = 1;
601 m_isInit = false;
602}
603
605{
606 this->deleteDaughters();
607
608 delete this;
609}
610
612{
613 EvtVector4C temp;
615 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
616 << "and you have asked for the:" << i << "th polarization vector."
617 << " I.e. you thought it was a"
618 << " vector particle!" << endl;
619 ::abort();
620 return temp;
621}
622
624{
625 EvtVector4C temp;
627 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
628 << "and you have asked for the:" << i << "th polarization vector."
629 << " I.e. you thought it was a"
630 << " vector particle!" << endl;
631 ::abort();
632 return temp;
633}
634
636{
637 EvtVector4C temp;
639 EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the:" << i
640 << "th polarization vector of photon."
641 << " I.e. you thought it was a"
642 << " photon particle!" << endl;
643 ::abort();
644 return temp;
645}
646
648{
649 EvtVector4C temp;
651 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
652 << "and you have asked for the:" << i
653 << "th polarization vector of a photon."
654 << " I.e. you thought it was a"
655 << " photon particle!" << endl;
656 ::abort();
657 return temp;
658}
659
661{
662 EvtDiracSpinor tempD;
664 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
665 << "and you have asked for the:" << i << "th dirac spinor."
666 << " I.e. you thought it was a"
667 << " Dirac particle!" << endl;
668 ::abort();
669 return tempD;
670}
671
673{
674 EvtDiracSpinor tempD;
676 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
677 << "and you have asked for the:" << i << "th dirac spinor."
678 << " I.e. you thought it was a"
679 << " Dirac particle!" << endl;
680 ::abort();
681 return tempD;
682}
683
685{
686 EvtDiracSpinor tempD;
688 EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the "
689 << "dirac spinor."
690 << " I.e. you thought it was a"
691 << " neutrino particle!" << endl;
692 ::abort();
693 return tempD;
694}
695
697{
698 EvtDiracSpinor tempD;
700 EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "and you have asked for the "
701 << "dirac spinor."
702 << " I.e. you thought it was a"
703 << " neutrino particle!" << endl;
704 ::abort();
705 return tempD;
706}
707
709{
710 EvtTensor4C tempC;
712 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
713 << "and you have asked for the:" << i << "th tensor."
714 << " I.e. you thought it was a"
715 << " Tensor particle!" << endl;
716 ::abort();
717 return tempC;
718}
719
721{
722 EvtTensor4C tempC;
724 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
725 << "and you have asked for the:" << i << "th tensor."
726 << " I.e. you thought it was a"
727 << " Tensor particle!" << endl;
728 ::abort();
729 return tempC;
730}
731
733{
734 EvtRaritaSchwinger tempD;
736 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
737 << "and you have asked for the:" << i << "th Rarita-Schwinger spinor."
738 << " I.e. you thought it was a"
739 << " RaritaSchwinger particle!" << std::endl;
740 ::abort();
741 return tempD;
742}
743
745{
746 EvtRaritaSchwinger tempD;
748 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
749 << "and you have asked for the:" << i << "th Rarita-Schwinger spinor."
750 << " I.e. you thought it was a"
751 << " RaritaSchwinger particle!" << std::endl;
752 ::abort();
753 return tempD;
754}
755
757{
758 EvtVector4R temp, mom;
759 const EvtParticle* ptemp;
760
761 temp = this->getP4();
762 ptemp = this;
763
764 while ( ptemp->getParent() ) {
765 ptemp = ptemp->getParent();
766 mom = ptemp->getP4();
767 temp = boostTo( temp, mom );
768 }
769 return temp;
770}
771
773{
774 EvtVector4R temp, mom;
775 const EvtParticle* ptemp;
776
777 temp = this->m_pBeforeFSR;
778 ptemp = this;
779
780 while ( ptemp->getParent() ) {
781 ptemp = ptemp->getParent();
782 mom = ptemp->getP4();
783 temp = boostTo( temp, mom );
784 }
785 return temp;
786}
787
789{
790 return EvtVector4R( mass(), 0.0, 0.0, 0.0 );
791}
792
794{
795 EvtVector4R temp, mom;
796 EvtParticle* ptemp;
797
798 temp.set( 0.0, 0.0, 0.0, 0.0 );
799 ptemp = getParent();
800
801 if ( !ptemp ) {
802 return temp;
803 }
804
805 temp = ( ptemp->m_t / ptemp->mass() ) * ( ptemp->getP4() );
806
807 while ( ptemp->getParent() ) {
808 ptemp = ptemp->getParent();
809 mom = ptemp->getP4();
810 temp = boostTo( temp, mom );
811 temp = temp + ( ptemp->m_t / ptemp->mass() ) * ( ptemp->getP4() );
812 }
813
814 return temp;
815}
816
818{
819 EvtParticle* bpart;
820 EvtParticle* current;
821
822 current = this;
823 size_t i;
824
825 if ( m_ndaug != 0 )
826 return m_daug[0];
827
828 do {
829 bpart = current->m_parent;
830 if ( !bpart ) {
831 return nullptr;
832 }
833 i = 0;
834 while ( bpart->m_daug[i] != current ) {
835 i++;
836 }
837
838 if ( bpart == rootOfTree ) {
839 if ( i + 1 == bpart->m_ndaug ) {
840 return nullptr;
841 }
842 }
843
844 i++;
845 current = bpart;
846 } while ( i >= bpart->m_ndaug );
847
848 return bpart->m_daug[i];
849}
850
852 EvtId* list_of_stable )
853{
854 //first add particle to the stdhep list;
855 stdhep.createParticle( getP4Lab(), get4Pos(), -1, -1,
857
858 int ii = 0;
859
860 //lets see if this is a longlived particle and terminate the
861 //list building!
862
863 while ( list_of_stable[ii] != EvtId( -1, -1 ) ) {
864 if ( getId() == list_of_stable[ii] ) {
865 secondary.createSecondary( 0, this );
866 return;
867 }
868 ii++;
869 }
870
871 for ( size_t i = 0; i < m_ndaug; i++ ) {
872 stdhep.createParticle( m_daug[i]->getP4Lab(), m_daug[i]->get4Pos(), 0,
873 0, EvtPDL::getStdHep( m_daug[i]->getId() ) );
874 }
875
876 for ( size_t i = 0; i < m_ndaug; i++ ) {
877 m_daug[i]->makeStdHepRec( 1 + i, 1 + i, stdhep, secondary,
878 list_of_stable );
879 }
880 return;
881}
882
884{
885 //first add particle to the stdhep list;
886 stdhep.createParticle( getP4Lab(), get4Pos(), -1, -1,
888
889 for ( size_t i = 0; i < m_ndaug; i++ ) {
890 stdhep.createParticle( m_daug[i]->getP4Lab(), m_daug[i]->get4Pos(), 0,
891 0, EvtPDL::getStdHep( m_daug[i]->getId() ) );
892 }
893
894 for ( size_t i = 0; i < m_ndaug; i++ ) {
895 m_daug[i]->makeStdHepRec( 1 + i, 1 + i, stdhep );
896 }
897 return;
898}
899
900void EvtParticle::makeStdHepRec( int firstparent, int lastparent,
901 EvtStdHep& stdhep, EvtSecondary& secondary,
902 EvtId* list_of_stable )
903{
904 int ii = 0;
905
906 //lets see if this is a longlived particle and terminate the
907 //list building!
908
909 while ( list_of_stable[ii] != EvtId( -1, -1 ) ) {
910 if ( getId() == list_of_stable[ii] ) {
911 secondary.createSecondary( firstparent, this );
912 return;
913 }
914 ii++;
915 }
916
917 int parent_num = stdhep.getNPart();
918 for ( size_t i = 0; i < m_ndaug; i++ ) {
919 stdhep.createParticle( m_daug[i]->getP4Lab(), m_daug[i]->get4Pos(),
920 firstparent, lastparent,
921 EvtPDL::getStdHep( m_daug[i]->getId() ) );
922 }
923
924 for ( size_t i = 0; i < m_ndaug; i++ ) {
925 m_daug[i]->makeStdHepRec( parent_num + i, parent_num + i, stdhep,
926 secondary, list_of_stable );
927 }
928 return;
929}
930
931void EvtParticle::makeStdHepRec( int firstparent, int lastparent,
932 EvtStdHep& stdhep )
933{
934 int parent_num = stdhep.getNPart();
935 for ( size_t i = 0; i < m_ndaug; i++ ) {
936 stdhep.createParticle( m_daug[i]->getP4Lab(), m_daug[i]->get4Pos(),
937 firstparent, lastparent,
938 EvtPDL::getStdHep( m_daug[i]->getId() ) );
939 }
940
941 for ( size_t i = 0; i < m_ndaug; i++ ) {
942 m_daug[i]->makeStdHepRec( parent_num + i, parent_num + i, stdhep );
943 }
944 return;
945}
946
947void EvtParticle::printTreeRec( unsigned int level ) const
948{
949 size_t newlevel, i;
950 newlevel = level + 1;
951
952 if ( m_ndaug != 0 ) {
953 if ( level > 0 ) {
954 for ( i = 0; i < ( 5 * level ); i++ ) {
955 EvtGenReport( EVTGEN_INFO, "" ) << " ";
956 }
957 }
958 EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( m_id ).c_str();
959 EvtGenReport( EVTGEN_INFO, "" ) << " -> ";
960 for ( i = 0; i < m_ndaug; i++ ) {
962 << EvtPDL::name( m_daug[i]->getId() ).c_str() << " ";
963 }
964 for ( i = 0; i < m_ndaug; i++ ) {
966 << m_daug[i]->mass() << " " << m_daug[i]->getP4() << " "
967 << m_daug[i]->getSpinStates() << "; ";
968 }
969 EvtGenReport( EVTGEN_INFO, "" ) << endl;
970 for ( i = 0; i < m_ndaug; i++ ) {
971 m_daug[i]->printTreeRec( newlevel );
972 }
973 }
974}
975
977{
978 EvtGenReport( EVTGEN_INFO, "EvtGen" )
979 << "This is the current decay chain" << endl;
981 << "This top particle is " << EvtPDL::name( m_id ).c_str() << " "
982 << this->mass() << " " << this->getP4() << endl;
983
984 this->printTreeRec( 0 );
985 EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "End of decay chain." << endl;
986}
987
988std::string EvtParticle::treeStrRec( unsigned int level ) const
989{
990 size_t newlevel, i;
991 newlevel = level + 1;
992
993 std::string retval = "";
994
995 for ( i = 0; i < m_ndaug; i++ ) {
996 retval += EvtPDL::name( m_daug[i]->getId() );
997 if ( m_daug[i]->getNDaug() > 0 ) {
998 retval += " (";
999 retval += m_daug[i]->treeStrRec( newlevel );
1000 retval += ") ";
1001 } else {
1002 if ( i + 1 != m_ndaug )
1003 retval += " ";
1004 }
1005 }
1006
1007 return retval;
1008}
1009
1010std::string EvtParticle::treeStr() const
1011{
1012 std::string retval = EvtPDL::name( m_id );
1013 retval += " -> ";
1014
1015 retval += treeStrRec( 0 );
1016
1017 return retval;
1018}
1019
1021{
1022 switch ( EvtPDL::getSpinType( m_id ) ) {
1024 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1025 << "This is a scalar particle:" << EvtPDL::name( m_id ).c_str()
1026 << "\n";
1027 break;
1029 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1030 << "This is a vector particle:" << EvtPDL::name( m_id ).c_str()
1031 << "\n";
1032 break;
1034 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1035 << "This is a tensor particle:" << EvtPDL::name( m_id ).c_str()
1036 << "\n";
1037 break;
1038 case EvtSpinType::DIRAC:
1039 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1040 << "This is a dirac particle:" << EvtPDL::name( m_id ).c_str()
1041 << "\n";
1042 break;
1044 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1045 << "This is a photon:" << EvtPDL::name( m_id ).c_str() << "\n";
1046 break;
1048 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1049 << "This is a neutrino:" << EvtPDL::name( m_id ).c_str() << "\n";
1050 break;
1052 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1053 << "This is a string:" << EvtPDL::name( m_id ).c_str() << "\n";
1054 break;
1055 default:
1056 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1057 << "Unknown particle type in EvtParticle::printParticle()"
1058 << endl;
1059 break;
1060 }
1061 EvtGenReport( EVTGEN_INFO, "EvtGen" )
1062 << "Number of daughters:" << m_ndaug << "\n";
1063}
1064
1066{
1067 *part = new EvtVectorParticle;
1068}
1069
1071{
1072 *part = new EvtScalarParticle;
1073}
1074
1076{
1077 *part = new EvtTensorParticle;
1078}
1079
1081{
1082 *part = new EvtDiracParticle;
1083}
1084
1086{
1087 *part = new EvtPhotonParticle;
1088}
1089
1091{
1092 *part = new EvtNeutrinoParticle;
1093}
1094
1096{
1097 *part = new EvtStringParticle;
1098}
1099
1100double EvtParticle::initializePhaseSpace( size_t numdaughter,
1101 const EvtId* daughters,
1102 bool forceDaugMassReset,
1103 double poleSize, int whichTwo1,
1104 int whichTwo2 )
1105{
1106 double m_b;
1107 size_t i;
1108 //lange
1109 // this->makeDaughters(numdaughter,daughters);
1110
1111 static thread_local EvtVector4R p4[100];
1112 static thread_local double mass[100];
1113
1114 m_b = this->mass();
1115
1116 //lange - Jan2,2002 - Need to check to see if the daughters of the parent
1117 // have changed. If so, delete them and start over.
1118 //EvtGenReport(EVTGEN_INFO,"EvtGen") << "the parent is\n";
1119 //if ( this->getParent() ) {
1120 // if ( this->getParent()->getParent() ) this->getParent()->getParent()->printTree();
1121 // this->getParent()->printTree();
1122 //}
1123 //EvtGenReport(EVTGEN_INFO,"EvtGen") << "and this is\n";
1124 //if ( this) this->printTree();
1125 bool resetDaughters = false;
1126
1127 if ( numdaughter != this->getNDaug() && this->getNDaug() > 0 )
1128 resetDaughters = true;
1129 if ( numdaughter == this->getNDaug() )
1130 for ( i = 0; i < numdaughter; i++ ) {
1131 if ( this->getDaug( i )->getId() != daughters[i] )
1132 resetDaughters = true;
1133 //EvtGenReport(EVTGEN_INFO,"EvtGen") << EvtPDL::name(this->getDaug(i)->getId())
1134 // << " " << EvtPDL::name(daughters[i]) << endl;
1135 }
1136
1137 if ( resetDaughters || forceDaugMassReset ) {
1138 bool t1 = true;
1139 //but keep the decay channel of the parent.
1140 this->deleteDaughters( t1 );
1141 this->makeDaughters( numdaughter, daughters );
1142 bool massTreeOK = this->generateMassTree();
1143 if ( massTreeOK == false ) {
1144 return 0.0;
1145 }
1146 }
1147
1148 double weight = 0.;
1149 for ( i = 0; i < numdaughter; i++ ) {
1150 mass[i] = this->getDaug( i )->mass();
1151 }
1152
1153 if ( poleSize < -0.1 ) {
1154 //special case to enforce 4-momentum conservation in 1->1 decays
1155 if ( numdaughter == 1 ) {
1156 this->getDaug( 0 )->init( daughters[0],
1157 EvtVector4R( m_b, 0.0, 0.0, 0.0 ) );
1158 } else {
1159 EvtGenKine::PhaseSpace( numdaughter, mass, p4, m_b );
1160 for ( i = 0; i < numdaughter; i++ ) {
1161 this->getDaug( i )->init( daughters[i], p4[i] );
1162 }
1163 }
1164 } else {
1165 if ( numdaughter != 3 ) {
1166 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
1167 << "Only can generate pole phase space "
1168 << "distributions for 3 body final states" << endl
1169 << "Will terminate." << endl;
1170 ::abort();
1171 }
1172 bool ok = false;
1173 if ( ( whichTwo1 == 1 && whichTwo2 == 0 ) ||
1174 ( whichTwo1 == 0 && whichTwo2 == 1 ) ) {
1175 weight = EvtGenKine::PhaseSpacePole( m_b, mass[0], mass[1], mass[2],
1176 poleSize, p4 );
1177 this->getDaug( 0 )->init( daughters[0], p4[0] );
1178 this->getDaug( 1 )->init( daughters[1], p4[1] );
1179 this->getDaug( 2 )->init( daughters[2], p4[2] );
1180 ok = true;
1181 }
1182 if ( ( whichTwo1 == 1 && whichTwo2 == 2 ) ||
1183 ( whichTwo1 == 2 && whichTwo2 == 1 ) ) {
1184 weight = EvtGenKine::PhaseSpacePole( m_b, mass[2], mass[1], mass[0],
1185 poleSize, p4 );
1186 this->getDaug( 0 )->init( daughters[0], p4[2] );
1187 this->getDaug( 1 )->init( daughters[1], p4[1] );
1188 this->getDaug( 2 )->init( daughters[2], p4[0] );
1189 ok = true;
1190 }
1191 if ( ( whichTwo1 == 0 && whichTwo2 == 2 ) ||
1192 ( whichTwo1 == 2 && whichTwo2 == 0 ) ) {
1193 weight = EvtGenKine::PhaseSpacePole( m_b, mass[1], mass[0], mass[2],
1194 poleSize, p4 );
1195 this->getDaug( 0 )->init( daughters[0], p4[1] );
1196 this->getDaug( 1 )->init( daughters[1], p4[0] );
1197 this->getDaug( 2 )->init( daughters[2], p4[2] );
1198 ok = true;
1199 }
1200 if ( !ok ) {
1201 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
1202 << "Invalid pair of particle to generate a pole dist "
1203 << whichTwo1 << " " << whichTwo2 << endl
1204 << "Will terminate." << endl;
1205 ::abort();
1206 }
1207 }
1208
1209 return weight;
1210}
1211
1212void EvtParticle::makeDaughters( size_t ndaugstore, std::vector<EvtId> idVector )
1213{
1214 // Convert the STL vector method to use the array method for now, since the
1215 // array method pervades most of the EvtGen code...
1216
1217 size_t nVector = idVector.size();
1218 if ( nVector < ndaugstore ) {
1219 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
1220 << "Asking to make " << ndaugstore << " daughters when there "
1221 << "are only " << nVector << " EvtId values available" << endl;
1222 return;
1223 }
1224
1225 EvtId* idArray = new EvtId[ndaugstore];
1226 for ( size_t i = 0; i < ndaugstore; i++ ) {
1227 idArray[i] = idVector[i];
1228 }
1229
1230 this->makeDaughters( ndaugstore, idArray );
1231
1232 delete[] idArray;
1233}
1234
1235void EvtParticle::makeDaughters( size_t ndaugstore, const EvtId* id )
1236{
1237 if ( m_channel < 0 ) {
1238 setChannel( 0 );
1239 }
1240 EvtParticle* pdaug;
1241 if ( m_ndaug != 0 ) {
1242 if ( m_ndaug != ndaugstore ) {
1243 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
1244 << "Asking to make a different number of "
1245 << "daughters than what was previously created." << endl;
1246 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
1247 << "Original parent:" << EvtPDL::name( m_id ) << endl;
1248 for ( size_t i = 0; i < m_ndaug; i++ ) {
1249 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
1250 << "Original daugther:"
1251 << EvtPDL::name( getDaug( i )->getId() ) << endl;
1252 }
1253 for ( size_t i = 0; i < ndaugstore; i++ ) {
1254 EvtGenReport( EVTGEN_ERROR, "EvtGen" )
1255 << "New Daug:" << EvtPDL::name( id[i] ) << endl;
1256 }
1257 EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Will terminate." << endl;
1258 ::abort();
1259 }
1260 } else {
1261 for ( size_t i = 0; i < ndaugstore; i++ ) {
1263 EvtPDL::getSpinType( id[i] ) );
1264 pdaug->setId( id[i] );
1265 pdaug->addDaug( this );
1266 }
1267
1268 } //else
1269} //makeDaughters
1270
1271void EvtParticle::setDecayProb( double prob )
1272{
1273 if ( m_decayProb == nullptr )
1274 m_decayProb = new double;
1275 *m_decayProb = prob;
1276}
1277
1278std::string EvtParticle::getName() const
1279{
1280 std::string theName = m_id.getName();
1281 return theName;
1282}
1283
1284int EvtParticle::getAttribute( std::string attName ) const
1285{
1286 // Retrieve the attribute integer if the name exists.
1287 // Otherwise, simply return 0
1288
1289 int attValue = 0;
1290
1291 EvtAttIntMap::const_iterator mapIter;
1292
1293 if ( ( mapIter = m_intAttributes.find( attName ) ) != m_intAttributes.end() ) {
1294 attValue = mapIter->second;
1295 }
1296
1297 return attValue;
1298}
1299
1300double EvtParticle::getAttributeDouble( std::string attName ) const
1301{
1302 // Retrieve the attribute double if the name exists.
1303 // Otherwise, simply return 0.0
1304
1305 double attValue = 0.0;
1306
1307 EvtAttDblMap::const_iterator mapIter;
1308
1309 if ( ( mapIter = m_dblAttributes.find( attName ) ) != m_dblAttributes.end() ) {
1310 attValue = mapIter->second;
1311 }
1312
1313 return attValue;
1314}
EvtComplex conj(const EvtComplex &c)
void init_photon(EvtParticle **part)
void init_dirac(EvtParticle **part)
void init_neutrino(EvtParticle **part)
void init_vector(EvtParticle **part)
void init_tensor(EvtParticle **part)
void init_scalar(EvtParticle **part)
void init_string(EvtParticle **part)
EvtRaritaSchwinger boostTo(const EvtRaritaSchwinger &rs, const EvtVector4R p4)
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
static EvtCPUtil * getInstance()
Definition EvtCPUtil.cpp:42
void incoherentMix(const EvtId id, double &t, int &mix)
virtual void makeDecay(EvtParticle *p, bool recursive=true)=0
virtual int nRealDaughters() const
const EvtId * getDaugs() const
static EvtDecayTable & getInstance()
EvtDecayBase * getDecayFunc(EvtParticle *p)
static double PhaseSpacePole(double M, double m1, double m2, double m3, double a, EvtVector4R p4[10])
static double PhaseSpace(int ndaug, double mass[30], EvtVector4R p4[30], double mp)
bool contains(const EvtId &id) const
Definition EvtIdSet.cpp:46
Definition EvtId.hh:27
static double getWidth(EvtId i)
Definition EvtPDL.cpp:346
static EvtSpinType::spintype getSpinType(EvtId i)
Definition EvtPDL.cpp:371
static int getStdHep(EvtId id)
Definition EvtPDL.cpp:356
static double getMass(EvtId i)
Definition EvtPDL.cpp:311
static double getRandMass(EvtId i, EvtId *parId, int nDaug, EvtId *dauId, EvtId *othDaugId, double maxMass, double *dauMasses)
Definition EvtPDL.cpp:316
static std::string name(EvtId i)
Definition EvtPDL.cpp:376
static double getMeanMass(EvtId i)
Definition EvtPDL.cpp:306
static EvtId chargeConj(EvtId id)
Definition EvtPDL.cpp:201
static double getMassProb(EvtId i, double mass, double massPar, int nDaug, double *massDau)
Definition EvtPDL.cpp:324
static double getctau(EvtId i)
Definition EvtPDL.cpp:351
static double getMinMass(EvtId i)
Definition EvtPDL.cpp:336
static EvtId getId(const std::string &name)
Definition EvtPDL.cpp:283
static EvtParticle * particleFactory(EvtSpinType::spintype spinType)
void setMass(double m)
void setSpinDensityForwardHelicityBasis(const EvtSpinDensity &rho)
void setDecayProb(double p)
virtual ~EvtParticle()
virtual EvtVector4C epsParent(int i) const
EvtAttIntMap m_intAttributes
double getAttributeDouble(std::string attName) const
void initDecay(bool useMinMass=false)
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
void insertDaugPtr(int idaug, EvtParticle *partptr)
virtual EvtTensor4C epsTensorParent(int i) const
double initializePhaseSpace(size_t numdaughter, const EvtId *daughters, bool forceResetMasses=false, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
EvtVector4R m_p
std::string treeStrRec(unsigned int level) const
EvtId getId() const
virtual EvtRaritaSchwinger spRSParent(int) const
EvtVector4R getP4Restframe() const
void printTreeRec(unsigned int level) const
virtual EvtDiracSpinor spParentNeutrino() const
virtual EvtDiracSpinor spParent(int) const
void setVectorSpinDensity()
bool hasValidP4()
EvtVector4R getP4LabBeforeFSR() const
void printParticle() const
virtual EvtDiracSpinor spNeutrino() const
EvtVector4R m_pBeforeFSR
virtual EvtRaritaSchwinger spRS(int) const
int getSpinStates() const
int getPDGId() const
void setLifetime()
void setDiagonalSpinDensity()
double compMassProb()
EvtSpinType::spintype getSpinType() const
void setChannel(int i)
const EvtVector4R & getP4() const
EvtParticle * nextIter(EvtParticle *rootOfTree=nullptr)
void printTree() const
void setLifetime(double tau)
virtual EvtSpinDensity rotateToHelicityBasis() const =0
EvtAttDblMap m_dblAttributes
void resetFirstOrNot()
std::string getName() const
EvtParticle * getDaug(const int i)
void deleteDaughters(bool keepChannel=false)
double getLifetime() const
double * m_decayProb
double mass() const
virtual EvtDiracSpinor sp(int) const
virtual EvtVector4C epsPhoton(int i) const
virtual EvtVector4C epsParentPhoton(int i) const
EvtParticle * m_daug[MAX_DAUG]
void makeStdHep(EvtStdHep &stdhep, EvtSecondary &secondary, EvtId *stable_parent_ihep)
size_t getNDaug() const
EvtSpinDensity m_rhoForward
int firstornot() const
EvtSpinDensity m_rhoBackward
EvtVector4R getP4Lab() const
EvtParticle * m_parent
virtual EvtVector4C eps(int i) const
void addDaug(EvtParticle *node)
std::string treeStr() const
bool generateMassTree()
int getChannel() const
virtual EvtTensor4C epsTensor(int i) const
void setId(EvtId id)
EvtVector4R get4Pos() const
void makeStdHepRec(int firstparent, int lastparent, EvtStdHep &stdhep, EvtSecondary &secondary, EvtId *stable_parent_ihep)
EvtParticle * getParent() const
void setFirstOrNot()
void makeDaughters(size_t ndaug, const EvtId *id)
int getAttribute(std::string attName) const
void deleteTree()
static double Flat()
Definition EvtRandom.cpp:95
void init(EvtId part_n, double e, double px, double py, double pz)
void createSecondary(int stdhepindex, EvtParticle *prnt)
void setDiag(int n)
const EvtComplex & get(int i, int j) const
void set(int i, int j, const EvtComplex &rhoij)
static int getSpinStates(spintype stype)
void createParticle(EvtVector4R p4, EvtVector4R x, int prntfirst, int prntlast, int id)
Definition EvtStdHep.cpp:39
int getNPart()
Definition EvtStdHep.cpp:34
void set(int i, double d)