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