BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
EvtDecayBase.cc
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2//
3// Environment:
4// This software is part of the EvtGen package developed jointly
5// for the BaBar and CLEO collaborations. If you use all or part
6// of it, please give an appropriate acknowledgement.
7//
8// Copyright Information: See EvtGen/COPYRIGHT
9// Copyright (C) 1998 Caltech, UCSB
10//
11// Module: EvtDecayBase.cc
12//
13// Description: Store decay parameters for one decay.
14//
15// Modification history:
16//
17// RYD September 30, 1997 Module created
18//
19//------------------------------------------------------------------------
20//
21#include "EvtDecayBase.hh"
22#include "EvtPDL.hh"
23#include "EvtParticle.hh"
24#include "EvtPatches.hh"
25#include "EvtReport.hh"
26#include "EvtSpinType.hh"
27#include "EvtStatus.hh"
28#include <ctype.h>
29#include <fstream>
30#include <iostream>
31#include <stdlib.h>
32#include <vector>
33using std::endl;
34using std::fstream;
36 int i;
37 int q = 0;
38 int qpar;
39
40 // If there are no daughters (jetset etc) then we do not
41 // want to do this test. Why? Because sometimes the parent
42 // will have a nonzero charge.
43
44 if ( _ndaug != 0 )
45 {
46 for ( i = 0; i < _ndaug; i++ ) { q += EvtPDL::chg3( _daug[i] ); }
47 qpar = EvtPDL::chg3( _parent );
48
49 if ( q != qpar )
50 {
51 report( ERROR, "EvtGen" ) << _modelname.c_str() << " generator expected "
52 << " charge to be conserved, found:" << endl;
53 report( ERROR, "EvtGen" ) << "Parent charge of " << ( qpar / 3 ) << endl;
54 report( ERROR, "EvtGen" ) << "Sum of daughter charge of " << ( q / 3 ) << endl;
55 report( ERROR, "EvtGen" ) << "The parent is " << EvtPDL::name( _parent ).c_str() << endl;
56 for ( i = 0; i < _ndaug; i++ )
57 { report( ERROR, "EvtGen" ) << "Daughter " << EvtPDL::name( _daug[i] ).c_str() << endl; }
58 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
59
60 ::abort();
61 }
62 }
63}
64
65double EvtDecayBase::getProbMax( double prob ) {
66
67 int i;
68
69 // diagnostics
70 sum_prob += prob;
71 if ( prob > max_prob ) max_prob = prob;
72
73 if ( defaultprobmax && ntimes_prob <= 500 )
74 {
75 // We are building up probmax with this iteration
76 ntimes_prob += 1;
77 if ( prob > probmax ) { probmax = prob; }
78 if ( ntimes_prob == 500 ) { probmax *= 1.2; }
79 return 1000000.0 * prob;
80 }
81
82 if ( prob > probmax * 1.0001 )
83 {
84
85 report( INFO, "EvtGen" ) << "prob > probmax:(" << prob << ">" << probmax << ")";
86 report( INFO, "" ) << "(" << _modelname.c_str() << ") ";
87 report( INFO, "" ) << EvtPDL::name( _parent ).c_str() << " -> ";
88 for ( i = 0; i < _ndaug; i++ )
89 { report( INFO, "" ) << EvtPDL::name( _daug[i] ).c_str() << " "; }
90 report( INFO, "" ) << endl;
91
92 if ( defaultprobmax ) probmax = prob;
93 }
94
95 ntimes_prob += 1;
96
97 return probmax;
98
99} // getProbMax
100
101double EvtDecayBase::resetProbMax( double prob ) {
102
103 report( INFO, "EvtGen" ) << "Reseting prob max\n";
104 report( INFO, "EvtGen" ) << "prob > probmax:(" << prob << ">" << probmax << ")";
105 report( INFO, "" ) << "(" << _modelname.c_str() << ")";
106 report( INFO, "" ) << EvtPDL::getStdHep( _parent ) << "->";
107
108 for ( int i = 0; i < _ndaug; i++ )
109 { report( INFO, "" ) << EvtPDL::getStdHep( _daug[i] ) << " "; }
110 report( INFO, "" ) << endl;
111
112 probmax = 0.0;
113 defaultprobmax = 0;
114 ntimes_prob = 0;
115
116 return prob;
117}
118
119std::string EvtDecayBase::commandName() { return std::string( "" ); }
120void EvtDecayBase::command( std::string cmd ) {
121 report( ERROR, "EvtGen" ) << "Should never call EvtDecayBase::command" << endl;
122 ::abort();
123}
124
126
127 // This default version of init does nothing;
128 // A specialized version of this function can be
129 // supplied for each decay model to do initialization.
130
131 return;
132}
133
135
136 // This function is called if the decay does not have a
137 // specialized initialization.
138 // The default is to set the maximum
139 // probability to 0 and the number of times called to 0
140 // and defaultprobmax to 1 such that the decay will be
141 // generated many many times
142 // in order to generate a reasonable maximum probability
143 // for the decay.
144
145 defaultprobmax = 1;
146 ntimes_prob = 0;
147 probmax = 0.0;
148
149} // initProbMax
150
151void EvtDecayBase::saveDecayInfo( EvtId ipar, int ndaug, EvtId* daug, int narg,
152 std::vector<std::string>& args, std::string name,
153 double brfr ) {
154
155 int i;
156
157 _brfr = brfr;
158 _ndaug = ndaug;
159 _narg = narg;
160 _parent = ipar;
161
162 _dsum = 0;
163
164 if ( _ndaug > 0 )
165 {
166 _daug = new EvtId[_ndaug];
167 for ( i = 0; i < _ndaug; i++ )
168 {
169 _daug[i] = daug[i];
170 _dsum += daug[i].getAlias();
171 }
172 }
173 else { _daug = 0; }
174
175 if ( _narg > 0 )
176 {
177 _args = new std::string[_narg + 1];
178 for ( i = 0; i < _narg; i++ ) { _args[i] = args[i]; }
179 }
180 else { _args = 0; }
181
182 _modelname = name;
183
184 this->init();
185 this->initProbMax();
186
187 if ( _chkCharge ) { this->checkQ(); }
188
189 if ( defaultprobmax )
190 {
191 report( INFO, "EvtGen" ) << "No default probmax for ";
192 report( INFO, "" ) << "(" << _modelname.c_str() << ") ";
193 report( INFO, "" ) << EvtPDL::name( _parent ).c_str() << " -> ";
194 for ( i = 0; i < _ndaug; i++ )
195 { report( INFO, "" ) << EvtPDL::name( _daug[i] ).c_str() << " "; }
196 report( INFO, "" ) << endl;
197 report( INFO, "" ) << "This is fine for development, but must be provided for production."
198 << endl;
199 report( INFO, "EvtGen" ) << "Never fear though - the decay will use the \n";
200 report( INFO, "EvtGen" ) << "500 iterations to build up a good probmax \n";
201 report( INFO, "EvtGen" ) << "before accepting a decay. " << endl;
202 }
203}
204
206
207 // the default is that the user module does _not_ set
208 // any probmax.
209 defaultprobmax = 1;
210 ntimes_prob = 0;
211 probmax = 0.0;
212
213 _photos = 0;
214 _verbose = 0;
215 _summary = 0;
216 _parent = EvtId( -1, -1 );
217 _ndaug = 0;
218 _narg = 0;
219 _daug = 0;
220 _args = 0;
221 _argsD = 0;
222 _modelname = "**********";
223
224 // Default is to check that charge is conserved
225 _chkCharge = 1;
226
227 // statistics collection!
228
229 max_prob = 0.0;
230 sum_prob = 0.0;
231}
232
234
235 int i;
236
237 if ( ntimes_prob > 0 )
238 {
239
240 report( INFO, "EvtGen" ) << "Calls=" << ntimes_prob
241 << " eff:" << sum_prob / ( probmax * ntimes_prob )
242 << " frac. max:" << max_prob / probmax;
243 report( INFO, "" ) << " probmax:" << probmax << " max:" << max_prob << " : ";
244 }
245
246 report( INFO, "" ) << EvtPDL::name( _parent ).c_str() << " -> ";
247 for ( i = 0; i < _ndaug; i++ )
248 { report( INFO, "" ) << EvtPDL::name( _daug[i] ).c_str() << " "; }
249 report( INFO, "" ) << " (" << _modelname.c_str() << "):" << endl;
250}
251
253
254 if ( _daug != 0 ) { delete[] _daug; }
255
256 if ( _args != 0 ) { delete[] _args; }
257
258 if ( _argsD != 0 ) { delete[] _argsD; }
259}
260
261void EvtDecayBase::setProbMax( double prbmx ) {
262
263 defaultprobmax = 0;
264 probmax = prbmx;
265}
266
267void EvtDecayBase::noProbMax() { defaultprobmax = 0; }
268
270
271 double maxOkMass = EvtPDL::getMaxMass( p->getId() );
272
273 // protect against vphotons
274 if ( maxOkMass < 0.0000000001 ) return 10000000.;
275 // and against already determined masses
276 if ( p->hasValidP4() ) maxOkMass = p->mass();
277
278 EvtParticle* par = p->getParent();
279 if ( par )
280 {
281 double maxParMass = findMaxMass( par );
282 int i;
283 double minDaugMass = 0.;
284 for ( i = 0; i < par->getNDaug(); i++ )
285 {
286 EvtParticle* dau = par->getDaug( i );
287 if ( dau != p )
288 {
289 // it might already have a mass
290 if ( dau->isInitialized() || dau->hasValidP4() ) minDaugMass += dau->mass();
291 else
292 // give it a bit of phase space
293 minDaugMass += 1.000001 * EvtPDL::getMinMass( dau->getId() );
294 }
295 }
296 if ( maxOkMass > ( maxParMass - minDaugMass ) ) maxOkMass = maxParMass - minDaugMass;
297 }
298 return maxOkMass;
299}
300
301// given list of daughters ( by number ) returns a
302// list of viable masses.
303
305
306 // Need to also check that this mass does not screw
307 // up the parent
308 // This code assumes that for the ith daughter, 0..i-1
309 // already have a mass
310 double maxOkMass = findMaxMass( p );
311
312 int count = 0;
313 double mass;
314 bool massOk = false;
315 int i;
316 while ( !massOk )
317 {
318 count++;
319 if ( count > 10000 )
320 {
321 report( INFO, "EvtGen" ) << "Can not find a valid mass for: "
322 << EvtPDL::name( p->getId() ).c_str() << endl;
323 report( INFO, "EvtGen" ) << "Now printing parent and/or grandparent tree\n";
324 if ( p->getParent() )
325 {
326 if ( p->getParent()->getParent() )
327 {
328 p->getParent()->getParent()->printTree();
329 report( INFO, "EvtGen" ) << p->getParent()->getParent()->mass() << endl;
330 report( INFO, "EvtGen" ) << p->getParent()->mass() << endl;
331 }
332 else
333 {
334 p->getParent()->printTree();
335 report( INFO, "EvtGen" ) << p->getParent()->mass() << endl;
336 }
337 }
338 else p->printTree();
339 report( INFO, "EvtGen" ) << "maxokmass=" << maxOkMass << " "
340 << EvtPDL::getMinMass( p->getId() ) << " "
341 << EvtPDL::getMaxMass( p->getId() ) << endl;
342 if ( p->getNDaug() )
343 {
344 for ( i = 0; i < p->getNDaug(); i++ )
345 { report( INFO, "EvtGen" ) << p->getDaug( i )->mass() << " "; }
346 report( INFO, "EvtGen" ) << endl;
347 }
348 if ( maxOkMass >= EvtPDL::getMinMass( p->getId() ) )
349 {
350 report( INFO, "EvtGen" ) << "taking a default value\n";
351 p->setMass( maxOkMass );
352 return;
353 }
354 assert( 0 );
355 }
356 mass = EvtPDL::getMass( p->getId() );
357 // Just need to check that this mass is > than
358 // the mass of all daughters
359 double massSum = 0.;
360 if ( p->getNDaug() )
361 {
362 for ( i = 0; i < p->getNDaug(); i++ ) { massSum += p->getDaug( i )->mass(); }
363 }
364 // some special cases are handled with 0 (stable) or 1 (k0->ks/kl) daughters
365 if ( p->getNDaug() < 2 ) massOk = true;
366 if ( p->getParent() )
367 {
368 if ( p->getParent()->getNDaug() == 1 ) massOk = true;
369 }
370 if ( !massOk )
371 {
372 if ( massSum < mass ) massOk = true;
373 if ( mass > maxOkMass ) massOk = false;
374 }
375 }
376
377 p->setMass( mass );
378}
379
380void EvtDecayBase::findMasses( EvtParticle* p, int ndaugs, EvtId daugs[10],
381 double masses[10] ) {
382
383 int i;
384 double mass_sum;
385
386 int count = 0;
387
388 if ( !( p->firstornot() ) )
389 {
390 for ( i = 0; i < ndaugs; i++ ) { masses[i] = p->getDaug( i )->mass(); } // for
391 } // if
392 else
393 {
394 p->setFirstOrNot();
395 // if only one daughter do it
396
397 if ( ndaugs == 1 )
398 {
399 masses[0] = p->mass();
400 return;
401 }
402
403 // until we get a combo whose masses are less than _parent mass.
404 do {
405 mass_sum = 0.0;
406
407 for ( i = 0; i < ndaugs; i++ )
408 {
409 masses[i] = EvtPDL::getMass( daugs[i] );
410 mass_sum = mass_sum + masses[i];
411 }
412
413 count++;
414
415 if ( count == 10000 )
416 {
417 report( ERROR, "EvtGen" ) << "Decaying particle:" << EvtPDL::name( p->getId() ).c_str()
418 << " (m=" << p->mass() << ")" << endl;
419 report( ERROR, "EvtGen" ) << "To the following daugthers" << endl;
420 for ( i = 0; i < ndaugs; i++ )
421 { report( ERROR, "EvtGen" ) << EvtPDL::name( daugs[i] ).c_str() << endl; }
422 report( ERROR, "EvtGen" )
423 << "Has been rejected " << count << " times, will now take minimal masses "
424 << " of daugthers" << endl;
425
426 mass_sum = 0.;
427 for ( i = 0; i < ndaugs; i++ )
428 {
429 masses[i] = EvtPDL::getMinMass( daugs[i] );
430 mass_sum = mass_sum + masses[i];
431 }
432 if ( mass_sum > p->mass() )
433 {
434 report( ERROR, "EvtGen" )
435 << "Parent mass=" << p->mass() << "to light for daugthers." << endl
436 << "Will throw the event away." << endl;
437 // dont terminate - start over on the event.
439 mass_sum = 0.;
440 // ::abort();
441 }
442 }
443 } while ( mass_sum > p->mass() );
444 } // else
445
446 return;
447}
448
449void EvtDecayBase::checkNArg( int a1, int a2, int a3, int a4 ) {
450
451 if ( _narg != a1 && _narg != a2 && _narg != a3 && _narg != a4 )
452 {
453 report( ERROR, "EvtGen" ) << _modelname.c_str() << " generator expected " << endl;
454 report( ERROR, "EvtGen" ) << a1 << endl;
455 ;
456 if ( a2 > -1 ) { report( ERROR, "EvtGen" ) << " or " << a2 << endl; }
457 if ( a3 > -1 ) { report( ERROR, "EvtGen" ) << " or " << a3 << endl; }
458 if ( a4 > -1 ) { report( ERROR, "EvtGen" ) << " or " << a4 << endl; }
459 report( ERROR, "EvtGen" ) << " arguments but found:" << _narg << endl;
460 printSummary();
461 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
462 ::abort();
463 }
464}
465void EvtDecayBase::checkNDaug( int d1, int d2 ) {
466
467 if ( _ndaug != d1 && _ndaug != d2 )
468 {
469 report( ERROR, "EvtGen" ) << _modelname.c_str() << " generator expected ";
470 report( ERROR, "EvtGen" ) << d1;
471 if ( d2 > -1 ) { report( ERROR, "EvtGen" ) << " or " << d2; }
472 report( ERROR, "EvtGen" ) << " daughters but found:" << _ndaug << endl;
473 printSummary();
474 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
475 ::abort();
476 }
477}
478
480
482 if ( parenttype != sp )
483 {
484 report( ERROR, "EvtGen" ) << _modelname.c_str()
485 << " did not get the correct parent spin\n";
486 printSummary();
487 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
488 ::abort();
489 }
490}
491
493
495 if ( parenttype != sp )
496 {
497 report( ERROR, "EvtGen" ) << _modelname.c_str()
498 << " did not get the correct daughter spin d=" << d1 << endl;
499 printSummary();
500 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
501 ::abort();
502 }
503}
504
506
507 if ( _argsD ) return _argsD;
508 // The user has asked for a list of doubles - the arguments
509 // better all be doubles...
510 if ( _narg == 0 ) return _argsD;
511
512 _argsD = new double[_narg];
513
514 int i;
515 char* tc;
516 for ( i = 0; i < _narg; i++ ) { _argsD[i] = strtod( _args[i].c_str(), &tc ); }
517 return _argsD;
518}
519
520double EvtDecayBase::getArg( int j ) {
521
522 // Verify string
523
524 const char* str = _args[j].c_str();
525 int i = 0;
526 while ( str[i] != 0 )
527 {
528 if ( isalpha( str[i] ) && str[i] != 'e' )
529 {
530
531 report( INFO, "EvtGen" ) << "String " << str << " is not a number" << endl;
532 assert( 0 );
533 }
534 i++;
535 }
536
537 char** tc = 0;
538 return strtod( _args[j].c_str(), tc );
539}
540
541bool EvtDecayBase::matchingDecay( const EvtDecayBase& other ) const {
542
543 if ( _ndaug != other._ndaug ) return false;
544 if ( _parent != other._parent ) return false;
545
546 std::vector<int> useDs;
547 for ( unsigned int i = 0; i < _ndaug; i++ ) useDs.push_back( 0 );
548
549 for ( unsigned int i = 0; i < _ndaug; i++ )
550 {
551 bool foundIt = false;
552 for ( unsigned int j = 0; j < _ndaug; j++ )
553 {
554 if ( useDs[j] == 1 ) continue;
555 if ( _daug[i] == other._daug[j] && _daug[i].getAlias() == other._daug[j].getAlias() )
556 {
557 foundIt = true;
558 useDs[j] = 1;
559 break;
560 }
561 }
562 if ( foundIt == false ) return false;
563 }
564 for ( unsigned int i = 0; i < _ndaug; i++ )
565 if ( useDs[i] == 0 ) return false;
566
567 return true;
568}
double mass
DOUBLE_PRECISION count[3]
ostream & report(Severity severity, const char *facility)
Definition EvtReport.cc:34
@ ERROR
Definition EvtReport.hh:49
@ INFO
Definition EvtReport.hh:52
****INTEGER imax DOUBLE PRECISION m_pi *DOUBLE PRECISION m_amfin DOUBLE PRECISION m_Chfin DOUBLE PRECISION m_Xenph DOUBLE PRECISION m_sinw2 DOUBLE PRECISION m_GFermi DOUBLE PRECISION m_MfinMin DOUBLE PRECISION m_ta2 INTEGER m_out INTEGER m_KeyFSR INTEGER m_KeyQCD *COMMON c_Semalib $ !copy of input $ !CMS energy $ !beam mass $ !final mass $ !beam charge $ !final charge $ !smallest final mass $ !Z mass $ !Z width $ !EW mixing angle $ !Gmu Fermi $ alphaQED at q
Definition KKsem.h:33
void checkSpinDaughter(int d1, EvtSpinType::spintype sp)
void checkSpinParent(EvtSpinType::spintype sp)
double getArg(int j)
virtual ~EvtDecayBase()
double resetProbMax(double prob)
void setProbMax(double prbmx)
virtual void init()
static void findMass(EvtParticle *p)
virtual bool matchingDecay(const EvtDecayBase &other) const
static double findMaxMass(EvtParticle *p)
EvtId getParentId()
void printSummary()
void saveDecayInfo(EvtId ipar, int ndaug, EvtId *daug, int narg, std::vector< std::string > &args, std::string name, double brfr)
virtual void command(std::string cmd)
double * getArgs()
double getProbMax(double prob)
static void findMasses(EvtParticle *p, int ndaugs, EvtId daugs[10], double masses[10])
void checkNDaug(int d1, int d2=-1)
void checkNArg(int a1, int a2=-1, int a3=-1, int a4=-1)
virtual void initProbMax()
virtual std::string commandName()
EvtId getDaug(int i)
Definition EvtId.hh:27
int getAlias() const
Definition EvtId.hh:42
static int getStdHep(EvtId id)
Definition EvtPDL.hh:61
static std::string name(EvtId i)
Definition EvtPDL.hh:70
static double getMinMass(EvtId i)
Definition EvtPDL.hh:56
static EvtSpinType::spintype getSpinType(EvtId i)
Definition EvtPDL.hh:66
static int chg3(EvtId i)
Definition EvtPDL.hh:65
static double getMaxMass(EvtId i)
Definition EvtPDL.hh:55
static double getMass(EvtId i)
Definition EvtPDL.hh:44
void setMass(double m)
EvtId getId() const
EvtParticle * getParent()
bool hasValidP4()
void printTree() const
int getNDaug() const
EvtParticle * getDaug(int i)
bool isInitialized()
double mass() const
int firstornot() const
void setFirstOrNot()
static void setRejectFlag()
Definition EvtStatus.hh:36