CGEM BOSS 6.6.5.f
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//
22#include <iostream>
23#include <fstream>
24#include <stdlib.h>
25#include <ctype.h>
29#include "EvtGenBase/EvtPDL.hh"
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 for(i=0; i<_ndaug; i++ ) {
46 q += EvtPDL::chg3(_daug[i]);
47 }
48 qpar = EvtPDL::chg3(_parent);
49
50 if ( q != qpar ) {
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 }
59 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
60
61 ::abort();
62 }
63 }
64}
65
66
67double EvtDecayBase::getProbMax( double prob ) {
68
69 int i;
70
71 //diagnostics
72 sum_prob+=prob;
73 if (prob>max_prob) max_prob=prob;
74
75
76 if ( defaultprobmax && ntimes_prob<=500 ) {
77 //We are building up probmax with this iteration
78 ntimes_prob += 1;
79 if ( prob > probmax ) { probmax = prob;}
80 if (ntimes_prob==500) {
81 probmax*=1.2;
82 }
83 return 1000000.0*prob;
84 }
85
86 if ( prob> probmax*1.0001) {
87
88 report(INFO,"EvtGen") << "prob > probmax:("<<prob<<">"<<probmax<<")";
89 report(INFO,"") << "("<<_modelname.c_str()<<") ";
90 report(INFO,"") << EvtPDL::name(_parent).c_str()<<" -> ";
91 for(i=0;i<_ndaug;i++){
92 report(INFO,"") << EvtPDL::name(_daug[i]).c_str() << " ";
93 }
94 report(INFO,"") << endl;
95
96 if (defaultprobmax) probmax = prob;
97
98 }
99
100 ntimes_prob += 1;
101
102
103 return probmax;
104
105} //getProbMax
106
107
108double EvtDecayBase::resetProbMax(double prob) {
109
110 report(INFO,"EvtGen") << "Reseting prob max\n";
111 report(INFO,"EvtGen") << "prob > probmax:("<<prob<<">"<<probmax<<")";
112 report(INFO,"") << "("<<_modelname.c_str()<<")";
113 report(INFO,"") << EvtPDL::getStdHep(_parent)<<"->";
114
115 for( int i=0;i<_ndaug;i++){
116 report(INFO,"") << EvtPDL::getStdHep(_daug[i]) << " ";
117 }
118 report(INFO,"") << endl;
119
120 probmax = 0.0;
121 defaultprobmax = 0;
122 ntimes_prob = 0;
123
124 return prob;
125
126}
127
128
130 return std::string("");
131}
132void EvtDecayBase::command(std::string cmd){
133 report(ERROR,"EvtGen") << "Should never call EvtDecayBase::command"<<endl;
134 ::abort();
135}
136
137
138
140
141 //This default version of init does nothing;
142 //A specialized version of this function can be
143 //supplied for each decay model to do initialization.
144
145 return;
146
147}
148
150
151 //This function is called if the decay does not have a
152 //specialized initialization.
153 //The default is to set the maximum
154 //probability to 0 and the number of times called to 0
155 //and defaultprobmax to 1 such that the decay will be
156 //generated many many times
157 //in order to generate a reasonable maximum probability
158 //for the decay.
159
160 defaultprobmax=1;
161 ntimes_prob = 0;
162 probmax = 0.0;
163
164} //initProbMax
165
166
167void EvtDecayBase::saveDecayInfo(EvtId ipar, int ndaug, EvtId *daug,
168 int narg,std::vector<std::string>& args,
169 std::string name,
170 double brfr) {
171
172 int i;
173
174 _brfr=brfr;
175 _ndaug=ndaug;
176 _narg=narg;
177 _parent=ipar;
178
179 _dsum=0;
180
181 if (_ndaug>0) {
182 _daug=new EvtId [_ndaug];
183 for(i=0;i<_ndaug;i++){
184 _daug[i]=daug[i];
185 _dsum+=daug[i].getAlias();
186 }
187 }
188 else{
189 _daug=0;
190 }
191
192 if (_narg>0) {
193 _args=new std::string[_narg+1];
194 for(i=0;i<_narg;i++){
195 _args[i]=args[i];
196 }
197 }
198 else{
199 _args = 0;
200 }
201
202 _modelname=name;
203
204 this->init();
205 this->initProbMax();
206
207 if (_chkCharge){
208 this->checkQ();
209 }
210
211
212 if (defaultprobmax){
213 report(INFO,"EvtGen") << "No default probmax for ";
214 report(INFO,"") << "("<<_modelname.c_str()<<") ";
215 report(INFO,"") << EvtPDL::name(_parent).c_str()<<" -> ";
216 for(i=0;i<_ndaug;i++){
217 report(INFO,"") << EvtPDL::name(_daug[i]).c_str() << " ";
218 }
219 report(INFO,"") << endl;
220 report(INFO,"") << "This is fine for development, but must be provided for production."<<endl;
221 report(INFO,"EvtGen") << "Never fear though - the decay will use the \n";
222 report(INFO,"EvtGen") << "500 iterations to build up a good probmax \n";
223 report(INFO,"EvtGen") << "before accepting a decay. "<<endl;
224 }
225
226}
227
229
230 //the default is that the user module does _not_ set
231 // any probmax.
232 defaultprobmax=1;
233 ntimes_prob = 0;
234 probmax = 0.0;
235
236 _photos=0;
237 _verbose=0;
238 _summary=0;
239 _parent=EvtId(-1,-1);
240 _ndaug=0;
241 _narg=0;
242 _daug=0;
243 _args=0;
244 _argsD=0;
245 _modelname="**********";
246
247 //Default is to check that charge is conserved
248 _chkCharge=1;
249
250 //statistics collection!
251
252 max_prob=0.0;
253 sum_prob=0.0;
254
255}
256
257
258
260
261 int i;
262
263 if (ntimes_prob>0) {
264
265 report(INFO,"EvtGen") << "Calls="<<ntimes_prob<<" eff:"<<
266 sum_prob/(probmax*ntimes_prob)<<" frac. max:"<<max_prob/probmax;
267 report(INFO,"") <<" probmax:"<<probmax<<" max:"<<max_prob<<" : ";
268 }
269
270 report(INFO,"") << EvtPDL::name(_parent).c_str()<<" -> ";
271 for(i=0;i<_ndaug;i++){
272 report(INFO,"") << EvtPDL::name(_daug[i]).c_str() << " ";
273 }
274 report(INFO,"") << " ("<<_modelname.c_str()<<"):"<< endl;
275
276
277
278}
279
280
282
283 if (_daug!=0){
284 delete [] _daug;
285 }
286
287 if (_args!=0){
288 delete [] _args;
289 }
290
291 if (_argsD!=0){
292 delete [] _argsD;
293 }
294
295}
296
297void EvtDecayBase::setProbMax(double prbmx){
298
299 defaultprobmax=0;
300 probmax=prbmx;
301
302}
303
305
306 defaultprobmax=0;
307
308}
309
310
312
313
314 double maxOkMass=EvtPDL::getMaxMass(p->getId());
315
316 //protect against vphotons
317 if ( maxOkMass < 0.0000000001 ) return 10000000.;
318 //and against already determined masses
319 if ( p->hasValidP4() ) maxOkMass=p->mass();
320
321 EvtParticle *par=p->getParent();
322 if ( par ) {
323 double maxParMass=findMaxMass(par);
324 int i;
325 double minDaugMass=0.;
326 for(i=0;i<par->getNDaug();i++){
327 EvtParticle *dau=par->getDaug(i);
328 if ( dau!=p) {
329 // it might already have a mass
330 if ( dau->isInitialized() || dau->hasValidP4() )
331 minDaugMass+=dau->mass();
332 else
333 //give it a bit of phase space
334 minDaugMass+=1.000001*EvtPDL::getMinMass(dau->getId());
335 }
336 }
337 if ( maxOkMass>(maxParMass-minDaugMass)) maxOkMass=maxParMass-minDaugMass;
338 }
339 return maxOkMass;
340}
341
342
343// given list of daughters ( by number ) returns a
344// list of viable masses.
345
347
348 //Need to also check that this mass does not screw
349 //up the parent
350 //This code assumes that for the ith daughter, 0..i-1
351 //already have a mass
352 double maxOkMass=findMaxMass(p);
353
354 int count=0;
355 double mass;
356 bool massOk=false;
357 int i;
358 while (!massOk) {
359 count++;
360 if ( count > 10000 ) {
361 report(INFO,"EvtGen") << "Can not find a valid mass for: " << EvtPDL::name(p->getId()).c_str() <<endl;
362 report(INFO,"EvtGen") << "Now printing parent and/or grandparent tree\n";
363 if ( p->getParent() ) {
364 if ( p->getParent()->getParent() ) {
365 p->getParent()->getParent()->printTree();
366 report(INFO,"EvtGen") << p->getParent()->getParent()->mass() <<endl;
367 report(INFO,"EvtGen") << p->getParent()->mass() <<endl;
368 }
369 else{
370 p->getParent()->printTree();
371 report(INFO,"EvtGen") << p->getParent()->mass() <<endl;
372 }
373 }
374 else p->printTree();
375 report(INFO,"EvtGen") << "maxokmass=" << maxOkMass << " " << EvtPDL::getMinMass(p->getId()) << " " << EvtPDL::getMaxMass(p->getId())<<endl;
376 if ( p->getNDaug() ) {
377 for (i=0; i<p->getNDaug(); i++) {
378 report(INFO,"EvtGen") << p->getDaug(i)->mass()<<" ";
379 }
380 report(INFO,"EvtGen") << endl;
381 }
382 if ( maxOkMass >= EvtPDL::getMinMass(p->getId()) ) {
383 report(INFO,"EvtGen") << "taking a default value\n";
384 p->setMass(maxOkMass);
385 return;
386 }
387 assert(0);
388 }
389 mass = EvtPDL::getMass(p->getId());
390 //Just need to check that this mass is > than
391 //the mass of all daughters
392 double massSum=0.;
393 if ( p->getNDaug() ) {
394 for (i=0; i<p->getNDaug(); i++) {
395 massSum+= p->getDaug(i)->mass();
396 }
397 }
398 //some special cases are handled with 0 (stable) or 1 (k0->ks/kl) daughters
399 if (p->getNDaug()<2) massOk=true;
400 if ( p->getParent() ) {
401 if ( p->getParent()->getNDaug()==1 ) massOk=true;
402 }
403 if ( !massOk ) {
404 if (massSum < mass) massOk=true;
405 if ( mass> maxOkMass) massOk=false;
406 }
407 }
408
409 p->setMass(mass);
410
411}
412
413
415 EvtId daugs[10], double masses[10]) {
416
417 int i;
418 double mass_sum;
419
420 int count=0;
421
422 if (!( p->firstornot() )) {
423 for (i = 0; i < ndaugs; i++ ) {
424 masses[i] = p->getDaug(i)->mass();
425 } //for
426 } //if
427 else {
428 p->setFirstOrNot();
429 // if only one daughter do it
430
431 if (ndaugs==1) {
432 masses[0]=p->mass();
433 return;
434 }
435
436 //until we get a combo whose masses are less than _parent mass.
437 do {
438 mass_sum = 0.0;
439
440 for (i = 0; i < ndaugs; i++ ) {
441 masses[i] = EvtPDL::getMass(daugs[i]);
442 mass_sum = mass_sum + masses[i];
443 }
444
445 count++;
446
447
448 if(count==10000) {
449 report(ERROR,"EvtGen") <<"Decaying particle:"<<
450 EvtPDL::name(p->getId()).c_str()<<" (m="<<p->mass()<<")"<<endl;
451 report(ERROR,"EvtGen") <<"To the following daugthers"<<endl;
452 for (i = 0; i < ndaugs; i++ ) {
453 report(ERROR,"EvtGen") <<
454 EvtPDL::name(daugs[i]).c_str() << endl;
455 }
456 report(ERROR,"EvtGen") << "Has been rejected "<<count
457 << " times, will now take minimal masses "
458 << " of daugthers"<<endl;
459
460 mass_sum=0.;
461 for (i = 0; i < ndaugs; i++ ) {
462 masses[i] = EvtPDL::getMinMass(daugs[i]);
463 mass_sum = mass_sum + masses[i];
464 }
465 if (mass_sum > p->mass()){
466 report(ERROR,"EvtGen") << "Parent mass="<<p->mass()
467 << "to light for daugthers."<<endl
468 << "Will throw the event away."<<endl;
469 //dont terminate - start over on the event.
471 mass_sum=0.;
472 // ::abort();
473 }
474
475 }
476 } while ( mass_sum > p->mass());
477 } //else
478
479 return;
480}
481
482void EvtDecayBase::checkNArg(int a1, int a2, int a3, int a4) {
483
484 if ( _narg != a1 && _narg != a2 && _narg != a3 && _narg != a4 ) {
485 report(ERROR,"EvtGen") << _modelname.c_str() << " generator expected "<<endl;
486 report(ERROR,"EvtGen") << a1<<endl;;
487 if ( a2>-1) {
488 report(ERROR,"EvtGen") << " or " << a2<<endl;
489 }
490 if ( a3>-1) {
491 report(ERROR,"EvtGen") << " or " << a3<<endl;
492 }
493 if ( a4>-1) {
494 report(ERROR,"EvtGen") << " or " << a4<<endl;
495 }
496 report(ERROR,"EvtGen") << " arguments but found:"<< _narg << endl;
497 printSummary();
498 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
499 ::abort();
500
501 }
502
503}
504void EvtDecayBase::checkNDaug(int d1, int d2){
505
506 if ( _ndaug != d1 && _ndaug != d2 ) {
507 report(ERROR,"EvtGen") << _modelname.c_str() << " generator expected ";
508 report(ERROR,"EvtGen") << d1;
509 if ( d2>-1) {
510 report(ERROR,"EvtGen") << " or " << d2;
511 }
512 report(ERROR,"EvtGen") << " daughters but found:"<< _ndaug << endl;
513 printSummary();
514 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
515 ::abort();
516 }
517
518}
519
521
523 if ( parenttype != sp ) {
524 report(ERROR,"EvtGen") << _modelname.c_str()
525 << " did not get the correct parent spin\n";
526 printSummary();
527 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
528 ::abort();
529 }
530
531}
532
534
536 if ( parenttype != sp ) {
537 report(ERROR,"EvtGen") << _modelname.c_str()
538 << " did not get the correct daughter spin d="
539 << d1 << endl;
540 printSummary();
541 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
542 ::abort();
543 }
544
545}
546
548
549 if ( _argsD ) return _argsD;
550 //The user has asked for a list of doubles - the arguments
551 //better all be doubles...
552 if ( _narg==0 ) return _argsD;
553
554 _argsD = new double[_narg];
555
556 int i;
557 char * tc;
558 for(i=0;i<_narg;i++) {
559 _argsD[i] = strtod(_args[i].c_str(),&tc);
560 }
561 return _argsD;
562}
563
564double EvtDecayBase::getArg(int j) {
565
566 // Verify string
567
568 const char* str = _args[j].c_str();
569 int i = 0;
570 while(str[i]!=0){
571 if (isalpha(str[i]) && str[i]!='e') {
572
573 report(INFO,"EvtGen") << "String " << str << " is not a number" << endl;
574 assert(0);
575 }
576 i++;
577 }
578
579 char** tc=0;
580 return strtod(_args[j].c_str(),tc);
581}
582
583
584
585
586
588
589 if ( _ndaug != other._ndaug) return false;
590 if ( _parent != other._parent) return false;
591
592 std::vector<int> useDs;
593 for ( unsigned int i=0; i<_ndaug; i++) useDs.push_back(0);
594
595 for ( unsigned int i=0; i<_ndaug; i++) {
596 bool foundIt=false;
597 for ( unsigned int j=0; j<_ndaug; j++) {
598 if ( useDs[j] == 1 ) continue;
599 if ( _daug[i] == other._daug[j] && _daug[i].getAlias() == other._daug[j].getAlias()) {
600 foundIt=true;
601 useDs[j]=1;
602 break;
603 }
604 }
605 if ( foundIt==false) return false;
606 }
607 for ( unsigned int i=0; i<_ndaug; i++) if ( useDs[i]==0) return false;
608
609 return true;
610
611}
double mass
ostream & report(Severity severity, const char *facility)
Definition: EvtReport.cc:36
@ 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)
void noProbMax()
virtual bool matchingDecay(const EvtDecayBase &other) const
static double findMaxMass(EvtParticle *p)
EvtId getParentId()
Definition: EvtDecayBase.hh:60
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)
Definition: EvtDecayBase.cc:67
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: EvtDecayBase.hh:66
Definition: EvtId.hh:27
int getAlias() const
Definition: EvtId.hh:43
static int getStdHep(EvtId id)
Definition: EvtPDL.hh:56
static std::string name(EvtId i)
Definition: EvtPDL.hh:64
static double getMinMass(EvtId i)
Definition: EvtPDL.hh:51
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.hh:61
static int chg3(EvtId i)
Definition: EvtPDL.hh:60
static double getMaxMass(EvtId i)
Definition: EvtPDL.hh:50
static double getMass(EvtId i)
Definition: EvtPDL.hh:46
void setMass(double m)
Definition: EvtParticle.hh:358
EvtId getId() const
Definition: EvtParticle.cc:113
EvtParticle * getParent()
Definition: EvtParticle.cc:87
bool hasValidP4()
Definition: EvtParticle.hh:369
void printTree() const
Definition: EvtParticle.cc:895
int getNDaug() const
Definition: EvtParticle.cc:125
EvtParticle * getDaug(int i)
Definition: EvtParticle.cc:85
bool isInitialized()
Definition: EvtParticle.hh:368
double mass() const
Definition: EvtParticle.cc:127
int firstornot() const
Definition: EvtParticle.cc:111
void setFirstOrNot()
Definition: EvtParticle.cc:74
static void setRejectFlag()
Definition: EvtStatus.hh:39