//************************************************************************// // // // Copyright 2013 Bertram Kopf (bertram@ep1.rub.de) // // Julian Pychy (julian@ep1.rub.de) // // - Ruhr-Universit??t Bochum // // // // This file is part of Pawian. // // // // Pawian is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // Pawian is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with Pawian. If not, see <http://www.gnu.org/licenses/>. // // // //************************************************************************// // AbsDecay class definition file. -*- C++ -*- // Copyright 2012 Bertram Kopf #include <getopt.h> #include <fstream> #include <sstream> #include <algorithm> #include "PwaUtils/AbsDecay.hh" #include "PwaUtils/AbsDecayList.hh" #include "qft++/relativistic-quantum-mechanics/Utils.hh" #include "Particle/Particle.hh" #include "Particle/ParticleTable.hh" #include "Utils/PawianCollectionUtils.hh" #include "Utils/FunctionUtils.hh" #include "Utils/IdStringMapRegistry.hh" #include "PwaUtils/KinUtils.hh" #include "PwaUtils/EvtDataBaseList.hh" #include "PwaUtils/DynRegistry.hh" #include "PwaUtils/AbsDynamics.hh" #include "PwaUtils/GlobalEnv.hh" #include "PwaUtils/ProdChannelInfo.hh" #include "PwaDynamics/BarrierFactor.hh" #include "ErrLogger/ErrLogger.hh" AbsDecay::AbsDecay(Particle* mother, Particle* daughter1, Particle* daughter2, ChannelID channelId, std::string typeName) : _typeName(typeName) ,_channelId(channelId) ,_mother(mother) ,_daughter1(daughter1) ,_daughter2(daughter2) ,_daughter1IsStable(true) ,_daughter2IsStable(true) ,_hasMotherPart(true) ,_motherJPCPtr(getJPCPtr(mother)) ,_motherIGJPCPtr(getIGJPCPtr(mother)) ,_daughter1IGJPCPtr(getIGJPCPtr(daughter1)) ,_daughter2IGJPCPtr(getIGJPCPtr(daughter2)) ,_isospinClebschG(1.) ,_qR(BarrierFactor::qRDefault) ,_name(mother->name()+"To"+daughter1->name()+"_"+daughter2->name()) ,_nameId(0) ,_fitParamSuffix(_name) ,_massParamKey(_mother->name()) ,_massParamId(IdStringMapRegistry::instance()->keyStringId("grandMaAndMassParKey", _massParamKey)) ,_prodParamKey("") ,_wignerDId(0) ,_wignerDqNormId(0) ,_wignerDRefKey("default") ,_wigDWigDRefId(0) ,_dynType("WoDynamics") ,_dynEnabled(false) ,_preFactor(1.) ,_pathParserFile("") // ,_dynKey(mother->name()) ,_decPair1stChannel(make_pair(daughter1, daughter2)) ,_isDaughter1Photon(false) ,_isDaughter2Photon(false) ,_gParity(mother->theGParity()) ,_useIsospin(true) ,_isProdAmp(false) ,_useProdBarrier(false) ,_massSumFsParticles(0.) ,_Lmin(0) ,_decLevel(decayLevel::noLevel) ,_prodChannelInfo(std::shared_ptr<ProdChannelInfo>(new ProdChannelInfo())) { _absDecDaughter1=GlobalEnv::instance()->Channel(_channelId)->absDecayList()->decay(_daughter1); if(0 != _absDecDaughter1){ _daughter1IsStable=false; _finalStateParticlesDaughter1=_absDecDaughter1->finalStateParticles(); _finalStateParticles.insert(_finalStateParticles.end(), _finalStateParticlesDaughter1.begin(), _finalStateParticlesDaughter1.end()); } else{ _finalStateParticles.push_back(daughter1); _finalStateParticlesDaughter1.push_back(daughter1); addToFsParticleNameList(daughter1->name()); } _absDecDaughter2=GlobalEnv::instance()->Channel(_channelId)->absDecayList()->decay(_daughter2); if(0 != _absDecDaughter2){ _daughter2IsStable=false; _finalStateParticlesDaughter2=_absDecDaughter2->finalStateParticles(); _finalStateParticles.insert(_finalStateParticles.end(), _finalStateParticlesDaughter2.begin(), _finalStateParticlesDaughter2.end()); } else{ _finalStateParticles.push_back(daughter2); _finalStateParticlesDaughter2.push_back(daughter2); addToFsParticleNameList(daughter2->name()); } pawian::Collection::PtrLess thePtrLess; std::sort(_finalStateParticles.begin(), _finalStateParticles.end(), thePtrLess); // _wignerDKey=FunctionUtils::particleListName(_finalStateParticlesDaughter2)+"_"+_motherJPCPtr->name()+FunctionUtils::particleListName(_finalStateParticles); _wignerDKey=FunctionUtils::particleListName(_finalStateParticlesDaughter2)+"_"+FunctionUtils::particleListName(_finalStateParticles); _refKey=FunctionUtils::particleListName(_finalStateParticles); _idaughter1=Spin(_daughter1->twoIso(), 2); _i3daughter1=Spin(_daughter1->twoIso3(), 2); _idaughter2=Spin(_daughter2->twoIso(), 2); _i3daughter2=Spin(_daughter2->twoIso3(), 2); Spin Imother(_mother->twoIso(), 2); Spin I3mother(_mother->twoIso3(), 2); _isospinClebschG=Clebsch(_idaughter1, _i3daughter1, _idaughter2, _i3daughter2, Imother, I3mother); if(fabs(_isospinClebschG)<1.e-8){ Warning << "no isospin coupling for decay " << _mother->name() << " to " << _daughter1->name() << " " << _daughter2->name() << endmsg; Warning << "Imother: " << Imother << "\tI3mother: " << I3mother << endmsg; Warning << "idaughter1: " << _idaughter1 << "\ti3daughter1: " << _i3daughter1 << endmsg; Warning << "idaughter2: " << _idaughter2 << "\ti3daughter2: " << _i3daughter2 << endmsg; } // if( (*daughter1) == *(GlobalEnv::instance()->particleTable()->particle("photon")) || (*daughter2) == *(GlobalEnv::instance()->particleTable()->particle("photon"))) disableIsospin(); if(daughter1->twoJ() == 2 && daughter1->theParity() == -1 && daughter1->theCParity()==-1 && daughter1->mass() < 1.e-6){ _isDaughter1Photon=true; } if(daughter2->twoJ() == 2 && daughter2->theParity() == -1 && daughter2->theCParity()==-1 && daughter1->mass() < 1.e-6){ _isDaughter2Photon=true; } if( _isDaughter1Photon || _isDaughter2Photon) disableIsospin(); //fill mass sum of final state particles std::vector<Particle*>::iterator itP; for(itP = _finalStateParticles.begin(); itP != _finalStateParticles.end(); ++itP){ _massSumFsParticles+=(*itP)->mass(); } } AbsDecay::AbsDecay(std::shared_ptr<const IGJPC> motherIGJPCPtr, Particle* daughter1, Particle* daughter2, std::string motherName, ChannelID channelId, std::string typeName) : _typeName(typeName) ,_channelId(channelId) ,_mother(0) ,_daughter1(daughter1) ,_daughter2(daughter2) ,_daughter1IsStable(true) ,_daughter2IsStable(true) ,_hasMotherPart(false) ,_motherJPCPtr(std::shared_ptr<const jpcRes>(new jpcRes(motherIGJPCPtr->J, motherIGJPCPtr->P, motherIGJPCPtr->C)) ) ,_motherIGJPCPtr(motherIGJPCPtr) ,_daughter1IGJPCPtr(getIGJPCPtr(daughter1)) ,_daughter2IGJPCPtr(getIGJPCPtr(daughter2)) ,_isospinClebschG(1.) ,_qR(BarrierFactor::qRDefault) ,_name(_motherIGJPCPtr->name()+"To"+daughter1->name()+"_"+daughter2->name()) ,_nameId(0) ,_fitParamSuffix(_motherIGJPCPtr->jpcname()+"To"+daughter1->name()+"_"+daughter2->name()) // ,_massParamKey(motherIGJPCPtr->name()) ,_massParamKey(motherIGJPCPtr->jpcname()) ,_massParamId(IdStringMapRegistry::instance()->keyStringId("grandMaAndMassParKey", _massParamKey)) ,_prodParamKey(GlobalEnv::instance()->Channel(channelId)->channelTypeName()+"To"+daughter1->name()+"_"+daughter2->name()) ,_wignerDId(0) ,_wignerDqNormId(0) ,_wignerDRefKey("default") ,_wigDWigDRefId(0) ,_dynType("WoDynamics") ,_dynEnabled(false) ,_preFactor(1.) ,_pathParserFile("") // ,_dynKey(motherJPCPtr->name()) ,_decPair1stChannel(make_pair(daughter1, daughter2)) ,_isDaughter1Photon(false) ,_isDaughter2Photon(false) ,_gParity(motherIGJPCPtr->G) ,_useIsospin(true) ,_isProdAmp(false) ,_useProdBarrier(false) ,_massSumFsParticles(0.) ,_Lmin(0) ,_decLevel(decayLevel::noLevel) ,_prodChannelInfo(std::shared_ptr<ProdChannelInfo>(new ProdChannelInfo())) { _absDecDaughter1=GlobalEnv::instance()->Channel(_channelId)->absDecayList()->decay(_daughter1); if(0 != _absDecDaughter1){ _daughter1IsStable=false; _finalStateParticlesDaughter1=_absDecDaughter1->finalStateParticles(); _finalStateParticles.insert(_finalStateParticles.end(), _finalStateParticlesDaughter1.begin(), _finalStateParticlesDaughter1.end()); } else{ _finalStateParticles.push_back(daughter1); _finalStateParticlesDaughter1.push_back(daughter1); addToFsParticleNameList(daughter1->name()); } _absDecDaughter2=GlobalEnv::instance()->Channel(_channelId)->absDecayList()->decay(_daughter2); if(0 != _absDecDaughter2){ _daughter2IsStable=false; _finalStateParticlesDaughter2=_absDecDaughter2->finalStateParticles(); _finalStateParticles.insert(_finalStateParticles.end(), _finalStateParticlesDaughter2.begin(), _finalStateParticlesDaughter2.end()); } else{ _finalStateParticles.push_back(daughter2); _finalStateParticlesDaughter2.push_back(daughter2); addToFsParticleNameList(daughter2->name()); } pawian::Collection::PtrLess thePtrLess; std::sort(_finalStateParticles.begin(), _finalStateParticles.end(), thePtrLess); // _wignerDKey=FunctionUtils::particleListName(_finalStateParticlesDaughter2)+"_"+motherName; _wignerDKey=FunctionUtils::particleListName(_finalStateParticlesDaughter2)+"_"+FunctionUtils::particleListName(_finalStateParticles); _refKey=FunctionUtils::particleListName(_finalStateParticles); _daughter1->print(std::cout); _daughter2->print(std::cout); _idaughter1=Spin(_daughter1->twoIso(), 2); _i3daughter1=Spin(_daughter1->twoIso3(), 2); _idaughter2=Spin(_daughter2->twoIso(), 2); _i3daughter2=Spin(_daughter2->twoIso3(), 2); if ( GlobalEnv::instance()->Channel(channelId)->channelType()==AbsChannelEnv::CHANNEL_PBARP || GlobalEnv::instance()->Channel(channelId)->channelType()==AbsChannelEnv::CHANNEL_EPEM ){ _isospinClebschG=Clebsch(_idaughter1, _i3daughter1, _idaughter2, _i3daughter2, motherIGJPCPtr->I, 0); //attention } else if (GlobalEnv::instance()->Channel(channelId)->channelType()==AbsChannelEnv::CHANNEL_GAMMAP){ _isospinClebschG=Clebsch(_idaughter1, _i3daughter1, _idaughter2, _i3daughter2, motherIGJPCPtr->I, 1./2); //p gamma } else{ Alert << "AbsDecay cannot be set up for channel type " << GlobalEnv::instance()->Channel(channelId)->channelType() << endmsg; exit(0); } // if( (*daughter1) == *(GlobalEnv::instance()->particleTable()->particle("photon")) || (*daughter2) == *(GlobalEnv::instance()->particleTable()->particle("photon"))) disableIsospin(); if(daughter1->twoJ() == 2 && daughter1->theParity() == -1 && daughter1->theCParity()==-1 && daughter1->mass() < 1.e-6){ _isDaughter1Photon=true; } if(daughter2->twoJ() == 2 && daughter2->theParity() == -1 && daughter2->theCParity()==-1 && daughter2->mass() < 1.e-6){ _isDaughter2Photon=true; } if( _isDaughter1Photon || _isDaughter2Photon) disableIsospin(); //fill mass sum of final state particles std::vector<Particle*>::iterator itP; for(itP = _finalStateParticles.begin(); itP != _finalStateParticles.end(); ++itP){ _massSumFsParticles+=(*itP)->mass(); } } AbsDecay::~AbsDecay(){ } void AbsDecay::enableDynamics(std::string& dynString, std::vector<std::string>& additionalStringVec) { if(_dynEnabled){ Alert << "dynamics already enabled for " << name() << endmsg; exit(0); } _dynType=dynString; if(_dynType=="KMatrix") _pathParserFile=additionalStringVec[0]; else if(_dynType=="Flatte"){ //fill second decay channel (Flatte) Particle* firstParticle=GlobalEnv::instance()->particleTable()->particle(additionalStringVec[0]); if(0==firstParticle){ Alert << "particle with name\t" << additionalStringVec[0] << "\tnot available in the particle table" << endmsg; exit(1); } Particle* secondParticle=GlobalEnv::instance()->particleTable()->particle(additionalStringVec[1]); if(0==secondParticle){ Alert << "particle with name\t" << additionalStringVec[1] << "\tnot available in the particle table" << endmsg; exit(1); } _decPair2ndChannel=make_pair(firstParticle,secondParticle); } else if(_dynType=="BlattWBarrier" || _dynType=="BlattWBarrierTensor" || _dynType=="BreitWignerBlattWRel" || _dynType=="BreitWignerBlattWTensorRel"){ if(additionalStringVec.size()>0){ _qR=stof(additionalStringVec[0]); if ( _qR <1.e-5 || _qR > 20.){ Alert << "radius for barrier factor too high or too low qr=" << _qR << endmsg; exit(0); } } Info << "AmpName: " << name() << " radius for barrier factor qr= " << _qR << endmsg; } _absDynPtr=DynRegistry::instance()->getDynamics(shared_from_this()); _dynEnabled=true; } void AbsDecay::fillWignerDs(std::map<std::string, Vector4<double> >& fsMap, Vector4<double>& prodParticle4Vec, EvtData* evtData){ // int evtNo=evtData->evtNo; // std::map<int, bool>::const_iterator it = _alreadyFilledMap.find(evtNo); // if(it!=_alreadyFilledMap.end() && it->second) return; //already filled std::vector<Particle*>::iterator itP; std::map<std::string, Vector4<double> >::iterator itMap; Vector4<double> all4Vec(0.,0.,0.,0.); Vector4<double> mother4Vec(0.,0.,0.,0.); Vector4<double> daughter1_4Vec(0.,0.,0.,0.); Vector4<double> daughter2_4Vec(0.,0.,0.,0.); //fill all4Vec for(itMap=fsMap.begin(); itMap!=fsMap.end(); ++itMap){ all4Vec+=itMap->second; } //fill mother4Vec for(itP = _finalStateParticles.begin(); itP != _finalStateParticles.end(); ++itP){ itMap=fsMap.find((*itP)->name()); mother4Vec+=itMap->second; } //fill daughter1 for(itP=_finalStateParticlesDaughter1.begin(); itP!=_finalStateParticlesDaughter1.end(); ++itP){ itMap=fsMap.find((*itP)->name()); daughter1_4Vec+=itMap->second; } //fill daughter2 for(itP=_finalStateParticlesDaughter2.begin(); itP!=_finalStateParticlesDaughter2.end(); ++itP){ itMap=fsMap.find((*itP)->name()); daughter2_4Vec+=itMap->second; } Vector4<double> daughter2HelMother(0.,0.,0.,0.); Vector4<double> daughter1HelMother(0.,0.,0.,0.); if(_hasMotherPart){ if(mother4Vec==all4Vec){ daughter2HelMother=daughter2_4Vec; daughter1HelMother=daughter1_4Vec; if( fabs(mother4Vec.P()) > 1.e-6 ){ //daughter2HelMother.Boost(mother4Vec); //daughter1HelMother.Boost(mother4Vec); Vector4<double> defaultRefVec(sqrt(mother4Vec.M()*mother4Vec.M()+1.0) , 0., 0., 1.); //z-axis = quantisation axis daughter2HelMother=helicityVec(defaultRefVec, mother4Vec, daughter2_4Vec); daughter1HelMother=helicityVec(defaultRefVec, mother4Vec, daughter1_4Vec); } } else{ daughter2HelMother=helicityVec(prodParticle4Vec, mother4Vec, daughter2_4Vec); daughter1HelMother=helicityVec(prodParticle4Vec, mother4Vec, daughter1_4Vec); } } else{ daughter2HelMother=daughter2_4Vec; daughter1HelMother=daughter1_4Vec; if( fabs(mother4Vec.P()) > 1.e-6 ){ //daughter2HelMother.Boost(mother4Vec); //daughter1HelMother.Boost(mother4Vec); Vector4<double> defaultRefVec(sqrt(mother4Vec.M()*mother4Vec.M()+1.0) , 0., 0., 1.); //z-axis = quantisation axis daughter2HelMother=helicityVec(defaultRefVec, mother4Vec, daughter2_4Vec); daughter1HelMother=helicityVec(defaultRefVec, mother4Vec, daughter1_4Vec); } } Spin spinMother=_motherIGJPCPtr->J; Spin spinDaughter1=_daughter1IGJPCPtr->J; Spin spinDaughter2=_daughter2IGJPCPtr->J; Spin lam12Max=spinDaughter1+spinDaughter2; if(lam12Max>spinMother) lam12Max=spinMother; Spin lamMotherMax=spinMother; if (whichDecayLevel()==decayLevel::isProdAmp && spinMother>1){ if ( GlobalEnv::instance()->Channel(_channelId)->channelType()==AbsChannelEnv::CHANNEL_PBARP || GlobalEnv::instance()->Channel(_channelId)->channelType()==AbsChannelEnv::CHANNEL_EPEM ){ lamMotherMax=1; //attention } else if (GlobalEnv::instance()->Channel(_channelId)->channelType()==AbsChannelEnv::CHANNEL_GAMMAP){ lamMotherMax=3./2; } } for (Spin lamMother=-lamMotherMax; lamMother<=lamMotherMax; ++lamMother){ for (Spin lam12=-lam12Max; lam12<=lam12Max; ++lam12){ double thePhi=0.; if(whichDecayLevel()!=decayLevel::isProdAmp) thePhi=daughter2HelMother.Phi(); Id3StringType IdSpinMotherLamMotherLam12=FunctionUtils::spin3Index(spinMother, lamMother, lam12); std::map<Id3StringType, complex<double> >::iterator found = evtData->WignerDIdId3[_wigDWigDRefId].find(IdSpinMotherLamMotherLam12); if(found != evtData->WignerDIdId3[_wigDWigDRefId].end()){ continue; } if (GlobalEnv::instance()->Channel(_channelId)->channelType()==AbsChannelEnv::CHANNEL_EPEM && whichDecayLevel()==decayLevel::isProdAmp){ evtData->WignerDIdId3[_wigDWigDRefId][IdSpinMotherLamMotherLam12]=Wigner_D(thePhi,daughter1HelMother.Theta(),0,spinMother,lamMother,lam12); } else evtData->WignerDIdId3[_wigDWigDRefId][IdSpinMotherLamMotherLam12]=Wigner_D(thePhi,daughter2HelMother.Theta(),0,spinMother,lamMother,lam12); if(evtData->WignerDIdId3[_wigDWigDRefId][IdSpinMotherLamMotherLam12].real() != evtData->WignerDIdId3[_wigDWigDRefId][IdSpinMotherLamMotherLam12].real()){ Alert << "WignerD function of event No: " << evtData->evtNo << " is nan!!! " << endmsg; Alert << "Set it manually to complex<double>(1.e-10, 1.e-10)" << endmsg; evtData->WignerDIdId3[_wigDWigDRefId][IdSpinMotherLamMotherLam12]= complex<double>(1.e-10, 1.e-10); Alert << "daughter2HelMother phi: " << daughter2HelMother.Phi() << "\ttheta: " << daughter2HelMother.Theta() << endmsg; Alert << "spinMother: " << spinMother << "\tlam12: " << lam12 << endmsg; Alert << "daughter2HelMother: Mass: " << daughter2HelMother.Mass() << "\tE: " << daughter2HelMother.E() << "\tPx: " << daughter2HelMother.Px() << "\tPy: " << daughter2HelMother.Py() << "\tPz: " << daughter2HelMother.Pz() << endmsg; exit(1); } } } if (!_daughter1IsStable){ _absDecDaughter1->fillWignerDs(fsMap, mother4Vec, evtData); } if (!_daughter2IsStable){ _absDecDaughter2->fillWignerDs(fsMap, mother4Vec, evtData); } bool fillqVals=false; if(_isProdAmp && _useProdBarrier) fillqVals=true; else if(0!=_absDynPtr){ if(_absDynPtr->type()=="BlattWBarrierDynamics" || _absDynPtr->type()=="BlattWBarrierTensorDynamics") fillqVals=true; } if(fillqVals){ double qVal=daughter2HelMother.P(); double qValNorm=breakupMomQ(mother4Vec.M(), massSumFsParticlesDec1(), massSumFsParticlesDec2()).real(); evtData->DoubleMassId[_wignerDqId]=qVal; evtData->DoubleMassId[_wignerDqNormId] = qValNorm; } // _alreadyFilledMap[evtNo]=true; } void AbsDecay::print(std::ostream& os) const{ if(!_daughter1IsStable){ os << "with further decay:"; _absDecDaughter1->print(os); } if(!_daughter2IsStable){ os << "with further decay:"; _absDecDaughter2->print(os); } os << "\n"; } void AbsDecay::resetFilledMap() { _alreadyFilledMap.clear(); if (!_daughter1IsStable){ _absDecDaughter1->resetFilledMap(); } if (!_daughter2IsStable){ _absDecDaughter2->resetFilledMap(); } } void AbsDecay::enableProdBarrier(){ if(_dynEnabled){ Alert << "dynamics already enabled for " << name() << endmsg; exit(1); } if(!_prodChannelInfo->isProductionChannel()){ Warning << name() << " is not a production amplitide! Barrier factors for the production can not be enabled!" << endmsg; return; } if(!_prodChannelInfo->withProdBarrier()){ Warning << name() << "production barrier disabled" << endmsg; return; } _useProdBarrier=true; if(_prodChannelInfo->prodBarrierType()=="BlattWBarrier"){ _dynType="BlattWBarrier"; _qR=_prodChannelInfo->qRPod(); } else if(_prodChannelInfo->prodBarrierType()=="RadM1"){ _dynType="RadM1"; } Info << "Barrier factors for production amplitude " << name() << " enabled!" << endmsg; _absDynPtr=DynRegistry::instance()->getDynamics(shared_from_this()); _dynEnabled=true; } double AbsDecay::massSumFsParticlesDec1(){ if (!_daughter1IsStable) return _absDecDaughter1->massSumFsParticles(); else return _daughter1->mass(); } double AbsDecay::massSumFsParticlesDec2(){ if (!_daughter2IsStable) return _absDecDaughter2->massSumFsParticles(); return _daughter2->mass(); } void AbsDecay::extractLmin(){ std::vector< std::shared_ptr<const LScomb> > LSDecAmps; if (_useIsospin){ Spin currentGParity=_motherIGJPCPtr->G; int daughter1GParity=_daughter1->theGParity(); int daughter2GParity=_daughter2->theGParity(); if( fabs(currentGParity)==1 && fabs(daughter1GParity)==1 && fabs(daughter2GParity)==1){ validLS( _motherIGJPCPtr, _daughter1, _daughter2, LSDecAmps, true, _gParity, true); } else{ validLS( _motherIGJPCPtr, _daughter1, _daughter2, LSDecAmps); } } else{ validLS( _motherIGJPCPtr, _daughter1, _daughter2, LSDecAmps); } _Lmin=100; std::vector< std::shared_ptr<const LScomb> >::iterator it; for (it=LSDecAmps.begin(); it!=LSDecAmps.end(); ++it){ int currentL=(*it)->L; if(_Lmin>currentL) _Lmin=currentL; } } void AbsDecay::setDecayLevel(decLevel theLevel){ if (_decLevel==decayLevel::noLevel){ _decLevel=theLevel; } else if(_decLevel != theLevel) _decLevel=decayLevel::severalLevels; else return; Info << name() << " set decay level to " << _decLevel << endmsg; } void AbsDecay::setDecayLevelTree(decLevel theLevel, std::shared_ptr<AbsDecay> motherDecPtr, std::shared_ptr<AbsDecay> prodDecPtr){ setDecayLevel(theLevel); if(prodDecPtr->whichDecayLevel() != AbsDecay::decayLevel::isProdAmp){ Alert << "prodDecPtr with the name " << prodDecPtr->name() << " is not a production amplitude!!!" << endmsg; exit(1); } //check if prod decay already exists const std::string key = prodDecPtr->name(); std::vector<std::shared_ptr<AbsDecay> >::iterator it; for(it=_prodAmpRefList.begin(); it!=_prodAmpRefList.end();++it){ if (key==(*it)->name()){ //prod decay already exists Alert << "production amplitude " << key << " aleady exists in the reference list!!!" << endmsg; Alert << "It is not allowed to refer to the same production amplitude more than once!!!!" << endmsg; exit(1); } } _prodAmpRefList.push_back(prodDecPtr); const std::string keyMotherDec = motherDecPtr->name(); for(it=_motherAmpRefList.begin(); it!=_motherAmpRefList.end();++it){ if (key==(*it)->name()){ //prod decay already exists Alert << "mother amplitude " << keyMotherDec << " aleady exists in the reference list!!!" << endmsg; Alert << "It is not allowed to refer to the same mother amplitude more than once!!!!" << endmsg; exit(1); } } if(whichDecayLevel() != AbsDecay::decayLevel::isProdAmp) _motherAmpRefList.push_back(motherDecPtr); if (!_daughter1IsStable){ _absDecDaughter1->setDecayLevelTree(decayLevel(theLevel+1), shared_from_this(), prodDecPtr); } else{ prodDecPtr->addToFsParticleNameList(_daughter1->name()); motherDecPtr->addToFsParticleNameList(_daughter1->name()); } if (!_daughter2IsStable){ _absDecDaughter2->setDecayLevelTree(decayLevel(theLevel+1), shared_from_this(), prodDecPtr); } else{ prodDecPtr->addToFsParticleNameList(_daughter2->name()); motherDecPtr->addToFsParticleNameList(_daughter2->name()); } } void AbsDecay::addToFsParticleNameList(const std::string& name){ std::vector<std::string>::iterator it; bool alreadyThere=false; for(it = _fsParticleNameList.begin(); it!=_fsParticleNameList.end(); ++it){ if (name==(*it)) alreadyThere=true; } if( !alreadyThere ) _fsParticleNameList.push_back(name); } void AbsDecay::setWigDRefKey(std::string& ref){ if(ref == _wignerDRefKey) return; if (_wignerDRefKey != "default"){ Alert << "two different reference keys for the WignerD functions not allowed!!!" << "\n which are: " << _wignerDRefKey << " and: " << ref << "\n clone particle(s) for at least one decay chain" << endmsg; exit(1); } _wignerDRefKey=ref; // Info << _name << ":\twignerDKey= " << _wignerDKey << "\twignerDRefKey= " << _wignerDRefKey << endmsg; if (!_daughter1IsStable){ _absDecDaughter1->setWigDRefKey(_refKey); } if (!_daughter2IsStable){ _absDecDaughter2->setWigDRefKey(_refKey); } _nameId=IdStringMapRegistry::instance()->stringId(_name); _wignerDId=IdStringMapRegistry::instance()->stringId(_wignerDKey); std::string wignerDqNormKey=_wignerDKey+"qNorm"; std::string keyForMassList="Mass"; _wignerDqId=IdStringMapRegistry::instance()->keyStringId(keyForMassList,_wignerDKey); _wignerDqNormId = IdStringMapRegistry::instance()->keyStringId(keyForMassList, wignerDqNormKey); _wigDWigDRefId=IdStringMapRegistry::instance()->stringStringId(_wignerDKey, _wignerDRefKey); Info << "wigDWigDRefId = " << _wigDWigDRefId << endmsg; std::pair<std::string, std::string > wigDWigDRefPair=IdStringMapRegistry::instance()->stringPair(_wigDWigDRefId); Info << "name of amplitude: " << _name << "\tnameId: " << _nameId <<"\n_wigDWigDRefId = " << _wigDWigDRefId << "\t_wignerDId = " << _wignerDId << "\nwith wignerDKey: " << wigDWigDRefPair.first << "\twignerDRefKey: " << wigDWigDRefPair.second << endmsg; } void AbsDecay::setMassParKey(const std::string& newKey){ _massParamKey = newKey; _massParamId = IdStringMapRegistry::instance()->keyStringId("grandMaAndMassParKey", _massParamKey); }