1 //--------------------------------------------------------------------------
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.
8 // Copyright Information: See EvtGen/COPYRIGHT
9 // Copyright (C) 1998 Caltech, UCSB
11 // Module: EvtDecayBase.cc
13 // Description: Store decay parameters for one decay.
15 // Modification history:
17 // RYD September 30, 1997 Module created
19 //------------------------------------------------------------------------
21 #include "EvtGenBase/EvtPatches.hh"
26 #include "EvtGenBase/EvtStatus.hh"
27 #include "EvtGenBase/EvtDecayBase.hh"
28 #include "EvtGenBase/EvtParticle.hh"
29 #include "EvtGenBase/EvtPDL.hh"
30 #include "EvtGenBase/EvtReport.hh"
31 #include "EvtGenBase/EvtSpinType.hh"
35 void EvtDecayBase::checkQ() {
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.
45 for(i=0; i<_ndaug; i++ ) {
46 q += EvtPDL::chg3(_daug[i]);
48 qpar = EvtPDL::chg3(_parent);
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;
59 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
67 double EvtDecayBase::getProbMax( double prob ) {
73 if (prob>max_prob) max_prob=prob;
76 if ( defaultprobmax && ntimes_prob<=500 ) {
77 //We are building up probmax with this iteration
79 if ( prob > probmax ) { probmax = prob;}
80 if (ntimes_prob==500) {
83 return 1000000.0*prob;
86 if ( prob> probmax*1.0001) {
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() << " ";
94 report(INFO,"") << endl;
96 if (defaultprobmax) probmax = prob;
108 double EvtDecayBase::resetProbMax(double prob) {
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)<<"->";
115 for( int i=0;i<_ndaug;i++){
116 report(INFO,"") << EvtPDL::getStdHep(_daug[i]) << " ";
118 report(INFO,"") << endl;
129 std::string EvtDecayBase::commandName(){
130 return std::string("");
133 void EvtDecayBase::command(std::string){
134 report(ERROR,"EvtGen") << "Should never call EvtDecayBase::command"<<endl;
138 std::string EvtDecayBase::getParamName(int i) {
165 std::string EvtDecayBase::getParamDefault(int /*i*/) {
169 void EvtDecayBase::init() {
171 //This default version of init does nothing;
172 //A specialized version of this function can be
173 //supplied for each decay model to do initialization.
179 void EvtDecayBase::initProbMax() {
181 //This function is called if the decay does not have a
182 //specialized initialization.
183 //The default is to set the maximum
184 //probability to 0 and the number of times called to 0
185 //and defaultprobmax to 1 such that the decay will be
186 //generated many many times
187 //in order to generate a reasonable maximum probability
197 void EvtDecayBase::saveDecayInfo(EvtId ipar, int ndaug, EvtId *daug,
198 int narg,std::vector<std::string>& args,
212 _daug=new EvtId [_ndaug];
213 for(i=0;i<_ndaug;i++){
215 _dsum+=daug[i].getAlias();
223 _args=new std::string[_narg+1];
224 for(i=0;i<_narg;i++){
243 report(INFO,"EvtGen") << "No default probmax for ";
244 report(INFO,"") << "("<<_modelname.c_str()<<") ";
245 report(INFO,"") << EvtPDL::name(_parent).c_str()<<" -> ";
246 for(i=0;i<_ndaug;i++){
247 report(INFO,"") << EvtPDL::name(_daug[i]).c_str() << " ";
249 report(INFO,"") << endl;
250 report(INFO,"") << "This is fine for development, but must be provided for production."<<endl;
251 report(INFO,"EvtGen") << "Never fear though - the decay will use the \n";
252 report(INFO,"EvtGen") << "500 iterations to build up a good probmax \n";
253 report(INFO,"EvtGen") << "before accepting a decay. "<<endl;
258 EvtDecayBase::EvtDecayBase() {
260 //the default is that the user module does _not_ set
269 _parent=EvtId(-1,-1);
275 _modelname="**********";
277 //Default is to check that charge is conserved
280 //statistics collection!
289 void EvtDecayBase::printSummary() const {
292 report(INFO,"EvtGen") << "Calls = "<<ntimes_prob<<" eff: "<<
293 sum_prob/(probmax*ntimes_prob)<<" frac. max:"<<max_prob/probmax;
294 report(INFO,"") <<" probmax:"<<probmax<<" max:"<<max_prob<<" : ";
301 void EvtDecayBase::printInfo() const {
302 report(INFO,"") << EvtPDL::name(_parent).c_str()<<" -> ";
303 for(int i=0;i<_ndaug;i++){
304 report(INFO,"") << EvtPDL::name(_daug[i]).c_str() << " ";
306 report(INFO,"") << " ("<<_modelname.c_str()<<")"<< endl;
310 EvtDecayBase::~EvtDecayBase() {
327 void EvtDecayBase::setProbMax(double prbmx){
334 void EvtDecayBase::noProbMax(){
341 double EvtDecayBase::findMaxMass(EvtParticle *p) {
344 double maxOkMass=EvtPDL::getMaxMass(p->getId());
346 //protect against vphotons
347 if ( maxOkMass < 0.0000000001 ) return 10000000.;
348 //and against already determined masses
349 if ( p->hasValidP4() ) maxOkMass=p->mass();
351 EvtParticle *par=p->getParent();
353 double maxParMass=findMaxMass(par);
355 double minDaugMass=0.;
356 for(i=0;i<par->getNDaug();i++){
357 EvtParticle *dau=par->getDaug(i);
359 // it might already have a mass
360 if ( dau->isInitialized() || dau->hasValidP4() )
361 minDaugMass+=dau->mass();
363 //give it a bit of phase space
364 minDaugMass+=1.000001*EvtPDL::getMinMass(dau->getId());
367 if ( maxOkMass>(maxParMass-minDaugMass)) maxOkMass=maxParMass-minDaugMass;
373 // given list of daughters ( by number ) returns a
374 // list of viable masses.
376 void EvtDecayBase::findMass(EvtParticle *p) {
378 //Need to also check that this mass does not screw
380 //This code assumes that for the ith daughter, 0..i-1
381 //already have a mass
382 double maxOkMass=findMaxMass(p);
390 if ( count > 10000 ) {
391 report(INFO,"EvtGen") << "Can not find a valid mass for: " << EvtPDL::name(p->getId()).c_str() <<endl;
392 report(INFO,"EvtGen") << "Now printing parent and/or grandparent tree\n";
393 if ( p->getParent() ) {
394 if ( p->getParent()->getParent() ) {
395 p->getParent()->getParent()->printTree();
396 report(INFO,"EvtGen") << p->getParent()->getParent()->mass() <<endl;
397 report(INFO,"EvtGen") << p->getParent()->mass() <<endl;
400 p->getParent()->printTree();
401 report(INFO,"EvtGen") << p->getParent()->mass() <<endl;
405 report(INFO,"EvtGen") << "maxokmass=" << maxOkMass << " " << EvtPDL::getMinMass(p->getId()) << " " << EvtPDL::getMaxMass(p->getId())<<endl;
406 if ( p->getNDaug() ) {
407 for (i=0; i<p->getNDaug(); i++) {
408 report(INFO,"EvtGen") << p->getDaug(i)->mass()<<" ";
410 report(INFO,"EvtGen") << endl;
412 if ( maxOkMass >= EvtPDL::getMinMass(p->getId()) ) {
413 report(INFO,"EvtGen") << "taking a default value\n";
414 p->setMass(maxOkMass);
419 mass = EvtPDL::getMass(p->getId());
420 //Just need to check that this mass is > than
421 //the mass of all daughters
423 if ( p->getNDaug() ) {
424 for (i=0; i<p->getNDaug(); i++) {
425 massSum+= p->getDaug(i)->mass();
428 //some special cases are handled with 0 (stable) or 1 (k0->ks/kl) daughters
429 if (p->getNDaug()<2) massOk=true;
430 if ( p->getParent() ) {
431 if ( p->getParent()->getNDaug()==1 ) massOk=true;
434 if (massSum < mass) massOk=true;
435 if ( mass> maxOkMass) massOk=false;
444 void EvtDecayBase::findMasses(EvtParticle *p, int ndaugs,
445 EvtId daugs[10], double masses[10]) {
452 if (!( p->firstornot() )) {
453 for (i = 0; i < ndaugs; i++ ) {
454 masses[i] = p->getDaug(i)->mass();
459 // if only one daughter do it
466 //until we get a combo whose masses are less than _parent mass.
470 for (i = 0; i < ndaugs; i++ ) {
471 masses[i] = EvtPDL::getMass(daugs[i]);
472 mass_sum = mass_sum + masses[i];
479 report(ERROR,"EvtGen") <<"Decaying particle:"<<
480 EvtPDL::name(p->getId()).c_str()<<" (m="<<p->mass()<<")"<<endl;
481 report(ERROR,"EvtGen") <<"To the following daugthers"<<endl;
482 for (i = 0; i < ndaugs; i++ ) {
483 report(ERROR,"EvtGen") <<
484 EvtPDL::name(daugs[i]).c_str() << endl;
486 report(ERROR,"EvtGen") << "Has been rejected "<<count
487 << " times, will now take minimal masses "
488 << " of daugthers"<<endl;
491 for (i = 0; i < ndaugs; i++ ) {
492 masses[i] = EvtPDL::getMinMass(daugs[i]);
493 mass_sum = mass_sum + masses[i];
495 if (mass_sum > p->mass()){
496 report(ERROR,"EvtGen") << "Parent mass="<<p->mass()
497 << "to light for daugthers."<<endl
498 << "Will throw the event away."<<endl;
499 //dont terminate - start over on the event.
500 EvtStatus::setRejectFlag();
506 } while ( mass_sum > p->mass());
512 void EvtDecayBase::checkNArg(int a1, int a2, int a3, int a4) {
514 if ( _narg != a1 && _narg != a2 && _narg != a3 && _narg != a4 ) {
515 report(ERROR,"EvtGen") << _modelname.c_str() << " generator expected "<<endl;
516 report(ERROR,"EvtGen") << a1<<endl;;
518 report(ERROR,"EvtGen") << " or " << a2<<endl;
521 report(ERROR,"EvtGen") << " or " << a3<<endl;
524 report(ERROR,"EvtGen") << " or " << a4<<endl;
526 report(ERROR,"EvtGen") << " arguments but found:"<< _narg << endl;
528 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
534 void EvtDecayBase::checkNDaug(int d1, int d2){
536 if ( _ndaug != d1 && _ndaug != d2 ) {
537 report(ERROR,"EvtGen") << _modelname.c_str() << " generator expected ";
538 report(ERROR,"EvtGen") << d1;
540 report(ERROR,"EvtGen") << " or " << d2;
542 report(ERROR,"EvtGen") << " daughters but found:"<< _ndaug << endl;
544 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
550 void EvtDecayBase::checkSpinParent(EvtSpinType::spintype sp) {
552 EvtSpinType::spintype parenttype = EvtPDL::getSpinType(getParentId());
553 if ( parenttype != sp ) {
554 report(ERROR,"EvtGen") << _modelname.c_str()
555 << " did not get the correct parent spin\n";
557 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
563 void EvtDecayBase::checkSpinDaughter(int d1, EvtSpinType::spintype sp) {
565 EvtSpinType::spintype parenttype = EvtPDL::getSpinType(getDaug(d1));
566 if ( parenttype != sp ) {
567 report(ERROR,"EvtGen") << _modelname.c_str()
568 << " did not get the correct daughter spin d="
571 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
577 double* EvtDecayBase::getArgs() {
579 if ( _argsD ) return _argsD;
580 //The user has asked for a list of doubles - the arguments
581 //better all be doubles...
582 if ( _narg==0 ) return _argsD;
584 _argsD = new double[_narg];
588 for(i=0;i<_narg;i++) {
589 _argsD[i] = strtod(_args[i].c_str(),&tc);
594 double EvtDecayBase::getArg(unsigned int j) {
598 if (getParentId().getId() == 25) {
603 const char* str = _args[j].c_str();
606 if (isalpha(str[i]) && str[i]!='e') {
608 report(INFO,"EvtGen") << "String " << str << " is not a number" << endl;
615 double result = strtod(_args[j].c_str(),tc);
617 if (_storedArgs.size() < j+1 ){ // then store the argument's value
618 _storedArgs.push_back(result);
628 bool EvtDecayBase::matchingDecay(const EvtDecayBase &other) const {
630 if ( _ndaug != other._ndaug) return false;
631 if ( _parent != other._parent) return false;
633 std::vector<int> useDs;
634 for ( int i=0; i<_ndaug; i++) useDs.push_back(0);
636 for ( int i=0; i<_ndaug; i++) {
638 for ( int j=0; j<_ndaug; j++) {
639 if ( useDs[j] == 1 ) continue;
640 if ( _daug[i] == other._daug[j] && _daug[i].getAlias() == other._daug[j].getAlias()) {
646 if ( foundIt==false) return false;
648 for ( int i=0; i<_ndaug; i++) if ( useDs[i]==0) return false;