#ifndef __JAANET__JPDB__ #define __JAANET__JPDB__ #include #include #include #include #include #include "JAAnet/JParticleTypes.hh" #include "JPhysics/JConstants.hh" #include "JLang/JPredicate.hh" #include "JLang/JException.hh" #include "JLang/JManip.hh" #include "TDatabasePDG.h" #include "TParticlePDG.h" #include "TCollection.h" #include "THashList.h" /** * \author mdejong */ namespace JAANET {} namespace JPP { using namespace JAANET; } namespace JAANET { using JLANG::JException; /** * Auxiliary class to handle particle name, codes and mass. */ struct JParticle { /** * Default constructor. */ JParticle() { this->name = ""; this->pdg = 0; this->geant = 0; this->mass = 0.0; } /** * Constructor. * * \param name name of particle * \param pdg PDG code of particle * \param geant GEANT code of particle * \param mass mass of particle */ JParticle(const std::string& name, const int pdg, const int geant, const double mass) { this->name = name; this->pdg = pdg; this->geant = geant; this->mass = mass; } /** * Print particle. * * \param out output stream * \param particle particle * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JParticle& particle) { using namespace std; using namespace JPP; return out << setw(32) << left << particle.name << " " << setw( 6) << right << particle.pdg << " " << setw( 6) << right << particle.geant << " " << FIXED(12,10) << particle.mass; } std::string name; //!< name of particle int pdg; //!< PDG code of particle int geant; //!< GEANT code of particle double mass; //!< mass of particle [GeV] }; /** * Auxiliary macro for particle creation. * * \param PDG PDG code * \param GEANT GEANT code * \param MASS mass */ #define MAKE_PARTICLE(PDG, GEANT, MASS) JParticle(#PDG, PDG, GEANT, MASS) /** * Collection of particles. */ struct JPDB : public std::vector { /** * Default constructor. */ JPDB() {} /** * Get particle data book. * This particle data book contains all known GEANT particle codes. * * \return particle data book */ static const JPDB& getInstance() { using namespace JPP; static JPDB pdb; if (pdb.empty()) { TDatabasePDG::Instance()->ReadPDGTable(); TIter next(TDatabasePDG::Instance()->ParticleList()); while (TParticlePDG* p = (TParticlePDG*) next()) { const JParticle particle(p->GetName(), p->PdgCode(), convertPDGtoGEANT(p->PdgCode()), p->Mass()); pdb.push_back(particle); } } return pdb; } /** * Check if PDB has particle corresponding to given GEANT code. * * \param geant GEANT code * \return true if available; else false */ bool hasGEANT(const int geant) const { return (find_if(this->begin(), this->end(), JLANG::make_predicate(&JParticle::geant, geant)) != this->end()); } /** * Get particle corresponding to given GEANT code.\n * This method throws an error if the particle cannot be found. * * \param geant GEANT code * \return particle */ const JParticle& getGEANT(const int geant) const { const_iterator p = find_if(this->begin(), this->end(), JLANG::make_predicate(&JParticle::geant, geant)); if (p != this->end()) return *p; else THROW(JException, "Invalid GEANT particle code " << geant); } /** * Retrieve GEANT code for a given PDG code. * * \param pdg PDG code * \return GEANT code */ static int convertPDGtoGEANT(const int pdg) { switch (pdg) { case TRACK_TYPE_NUE: case TRACK_TYPE_NUMU: case TRACK_TYPE_NUTAU: case TRACK_TYPE_ANTINUE: case TRACK_TYPE_ANTINUMU: case TRACK_TYPE_ANTINUTAU: return GEANT4_TYPE_NEUTRINO; case TRACK_TYPE_ANTISIGMA_MINUS: return GEANT4_TYPE_ANTISIGMA_MINUS; case TRACK_TYPE_NEUTRAL_ANTISIGMA: return GEANT4_TYPE_NEUTRAL_ANTISIGMA; case TRACK_TYPE_ANTISIGMA_PLUS: return GEANT4_TYPE_ANTISIGMA_PLUS; case TRACK_TYPE_NEUTRAL_ANTIXI: return GEANT4_TYPE_NEUTRAL_ANTIXI; default: return TDatabasePDG::Instance()->ConvertPdgToGeant3(pdg); } } /** * Check if PDB has particle corresponding to given PDG code. * * \param pdg PDG code * \return true if available; else false */ bool hasPDG(const int pdg) const { return (find_if(this->begin(), this->end(), JLANG::make_predicate(&JParticle::pdg, pdg)) != this->end()); } /** * Get particle corresponding to given PDG code.\n * This method throws an error if the particle cannot be found. * * \param pdg PDG code * \return particle */ const JParticle& getPDG(const int pdg) const { const_iterator p = find_if(this->begin(), this->end(), JLANG::make_predicate(&JParticle::pdg, pdg)); if (p != this->end()) return *p; else THROW(JException, "Invalid PDG particle code " << pdg); } /** * Print particle data book. * * \param out output stream * \param pdb particle data book * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JPDB& pdb) { using namespace std; out << setw(32) << left << "particle" << " " << setw( 6) << right << "PDG" << " " << setw( 6) << right << "GEANT" << " " << setw(12) << right << "Mass [GeV]" << endl; for (JPDB::const_iterator i = pdb.begin(); i != pdb.end(); ++i) { out << *i << endl; } return out; } }; } #endif