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.
EvtParticleDecayList.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/EvtPDL.hh"
25 #include "EvtGenBase/EvtPatches.hh"
26 #include "EvtGenBase/EvtRandom.hh"
27 #include "EvtGenBase/EvtReport.hh"
28 #include "EvtGenBase/EvtStatus.hh"
29 
30 #include <ctype.h>
31 #include <fstream>
32 #include <iostream>
33 #include <stdlib.h>
34 using std::endl;
35 using std::fstream;
36 
38 {
39  _nmode = o._nmode;
42 
43  int i;
44  for ( i = 0; i < _nmode; i++ ) {
46 
47  EvtDecayBase* tModel = o._decaylist[i]->getDecayModel();
48 
49  EvtDecayBase* tModelNew = tModel->clone();
50  if ( tModel->getPHOTOS() ) {
51  tModelNew->setPHOTOS();
52  }
53  if ( tModel->verbose() ) {
54  tModelNew->setVerbose();
55  }
56  if ( tModel->summary() ) {
57  tModelNew->setSummary();
58  }
59  std::vector<std::string> args;
60  int j;
61  for ( j = 0; j < tModel->getNArg(); j++ ) {
62  args.push_back( tModel->getArgStr( j ) );
63  }
64  tModelNew->saveDecayInfo( tModel->getParentId(), tModel->getNDaug(),
65  tModel->getDaugs(), tModel->getNArg(), args,
66  tModel->getModelName(),
67  tModel->getBranchingFraction() );
68  _decaylist[i]->setDecayModel( tModelNew );
69 
72  }
73 }
74 
76 {
77  int i;
78  for ( i = 0; i < _nmode; i++ ) {
79  delete _decaylist[i];
80  }
81 
82  if ( _decaylist != 0 )
83  delete[] _decaylist;
84 }
85 
87 {
88  int i;
89  for ( i = 0; i < _nmode; i++ ) {
91  }
92 }
93 
95 {
96  int i;
97  for ( i = 0; i < _nmode; i++ ) {
98  delete _decaylist[i];
99  }
100 
101  delete[] _decaylist;
102  _decaylist = 0;
103  _nmode = 0;
104  _rawbrfrsum = 0.0;
105 }
106 
108 {
109  EvtDecayBase* theModel( 0 );
110  if ( imode >= 0 && imode < _nmode ) {
111  EvtParticleDecay* theDecay = _decaylist[imode];
112  if ( theDecay != 0 ) {
113  theModel = theDecay->getDecayModel();
114  }
115  }
116 
117  return theModel;
118 }
119 
121 {
122  if ( p->getNDaug() != 0 ) {
123  assert( p->getChannel() >= 0 );
124  return getDecay( p->getChannel() ).getDecayModel();
125  }
126  if ( p->getChannel() > ( -1 ) ) {
127  return getDecay( p->getChannel() ).getDecayModel();
128  }
129 
130  if ( getNMode() == 0 ) {
131  return 0;
132  }
133  if ( getRawBrfrSum() < 0.00000001 ) {
134  return 0;
135  }
136 
137  if ( getNMode() == 1 ) {
138  p->setChannel( 0 );
139  return getDecay( 0 ).getDecayModel();
140  }
141 
142  if ( p->getChannel() > ( -1 ) ) {
143  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Internal error!!!" << endl;
144  ::abort();
145  }
146 
147  int j;
148 
149  for ( j = 0; j < 10000000; j++ ) {
150  double u = EvtRandom::Flat();
151 
152  int i;
153  bool breakL = false;
154  for ( i = 0; i < getNMode(); i++ ) {
155  if ( breakL )
156  continue;
157  if ( u < getDecay( i ).getBrfrSum() ) {
158  breakL = true;
159  //special case for decay of on particel to another
160  // e.g. K0->K0S
161 
162  if ( getDecay( i ).getDecayModel()->getNDaug() == 1 ) {
163  p->setChannel( i );
164  return getDecay( i ).getDecayModel();
165  }
166 
167  if ( p->hasValidP4() ) {
168  if ( getDecay( i ).getMassMin() < p->mass() ) {
169  p->setChannel( i );
170  return getDecay( i ).getDecayModel();
171  }
172  } else {
173  //Lange apr29-2002 - dont know the mass yet
174  p->setChannel( i );
175  return getDecay( i ).getDecayModel();
176  }
177  }
178  }
179  }
180 
181  //Ok, we tried 10000000 times above to pick a decay channel that is
182  //kinematically allowed! Now we give up and search all channels!
183  //if that fails, the particle will not be decayed!
184 
185  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
186  << "Tried 10000000 times to generate decay of "
187  << EvtPDL::name( p->getId() ) << " with mass=" << p->mass() << endl;
188  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
189  << "Will take first kinematically allowed decay in the decay table"
190  << endl;
191 
192  int i;
193 
194  //Need to check that we don't use modes with 0 branching fractions.
195  double previousBrSum = 0.0;
196  for ( i = 0; i < getNMode(); i++ ) {
197  if ( getDecay( i ).getBrfrSum() != previousBrSum ) {
198  if ( getDecay( i ).getMassMin() < p->mass() ) {
199  p->setChannel( i );
200  return getDecay( i ).getDecayModel();
201  }
202  }
203  previousBrSum = getDecay( i ).getBrfrSum();
204  }
205 
206  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
207  << "Could not decay:" << EvtPDL::name( p->getId() ).c_str()
208  << " with mass:" << p->mass() << " will throw event away! " << endl;
209 
211  return 0;
212 }
213 
215 {
216  EvtParticleDecayPtr* _decaylist_new = new EvtParticleDecayPtr[nmode];
217 
218  if ( _nmode != 0 ) {
219  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
220  << "Error _nmode not equal to zero!!!" << endl;
221  ::abort();
222  }
223  if ( _decaylist != 0 ) {
224  delete[] _decaylist;
225  }
226  _decaylist = _decaylist_new;
227  _nmode = nmode;
228 }
229 
231 {
232  if ( nchannel >= _nmode ) {
233  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
234  << "Error getting channel:" << nchannel << " with only " << _nmode
235  << " stored!" << endl;
236  ::abort();
237  }
238  return *( _decaylist[nchannel] );
239 }
240 
242 {
243  _rawbrfrsum = conjDecayList->_rawbrfrsum;
244 
245  setNMode( conjDecayList->_nmode );
246 
247  int i;
248 
249  for ( i = 0; i < _nmode; i++ ) {
250  _decaylist[i] = new EvtParticleDecay;
251  _decaylist[i]->chargeConj( conjDecayList->_decaylist[i] );
252  }
253 }
254 
255 void EvtParticleDecayList::addMode( EvtDecayBase* decay, double brfrsum,
256  double massmin )
257 {
258  EvtParticleDecayPtr* newlist = new EvtParticleDecayPtr[_nmode + 1];
259 
260  int i;
261  for ( i = 0; i < _nmode; i++ ) {
262  newlist[i] = _decaylist[i];
263  }
264 
265  _rawbrfrsum = brfrsum;
266 
267  newlist[_nmode] = new EvtParticleDecay;
268 
269  newlist[_nmode]->setDecayModel( decay );
270  newlist[_nmode]->setBrfrSum( brfrsum );
271  newlist[_nmode]->setMassMin( massmin );
272 
273  EvtDecayBase* newDec = newlist[_nmode]->getDecayModel();
274  for ( i = 0; i < _nmode; i++ ) {
275  if ( newDec->matchingDecay( *( newlist[i]->getDecayModel() ) ) ) {
276  //sometimes its ok..
277  if ( newDec->getModelName() == "JETSET" ||
278  newDec->getModelName() == "PYTHIA" )
279  continue;
280  if ( newDec->getModelName() == "JSCONT" ||
281  newDec->getModelName() == "PYCONT" )
282  continue;
283  if ( newDec->getModelName() == "PYGAGA" )
284  continue;
285  if ( newDec->getModelName() == "LUNDAREALAW" )
286  continue;
287  if ( newDec->getModelName() == "TAUOLA" )
288  continue;
289  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
290  << "Two matching decays with same parent in decay table\n";
291  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Please fix that\n";
292  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
293  << "Parent " << EvtPDL::name( newDec->getParentId() ).c_str()
294  << endl;
295  for ( int j = 0; j < newDec->getNDaug(); j++ )
296  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
297  << "Daughter "
298  << EvtPDL::name( newDec->getDaug( j ) ).c_str() << endl;
299  assert( 0 );
300  }
301  }
302 
303  if ( _nmode != 0 ) {
304  delete[] _decaylist;
305  }
306 
307  if ( ( _nmode == 0 ) && ( _decaylist != 0 ) )
308  delete[] _decaylist;
309 
310  _nmode++;
311 
312  _decaylist = newlist;
313 }
314 
316 {
317  if ( _nmode > 0 ) {
318  if ( _rawbrfrsum < 0.000001 ) {
319  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
320  << "Please give me a "
321  << "branching fraction sum greater than 0\n";
322  assert( 0 );
323  }
324  if ( fabs( _rawbrfrsum - 1.0 ) > 0.0001 ) {
325  EvtGenReport( EVTGEN_INFO, "EvtGen" )
326  << "Warning, sum of branching fractions for "
327  << EvtPDL::name( _decaylist[0]->getDecayModel()->getParentId() )
328  .c_str()
329  << " is " << _rawbrfrsum << endl;
330  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "rescaled to one! " << endl;
331  }
332 
333  int i;
334 
335  for ( i = 0; i < _nmode; i++ ) {
336  double brfrsum = _decaylist[i]->getBrfrSum() / _rawbrfrsum;
337  _decaylist[i]->setBrfrSum( brfrsum );
338  }
339  }
340 }
341 
343 {
344  if ( this != &o ) {
345  removeDecay();
346  _nmode = o._nmode;
349 
350  int i;
351  for ( i = 0; i < _nmode; i++ ) {
352  _decaylist[i] = new EvtParticleDecay;
353 
354  EvtDecayBase* tModel = o._decaylist[i]->getDecayModel();
355 
356  EvtDecayBase* tModelNew = tModel->clone();
357  if ( tModel->getPHOTOS() ) {
358  tModelNew->setPHOTOS();
359  }
360  if ( tModel->verbose() ) {
361  tModelNew->setVerbose();
362  }
363  if ( tModel->summary() ) {
364  tModelNew->setSummary();
365  }
366  std::vector<std::string> args;
367  int j;
368  for ( j = 0; j < tModel->getNArg(); j++ ) {
369  args.push_back( tModel->getArgStr( j ) );
370  }
371  tModelNew->saveDecayInfo( tModel->getParentId(), tModel->getNDaug(),
372  tModel->getDaugs(), tModel->getNArg(),
373  args, tModel->getModelName(),
374  tModel->getBranchingFraction() );
375  _decaylist[i]->setDecayModel( tModelNew );
376 
377  //_decaylist[i]->setDecayModel(tModel);
380  }
381  }
382  return *this;
383 }
384 
386 {
387  // here we will delete a decay with the same final state particles
388  // and recalculate the branching fractions for the remaining modes
389  int match = -1;
390  int i;
391  double match_bf;
392 
393  for ( i = 0; i < _nmode; i++ ) {
394  if ( decay->matchingDecay( *( _decaylist[i]->getDecayModel() ) ) ) {
395  match = i;
396  }
397  }
398 
399  if ( match < 0 ) {
400  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
401  << " Attempt to remove undefined mode for" << endl
402  << "Parent " << EvtPDL::name( decay->getParentId() ).c_str() << endl
403  << "Daughters: ";
404  for ( int j = 0; j < decay->getNDaug(); j++ )
406  << EvtPDL::name( decay->getDaug( j ) ).c_str() << " ";
407  EvtGenReport( EVTGEN_ERROR, "" ) << endl;
408  ::abort();
409  }
410 
411  if ( match == 0 ) {
412  match_bf = _decaylist[match]->getBrfrSum();
413  } else {
414  match_bf = ( _decaylist[match]->getBrfrSum() -
415  _decaylist[match - 1]->getBrfrSum() );
416  }
417 
418  double divisor = 1 - match_bf;
419  if ( divisor < 0.000001 && _nmode > 1 ) {
420  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
421  << "Removing requested mode leaves "
422  << EvtPDL::name( decay->getParentId() ).c_str()
423  << " with zero sum branching fraction," << endl
424  << "but more than one decay mode remains. Aborting." << endl;
425  ::abort();
426  }
427 
428  EvtParticleDecayPtr* newlist = new EvtParticleDecayPtr[_nmode - 1];
429 
430  for ( i = 0; i < match; i++ ) {
431  newlist[i] = _decaylist[i];
432  newlist[i]->setBrfrSum( newlist[i]->getBrfrSum() / divisor );
433  }
434  for ( i = match + 1; i < _nmode; i++ ) {
435  newlist[i - 1] = _decaylist[i];
436  newlist[i - 1]->setBrfrSum(
437  ( newlist[i - 1]->getBrfrSum() - match_bf ) / divisor );
438  }
439 
440  delete[] _decaylist;
441 
442  _nmode--;
443 
444  _decaylist = newlist;
445 
446  if ( _nmode == 0 ) {
447  delete[] _decaylist;
448  }
449 }
450 
452 {
453  int i;
454  EvtDecayBase* decayer;
455 
456  for ( i = 0; i < getNMode(); i++ ) {
457  decayer = getDecay( i ).getDecayModel();
458  if ( decayer->getModelName() == "PYTHIA" )
459  return true;
460  }
461 
462  return false;
463 }
void setChannel(int i)
Definition: EvtParticle.cpp:86
const char * c_str(Index i)
Definition: EvtCyclic3.cpp:323
void addMode(EvtDecayBase *decay, double brfr, double massmin)
static std::string name(EvtId i)
Definition: EvtPDL.cpp:382
void setDecayModel(EvtDecayBase *decay)
void removeMode(EvtDecayBase *decay)
std::string getArgStr(int j) const
Definition: EvtDecayBase.hh:78
void setPHOTOS()
Definition: EvtDecayBase.hh:70
void makeChargeConj(EvtParticleDecayList *conjDecayList)
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
EvtDecayBase * getDecayModel()
EvtId getId() const
int summary() const
Definition: EvtDecayBase.hh:81
EvtId * getDaugs()
Definition: EvtDecayBase.hh:66
bool hasValidP4()
Definition: EvtParticle.hh:403
size_t getNDaug() const
int getPHOTOS() const
Definition: EvtDecayBase.hh:69
EvtId getParentId() const
Definition: EvtDecayBase.hh:61
void setBrfrSum(double brfrsum)
void saveDecayInfo(EvtId ipar, int ndaug, EvtId *daug, int narg, std::vector< std::string > &args, std::string name, double brfr)
double getBranchingFraction() const
Definition: EvtDecayBase.hh:62
EvtParticleDecayPtr * _decaylist
static double Flat()
Definition: EvtRandom.cpp:72
int getChannel() const
std::string getModelName() const
Definition: EvtDecayBase.hh:79
static void setRejectFlag()
Definition: EvtStatus.hh:26
EvtParticleDecayList & operator=(const EvtParticleDecayList &o)
double mass() const
void chargeConj(EvtParticleDecay *decay)
int getNDaug() const
Definition: EvtDecayBase.hh:65
EvtDecayBase * getDecayModel(EvtParticle *p)
virtual EvtDecayBase * clone()=0
int verbose() const
Definition: EvtDecayBase.hh:82
void setVerbose()
Definition: EvtDecayBase.hh:71
void setMassMin(double massmin)
virtual bool matchingDecay(const EvtDecayBase &other) const
void setSummary()
Definition: EvtDecayBase.hh:72
int getNArg() const
Definition: EvtDecayBase.hh:68
EvtParticleDecay & getDecay(int nchannel) const
EvtId getDaug(int i) const
Definition: EvtDecayBase.hh:67