diff --git a/corsika/framework/core/ParticleProperties.hpp b/corsika/framework/core/ParticleProperties.hpp index b4db8bd04948babd876cfe7a49169cc02e6493be..e3a7bec2d5d2989f9ad60fe8697572fff1d222af 100644 --- a/corsika/framework/core/ParticleProperties.hpp +++ b/corsika/framework/core/ParticleProperties.hpp @@ -16,6 +16,7 @@ #include <array> #include <cstdint> +#include <cmath> #include <iosfwd> #include <corsika/framework/core/PhysicalUnits.hpp> @@ -28,7 +29,6 @@ */ namespace corsika { - /** * @enum Code * The Code enum is the actual place to define CORSIKA 8 particle codes. @@ -39,126 +39,115 @@ namespace corsika { using PDGCodeType = std::underlying_type<PDGCode>::type; // forward declarations to be used in GeneratedParticleProperties - int16_t constexpr GetChargeNumber(Code const); - ElectricChargeType constexpr GetCharge(Code const); - HEPMassType constexpr GetMass(Code const); - PDGCode constexpr GetPDG(Code const); - constexpr std::string const& GetName(Code const); - TimeType constexpr GetLifetime(Code const); - - bool constexpr IsNucleus(Code const); - bool constexpr IsHadron(Code const); - bool constexpr IsEM(Code const); - bool constexpr IsMuon(Code const); - bool constexpr IsNeutrino(Code const); - int constexpr GetNucleusA(Code const); - int constexpr GetNucleusZ(Code const); + int16_t constexpr charge_number(Code const); //!< electric charge in units of e + ElectricChargeType constexpr charge(Code const); //!< electric charge + HEPMassType constexpr mass(Code const); //!< mass + + //! Particle code according to PDG, "Monte Carlo Particle Numbering Scheme" + PDGCode constexpr PDG(Code const); + constexpr std::string const& name(Code const); //!< name of the particle as string + TimeType constexpr lifetime(Code const); //!< lifetime + + //! true iff the particle is a hard-coded nucleus or Code::Nucleus + bool constexpr is_nucleus(Code const); + bool constexpr is_hadron(Code const); //!< true iff particle is hadron + bool constexpr is_em(Code const); //!< true iff particle is electron, positron or gamma + bool constexpr is_muon(Code const); //!< true iff particle is mu+ or mu- + bool constexpr is_neutrino(Code const); //!< true iff particle is (anti-) neutrino + int constexpr nucleus_A(Code const); //!< returns A for hard-coded nucleus, otherwise 0 + int constexpr nucleus_Z(Code const); //!< returns Z for hard-coded nucleus, otherwise 0 +} // namespace corsika #include <corsika/framework/core/GeneratedParticleProperties.inc> -namespace corsika::particles { +namespace corsika { - /*! - * returns mass of particle in natural units - */ - HEPMassType constexpr GetMass(Code const p) { + HEPMassType constexpr mass(Code const p) { if (p == Code::Nucleus) throw std::runtime_error("Cannot GetMass() of particle::Nucleus -> unspecified"); return particle::detail::masses[static_cast<CodeIntType>(p)]; } - /*! - * returns PDG id - */ - PDGCode constexpr GetPDG(Code const p) { + PDGCode constexpr PDG(Code const p) { return particle::detail::pdg_codes[static_cast<CodeIntType>(p)]; } - /*! - * returns electric charge number of particle return 1 for a proton. - */ - int16_t constexpr GetChargeNumber(Code const p) { - if (p == Code::Nucleus) - throw std::runtime_error( - "Cannot GetChargeNumber() of particle::Nucleus -> unspecified"); - // electric_charges stores charges in units of (e/3), e.g. 3 for a proton - return particle::detail::electric_charges[static_cast<CodeIntType>(p)] / 3; + int16_t constexpr charge_number(Code const code) { + if (code == Code::Nucleus) + throw std::runtime_error("charge of particle::Nucleus undefined"); + return particle::detail::electric_charges[static_cast<CodeIntType>(code)]; } - /*! - * returns electric charge of particle, e.g. return 1.602e-19_C for a proton. - */ - ElectricChargeType constexpr GetCharge(Code const p) { - if (p == Code::Nucleus) + ElectricChargeType constexpr charge(Code const code) { + if (code == Code::Nucleus) throw std::runtime_error("Cannot GetCharge() of particle::Nucleus -> unspecified"); - return GetChargeNumber(p) * constants::e; + return charge_number(code) * constants::e; } - constexpr std::string const& GetName(Code const p) { - return particle::detail::names[static_cast<CodeIntType>(p)]; + constexpr std::string const& name(Code const code) { + return particle::detail::names[static_cast<CodeIntType>(code)]; } - inline TimeType constexpr GetLifetime(Code const p) { + TimeType constexpr lifetime(Code const p) { return particle::detail::lifetime[static_cast<CodeIntType>(p)] * second; } - inline bool constexpr IsHadron(Code const p) { + bool constexpr is_hadron(Code const p) { return particle::detail::isHadron[static_cast<CodeIntType>(p)]; } - inline bool constexpr IsEM(Code c) { + bool constexpr is_em(Code c) { return c == Code::Electron || c == Code::Positron || c == Code::Gamma; } - inline bool constexpr IsMuon(Code c) { return c == Code::MuPlus || c == Code::MuMinus; } + bool constexpr is_muon(Code c) { return c == Code::MuPlus || c == Code::MuMinus; } - inline bool constexpr IsNeutrino(Code c) { + bool constexpr is_neutrino(Code c) { return c == Code::NuE || c == Code::NuMu || c == Code::NuTau || c == Code::NuEBar || c == Code::NuMuBar || c == Code::NuTauBar; } - inline int constexpr GetNucleusA(Code const p) { - if (p == Code::Nucleus) { - throw std::runtime_error("GetNucleusA(Code::Nucleus) is impossible!"); + int constexpr nucleus_A(Code const code) { + if (code == Code::Nucleus) { + throw std::runtime_error("nucleus_A(Code::Nucleus) is impossible!"); } - return particle::detail::nucleusA[static_cast<CodeIntType>(p)]; + return particle::detail::nucleusA[static_cast<CodeIntType>(code)]; } - inline int constexpr GetNucleusZ(Code const p) { - if (p == Code::Nucleus) { - throw std::runtime_error("GetNucleusZ(Code::Nucleus) is impossible!"); + int constexpr nucleus_Z(Code const code) { + if (code == Code::Nucleus) { + throw std::runtime_error("nucleus_Z(Code::Nucleus) is impossible!"); } - return particle::detail::nucleusZ[static_cast<CodeIntType>(p)]; + return particle::detail::nucleusZ[static_cast<CodeIntType>(code)]; } - inline bool constexpr IsNucleus(Code const p) { - return (p == Code::Nucleus) || (GetNucleusA(p) != 0); + bool constexpr is_nucleus(Code const code) { + return (code == Code::Nucleus) || (nucleus_A(code) != 0); } - /** - * the output operator for humand-readable particle codes - **/ - - inline std::ostream& operator<<(std::ostream& stream, corsika::Code const p) { - return stream << corsika::GetName(p); + //! the output stream operator for human-readable particle codes + inline std::ostream& operator<<(std::ostream& stream, corsika::Code const code) { + return stream << name(code); } - inline Code ConvertFromPDG(PDGCode p) { + //! convert PDG code to CORSIKA 8 internal code + inline Code convert_from_PDG(PDGCode p) { static_assert(particle::detail::conversionArray.size() % 2 == 1); // this will fail, for the strange case where the maxPDG is negative... - unsigned int constexpr maxPDG{(particle::detail::conversionArray.size() - 1) >> 1}; - auto k = static_cast<PDGCodeType>(p); - if ((unsigned int)abs(k) <= maxPDG) { + int constexpr maxPDG{(particle::detail::conversionArray.size() - 1) >> 1}; + auto const k = static_cast<PDGCodeType>(p); + if (std::abs(k) <= maxPDG) { return particle::detail::conversionArray[k + maxPDG]; } else { return particle::detail::conversionMap.at(p); } } - /** - * Get mass of nucleus - **/ - inline HEPMassType constexpr GetNucleusMass(const int vA, const int vZ) { - return Proton::GetMass() * vZ + (vA - vZ) * Neutron::GetMass(); + + //! returns mass of (A,Z) nucleus, disregarding binding energy + HEPMassType constexpr nucleus_mass(const int A, const int Z) { + auto const absA = std::abs(A); + auto const absZ = std::abs(Z); + return Proton::mass() * absZ + (absA - absZ) * Neutron::mass(); } } // namespace corsika diff --git a/src/framework/core/pdxml_reader.py b/src/framework/core/pdxml_reader.py index 8ce20b80a058cc86090e053ddde888b1902d5db9..e9c61b3a836a7ac0eca9a2c6c99d09341b87e357 100755 --- a/src/framework/core/pdxml_reader.py +++ b/src/framework/core/pdxml_reader.py @@ -346,7 +346,7 @@ def gen_properties(particle_db): # electric charges table string += "static constexpr std::array<int16_t, size> electric_charges = {\n" for p in particle_db.values(): - string += " {charge:d},\n".format(charge = p['electric_charge']) + string += " {charge:d},\n".format(charge = p['electric_charge'] // 3) string += "};\n" # anti-particle table @@ -416,7 +416,7 @@ def gen_classes(particle_db): string += " * Particle properties are taken from the PYTHIA8 ParticleData.xml file:<br>\n" string += " * - pdg=" + str(particle_db[cname]['pdg']) +"\n" string += " * - mass=" + str(particle_db[cname]['mass']) + " GeV \n" - string += " * - charge= " + str(particle_db[cname]['electric_charge']/3) + " \n" + string += " * - charge= " + str(particle_db[cname]['electric_charge'] // 3) + " \n" string += " * - name=" + str(cname) + "\n" string += " * - anti=" + str(antiP) + "\n" if (particle_db[cname]['isNucleus']): @@ -425,19 +425,18 @@ def gen_classes(particle_db): string += "*/\n\n" string += "class " + cname + " {\n" string += " public:\n" - string += " static constexpr Code GetCode() { return Type; }\n" - string += " static constexpr corsika::units::si::HEPMassType GetMass() { return corsika::GetMass(Type); }\n" - string += " static constexpr corsika::units::si::ElectricChargeType GetCharge() { return corsika::GetCharge(Type); }\n" - string += " static constexpr int16_t GetChargeNumber() { return corsika::GetChargeNumber(Type); }\n" - string += " static std::string const& GetName() { return corsika::GetName(Type); }\n" - string += " static constexpr Code GetAntiParticle() { return AntiType; }\n" - string += " static constexpr bool IsNucleus() { return corsika::IsNucleus(Type); }\n" - string += " static constexpr int16_t GetNucleusA() { return corsika::GetNucleusA(Type); }\n" - string += " static constexpr int16_t GetNucleusZ() { return corsika::GetNucleusZ(Type); }\n" - string += " static constexpr Code Type = Code::" + cname + ";\n" - string += " static constexpr Code AntiType = Code::" + antiP + ";\n" + string += " " + cname + "() = delete;\n" + string += " static constexpr Code code = Code::" + cname + ";\n" + string += " static constexpr HEPMassType mass() {return corsika::mass(code);}\n" + string += " static constexpr ElectricChargeType charge() { return corsika::charge(code); }\n" + string += " static constexpr int16_t charge_number() { return corsika::charge_number(code); }\n" + string += " static std::string const& name() { return corsika::name(code); }\n" + string += " static constexpr bool is_nucleus() { return corsika::is_nucleus(code); }\n" + string += " static constexpr int16_t nucleus_A() { return corsika::nucleus_A(code); }\n" + string += " static constexpr int16_t nucleus_Z() { return corsika::nucleus_Z(code); }\n" + string += " static constexpr Code anti_code = Code::" + antiP + ";\n" string += " private:\n" - string += " static constexpr CodeIntType TypeIndex = static_cast<CodeIntType const>(Type);\n" + string += " static constexpr CodeIntType TypeIndex = static_cast<CodeIntType>(code);\n" string += "};\n" return string @@ -448,7 +447,9 @@ def gen_classes(particle_db): # def inc_start(): string = ('// generated by pdxml_reader.py\n' - '// MANUAL EDITS ON OWN RISK. THEY WILL BE OVERWRITTEN. \n') + '// MANUAL EDITS ON OWN RISK. THEY WILL BE OVERWRITTEN. \n' + '\n' + 'namespace corsika {\n') return string @@ -471,7 +472,7 @@ def detail_end(): # # def inc_end(): - string = "" + string = "} // end namespace corsika" return string