From 3c70ce61d834850d17eaece36c58fba24e069bae Mon Sep 17 00:00:00 2001 From: ralfulrich <ralf.ulrich@kit.edu> Date: Mon, 21 Dec 2020 22:55:50 +0100 Subject: [PATCH] onshellcheck --- .gitlab-ci.yml | 17 +- .../framework/utility/CorsikaFenvFallback.inl | 4 +- corsika/detail/modules/ObservationPlane.inl | 2 +- corsika/detail/modules/pythia8/Decay.inl | 249 +++++++++++++----- .../detail/modules/pythia8/Interaction.inl | 243 ++++++++--------- corsika/detail/modules/pythia8/Random.inl | 2 +- corsika/detail/modules/urqmd/UrQMD.inl | 156 ++++++----- corsika/modules/pythia8/Decay.hpp | 51 +++- corsika/modules/pythia8/Interaction.hpp | 40 ++- corsika/modules/pythia8/Random.hpp | 5 +- corsika/modules/urqmd/UrQMD.hpp | 28 +- tests/modules/CMakeLists.txt | 4 +- tests/modules/testOnShellCheck.cpp | 63 ++--- tests/modules/testPythia8.cpp | 108 ++++---- tests/modules/testUrQMD.cpp | 138 +++++----- 15 files changed, 606 insertions(+), 504 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4d1503e37..d483397b8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -67,8 +67,18 @@ check-clang-format: - if: $CI_COMMIT_BRANCH allow_failure: true +### CodeQuality tool #### +include: + - template: Code-Quality.gitlab-ci.yml - +code_quality: + stage: quality + rules: + - if: '$CODE_QUALITY_DISABLED' + when: never + - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Run code quality job in merge request pipelines + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' # Run code quality job in pipelines on the master branch (but not in other branch pipelines) + - if: '$CI_COMMIT_TAG' # Run code quality job in pipelines for tags ####### CONFIG ############## @@ -87,6 +97,11 @@ check-clang-format: - if: $CI_MERGE_REQUEST_ID - if: $CI_COMMIT_TAG - if: $CI_COMMIT_BRANCH + artifacts: + when: on_failure + expire_in: 3 days + paths: + - ${CI_PROJECT_DIR}/build/CMakeFiles/CMakeOutput.log cache: paths: - ${CI_PROJECT_DIR}/build/ diff --git a/corsika/detail/framework/utility/CorsikaFenvFallback.inl b/corsika/detail/framework/utility/CorsikaFenvFallback.inl index ba0dd888a..40a1079ec 100644 --- a/corsika/detail/framework/utility/CorsikaFenvFallback.inl +++ b/corsika/detail/framework/utility/CorsikaFenvFallback.inl @@ -12,7 +12,7 @@ extern "C" { #warning No enabling/disabling of floating point exceptions - platform needs better implementation -int feenableexcept(int excepts) { return -1; } +inline int feenableexcept(int excepts) { return -1; } -int fedisableexcept(int excepts) { return -1; } +inline int fedisableexcept(int excepts) { return -1; } } diff --git a/corsika/detail/modules/ObservationPlane.inl b/corsika/detail/modules/ObservationPlane.inl index 42dd6ad5f..68ef5b49a 100644 --- a/corsika/detail/modules/ObservationPlane.inl +++ b/corsika/detail/modules/ObservationPlane.inl @@ -66,7 +66,7 @@ namespace corsika::observation_plane { auto const pointOfIntersection = trajectory.getPosition(timeOfIntersection); auto dist = (trajectory.getStartPoint() - pointOfIntersection).getNorm() * 1.0001; - CORSIKA_LOG_TRACE("ObservationPlane::MaxStepLength l={} m", dist / 1_m); + CORSIKA_LOG_TRACE("ObservationPlane::getMaxStepLength l={} m", dist / 1_m); return dist; } diff --git a/corsika/detail/modules/pythia8/Decay.inl b/corsika/detail/modules/pythia8/Decay.inl index 2e639d2b8..224b48025 100644 --- a/corsika/detail/modules/pythia8/Decay.inl +++ b/corsika/detail/modules/pythia8/Decay.inl @@ -10,127 +10,238 @@ #include <corsika/modules/pythia8/Decay.hpp> #include <corsika/modules/pythia8/Random.hpp> +#include <corsika/framework/utility/COMBoost.hpp> + #include <corsika/setup/SetupStack.hpp> #include <corsika/setup/SetupTrajectory.hpp> namespace corsika::pythia8 { - Decay::Decay(std::vector<corsika::Code> pParticles) - : fTrackedParticles(pParticles) {} - - Decay::~Decay() { std::cout << "Pythia::Decay n=" << fCount << std::endl; } - - void Decay::Init() { - - Decay::SetParticleListStable(fTrackedParticles); + Decay::Decay(const bool print_listing) + : print_listing_(print_listing) { // set random number generator in pythia Pythia8::RndmEngine* rndm = new corsika::pythia8::Random(); - fPythia.setRndmEnginePtr(rndm); - - fPythia.readString("Next:numberShowInfo = 0"); - fPythia.readString("Next:numberShowProcess = 0"); - fPythia.readString("Next:numberShowEvent = 0"); + pythia_.setRndmEnginePtr(rndm); + + /* + issue xyz: definition of particles and decay channels use the same mechanism in + corsika and pythia we should force pythia to use the file in corsika. + */ + // bool ParticleData::reInit(string startFile, bool xmlFormat = true) + // read in particle data from Corsika 8 + // pythia_.particleData.reInit("/home/felix/ngcorsika/corsika-build/include/corsika/particles/ParticleData.xml"); + // pythia_.particleData.checkTable(); + + pythia_.readString("Next:numberShowInfo = 0"); + pythia_.readString("Next:numberShowProcess = 0"); + pythia_.readString("Next:numberShowEvent = 0"); + + pythia_.readString("Print:quiet = on"); + pythia_.readString("Check:particleData = 0"); + + /* + switching off event check in pythia is needed to allow decays that are off-shell + according to the mass definition in pythia. + the consistency of particle masses between event generators is an unsolved issues + */ + std::cout << "Pythia::Init: switching off event checking in pythia.." << std::endl; + pythia_.readString("Check:event = 1"); + + pythia_.readString("ProcessLevel:all = off"); + pythia_.readString("ProcessLevel:resonanceDecays = off"); + + // making sure + setStable(Code::Pi0); + + // pythia_.particleData.readString("59:m0 = 101.00"); + + if (!pythia_.init()) + throw std::runtime_error("Pythia::Decay: Initialization failed!"); + } - fPythia.readString("Print:quiet = on"); + Decay::Decay(std::set<Code> const& those) + : handleAllDecays_(false) + , handledDecays_(those) {} + + Decay::~Decay() { std::cout << "Pythia::Decay n=" << count_ << std::endl; } + + bool Decay::canHandleDecay(Code const vParticleCode) { + // if known to pythia and not proton, electron or neutrino it can decay + if (vParticleCode == Code::Proton || vParticleCode == Code::AntiProton || + vParticleCode == Code::NuE || vParticleCode == Code::NuMu || + vParticleCode == Code::NuTau || vParticleCode == Code::NuEBar || + vParticleCode == Code::NuMuBar || vParticleCode == Code::NuTauBar || + vParticleCode == Code::Electron || vParticleCode == Code::Positron) + return false; + else if (canDecay(vParticleCode)) // non-zero for particles known to sibyll + return true; + else + return false; + } - fPythia.readString("ProcessLevel:all = off"); - fPythia.readString("ProcessLevel:resonanceDecays = off"); + void Decay::setHandleDecay(Code const vParticleCode) { + handleAllDecays_ = false; + std::cout << "Pythia::Decay: set to handle decay of " << vParticleCode << std::endl; + if (Decay::canHandleDecay(vParticleCode)) + handledDecays_.insert(vParticleCode); + else + throw std::runtime_error("this decay can not be handled by pythia!"); + } - fPythia.particleData.readString("59:m0 = 101.00"); + void Decay::setHandleDecay(std::vector<Code> const& vParticleList) { + handleAllDecays_ = false; + for (auto p : vParticleList) setHandleDecay(p); + } - fPythia.init(); + bool Decay::isDecayHandled(Code const vParticleCode) { + if (handleAllDecays_ && canHandleDecay(vParticleCode)) + return true; + else + return handledDecays_.find(vParticleCode) != Decay::handledDecays_.end(); } - void Decay::SetParticleListStable(const std::vector<corsika::Code> particleList) { - for (auto p : particleList) Decay::SetStable(p); + void Decay::setStable(std::vector<Code> const& particleList) { + for (auto p : particleList) Decay::setStable(p); } - void Decay::SetUnstable(const corsika::Code pCode) { + void Decay::setUnstable(Code const pCode) { std::cout << "Pythia::Decay: setting " << pCode << " unstable.." << std::endl; - fPythia.particleData.mayDecay(static_cast<int>(corsika::get_PDG(pCode)), true); + pythia_.particleData.mayDecay(static_cast<int>(get_PDG(pCode)), true); } - void Decay::SetStable(const corsika::Code pCode) { + void Decay::setStable(Code const pCode) { std::cout << "Pythia::Decay: setting " << pCode << " stable.." << std::endl; - fPythia.particleData.mayDecay(static_cast<int>(corsika::get_PDG(pCode)), false); + pythia_.particleData.mayDecay(static_cast<int>(get_PDG(pCode)), false); } - template <typename TParticle> - TimeType Decay::GetLifetime(TParticle const& p) { + bool Decay::isStable(Code const vCode) { + return pythia_.particleData.canDecay(static_cast<int>(get_PDG(vCode))); + } - HEPEnergyType E = p.GetEnergy(); - HEPMassType m = p.GetMass(); + bool Decay::canDecay(Code const pCode) { + std::cout << "Pythia::Decay: checking if particle: " << pCode + << " can decay in PYTHIA? "; + const bool ans = pythia_.particleData.canDecay(static_cast<int>(get_PDG(pCode))); + std::cout << ans << std::endl; + return ans; + } - const double gamma = E / m; + void Decay::printDecayConfig(const Code vCode) { + std::cout << "Decay: Pythia decay configuration:" << std::endl; + std::cout << vCode << " is "; + if (isStable(vCode)) + std::cout << "stable" << std::endl; + else + std::cout << "unstable" << std::endl; + } - const TimeType t0 = corsika::get_lifetime(p.GetPID()); - auto const lifetime = gamma * t0; + void Decay::printDecayConfig() { + std::cout << "Pythia::Decay: decay configuration:" << std::endl; + if (handleAllDecays_) + std::cout << " all particles known to Pythia are handled by Pythia::Decay!" + << std::endl; + else + for (auto& pCode : handledDecays_) + std::cout << "Decay of " << pCode << " is handled by Pythia!" << std::endl; + } - return lifetime; + template <typename TParticle> + TimeType Decay::getLifetime(TParticle const& particle) { + + const auto pid = particle.getPID(); + if (canDecay(pid)) { + HEPEnergyType E = particle.getEnergy(); + HEPMassType m = particle.getMass(); + + const double gamma = E / m; + + const TimeType t0 = get_lifetime(pid); + auto const lifetime = gamma * t0; + std::cout << "Pythia::Decay: code: " << particle.getPID() << std::endl; + std::cout << "Pythia::Decay: MinStep: t0: " << t0 << std::endl; + std::cout << "Pythia::Decay: MinStep: energy: " << E / 1_GeV << " GeV" << std::endl; + std::cout << "Pythia::Decay: momentum: " + << particle.getMomentum().getComponents() / 1_GeV << " GeV" << std::endl; + std::cout << "Pythia::Decay: MinStep: gamma: " << gamma << std::endl; + std::cout << "Pythia::Decay: MinStep: tau: " << lifetime << std::endl; + + return lifetime; + } else + return std::numeric_limits<double>::infinity() * 1_s; } - template <typename TProjectile> - void Decay::DoDecay(TProjectile& vP) { - using corsika::Point; + template <typename TView> + void Decay::doDecay(TView& view) { + + auto projectile = view.getProjectile(); - auto const decayPoint = vP.GetPosition(); - auto const t0 = vP.GetTime(); + auto const& decayPoint = projectile.getPosition(); + auto const t0 = projectile.getTime(); - // coordinate system, get global frame of reference - corsika::CoordinateSystem& rootCS = - corsika::RootCoordinateSystem::getInstance().GetRootCoordinateSystem(); + auto const& labMomentum = projectile.getMomentum(); + CoordinateSystemPtr const& labCS = labMomentum.getCoordinateSystem(); - fCount++; + // define target kinematics in lab frame + // define boost to and from CoM frame + // CoM frame definition in Pythia projectile: +z + COMBoost const boost(labMomentum, projectile.getMass()); + auto const& rotatedCS = boost.getRotatedCS(); + + count_++; // pythia stack - Pythia8::Event& event = fPythia.event; + Pythia8::Event& event = pythia_.event; event.reset(); + auto const particleId = projectile.getPID(); + // set particle unstable - Decay::SetUnstable(vP.GetPID()); + Decay::setUnstable(particleId); // input particle PDG - auto const pdgCode = static_cast<int>(corsika::get_PDG(vP.GetPID())); + auto const pdgCode = static_cast<int>(get_PDG(particleId)); - auto const pcomp = vP.GetMomentum().GetComponents(); - double px = pcomp[0] / 1_GeV; - double py = pcomp[1] / 1_GeV; - double pz = pcomp[2] / 1_GeV; - double en = vP.GetEnergy() / 1_GeV; - double m = corsika::get_mass(vP.GetPID()) / 1_GeV; + double constexpr px = 0; + double constexpr py = 0; + double constexpr pz = 0; + double const en = projectile.getMass() / 1_GeV; + double const m = en; // add particle to pythia stack event.append(pdgCode, 1, 0, 0, px, py, pz, en, m); - if (!fPythia.next()) - std::cout << "Pythia::Decay: decay failed!" << std::endl; + if (!pythia_.next()) + throw std::runtime_error("Pythia::Decay: decay failed!"); else std::cout << "Pythia::Decay: particles after decay: " << event.size() << std::endl; - // list final state - event.list(); + if (print_listing_) { + // list final state + event.list(); + } // loop over final state for (int i = 0; i < event.size(); ++i) if (event[i].isFinal()) { - auto const pyId = - corsika::convert_from_PDG(static_cast<corsika::PDGCode>(event[i].id())); - HEPEnergyType pyEn = event[i].e() * 1_GeV; - MomentumVector pyP(rootCS, {event[i].px() * 1_GeV, event[i].py() * 1_GeV, - event[i].pz() * 1_GeV}); - - std::cout << "particle: id=" << pyId - << " momentum=" << pyP.GetComponents() / 1_GeV << " energy=" << pyEn - << std::endl; - - vP.AddSecondary( - std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, - corsika::Point, TimeType>{pyId, pyEn, pyP, decayPoint, t0}); + auto const pyId = convert_from_PDG(static_cast<PDGCode>(event[i].id())); + HEPEnergyType const Erest = event[i].e() * 1_GeV; + MomentumVector const pRest( + rotatedCS, + {event[i].px() * 1_GeV, event[i].py() * 1_GeV, event[i].pz() * 1_GeV}); + FourVector const fourMomRest{Erest, pRest}; + auto const fourMomLab = boost.fromCoM(fourMomRest); + + std::cout << "particle: id=" << pyId << " momentum=" + << fourMomLab.getSpaceLikeComponents().getComponents(labCS) / 1_GeV + << " energy=" << fourMomLab.getTimeLikeComponent() << std::endl; + + view.addSecondary(std::make_tuple(pyId, fourMomLab.getTimeLikeComponent(), + fourMomLab.getSpaceLikeComponents(), decayPoint, + t0)); } // set particle stable - Decay::SetStable(vP.GetPID()); + Decay::setStable(particleId); } - } // namespace corsika::pythia8 diff --git a/corsika/detail/modules/pythia8/Interaction.inl b/corsika/detail/modules/pythia8/Interaction.inl index 687f40c37..e67d140a9 100644 --- a/corsika/detail/modules/pythia8/Interaction.inl +++ b/corsika/detail/modules/pythia8/Interaction.inl @@ -18,126 +18,116 @@ #include <tuple> -using Projectile = corsika::setup::StackView::ParticleType; -using Particle = corsika::setup::Stack::ParticleType; +using Projectile = corsika::setup::StackView::particle_type; +using Particle = corsika::setup::Stack::particle_type; namespace corsika::pythia8 { - typedef corsika::Vector<corsika::hepmomentum_d> MomentumVector; - Interaction::~Interaction() { - std::cout << "Pythia::Interaction n=" << fCount << std::endl; + std::cout << "Pythia::Interaction n=" << count_ << std::endl; } - void Interaction::Init() { + Interaction::Interaction(const bool print_listing) + : print_listing_(print_listing) { - using corsika::RNGManager; + std::cout << "Pythia::Interaction n=" << count_ << std::endl; // initialize Pythia - if (!fInitialized) { + if (!initialized_) { - fPythia.readString("Print:quiet = on"); + pythia_.readString("Print:quiet = on"); // TODO: proper process initialization for MinBias needed - fPythia.readString("HardQCD:all = on"); - fPythia.readString("ProcessLevel:resonanceDecays = off"); + pythia_.readString("HardQCD:all = on"); + pythia_.readString("ProcessLevel:resonanceDecays = off"); - fPythia.init(); + pythia_.init(); // any decays in pythia? if yes need to define which particles - if (fInternalDecays) { + if (internalDecays_) { // define which particles are passed to corsika, i.e. which particles make it into // history even very shortlived particles like charm or pi0 are of interest here - const std::vector<corsika::Code> HadronsWeWantTrackedByCorsika = { - corsika::Code::PiPlus, corsika::Code::PiMinus, - corsika::Code::Pi0, corsika::Code::KMinus, - corsika::Code::KPlus, corsika::Code::K0Long, - corsika::Code::K0Short, corsika::Code::SigmaPlus, - corsika::Code::SigmaMinus, corsika::Code::Lambda0, - corsika::Code::Xi0, corsika::Code::XiMinus, - corsika::Code::OmegaMinus, corsika::Code::DPlus, - corsika::Code::DMinus, corsika::Code::D0, - corsika::Code::D0Bar}; - - Interaction::SetParticleListStable(HadronsWeWantTrackedByCorsika); + const std::vector<Code> HadronsWeWantTrackedByCorsika = { + Code::PiPlus, Code::PiMinus, Code::Pi0, Code::KMinus, + Code::KPlus, Code::K0Long, Code::K0Short, Code::SigmaPlus, + Code::SigmaMinus, Code::Lambda0, Code::Xi0, Code::XiMinus, + Code::OmegaMinus, Code::DPlus, Code::DMinus, Code::D0, + Code::D0Bar}; + + Interaction::setStable(HadronsWeWantTrackedByCorsika); } // basic initialization of cross section routines - fSigma.init(&fPythia.info, fPythia.settings, &fPythia.particleData, &fPythia.rndm); + sigma_.init(&pythia_.info, pythia_.settings, &pythia_.particleData, &pythia_.rndm); - fInitialized = true; + initialized_ = true; } } - void Interaction::SetParticleListStable( - std::vector<corsika::Code> const& particleList) { - for (auto p : particleList) Interaction::SetStable(p); + void Interaction::setStable(std::vector<Code> const& particleList) { + for (auto p : particleList) Interaction::setStable(p); } - void Interaction::SetUnstable(const corsika::Code pCode) { + void Interaction::setUnstable(Code const pCode) { std::cout << "Pythia::Interaction: setting " << pCode << " unstable.." << std::endl; - fPythia.particleData.mayDecay(static_cast<int>(corsika::get_PDG(pCode)), true); + pythia_.particleData.mayDecay(static_cast<int>(get_PDG(pCode)), true); } - void Interaction::SetStable(const corsika::Code pCode) { + void Interaction::setStable(Code const pCode) { std::cout << "Pythia::Interaction: setting " << pCode << " stable.." << std::endl; - fPythia.particleData.mayDecay(static_cast<int>(corsika::get_PDG(pCode)), false); + pythia_.particleData.mayDecay(static_cast<int>(get_PDG(pCode)), false); } - void Interaction::ConfigureLabFrameCollision(const corsika::Code BeamId, - const corsika::Code TargetId, + void Interaction::configureLabFrameCollision(const Code BeamId, const Code TargetId, const HEPEnergyType BeamEnergy) { // Pythia configuration of the current event // very clumsy. I am sure this can be done better.. // set beam // beam id for pythia - auto const pdgBeam = static_cast<int>(corsika::get_PDG(BeamId)); + auto const pdgBeam = static_cast<int>(get_PDG(BeamId)); std::stringstream stBeam; stBeam << "Beams:idA = " << pdgBeam; - fPythia.readString(stBeam.str()); + pythia_.readString(stBeam.str()); // set target - auto pdgTarget = static_cast<int>(corsika::get_PDG(TargetId)); + auto pdgTarget = static_cast<int>(get_PDG(TargetId)); // replace hydrogen with proton, otherwise pythia goes into heavy ion mode! - if (TargetId == corsika::Code::Hydrogen) - pdgTarget = static_cast<int>(corsika::get_PDG(corsika::Code::Proton)); + if (TargetId == Code::Hydrogen) pdgTarget = static_cast<int>(get_PDG(Code::Proton)); std::stringstream stTarget; stTarget << "Beams:idB = " << pdgTarget; - fPythia.readString(stTarget.str()); + pythia_.readString(stTarget.str()); // set frame to lab. frame - fPythia.readString("Beams:frameType = 2"); + pythia_.readString("Beams:frameType = 2"); // set beam energy const double Elab = BeamEnergy / 1_GeV; std::stringstream stEnergy; stEnergy << "Beams:eA = " << Elab; - fPythia.readString(stEnergy.str()); + pythia_.readString(stEnergy.str()); // target at rest - fPythia.readString("Beams:eB = 0."); + pythia_.readString("Beams:eB = 0."); // initialize this config - fPythia.init(); + pythia_.init(); } - bool Interaction::CanInteract(const corsika::Code pCode) { - return pCode == corsika::Code::Proton || pCode == corsika::Code::Neutron || - pCode == corsika::Code::AntiProton || pCode == corsika::Code::AntiNeutron || - pCode == corsika::Code::PiMinus || pCode == corsika::Code::PiPlus; + bool Interaction::canInteract(Code const pCode) { + return pCode == Code::Proton || pCode == Code::Neutron || pCode == Code::AntiProton || + pCode == Code::AntiNeutron || pCode == Code::PiMinus || pCode == Code::PiPlus; } - std::tuple<CrossSectionType, CrossSectionType> Interaction::GetCrossSection( - const corsika::Code BeamId, const corsika::Code TargetId, - const HEPEnergyType CoMenergy) { + std::tuple<CrossSectionType, CrossSectionType> Interaction::getCrossSection( + const Code BeamId, const Code TargetId, const HEPEnergyType CoMenergy) { // interaction possible in pythia? - if (TargetId == corsika::Code::Proton || TargetId == corsika::Code::Hydrogen) { - if (CanInteract(BeamId) && ValidCoMEnergy(CoMenergy)) { + if (TargetId == Code::Proton || TargetId == Code::Hydrogen) { + if (canInteract(BeamId) && isValidCoMEnergy(CoMenergy)) { // input particle PDG - auto const pdgCodeBeam = static_cast<int>(corsika::get_PDG(BeamId)); - auto const pdgCodeTarget = static_cast<int>(corsika::get_PDG(TargetId)); + auto const pdgCodeBeam = static_cast<int>(get_PDG(BeamId)); + auto const pdgCodeTarget = static_cast<int>(get_PDG(TargetId)); const double ecm = CoMenergy / 1_GeV; // calculate cross section - fSigma.calc(pdgCodeBeam, pdgCodeTarget, ecm); - if (fSigma.hasSigmaTot()) { - const double sigEla = fSigma.sigmaEl(); - const double sigProd = fSigma.sigmaTot() - sigEla; + sigma_.calc(pdgCodeBeam, pdgCodeTarget, ecm); + if (sigma_.hasSigmaTot()) { + const double sigEla = sigma_.sigmaEl(); + const double sigProd = sigma_.sigmaTot() - sigEla; return std::make_tuple(sigProd * (1_fm * 1_fm), sigEla * (1_fm * 1_fm)); @@ -154,38 +144,38 @@ namespace corsika::pythia8 { } template <> - GrammageType Interaction::GetInteractionLength(Particle& p) { + GrammageType Interaction::getInteractionLength(Particle& particle) { // coordinate system, get global frame of reference - CoordinateSystem& rootCS = - RootCoordinateSystem::getInstance().GetRootCoordinateSystem(); + MomentumVector const& pMomentum = particle.getMomentum(); + CoordinateSystemPtr const& labCS = pMomentum.getCoordinateSystem(); - const corsika::Code corsikaBeamId = p.GetPID(); + const Code corsikaBeamId = particle.getPID(); // beam particles for pythia : 1, 2, 3 for p, pi, k // read from cross section code table - const bool kInteraction = CanInteract(corsikaBeamId); + const bool kInteraction = canInteract(corsikaBeamId); // FOR NOW: assume target is at rest - corsika::MomentumVector pTarget(rootCS, {0_GeV, 0_GeV, 0_GeV}); + MomentumVector pTarget(labCS, {0_GeV, 0_GeV, 0_GeV}); // total momentum and energy - HEPEnergyType Elab = p.GetEnergy() + constants::nucleonMass; - corsika::MomentumVector pTotLab(rootCS, {0_GeV, 0_GeV, 0_GeV}); - pTotLab += p.GetMomentum(); + HEPEnergyType Elab = particle.getEnergy() + constants::nucleonMass; + MomentumVector pTotLab(labCS, {0_GeV, 0_GeV, 0_GeV}); + pTotLab += pMomentum; pTotLab += pTarget; - auto const pTotLabNorm = pTotLab.norm(); + auto const pTotLabNorm = pTotLab.getNorm(); // calculate cm. energy const HEPEnergyType ECoM = sqrt( (Elab + pTotLabNorm) * (Elab - pTotLabNorm)); // binomial for numerical accuracy std::cout << "Interaction: LambdaInt: \n" - << " input energy: " << p.GetEnergy() / 1_GeV << std::endl + << " input energy: " << particle.getEnergy() / 1_GeV << std::endl << " beam can interact:" << kInteraction << std::endl - << " beam pid:" << p.GetPID() << std::endl; + << " beam pid:" << particle.getPID() << std::endl; // TODO: move limits into variables - if (kInteraction && Elab >= 8.5_GeV && ValidCoMEnergy(ECoM)) { + if (kInteraction && Elab >= 8.5_GeV && isValidCoMEnergy(ECoM)) { // get target from environment /* @@ -193,23 +183,23 @@ namespace corsika::pythia8 { ideally as full particle object so that the four momenta and the boosts can be defined.. */ - const auto* currentNode = p.GetNode(); + const auto* currentNode = particle.getNode(); const auto mediumComposition = - currentNode->GetModelProperties().getNuclearComposition(); + currentNode->getModelProperties().getNuclearComposition(); // determine average interaction length auto const weightedProdCrossSection = - mediumComposition.WeightedSum([=](auto vTargetID) { - return std::get<0>(this->GetCrossSection(corsikaBeamId, vTargetID, ECoM)); + mediumComposition.getWeightedSum([=](auto vTargetID) { + return std::get<0>(this->getCrossSection(corsikaBeamId, vTargetID, ECoM)); }); std::cout << "Interaction: IntLength: weighted CrossSection (mb): " << weightedProdCrossSection / 1_mb << std::endl << "Interaction: IntLength: average mass number: " - << mediumComposition.GetAverageMassNumber() << std::endl; + << mediumComposition.getAverageMassNumber() << std::endl; // calculate interaction length in medium - GrammageType const int_length = mediumComposition.GetAverageMassNumber() * + GrammageType const int_length = mediumComposition.getAverageMassNumber() * constants::u / weightedProdCrossSection; std::cout << "Interaction: " << "interaction length (g/cm2): " << int_length / (0.001_kg) * 1_cm * 1_cm @@ -226,43 +216,43 @@ namespace corsika::pythia8 { event is copied (and boosted) into the shower lab frame. */ - template <> - void Interaction::doInteraction(Projectile& vP) { + template <class TView> + void Interaction::doInteraction(TView& view) { + + auto projectile = view.getProjectile(); - const auto corsikaBeamId = vP.GetPID(); + const auto corsikaBeamId = projectile.getPID(); std::cout << "Pythia::Interaction: " << "DoInteraction: " << corsikaBeamId << " interaction? " - << corsika::pythia8::Interaction::CanInteract(corsikaBeamId) << std::endl; + << corsika::pythia8::Interaction::canInteract(corsikaBeamId) << std::endl; - if (corsika::is_nucleus(corsikaBeamId)) { + if (is_nucleus(corsikaBeamId)) { // nuclei handled by different process, this should not happen throw std::runtime_error("Nuclear projectile are not handled by PYTHIA!"); } - if (corsika::pythia8::Interaction::CanInteract(corsikaBeamId)) { + if (corsika::pythia8::Interaction::canInteract(corsikaBeamId)) { - const CoordinateSystem& rootCS = - RootCoordinateSystem::getInstance().GetRootCoordinateSystem(); + // define projectile + HEPEnergyType const eProjectileLab = projectile.getEnergy(); + auto const pProjectileLab = projectile.getMomentum(); + CoordinateSystemPtr const& labCS = pProjectileLab.getCoordinateSystem(); // position and time of interaction, not used in Sibyll - Point pOrig = vP.GetPosition(); - TimeType tOrig = vP.GetTime(); + Point pOrig = projectile.getPosition(); + TimeType tOrig = projectile.getTime(); // define target // FOR NOW: target is always at rest const auto eTargetLab = 0_GeV + constants::nucleonMass; - const auto pTargetLab = MomentumVector(rootCS, 0_GeV, 0_GeV, 0_GeV); + const auto pTargetLab = MomentumVector(labCS, 0_GeV, 0_GeV, 0_GeV); const FourVector PtargLab(eTargetLab, pTargetLab); - // define projectile - HEPEnergyType const eProjectileLab = vP.GetEnergy(); - auto const pProjectileLab = vP.GetMomentum(); - std::cout << "Interaction: ebeam lab: " << eProjectileLab / 1_GeV << std::endl - << "Interaction: pbeam lab: " << pProjectileLab.GetComponents() / 1_GeV + << "Interaction: pbeam lab: " << pProjectileLab.getComponents() / 1_GeV << std::endl; std::cout << "Interaction: etarget lab: " << eTargetLab / 1_GeV << std::endl - << "Interaction: ptarget lab: " << pTargetLab.GetComponents() / 1_GeV + << "Interaction: ptarget lab: " << pTargetLab.getComponents() / 1_GeV << std::endl; const FourVector PprojLab(eProjectileLab, pProjectileLab); @@ -279,101 +269,98 @@ namespace corsika::pythia8 { // boost target auto const PtargCoM = boost.toCoM(PtargLab); - std::cout << "Interaction: ebeam CoM: " << PprojCoM.GetTimeLikeComponent() / 1_GeV + std::cout << "Interaction: ebeam CoM: " << PprojCoM.getTimeLikeComponent() / 1_GeV << std::endl << "Interaction: pbeam CoM: " - << PprojCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV << std::endl; - std::cout << "Interaction: etarget CoM: " << PtargCoM.GetTimeLikeComponent() / 1_GeV + << PprojCoM.getSpaceLikeComponents().getComponents() / 1_GeV << std::endl; + std::cout << "Interaction: etarget CoM: " << PtargCoM.getTimeLikeComponent() / 1_GeV << std::endl << "Interaction: ptarget CoM: " - << PtargCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV << std::endl; + << PtargCoM.getSpaceLikeComponents().getComponents() / 1_GeV << std::endl; - std::cout << "Interaction: position of interaction: " << pOrig.GetCoordinates() + std::cout << "Interaction: position of interaction: " << pOrig.getCoordinates() << std::endl; std::cout << "Interaction: time: " << tOrig << std::endl; HEPEnergyType Etot = eProjectileLab + eTargetLab; - MomentumVector Ptot = vP.GetMomentum(); + MomentumVector Ptot = projectile.getMomentum(); // invariant mass, i.e. cm. energy - HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.squaredNorm()); + HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.getSquaredNorm()); // sample target mass number - const auto* currentNode = vP.GetNode(); + const auto* currentNode = projectile.getNode(); const auto& mediumComposition = - currentNode->GetModelProperties().getNuclearComposition(); + currentNode->getModelProperties().getNuclearComposition(); // get cross sections for target materials /* Here we read the cross section from the interaction model again, - should be passed from GetInteractionLength if possible + should be passed from getInteractionLength if possible */ //#warning reading interaction cross section again, should not be necessary - auto const& compVec = mediumComposition.GetComponents(); + auto const& compVec = mediumComposition.getComponents(); std::vector<si::CrossSectionType> cross_section_of_components(compVec.size()); for (size_t i = 0; i < compVec.size(); ++i) { auto const targetId = compVec[i]; - const auto [sigProd, sigEla] = GetCrossSection(corsikaBeamId, targetId, Ecm); + const auto [sigProd, sigEla] = getCrossSection(corsikaBeamId, targetId, Ecm); [[maybe_unused]] const auto& dummy_sigEla = sigEla; cross_section_of_components[i] = sigProd; } const auto corsikaTargetId = - mediumComposition.SampleTarget(cross_section_of_components, fRNG); + mediumComposition.sampleTarget(cross_section_of_components, RNG_); std::cout << "Interaction: target selected: " << corsikaTargetId << std::endl; - if (corsikaTargetId != corsika::Code::Hydrogen && - corsikaTargetId != corsika::Code::Neutron && - corsikaTargetId != corsika::Code::Proton) + if (corsikaTargetId != Code::Hydrogen && corsikaTargetId != Code::Neutron && + corsikaTargetId != Code::Proton) throw std::runtime_error("DoInteraction: wrong target for PYTHIA"); std::cout << "Interaction: " << " DoInteraction: E(GeV):" << eProjectileLab / 1_GeV << " Ecm(GeV): " << Ecm / 1_GeV << std::endl; - if (eProjectileLab < 8.5_GeV || !ValidCoMEnergy(Ecm)) { + if (eProjectileLab < 8.5_GeV || !isValidCoMEnergy(Ecm)) { std::cout << "Interaction: " << " DoInteraction: should have dropped particle.. " << "THIS IS AN ERROR" << std::endl; throw std::runtime_error("energy too low for PYTHIA"); } else { - fCount++; + count_++; - ConfigureLabFrameCollision(corsikaBeamId, corsikaTargetId, eProjectileLab); + configureLabFrameCollision(corsikaBeamId, corsikaTargetId, eProjectileLab); // create event in pytia - if (!fPythia.next()) throw std::runtime_error("Pythia::DoInteraction: failed!"); + if (!pythia_.next()) throw std::runtime_error("Pythia::DoInteraction: failed!"); // link to pythia stack - Pythia8::Event& event = fPythia.event; + Pythia8::Event& event = pythia_.event; // print final state event.list(); - MomentumVector Plab_final(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV}); + MomentumVector Plab_final(labCS, {0.0_GeV, 0.0_GeV, 0.0_GeV}); HEPEnergyType Elab_final = 0_GeV; for (int i = 0; i < event.size(); ++i) { Pythia8::Particle& p8p = event[i]; // skip particles that have decayed in pythia if (!p8p.isFinal()) continue; - auto const pyId = - corsika::convert_from_PDG(static_cast<corsika::PDGCode>(p8p.id())); + auto const pyId = convert_from_PDG(static_cast<PDGCode>(p8p.id())); const MomentumVector pyPlab( - rootCS, {p8p.px() * 1_GeV, p8p.py() * 1_GeV, p8p.pz() * 1_GeV}); + labCS, {p8p.px() * 1_GeV, p8p.py() * 1_GeV, p8p.pz() * 1_GeV}); HEPEnergyType const pyEn = p8p.e() * 1_GeV; // add to corsika stack - auto pnew = vP.AddSecondary( - std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, - corsika::Point, TimeType>{pyId, pyEn, pyPlab, pOrig, tOrig}); + auto pnew = + projectile.addSecondary(std::make_tuple(pyId, pyEn, pyPlab, pOrig, tOrig)); - Plab_final += pnew.GetMomentum(); - Elab_final += pnew.GetEnergy(); + Plab_final += pnew.getMomentum(); + Elab_final += pnew.getEnergy(); } std::cout << "conservation (all GeV): " << "Elab_final=" << Elab_final / 1_GeV - << ", Plab_final=" << (Plab_final / 1_GeV).GetComponents() << std::endl; + << ", Plab_final=" << (Plab_final / 1_GeV).getComponents() << std::endl; } } } diff --git a/corsika/detail/modules/pythia8/Random.inl b/corsika/detail/modules/pythia8/Random.inl index 980052613..c077e0bf7 100644 --- a/corsika/detail/modules/pythia8/Random.inl +++ b/corsika/detail/modules/pythia8/Random.inl @@ -12,6 +12,6 @@ namespace corsika::pythia8 { - double Random::flat() { return fDist(fRNG); } + double Random::flat() { return Dist_(RNG_); } } // namespace corsika::pythia8 diff --git a/corsika/detail/modules/urqmd/UrQMD.inl b/corsika/detail/modules/urqmd/UrQMD.inl index f76772168..9909a6062 100644 --- a/corsika/detail/modules/urqmd/UrQMD.inl +++ b/corsika/detail/modules/urqmd/UrQMD.inl @@ -25,30 +25,25 @@ namespace corsika::urqmd { UrQMD::UrQMD() { ::urqmd::iniurqmdc8_(); } - using SetupStack = corsika::setup::Stack; - using SetupParticle = corsika::setup::Stack::StackIterator; - using SetupProjectile = corsika::setup::StackView::StackIterator; - - CrossSectionType UrQMD::GetCrossSection(corsika::Code vProjectileCode, - corsika::Code vTargetCode, + CrossSectionType UrQMD::getCrossSection(Code vProjectileCode, Code vTargetCode, HEPEnergyType vLabEnergy, int vAProjectile = 1) { // the following is a translation of ptsigtot() into C++ - if (vProjectileCode != corsika::Code::Nucleus && - !corsika::is_nucleus(vTargetCode)) { // both particles are "special" - auto const mProj = corsika::get_mass(vProjectileCode); - auto const mTar = corsika::get_mass(vTargetCode); + if (vProjectileCode != Code::Nucleus && + !is_nucleus(vTargetCode)) { // both particles are "special" + auto const mProj = get_mass(vProjectileCode); + auto const mTar = get_mass(vTargetCode); double sqrtS = sqrt(static_pow<2>(mProj) + static_pow<2>(mTar) + 2 * vLabEnergy * mTar) * (1 / 1_GeV); // we must set some UrQMD globals first... - auto const [ityp, iso3] = ConvertToUrQMD(vProjectileCode); + auto const [ityp, iso3] = convertToUrQMD(vProjectileCode); ::urqmd::inputs_.spityp[0] = ityp; ::urqmd::inputs_.spiso3[0] = iso3; - auto const [itypTar, iso3Tar] = ConvertToUrQMD(vTargetCode); + auto const [itypTar, iso3Tar] = convertToUrQMD(vTargetCode); ::urqmd::inputs_.spityp[1] = itypTar; ::urqmd::inputs_.spiso3[1] = iso3Tar; @@ -57,7 +52,7 @@ namespace corsika::urqmd { return ::urqmd::sigtot_(one, two, sqrtS) * 1_mb; } else { int const Ap = vAProjectile; - int const At = is_nucleus(vTargetCode) ? corsika::get_nucleus_A(vTargetCode) : 1; + int const At = is_nucleus(vTargetCode) ? get_nucleus_A(vTargetCode) : 1; double const maxImpact = ::urqmd::nucrad_(Ap) + ::urqmd::nucrad_(At) + 2 * ::urqmd::options_.CTParam[30 - 1]; @@ -68,85 +63,86 @@ namespace corsika::urqmd { template <typename TParticle> // need template here, as this is called both with // SetupParticle as well as SetupProjectile - CrossSectionType UrQMD::GetCrossSection(TParticle const& vProjectile, - corsika::Code vTargetCode) const { + CrossSectionType UrQMD::getCrossSection(TParticle const& vProjectile, + Code vTargetCode) const { // TODO: return 0 for non-hadrons? - auto const projectileCode = vProjectile.GetPID(); - auto const projectileEnergyLab = vProjectile.GetEnergy(); + auto const projectileCode = vProjectile.getPID(); + auto const projectileEnergyLab = vProjectile.getEnergy(); - if (projectileCode == corsika::Code::K0Long) { - return 0.5 * - (GetCrossSection(corsika::Code::K0, vTargetCode, projectileEnergyLab) + - GetCrossSection(corsika::Code::K0Bar, vTargetCode, projectileEnergyLab)); + if (projectileCode == Code::K0Long) { + return 0.5 * (getCrossSection(Code::K0, vTargetCode, projectileEnergyLab) + + getCrossSection(Code::K0Bar, vTargetCode, projectileEnergyLab)); } - int const Ap = - (projectileCode == corsika::Code::Nucleus) ? vProjectile.GetNuclearA() : 1; - return GetCrossSection(projectileCode, vTargetCode, projectileEnergyLab, Ap); + int const Ap = (projectileCode == Code::Nucleus) ? vProjectile.getNuclearA() : 1; + return getCrossSection(projectileCode, vTargetCode, projectileEnergyLab, Ap); } - bool UrQMD::CanInteract(corsika::Code vCode) const { + bool UrQMD::canInteract(Code vCode) const { // According to the manual, UrQMD can use all mesons, baryons and nucleons // which are modeled also as input particles. I think it is safer to accept // only the usual long-lived species as input. // TODO: Charmed mesons should be added to the list, too - static corsika::Code const validProjectileCodes[] = { - corsika::Code::Nucleus, corsika::Code::Proton, corsika::Code::AntiProton, - corsika::Code::Neutron, corsika::Code::AntiNeutron, corsika::Code::PiPlus, - corsika::Code::PiMinus, corsika::Code::KPlus, corsika::Code::KMinus, - corsika::Code::K0, corsika::Code::K0Bar, corsika::Code::K0Long}; + static Code const validProjectileCodes[] = { + Code::Nucleus, Code::Proton, Code::AntiProton, Code::Neutron, + Code::AntiNeutron, Code::PiPlus, Code::PiMinus, Code::KPlus, + Code::KMinus, Code::K0, Code::K0Bar, Code::K0Long}; return std::find(std::cbegin(validProjectileCodes), std::cend(validProjectileCodes), vCode) != std::cend(validProjectileCodes); } - GrammageType UrQMD::GetInteractionLength(SetupParticle& vParticle) const { + template <typename TParticle> + GrammageType UrQMD::getInteractionLength(TParticle const& vParticle) const { - if (!CanInteract(vParticle.GetPID())) { - // we could do the canInteract check in GetCrossSection, too but if + if (!canInteract(vParticle.getPID())) { + // we could do the canInteract check in getCrossSection, too but if // we do it here we have the advantage of avoiding the loop return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); } auto const& mediumComposition = - vParticle.GetNode()->GetModelProperties().getNuclearComposition(); + vParticle.getNode()->getModelProperties().getNuclearComposition(); using namespace std::placeholders; CrossSectionType const weightedProdCrossSection = mediumComposition.WeightedSum( - std::bind(&UrQMD::GetCrossSection<decltype(vParticle)>, this, vParticle, _1)); + std::bind(&UrQMD::getCrossSection<decltype(vParticle)>, this, vParticle, _1)); - return mediumComposition.GetAverageMassNumber() * constants::u / + return mediumComposition.getAverageMassNumber() * constants::u / weightedProdCrossSection; } - void UrQMD::doInteraction(SetupProjectile& vProjectile) { + template <typename TView> + void UrQMD::doInteraction(TView& view) { + + auto projectile = view.getProjectile(); - auto projectileCode = vProjectile.GetPID(); - auto const projectileEnergyLab = vProjectile.GetEnergy(); - auto const& projectileMomentumLab = vProjectile.GetMomentum(); - auto const& projectilePosition = vProjectile.GetPosition(); - auto const projectileTime = vProjectile.GetTime(); + auto projectileCode = projectile.getPID(); + auto const projectileEnergyLab = projectile.getEnergy(); + auto const& projectileMomentumLab = projectile.getMomentum(); + auto const& projectilePosition = projectile.getPosition(); + auto const projectileTime = projectile.getTime(); // sample target particle auto const& mediumComposition = - vProjectile.GetNode()->GetModelProperties().getNuclearComposition(); + projectile.getNode()->getModelProperties().getNuclearComposition(); auto const componentCrossSections = std::invoke([&]() { - auto const& components = mediumComposition.GetComponents(); + auto const& components = mediumComposition.getComponents(); std::vector<CrossSectionType> crossSections; crossSections.reserve(components.size()); for (auto const c : components) { - crossSections.push_back(GetCrossSection(vProjectile, c)); + crossSections.push_back(getCrossSection(projectile, c)); } return crossSections; }); - auto const targetCode = mediumComposition.SampleTarget(componentCrossSections, fRNG); - auto const targetA = corsika::get_nucleus_A(targetCode); - auto const targetZ = corsika::get_nucleus_Z(targetCode); + auto const targetCode = mediumComposition.sampleTarget(componentCrossSections, RNG_); + auto const targetA = get_nucleus_A(targetCode); + auto const targetZ = get_nucleus_Z(targetCode); ::urqmd::inputs_.nevents = 1; ::urqmd::sys_.eos = 0; // could be configurable in principle @@ -154,14 +150,14 @@ namespace corsika::urqmd { ::urqmd::sys_.nsteps = 1; // initialization regarding projectile - if (corsika::Code::Nucleus == projectileCode) { + if (Code::Nucleus == projectileCode) { // is this everything? ::urqmd::inputs_.prspflg = 0; - ::urqmd::sys_.Ap = vProjectile.GetNuclearA(); - ::urqmd::sys_.Zp = vProjectile.GetNuclearZ(); - ::urqmd::rsys_.ebeam = (projectileEnergyLab - vProjectile.GetMass()) * (1 / 1_GeV) / - vProjectile.GetNuclearA(); + ::urqmd::sys_.Ap = projectile.getNuclearA(); + ::urqmd::sys_.Zp = projectile.getNuclearZ(); + ::urqmd::rsys_.ebeam = (projectileEnergyLab - projectile.getMass()) * (1 / 1_GeV) / + projectile.getNuclearA(); ::urqmd::rsys_.bdist = ::urqmd::nucrad_(targetA) + ::urqmd::nucrad_(::urqmd::sys_.Ap) + @@ -175,22 +171,22 @@ namespace corsika::urqmd { 1; // even for non-baryons this has to be set, see vanilla UrQMD.f ::urqmd::rsys_.bdist = ::urqmd::nucrad_(targetA) + ::urqmd::nucrad_(1) + 2 * ::urqmd::options_.CTParam[30 - 1]; - ::urqmd::rsys_.ebeam = (projectileEnergyLab - vProjectile.GetMass()) * (1 / 1_GeV); + ::urqmd::rsys_.ebeam = (projectileEnergyLab - projectile.getMass()) * (1 / 1_GeV); - if (projectileCode == corsika::Code::K0Long) { - projectileCode = fBooleanDist(fRNG) ? corsika::Code::K0 : corsika::Code::K0Bar; - } else if (projectileCode == corsika::Code::K0Short) { + if (projectileCode == Code::K0Long) { + projectileCode = booleanDist_(RNG_) ? Code::K0 : Code::K0Bar; + } else if (projectileCode == Code::K0Short) { throw std::runtime_error("K0Short should not interact"); } - auto const [ityp, iso3] = ConvertToUrQMD(projectileCode); + auto const [ityp, iso3] = convertToUrQMD(projectileCode); // todo: conversion of K_long/short into strong eigenstates; ::urqmd::inputs_.spityp[0] = ityp; ::urqmd::inputs_.spiso3[0] = iso3; } // initilazation regarding target - if (corsika::is_nucleus(targetCode)) { + if (is_nucleus(targetCode)) { ::urqmd::sys_.Zt = targetZ; ::urqmd::sys_.At = targetA; ::urqmd::inputs_.trspflg = 0; // nucleus as target @@ -198,7 +194,7 @@ namespace corsika::urqmd { ::urqmd::cascinit_(::urqmd::sys_.Zt, ::urqmd::sys_.At, id); } else { ::urqmd::inputs_.trspflg = 1; // special particle as target - auto const [ityp, iso3] = ConvertToUrQMD(targetCode); + auto const [ityp, iso3] = convertToUrQMD(targetCode); ::urqmd::inputs_.spityp[1] = ityp; ::urqmd::inputs_.spiso3[1] = iso3; } @@ -207,49 +203,47 @@ namespace corsika::urqmd { ::urqmd::urqmd_(iflb); // now retrieve secondaries from UrQMD - auto const& originalCS = projectileMomentumLab.GetCoordinateSystem(); - corsika::CoordinateSystem const zAxisFrame = - originalCS.RotateToZ(projectileMomentumLab); + auto const& originalCS = projectileMomentumLab.getCoordinateSystem(); + CoordinateSystemPtr const& zAxisFrame = + make_rotationToZ(originalCS, projectileMomentumLab); for (int i = 0; i < ::urqmd::sys_.npart; ++i) { - auto code = ConvertFromUrQMD(::urqmd::isys_.ityp[i], ::urqmd::isys_.iso3[i]); - if (code == corsika::Code::K0 || code == corsika::Code::K0Bar) { - code = fBooleanDist(fRNG) ? corsika::Code::K0Short : corsika::Code::K0Long; + auto code = convertFromUrQMD(::urqmd::isys_.ityp[i], ::urqmd::isys_.iso3[i]); + if (code == Code::K0 || code == Code::K0Bar) { + code = booleanDist_(RNG_) ? Code::K0Short : Code::K0Long; } // "coor_.p0[i] * 1_GeV" is likely off-shell as UrQMD doesn't preserve masses well - auto momentum = corsika::Vector( - zAxisFrame, - corsika::QuantityVector<dimensionless_d>{ - ::urqmd::coor_.px[i], ::urqmd::coor_.py[i], ::urqmd::coor_.pz[i]} * - 1_GeV); + auto momentum = + Vector(zAxisFrame, + QuantityVector<dimensionless_d>{ + ::urqmd::coor_.px[i], ::urqmd::coor_.py[i], ::urqmd::coor_.pz[i]} * + 1_GeV); - auto const energy = sqrt(momentum.squaredNorm() + square(corsika::get_mass(code))); + auto const energy = sqrt(momentum.getSquaredNorm() + square(get_mass(code))); momentum.rebase(originalCS); // transform back into standard lab frame - std::cout << i << " " << code << " " << momentum.GetComponents() << std::endl; + std::cout << i << " " << code << " " << momentum.getComponents() << std::endl; - vProjectile.AddSecondary( - std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, - corsika::Point, TimeType>{code, energy, momentum, projectilePosition, - projectileTime}); + projectile.addSecondary( + std::make_tuple(code, energy, momentum, projectilePosition, projectileTime)); } std::cout << "UrQMD generated " << ::urqmd::sys_.npart << " secondaries!" << std::endl; } - corsika::Code ConvertFromUrQMD(int vItyp, int vIso3) { + Code convertFromUrQMD(int vItyp, int vIso3) { int const pdgInt = ::urqmd::pdgid_(vItyp, vIso3); // use the conversion function provided by UrQMD if (pdgInt == 0) { // ::urqmd::pdgid_ returns 0 on error throw std::runtime_error("UrQMD pdgid() returned 0"); } - auto const pdg = static_cast<corsika::PDGCode>(pdgInt); - return corsika::convert_from_PDG(pdg); + auto const pdg = static_cast<PDGCode>(pdgInt); + return convert_from_PDG(pdg); } - std::pair<int, int> ConvertToUrQMD(corsika::Code code) { + std::pair<int, int> convertToUrQMD(Code code) { static const std::map<int, std::pair<int, int>> mapPDGToUrQMD{ // data mostly from github.com/afedynitch/ParticleDataTool {22, {100, 0}}, // gamma diff --git a/corsika/modules/pythia8/Decay.hpp b/corsika/modules/pythia8/Decay.hpp index d80f0779b..4c3568fc7 100644 --- a/corsika/modules/pythia8/Decay.hpp +++ b/corsika/modules/pythia8/Decay.hpp @@ -17,29 +17,52 @@ namespace corsika::pythia8 { - typedef corsika::Vector<hepmomentum_d> MomentumVector; - - class Decay : public corsika::DecayProcess<Decay> { - const std::vector<corsika::Code> fTrackedParticles; - int fCount = 0; + class Decay : public DecayProcess<Decay> { public: - Decay(std::vector<corsika::Code>); + Decay(bool const print_listing = false); + Decay(std::set<Code> const&); ~Decay(); - void Init(); - void SetParticleListStable(const std::vector<corsika::Code>); - void SetUnstable(const corsika::Code); - void SetStable(const corsika::Code); + // is Pythia::Decay set to handle the decay of this particle? + bool isDecayHandled(Code const); + + //! is decay possible in principle? + bool canHandleDecay(Code const); + + //! set Pythia::Decay to handle the decay of this particle! + void setHandleDecay(Code const); + //! set Pythia::Decay to handle the decay of this list of particles! + void setHandleDecay(std::vector<Code> const&); + //! set Pythia::Decay to handle all particle decays + void setHandleAllDecays(); + + //! print internal configuration for this particle + void printDecayConfig(Code const); + //! print configuration of decays in corsika + void printDecayConfig(); + + bool canDecay(Code const); template <typename TParticle> - TimeType GetLifetime(TParticle const&); + TimeType getLifetime(TParticle const&); - template <typename TProjectile> - void DoDecay(TProjectile&); + template <typename TView> + void doDecay(TView&); private: - Pythia8::Pythia fPythia; + bool isStable(Code const vCode); + void setStable(std::vector<Code> const&); + void setUnstable(Code const); + void setStable(Code const); + + // data members + Pythia8::Pythia pythia_; + + std::set<Code> handledDecays_; + int count_ = 0; + bool handleAllDecays_ = true; + bool print_listing_ = false; }; } // namespace corsika::pythia8 diff --git a/corsika/modules/pythia8/Interaction.hpp b/corsika/modules/pythia8/Interaction.hpp index 71b58de38..eb06aefb4 100644 --- a/corsika/modules/pythia8/Interaction.hpp +++ b/corsika/modules/pythia8/Interaction.hpp @@ -20,31 +20,25 @@ namespace corsika::pythia8 { class Interaction : public corsika::InteractionProcess<Interaction> { - int fCount = 0; - bool fInitialized = false; - public: - Interaction() {} + Interaction(const bool print_listing = false); ~Interaction(); - void Init(); + void setStable(std::vector<Code> const&); + void setUnstable(const Code); + void setStable(const Code); - void SetParticleListStable(std::vector<corsika::Code> const&); - void SetUnstable(const corsika::Code); - void SetStable(const corsika::Code); + bool wasInitialized() { return initialized_; } + bool isValidCoMEnergy(HEPEnergyType ecm) { return (10_GeV < ecm) && (ecm < 1_PeV); } - bool WasInitialized() { return fInitialized; } - bool ValidCoMEnergy(HEPEnergyType ecm) { return (10_GeV < ecm) && (ecm < 1_PeV); } + bool canInteract(const Code); + void configureLabFrameCollision(const Code, const Code, const HEPEnergyType); - bool CanInteract(const corsika::Code); - void ConfigureLabFrameCollision(const corsika::Code, const corsika::Code, - const HEPEnergyType); - std::tuple<CrossSectionType, CrossSectionType> GetCrossSection( - const corsika::Code BeamId, const corsika::Code TargetId, - const HEPEnergyType CoMenergy); + std::tuple<CrossSectionType, CrossSectionType> getCrossSection( + const Code BeamId, const Code TargetId, const HEPEnergyType CoMenergy); template <typename TParticle> - GrammageType GetInteractionLength(TParticle&); + GrammageType getInteractionLength(TParticle&); /** In this function PYTHIA is called to produce one event. The @@ -55,11 +49,13 @@ namespace corsika::pythia8 { void doInteraction(TProjectile&); private: - corsika::default_prng_type& fRNG = - corsika::RNGManager::getInstance().getRandomStream("pythia"); - Pythia8::Pythia fPythia; - Pythia8::SigmaTotal fSigma; - const bool fInternalDecays = true; + default_prng_type& RNG_ = RNGManager::getInstance().getRandomStream("pythia"); + Pythia8::Pythia pythia_; + Pythia8::SigmaTotal sigma_; + const bool internalDecays_ = true; + int count_ = 0; + bool initialized_ = false; + bool print_listing_ = false; }; } // namespace corsika::pythia8 diff --git a/corsika/modules/pythia8/Random.hpp b/corsika/modules/pythia8/Random.hpp index e23c4be73..0e04cdb6b 100644 --- a/corsika/modules/pythia8/Random.hpp +++ b/corsika/modules/pythia8/Random.hpp @@ -18,9 +18,8 @@ namespace corsika::pythia8 { double flat(); private: - std::uniform_real_distribution<double> fDist; - corsika::default_prng_type& fRNG = - corsika::RNGManager::getInstance().getRandomStream("pythia"); + std::uniform_real_distribution<double> Dist_; + default_prng_type& RNG_ = RNGManager::getInstance().getRandomStream("pythia"); }; } // namespace corsika::pythia8 diff --git a/corsika/modules/urqmd/UrQMD.hpp b/corsika/modules/urqmd/UrQMD.hpp index 35bbe08f1..9fc261376 100644 --- a/corsika/modules/urqmd/UrQMD.hpp +++ b/corsika/modules/urqmd/UrQMD.hpp @@ -22,26 +22,28 @@ namespace corsika::urqmd { - class UrQMD : public corsika::InteractionProcess<UrQMD> { + class UrQMD : public InteractionProcess<UrQMD> { public: UrQMD(); - void Init() {} - GrammageType GetInteractionLength(corsika::setup::Stack::StackIterator&) const; template <typename TParticle> - CrossSectionType GetCrossSection(TParticle const&, corsika::Code) const; + GrammageType getInteractionLength(TParticle const&) const; - void doInteraction(corsika::setup::StackView::StackIterator&); + template <typename TParticle> + CrossSectionType getCrossSection(TParticle const&, Code) const; + + template <typename TView> + void doInteraction(TView&); - bool CanInteract(corsika::Code) const; + bool canInteract(Code) const; private: - static CrossSectionType GetCrossSection(corsika::Code, corsika::Code, HEPEnergyType, - int); - corsika::default_prng_type& fRNG = - corsika::RNGManager::getInstance().getRandomStream("urqmd"); + static CrossSectionType getCrossSection(Code, Code, HEPEnergyType, int); + + // data members + default_prng_type& RNG_ = RNGManager::getInstance().getRandomStream("urqmd"); - std::uniform_int_distribution<int> fBooleanDist{0, 1}; + std::uniform_int_distribution<int> booleanDist_{0, 1}; }; /** @@ -49,8 +51,8 @@ namespace corsika::urqmd { * * In the current implementation a detour via the PDG code is made. */ - std::pair<int, int> ConvertToUrQMD(corsika::Code); - corsika::Code ConvertFromUrQMD(int vItyp, int vIso3); + std::pair<int, int> convertToUrQMD(Code); + Code convertFromUrQMD(int vItyp, int vIso3); } // namespace corsika::urqmd diff --git a/tests/modules/CMakeLists.txt b/tests/modules/CMakeLists.txt index 335e68c7f..c96ac3a43 100644 --- a/tests/modules/CMakeLists.txt +++ b/tests/modules/CMakeLists.txt @@ -7,10 +7,10 @@ set (test_modules_sources testObservationPlane.cpp testQGSJetII.cpp # testSwitchProcess.cpp -> gone - # testPythia8.cpp + #testPythia8.cpp #testUrQMD.cpp #testCONEXSourceCut.cpp - #testOnShellCheck.cpp + testOnShellCheck.cpp testParticleCut.cpp testSibyll.cpp # testNullModel.cpp -> gone diff --git a/tests/modules/testOnShellCheck.cpp b/tests/modules/testOnShellCheck.cpp index 77c64e178..ab713f7b5 100644 --- a/tests/modules/testOnShellCheck.cpp +++ b/tests/modules/testOnShellCheck.cpp @@ -6,39 +6,35 @@ * the license. */ -#include <corsika/process/on_shell_check/OnShellCheck.h> +#include <corsika/modules/OnShellCheck.hpp> -#include <corsika/environment/Environment.h> -#include <corsika/geometry/FourVector.h> -#include <corsika/geometry/Point.h> -#include <corsika/geometry/RootCoordinateSystem.h> -#include <corsika/geometry/Vector.h> -#include <corsika/units/PhysicalUnits.h> -#include <corsika/utl/CorsikaFenv.h> +#include <corsika/media/Environment.hpp> +#include <corsika/framework/geometry/FourVector.hpp> +#include <corsika/framework/geometry/Point.hpp> +#include <corsika/framework/geometry/RootCoordinateSystem.hpp> +#include <corsika/framework/geometry/Vector.hpp> +#include <corsika/framework/core/PhysicalUnits.hpp> +#include <corsika/framework/utility/CorsikaFenv.hpp> -#include <corsika/setup/SetupStack.h> +#include <corsika/setup/SetupStack.hpp> #include <catch2/catch.hpp> using namespace corsika; -using namespace corsika::process::on_shell_check; -using namespace corsika::units; -using namespace corsika::units::si; TEST_CASE("OnShellCheck", "[processes]") { feenableexcept(FE_INVALID); using EnvType = setup::Environment; EnvType env; - const geometry::CoordinateSystem& rootCS = env.GetCoordinateSystem(); + CoordinateSystemPtr const& rootCS = env.getCoordinateSystem(); // setup empty particle stack setup::Stack stack; - stack.Clear(); + stack.clear(); // two energies const HEPEnergyType E = 10_GeV; // list of arbitrary particles - std::array const particleList{particles::Code::PiPlus, particles::Code::PiMinus, - particles::Code::Helium, particles::Code::Gamma}; + std::array const particleList{Code::PiPlus, Code::PiMinus, Code::Helium, Code::Gamma}; std::array const mass_shifts{1.1, 1.001, 1.0, 1.0}; @@ -46,43 +42,36 @@ TEST_CASE("OnShellCheck", "[processes]") { OnShellCheck check(1.e-2, 0.01, false); - check.Init(); - // add primary particle to stack - auto particle = stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ - particles::Code::Proton, E, - corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns}); + auto particle = stack.addParticle( + std::make_tuple(Code::Proton, E, MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), + Point(rootCS, 0_m, 0_m, 0_m), 0_ns)); // view on secondary particles setup::StackView view{particle}; // ref. to primary particle through the secondary view. // only this way the secondary view is populated - auto projectile = view.GetProjectile(); + auto projectile = view.getProjectile(); // add secondaries, all with energies above the threshold // only cut is by species int count = -1; for (auto proType : particleList) { count++; - const auto pz = sqrt((E - particles::GetMass(proType) * mass_shifts[count]) * - (E + particles::GetMass(proType) * mass_shifts[count])); - auto const momentum = corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, pz}); - projectile.AddSecondary(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::stack::MomentumVector, geometry::Point, - units::si::TimeType>{ - proType, E, momentum, geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns}); + const auto pz = sqrt((E - get_mass(proType) * mass_shifts[count]) * + (E + get_mass(proType) * mass_shifts[count])); + auto const momentum = MomentumVector(rootCS, {0_GeV, 0_GeV, pz}); + projectile.addSecondary( + std::make_tuple(proType, E, momentum, Point(rootCS, 0_m, 0_m, 0_m), 0_ns)); } - check.DoSecondaries(view); + check.doSecondaries(view); int i = -1; for (auto& p : view) { i++; - auto const Plab = corsika::geometry::FourVector(p.GetEnergy(), p.GetMomentum()); - auto const m_kinetic = Plab.GetNorm(); + auto const Plab = FourVector(p.getEnergy(), p.getMomentum()); + auto const m_kinetic = Plab.getNorm(); if (i == 0) - CHECK(m_kinetic / particles::PiPlus::GetMass() == Approx(1)); + CHECK(m_kinetic / PiPlus::mass == Approx(1)); else if (i == 1) - CHECK_FALSE(m_kinetic / particles::PiMinus::GetMass() == Approx(1)); + CHECK_FALSE(m_kinetic / PiMinus::mass == Approx(1)); } } } diff --git a/tests/modules/testPythia8.cpp b/tests/modules/testPythia8.cpp index e565edfdf..a3a0cffe1 100644 --- a/tests/modules/testPythia8.cpp +++ b/tests/modules/testPythia8.cpp @@ -13,8 +13,13 @@ #include <corsika/framework/geometry/Point.hpp> #include <corsika/framework/random/RNGManager.hpp> +#include <SetupTestEnvironment.hpp> +#include <SetupTestStack.hpp> + #include <catch2/catch.hpp> +using namespace corsika; + TEST_CASE("Pythia", "[processes]") { SECTION("linking pythia") { @@ -55,17 +60,11 @@ TEST_CASE("Pythia", "[processes]") { } SECTION("pythia interface") { - using namespace corsika; - - const std::vector<corsika::Code> particleList = { - corsika::Code::PiPlus, corsika::Code::PiMinus, corsika::Code::KPlus, - corsika::Code::KMinus, corsika::Code::K0Long, corsika::Code::K0Short}; - - corsika::RNGManager::getInstance().registerRandomStream("pythia"); + std::set<Code> const particleList = {Code::PiPlus, Code::PiMinus, Code::KPlus, + Code::KMinus, Code::K0Long, Code::K0Short}; + RNGManager::getInstance().registerRandomStream("pythia"); corsika::pythia8::Decay model(particleList); - - model.Init(); } } @@ -84,89 +83,86 @@ TEST_CASE("Pythia", "[processes]") { #include <corsika/media/NuclearComposition.hpp> using namespace corsika; -using namespace corsika::units::si; template <typename TStackView> -auto sumMomentum(TStackView const& view, geometry::CoordinateSystem const& vCS) { - geometry::Vector<hepenergy_d> sum{vCS, 0_eV, 0_eV, 0_eV}; - - for (auto const& p : view) { sum += p.GetMomentum(); } - +auto sumMomentum(TStackView const& view, CoordinateSystemPtr const& vCS) { + MomentumVector sum{vCS, 0_eV, 0_eV, 0_eV}; + for (auto const& p : view) { sum += p.getMomentum(); } return sum; } TEST_CASE("pythia process") { - auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Proton); + auto [env, csPtr, nodePtr] = setup::testing::setup_environment(Code::Proton); auto const& cs = *csPtr; [[maybe_unused]] auto const& env_dummy = env; [[maybe_unused]] auto const& node_dummy = nodePtr; SECTION("pythia decay") { - feenableexcept(FE_INVALID); - auto [stackPtr, secViewPtr] = - setup::testing::setupStack(particles::Code::PiPlus, 0, 0, P0, nodePtr, *csPtr); - const HEPEnergyType E0 = 10_GeV; - HEPMomentumType P0 = sqrt(E0 * E0 - corsika::PiPlus::mass * corsika::PiPlus::mass); - auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0}); - corsika::Point pos(cs, 0_m, 0_m, 0_m); - auto particle = stack.AddParticle( - std::tuple<corsika::Code, units::si::HEPEnergyType, corsika::MomentumVector, - corsika::Point, units::si::TimeType>{corsika::Code::PiPlus, E0, plab, - pos, 0_ns}); + HEPMomentumType P0 = sqrt(E0 * E0 - PiPlus::mass * PiPlus::mass); + + // feenableexcept(FE_INVALID); \todo how does this work nowadays...??? + auto [stackPtr, secViewPtr] = setup::testing::setup_stack( + Code::PiPlus, 0, 0, P0, (setup::Environment::BaseNodeType* const)nodePtr, *csPtr); + auto& stack = *stackPtr; + auto& view = *secViewPtr; + + auto plab = MomentumVector(cs, {0_GeV, 0_GeV, -P0}); + Point pos(cs, 0_m, 0_m, 0_m); + auto particle = + stackPtr->addParticle(std::make_tuple(Code::PiPlus, E0, plab, pos, 0_ns)); - const std::vector<corsika::Code> particleList = { - corsika::Code::PiPlus, corsika::Code::PiMinus, corsika::Code::KPlus, - corsika::Code::KMinus, corsika::Code::K0Long, corsika::Code::K0Short}; + std::set<Code> const particleList = {Code::PiPlus, Code::PiMinus, Code::KPlus, + Code::KMinus, Code::K0Long, Code::K0Short}; - corsika::RNGManager::getInstance().registerRandomStream("pythia"); + RNGManager::getInstance().registerRandomStream("pythia"); corsika::pythia8::Decay model(particleList); - [[maybe_unused]] const TimeType time = model.GetLifetime(particle); - model.DoDecay(view); + [[maybe_unused]] const TimeType time = model.getLifetime(particle); + model.doDecay(*secViewPtr); CHECK(stack.getEntries() == 3); auto const pSum = sumMomentum(view, cs); - CHECK((pSum - plab).norm() / 1_GeV == Approx(0).margin(1e-4)); - CHECK((pSum.norm() - plab.norm()) / 1_GeV == Approx(0).margin(1e-4)); + CHECK((pSum - plab).getNorm() / 1_GeV == Approx(0).margin(1e-4)); + CHECK((pSum.getNorm() - plab.getNorm()) / 1_GeV == Approx(0).margin(1e-4)); } SECTION("pythia decay config") { - process::pythia::Decay model({particles::Code::PiPlus, particles::Code::PiMinus}); - REQUIRE(model.IsDecayHandled(particles::Code::PiPlus)); - REQUIRE(model.IsDecayHandled(particles::Code::PiMinus)); - REQUIRE_FALSE(model.IsDecayHandled(particles::Code::KPlus)); + corsika::pythia8::Decay model({Code::PiPlus, Code::PiMinus}); + CHECK(model.isDecayHandled(Code::PiPlus)); + CHECK(model.isDecayHandled(Code::PiMinus)); + CHECK_FALSE(model.isDecayHandled(Code::KPlus)); - const std::vector<particles::Code> particleTestList = { - particles::Code::PiPlus, particles::Code::PiMinus, particles::Code::KPlus, - particles::Code::Lambda0Bar, particles::Code::D0Bar}; + const std::vector<Code> particleTestList = {Code::PiPlus, Code::PiMinus, Code::KPlus, + Code::Lambda0Bar, Code::D0Bar}; // setup decays - model.SetHandleDecay(particleTestList); - for (auto& pCode : particleTestList) REQUIRE(model.IsDecayHandled(pCode)); + model.setHandleDecay(particleTestList); + for (auto& pCode : particleTestList) CHECK(model.isDecayHandled(pCode)); // individually - model.SetHandleDecay(particles::Code::KMinus); + model.setHandleDecay(Code::KMinus); // possible decays - REQUIRE_FALSE(model.CanHandleDecay(particles::Code::Proton)); - REQUIRE_FALSE(model.CanHandleDecay(particles::Code::Electron)); - REQUIRE(model.CanHandleDecay(particles::Code::PiPlus)); - REQUIRE(model.CanHandleDecay(particles::Code::MuPlus)); + CHECK_FALSE(model.canHandleDecay(Code::Proton)); + CHECK_FALSE(model.canHandleDecay(Code::Electron)); + CHECK(model.canHandleDecay(Code::PiPlus)); + CHECK(model.canHandleDecay(Code::MuPlus)); } SECTION("pythia interaction") { - feenableexcept(FE_INVALID); - auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::PiPlus, 0, - 0, 100_GeV, nodePtr, *csPtr); + // feenableexcept(FE_INVALID); \todo how does this work nowadays + auto [stackPtr, secViewPtr] = setup::testing::setup_stack( + Code::PiPlus, 0, 0, 100_GeV, (setup::Environment::BaseNodeType* const)nodePtr, + *csPtr); auto& view = *secViewPtr; auto particle = stackPtr->first(); - process::pythia::Interaction model; - - [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(view); - [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle); + corsika::pythia8::Interaction model; + model.doInteraction(view); + [[maybe_unused]] const GrammageType length = model.getInteractionLength(particle); + CHECK(length == 50_g / square(1_cm)); } } diff --git a/tests/modules/testUrQMD.cpp b/tests/modules/testUrQMD.cpp index a51081fe4..13a3a572e 100644 --- a/tests/modules/testUrQMD.cpp +++ b/tests/modules/testUrQMD.cpp @@ -17,8 +17,8 @@ #include <corsika/framework/random/RNGManager.hpp> #include <corsika/framework/utility/CorsikaFenv.hpp> -#include <corsika/setup/SetupStack.hpp> -#include <corsika/setup/SetupTrajectory.hpp> +#include <SetupTestStack.hpp> +#include <SetupTestEnvironment.hpp> #include <corsika/media/Environment.hpp> #include <corsika/media/HomogeneousMedium.hpp> @@ -35,136 +35,126 @@ using namespace corsika::urqmd; template <typename TStackView> auto sumCharge(TStackView const& view) { int totalCharge = 0; - - for (auto const& p : view) { totalCharge += corsika::charge_number(p.GetPID()); } - + for (auto const& p : view) { totalCharge += get_charge_number(p.getPID()); } return totalCharge; } template <typename TStackView> -auto sumMomentum(TStackView const& view, corsika::CoordinateSystem const& vCS) { - corsika::Vector<hepenergy_d> sum{vCS, 0_eV, 0_eV, 0_eV}; - - for (auto const& p : view) { sum += p.GetMomentum(); } - +auto sumMomentum(TStackView const& view, CoordinateSystemPtr const& vCS) { + MomentumVector sum{vCS, 0_eV, 0_eV, 0_eV}; + for (auto const& p : view) { sum += p.getMomentum(); } return sum; } TEST_CASE("UrQMD") { SECTION("conversion") { - REQUIRE_THROWS(corsika::urqmd::ConvertFromUrQMD(106, 0)); - REQUIRE(corsika::urqmd::ConvertFromUrQMD(101, 0) == corsika::Code::Pi0); - REQUIRE(corsika::urqmd::ConvertToUrQMD(corsika::Code::PiPlus) == - std::make_pair<int, int>(101, 2)); + CHECK_THROWS(corsika::urqmd::convertFromUrQMD(106, 0)); + CHECK(corsika::urqmd::convertFromUrQMD(101, 0) == Code::Pi0); + CHECK(corsika::urqmd::convertToUrQMD(Code::PiPlus) == + std::make_pair<int, int>(101, 2)); } feenableexcept(FE_INVALID); - corsika::RNGManager::getInstance().registerRandomStream("urqmd"); + RNGManager::getInstance().registerRandomStream("urqmd"); UrQMD urqmd; SECTION("interaction length") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Nitrogen); + auto [env, csPtr, nodePtr] = setup::testing::setup_environment(Code::Nitrogen); auto const& cs = *csPtr; { [[maybe_unused]] auto const& env_dummy = env; } - corsika::Code validProjectileCodes[] = { - corsika::Code::PiPlus, corsika::Code::PiMinus, corsika::Code::Proton, - corsika::Code::Neutron, corsika::Code::KPlus, corsika::Code::KMinus, - corsika::Code::K0, corsika::Code::K0Bar, corsika::Code::K0Long}; + Code validProjectileCodes[] = {Code::PiPlus, Code::PiMinus, Code::Proton, + Code::Neutron, Code::KPlus, Code::KMinus, + Code::K0, Code::K0Bar, Code::K0Long}; for (auto code : validProjectileCodes) { - auto [stack, view] = setup::testing::setupStack(code, 0, 0, 100_GeV, nodePtr, cs); - REQUIRE(stack->getEntries() == 1); - REQUIRE(view->getEntries() == 0); + auto [stack, view] = setup::testing::setup_stack( + code, 0, 0, 100_GeV, (setup::Environment::BaseNodeType* const)nodePtr, cs); + CHECK(stack->getEntries() == 1); + CHECK(view->getEntries() == 0); // simple check whether the cross-section is non-vanishing - REQUIRE(urqmd.GetCrossSection(view->GetProjectile(), corsika::Code::Proton) / 1_mb > - 0); - REQUIRE(urqmd.GetCrossSection(view->GetProjectile(), corsika::Code::Nitrogen) / - 1_mb > - 0); - REQUIRE(urqmd.GetCrossSection(view->GetProjectile(), corsika::Code::Oxygen) / 1_mb > - 0); - REQUIRE(urqmd.GetCrossSection(view->GetProjectile(), corsika::Code::Argon) / 1_mb > - 0); + CHECK(urqmd.getCrossSection(view->getProjectile(), Code::Proton) / 1_mb > 0); + CHECK(urqmd.getCrossSection(view->getProjectile(), Code::Nitrogen) / 1_mb > 0); + CHECK(urqmd.getCrossSection(view->getProjectile(), Code::Oxygen) / 1_mb > 0); + CHECK(urqmd.getCrossSection(view->getProjectile(), Code::Argon) / 1_mb > 0); } } SECTION("nucleus projectile") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Oxygen); + auto [env, csPtr, nodePtr] = setup::testing::setup_environment(Code::Oxygen); [[maybe_unused]] auto const& env_dummy = env; // against warnings [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings unsigned short constexpr A = 14, Z = 7; - auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::Nucleus, A, - Z, 400_GeV, nodePtr, *csPtr); - REQUIRE(stackPtr->getEntries() == 1); - REQUIRE(secViewPtr->getEntries() == 0); + auto [stackPtr, secViewPtr] = setup::testing::setup_stack( + Code::Nucleus, A, Z, 400_GeV, (setup::Environment::BaseNodeType* const)nodePtr, + *csPtr); + CHECK(stackPtr->getEntries() == 1); + CHECK(secViewPtr->getEntries() == 0); // must be assigned to variable, cannot be used as rvalue?! - auto projectile = secViewPtr->GetProjectile(); - auto const projectileMomentum = projectile.GetMomentum(); - [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr); + auto projectile = secViewPtr->getProjectile(); + auto const projectileMomentum = projectile.getMomentum(); + urqmd.doInteraction(*secViewPtr); - REQUIRE(sumCharge(*secViewPtr) == Z + corsika::charge_number(corsika::Code::Oxygen)); + CHECK(sumCharge(*secViewPtr) == Z + get_charge_number(Code::Oxygen)); auto const secMomSum = - sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem()); - REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() == - Approx(0).margin(1e-2)); + sumMomentum(*secViewPtr, projectileMomentum.getCoordinateSystem()); + CHECK((secMomSum - projectileMomentum).getNorm() / projectileMomentum.getNorm() == + Approx(0).margin(1e-2)); } SECTION("\"special\" projectile") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Oxygen); + auto [env, csPtr, nodePtr] = setup::testing::setup_environment(Code::Oxygen); [[maybe_unused]] auto const& env_dummy = env; // against warnings [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings - auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::PiPlus, 0, - 0, 400_GeV, nodePtr, *csPtr); - REQUIRE(stackPtr->getEntries() == 1); - REQUIRE(secViewPtr->getEntries() == 0); + auto [stackPtr, secViewPtr] = setup::testing::setup_stack( + Code::PiPlus, 0, 0, 400_GeV, (setup::Environment::BaseNodeType* const)nodePtr, + *csPtr); + CHECK(stackPtr->getEntries() == 1); + CHECK(secViewPtr->getEntries() == 0); // must be assigned to variable, cannot be used as rvalue?! - auto projectile = secViewPtr->GetProjectile(); - auto const projectileMomentum = projectile.GetMomentum(); + auto projectile = secViewPtr->getProjectile(); + auto const projectileMomentum = projectile.getMomentum(); - [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr); + urqmd.doInteraction(*secViewPtr); - REQUIRE(sumCharge(*secViewPtr) == corsika::charge_number(corsika::Code::PiPlus) + - corsika::charge_number(corsika::Code::Oxygen)); + CHECK(sumCharge(*secViewPtr) == + get_charge_number(Code::PiPlus) + get_charge_number(Code::Oxygen)); auto const secMomSum = - sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem()); - REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() == - Approx(0).margin(1e-2)); + sumMomentum(*secViewPtr, projectileMomentum.getCoordinateSystem()); + CHECK((secMomSum - projectileMomentum).getNorm() / projectileMomentum.getNorm() == + Approx(0).margin(1e-2)); } SECTION("K0Long projectile") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Oxygen); + auto [env, csPtr, nodePtr] = setup::testing::setup_environment(Code::Oxygen); [[maybe_unused]] auto const& env_dummy = env; // against warnings [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings - auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::K0Long, 0, - 0, 400_GeV, nodePtr, *csPtr); - REQUIRE(stackPtr->getEntries() == 1); - REQUIRE(secViewPtr->getEntries() == 0); + auto [stackPtr, secViewPtr] = setup::testing::setup_stack( + Code::K0Long, 0, 0, 400_GeV, (setup::Environment::BaseNodeType* const)nodePtr, + *csPtr); + CHECK(stackPtr->getEntries() == 1); + CHECK(secViewPtr->getEntries() == 0); // must be assigned to variable, cannot be used as rvalue?! - auto projectile = secViewPtr->GetProjectile(); - auto const projectileMomentum = projectile.GetMomentum(); + auto projectile = secViewPtr->getProjectile(); + auto const projectileMomentum = projectile.getMomentum(); - [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr); + urqmd.doInteraction(*secViewPtr); - REQUIRE(sumCharge(*secViewPtr) == corsika::charge_number(corsika::Code::K0Long) + - corsika::charge_number(corsika::Code::Oxygen)); + CHECK(sumCharge(*secViewPtr) == + get_charge_number(Code::K0Long) + get_charge_number(Code::Oxygen)); auto const secMomSum = - sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem()); - REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() == - Approx(0).margin(1e-2)); + sumMomentum(*secViewPtr, projectileMomentum.getCoordinateSystem()); + CHECK((secMomSum - projectileMomentum).getNorm() / projectileMomentum.getNorm() == + Approx(0).margin(1e-2)); } } -- GitLab