/* Copyright : The FASTMC and SPHMC Collaboration Author : Ionut Cristian Arsene Affiliation : Oslo University, Norway & Institute for Space Sciences, Bucharest, Romania e-mail : i.c.arsene@fys.uio.no Date : 2007/05/30 This class is using the particle and decay lists provided by the THERMINATOR (Computer Physics Communications 174 669 (2006)) and SHARE (Computer Physics Communications 167 229 (2005)) collaborations. */ #ifndef DATABASE_PDG #include "DatabasePDG.h" #endif #include #include #include using std::cout; using std::endl; using std::strcmp; using std::strcpy; using std::ifstream; using std::ios; DatabasePDG::DatabasePDG() { fNParticles = 0; strcpy(fParticleFilename, "particles.data"); strcpy(fDecayFilename, "tabledecay.txt"); for(Int_t i=0; i> name >> mass >> width >> spin >> isospin >> isospinZ >> q >> s >> aq >> as >> c >> ac >> pdg; } catch (ios::failure const &problem) { cout << problem.what() << endl; break; } fParticles[fNParticles]->SetName(name); fParticles[fNParticles]->SetPDG(pdg); fParticles[fNParticles]->SetMass(mass); fParticles[fNParticles]->SetWidth(width); fParticles[fNParticles]->SetSpin(spin); fParticles[fNParticles]->SetIsospin(isospin); fParticles[fNParticles]->SetIsospinZ(isospinZ); fParticles[fNParticles]->SetLightQNumber(q); fParticles[fNParticles]->SetStrangeQNumber(s); fParticles[fNParticles]->SetLightAQNumber(aq); fParticles[fNParticles]->SetStrangeAQNumber(as); fParticles[fNParticles]->SetCharmQNumber(c); fParticles[fNParticles]->SetCharmAQNumber(ac); fStatus[fNParticles] = kTRUE; // check if we want charmed particles if(!fUseCharmParticles && (c>0 || ac>0)) { fStatus[fNParticles] = kFALSE; } // check that the particle mass is inside accepted limits if(!(fMinimumMass<=mass && mass<=fMaximumMass)) { fStatus[fNParticles] = kFALSE; } // check that the particle width is inside accepted limits if(!(fMinimumWidth<=width && width<=fMaximumWidth)) { fStatus[fNParticles] = kFALSE; } if(fStatus[fNParticles]) goodStatusParticles++; fNParticles++; } particleFile.close(); if(fNParticles==0) { cout << "Warning in DatabasePDG::LoadParticles(): No particles were found in the file specified!!" << endl; return kFALSE; } SortParticles(); cout << "Info in DatabasePDG::LoadParticles(): Particle definitions found = " << fNParticles << endl << " Good status particles = " << goodStatusParticles << endl; return kTRUE; } Bool_t DatabasePDG::LoadDecays() { ifstream decayFile; decayFile.open(fDecayFilename); if(!decayFile) { cout << "ERROR in DatabasePDG::LoadDecays() : The ASCII file containing the decays list (\"" << fDecayFilename << "\") was not found !! Aborting..." << endl; return kFALSE; } Int_t mother_pdg, daughter_pdg[3]; Double_t branching; decayFile.exceptions(ios::failbit); while(!decayFile.eof()) { mother_pdg = 0; for(Int_t i=0; i<3; i++) daughter_pdg[i] = 0; branching = -1.0; try { decayFile >> mother_pdg; for(Int_t i=0; i<3; i++) decayFile >> daughter_pdg[i]; decayFile >> branching; } catch (ios::failure const &problem) { cout << problem.what() << endl; break; } if((mother_pdg!=0) && (daughter_pdg[0]!=0) && (branching>=0)) { Int_t nDaughters = 0; for(Int_t i=0; i<3; i++) if(daughter_pdg[i]!=0) nDaughters++; ParticlePDG* particle = GetPDGParticle(mother_pdg); DecayChannel decay(mother_pdg, branching, nDaughters, daughter_pdg); particle->AddChannel(&decay); } } decayFile.close(); Int_t nDecayChannels = 0; for(Int_t i=0; iGetNDecayChannels(); } cout << "Info in DatabasePDG::LoadDecays(): Number of decays found in the database is " << nDecayChannels << endl; return kTRUE; } ParticlePDG* DatabasePDG::GetPDGParticleByIndex(Int_t index) { if(index<0 || index>fNParticles) { cout << "Warning in DatabasePDG::GetPDGParticleByIndex(Int_t): Particle index is negative or too big !!" << endl << " It must be inside this range: [0, " << fNParticles-1 << "]" << endl << " Returning null pointer!!" << endl; return 0x0; } return fParticles[index]; } Bool_t DatabasePDG::GetPDGParticleStatusByIndex(Int_t index) { if(index<0 || index>fNParticles) { cout << "Warning in DatabasePDG::GetPDGParticleStatusByIndex(Int_t): Particle index is negative or too big !!" << endl << " It must be inside this range: [0, " << fNParticles-1 << "]" << endl << " Returning null pointer!!" << endl; return kFALSE; } return fStatus[index]; } ParticlePDG* DatabasePDG::GetPDGParticle(Int_t pdg) { Int_t nFindings = 0; Int_t firstTimeIndex = 0; for(Int_t i=0; iGetPDG()) { if(nFindings == 0) firstTimeIndex = i; nFindings++; } } if(nFindings == 1) return fParticles[firstTimeIndex]; if(nFindings == 0) { //cout << "Warning in DatabasePDG::GetPDGParticle(Int_t): The particle required with PDG = " << pdg // << " was not found in the database!!" << endl; return 0x0; } if(nFindings >= 2) { cout << "Warning in DatabasePDG::GetPDGParticle(Int_t): The particle required with PDG = " << pdg << " was found with " << nFindings << " entries in the database. Check it out !!" << endl << "Returning the first instance found" << endl; return fParticles[firstTimeIndex]; } return 0x0; } Bool_t DatabasePDG::GetPDGParticleStatus(Int_t pdg) { Int_t nFindings = 0; Int_t firstTimeIndex = 0; for(Int_t i=0; iGetPDG()) { if(nFindings == 0) firstTimeIndex = i; nFindings++; } } if(nFindings == 1) return fStatus[firstTimeIndex]; if(nFindings == 0) { //cout << "Warning in DatabasePDG::GetPDGParticle(Int_t): The particle required with PDG = " << pdg // << " was not found in the database!!" << endl; return kFALSE; } if(nFindings >= 2) { cout << "Warning in DatabasePDG::GetPDGParticleStatus(Int_t): The particle status required for PDG = " << pdg << " was found with " << nFindings << " entries in the database. Check it out !!" << endl << "Returning the status of first instance found" << endl; return fStatus[firstTimeIndex]; } return kFALSE; } ParticlePDG* DatabasePDG::GetPDGParticle(Char_t* name) { Int_t nFindings = 0; Int_t firstTimeIndex = 0; for(Int_t i=0; iGetName())) { if(nFindings == 0) firstTimeIndex = i; nFindings++; } } if(nFindings == 1) return fParticles[firstTimeIndex]; if(nFindings == 0) { //cout << "Warning in DatabasePDG::GetPDGParticle(Char_t*): The particle required with name \"" << name // << "\" was not found in the database!!" << endl; return 0x0; } if(nFindings >= 2) { cout << "Warning in DatabasePDG::GetPDGParticle(Char_t*): The particle required with name \"" << name << "\" was found with " << nFindings << " entries in the database. Check it out !!" << endl << "Returning the first instance found" << endl; return fParticles[firstTimeIndex]; } return 0x0; } Bool_t DatabasePDG::GetPDGParticleStatus(Char_t* name) { Int_t nFindings = 0; Int_t firstTimeIndex = 0; for(Int_t i=0; iGetName())) { if(nFindings == 0) firstTimeIndex = i; nFindings++; } } if(nFindings == 1) return fStatus[firstTimeIndex]; if(nFindings == 0) { //cout << "Warning in DatabasePDG::GetPDGParticle(Char_t*): The particle required with name \"" << name // << "\" was not found in the database!!" << endl; return kFALSE; } if(nFindings >= 2) { cout << "Warning in DatabasePDG::GetPDGParticleStatus(Char_t*): The particle status required for name \"" << name << "\" was found with " << nFindings << " entries in the database. Check it out !!" << endl << "Returning the first instance found" << endl; return fStatus[firstTimeIndex]; } return kFALSE; } void DatabasePDG::DumpData(Bool_t dumpAll) { cout << "***********************************************************************************************************" << endl; cout << "Dumping all the information contained in the database..." << endl; Int_t nDecays = 0; Int_t nGoodStatusDecays = 0; Int_t nGoodStatusParticles = 0; for(Int_t currPart=0; currPartGetNDecayChannels() : 0); nDecays += fParticles[currPart]->GetNDecayChannels(); if(!(dumpAll || (!dumpAll && fStatus[currPart]))) continue; cout << "###### Particle: " << fParticles[currPart]->GetName() << " with PDG code " << fParticles[currPart]->GetPDG() << endl; cout << " status = " << fStatus[currPart] << endl; cout << " mass = " << fParticles[currPart]->GetMass() << " GeV" << endl; cout << " width = " << fParticles[currPart]->GetWidth() << " GeV" << endl; cout << " 2*spin = " << Int_t(2.*fParticles[currPart]->GetSpin()) << endl; cout << " 2*isospin = " << Int_t(2.*fParticles[currPart]->GetIsospin()) << endl; cout << " 2*isospin3 = " << Int_t(2.*fParticles[currPart]->GetIsospinZ()) << endl; cout << " u,d quarks = " << Int_t(fParticles[currPart]->GetLightQNumber()) << endl; cout << " s quarks = " << Int_t(fParticles[currPart]->GetStrangeQNumber()) << endl; cout << " c quarks = " << Int_t(fParticles[currPart]->GetCharmQNumber()) << endl; cout << " anti u,d quarks = " << Int_t(fParticles[currPart]->GetLightAQNumber()) << endl; cout << " anti s quarks = " << Int_t(fParticles[currPart]->GetStrangeAQNumber()) << endl; cout << " anti c quarks = " << Int_t(fParticles[currPart]->GetCharmAQNumber()) << endl; cout << " baryon number = " << Int_t(fParticles[currPart]->GetBaryonNumber()) << endl; cout << " strangeness = " << Int_t(fParticles[currPart]->GetStrangeness()) << endl; cout << " charmness = " << Int_t(fParticles[currPart]->GetCharmness()) << endl; cout << " electric charge = " << Int_t(fParticles[currPart]->GetElectricCharge()) << endl; cout << " full branching = " << fParticles[currPart]->GetFullBranching() << endl; cout << " decay modes = " << fParticles[currPart]->GetNDecayChannels() << endl; for(Int_t currChannel=0; currChannelGetNDecayChannels(); currChannel++) { cout << " channel " << currChannel+1 << " with branching " << fParticles[currPart]->GetDecayChannel(currChannel)->GetBranching() << endl; cout << " daughters PDG codes: "; Double_t daughtersMass = 0.0; for(Int_t currDaughter=0; currDaughterGetDecayChannel(currChannel)->GetNDaughters(); currDaughter++) { cout << fParticles[currPart]->GetDecayChannel(currChannel)->GetDaughterPDG(currDaughter) << "\t"; ParticlePDG *daughter = GetPDGParticle(fParticles[currPart]->GetDecayChannel(currChannel)->GetDaughterPDG(currDaughter)); daughtersMass += daughter->GetMass(); } cout << endl; cout << " daughters sum mass = " << daughtersMass << endl; } } if(dumpAll) { cout << "Finished dumping information for " << fNParticles << " particles with " << nDecays << " decay channels in total." << endl; cout << "*************************************************************************************************************" << endl; } else { cout << "Finished dumping information for " << nGoodStatusParticles << "(" << fNParticles << ")" << " particles with " << nGoodStatusDecays << "(" << nDecays << ")" << " decay channels in total." << endl; cout << "*************************************************************************************************************" << endl; } } Int_t DatabasePDG::CheckImpossibleDecays(Bool_t dump) { // Check the database for impossible decays Int_t nImpossibleDecays = 0; for(Int_t currPart=0; currPartGetNDecayChannels(); Int_t allowedChannels = GetNAllowedChannels(fParticles[currPart], fParticles[currPart]->GetMass()); if(dump) { cout << "Particle " << fParticles[currPart]->GetPDG() << " has " << allChannels << " decay channels specified in the database" << endl; cout << " Allowed channels assuming table mass = " << allowedChannels << endl; } if(dump && allChannels>0 && allowedChannels == 0) { cout << "**********************************************************************" << endl; cout << " All channels for this particles are not allowed" << endl; cout << "**********************************************************************" << endl; } if(dump && fParticles[currPart]->GetWidth() > 0. && allChannels == 0) { cout << "**********************************************************************" << endl; cout << " Particle has finite width but no decay channels specified" << endl; cout << "**********************************************************************" << endl; } for(Int_t currChannel=0; currChannelGetNDecayChannels(); currChannel++) { Double_t motherMass = fParticles[currPart]->GetMass(); Double_t daughtersSumMass = 0.; for(Int_t currDaughter=0; currDaughterGetDecayChannel(currChannel)->GetNDaughters(); currDaughter++) { ParticlePDG *daughter = GetPDGParticle(fParticles[currPart]->GetDecayChannel(currChannel)->GetDaughterPDG(currDaughter)); daughtersSumMass += daughter->GetMass(); } if(daughtersSumMass >= motherMass) { nImpossibleDecays++; if(dump) { cout << "Imposible decay for particle " << fParticles[currPart]->GetPDG() << endl; cout << " Channel: " << fParticles[currPart]->GetPDG() << " --> "; for(Int_t currDaughter=0; currDaughterGetDecayChannel(currChannel)->GetNDaughters(); currDaughter++) { ParticlePDG *daughter = GetPDGParticle(fParticles[currPart]->GetDecayChannel(currChannel)->GetDaughterPDG(currDaughter)); cout << daughter->GetPDG() << " "; } cout << endl; cout << " Mother particle mass = " << motherMass << endl; cout << " Daughters sum mass = " << daughtersSumMass << endl; } } } } return nImpossibleDecays; } void DatabasePDG::SetUseCharmParticles(Bool_t flag) { if(fNParticles>0) { fUseCharmParticles = flag; for(Int_t i=0; iGetCharmQNumber()>0 || fParticles[i]->GetCharmAQNumber()) fStatus[i] = flag; } SortParticles(); return; } else fUseCharmParticles = flag; return; } void DatabasePDG::SetMinimumWidth(Double_t value) { if(fNParticles>0) { fMinimumWidth = value; for(Int_t i=0; iGetWidth() < fMinimumWidth) fStatus[i] = kFALSE; } SortParticles(); return; } else fMinimumWidth = value; return; } void DatabasePDG::SetMaximumWidth(Double_t value) { if(fNParticles>0) { fMaximumWidth = value; for(Int_t i=0; iGetWidth() > fMaximumWidth) fStatus[i] = kFALSE; } SortParticles(); return; } else fMaximumWidth = value; return; } void DatabasePDG::SetWidthRange(Double_t min, Double_t max) { if(fNParticles>0) { fMinimumWidth = min; fMaximumWidth = max; for(Int_t i=0; iGetWidth()GetWidth()>fMaximumWidth)) fStatus[i] = kFALSE; } SortParticles(); return; } else { fMinimumWidth = min; fMaximumWidth = max; } return; } void DatabasePDG::SetMinimumMass(Double_t value) { if(fNParticles>0) { fMinimumMass = value; for(Int_t i=0; iGetMass() < fMinimumMass) fStatus[i] = kFALSE; } SortParticles(); return; } else fMinimumMass = value; return; } void DatabasePDG::SetMaximumMass(Double_t value) { if(fNParticles>0) { fMaximumMass = value; for(Int_t i=0; iGetMass() > fMaximumMass) fStatus[i] = kFALSE; } SortParticles(); return; } else fMaximumMass = value; return; } void DatabasePDG::SetMassRange(Double_t min, Double_t max) { if(fNParticles>0) { fMinimumMass = min; fMaximumMass = max; for(Int_t i=0; iGetMass()GetMass()>fMaximumMass)) fStatus[i] = kFALSE; } SortParticles(); return; } else { fMinimumMass = min; fMaximumMass = max; } return; } void DatabasePDG::SortParticles() { if(fNParticles<2) { cout << "Warning in DatabasePDG::SortParticles() : No particles to sort. Load data first!!" << endl; return; } Int_t nGoodStatus = 0; for(Int_t i=0; i> pdg; } catch (ios::failure const &problem) { cout << problem.what() << endl; break; } Int_t found = 0; for(Int_t i=0; iGetPDG()==pdg) { found++; flaggedIndexes[i] = kTRUE; } } if(!found) { cout << "Warning in DatabasePDG::UseThisListOfParticles(Char_t*, Bool_t) : The particle with PDG code " << pdg << " was asked but not found in the database!!" << endl; } if(found>1) { cout << "Warning in DatabasePDG::UseThisListOfParticles(Char_t*, Bool_t) : The particle with PDG code " << pdg << " was found more than once in the database!!" << endl; } } if(exclusive) { for(Int_t i=0; iGetNDaughters(); i++) daughtersSumMass += GetPDGParticle(channel->GetDaughterPDG(i))->GetMass(); if(daughtersSumMassGetNDecayChannels(); i++) nAllowedChannels += (IsChannelAllowed(particle->GetDecayChannel(i), motherMass) ? 1:0); return nAllowedChannels; }