From 8051172de392723296032997779efcfd83f73b3b Mon Sep 17 00:00:00 2001 From: ralfulrich <ralf.ulrich@kit.edu> Date: Thu, 28 Oct 2021 06:33:00 +0200 Subject: [PATCH] fixed P8 test --- corsika/detail/framework/core/Cascade.inl | 6 +- .../framework/process/ProcessSequence.inl | 1 + .../process/SwitchProcessSequence.inl | 228 +++++++++------ corsika/detail/media/NuclearComposition.inl | 8 +- .../detail/modules/pythia8/Interaction.inl | 275 ++++++++---------- corsika/framework/process/ProcessSequence.hpp | 52 ++-- corsika/media/IMediumPropertyModel.hpp | 3 +- corsika/media/MediumPropertyModel.hpp | 1 - corsika/modules/pythia8/Interaction.hpp | 14 +- .../sibyll/NuclearInteractionModel.hpp | 1 - corsika/stack/VectorStack.hpp | 8 +- tests/modules/testPythia8.cpp | 14 +- 12 files changed, 314 insertions(+), 297 deletions(-) diff --git a/corsika/detail/framework/core/Cascade.inl b/corsika/detail/framework/core/Cascade.inl index b003e83d4..f3e5938fe 100644 --- a/corsika/detail/framework/core/Cascade.inl +++ b/corsika/detail/framework/core/Cascade.inl @@ -78,9 +78,10 @@ namespace corsika { NuclearComposition const& composition = currentLogicalNode->getModelProperties().getNuclearComposition(); - // determine sqrtS per nucleon pair, sqrtS_NN + // determine projectile HEPEnergyType const Elab = particle.getEnergy(); FourMomentum const projectileP4{Elab, particle.getMomentum()}; + // determine cross section in material CrossSectionType const sigma = composition.getWeightedSum([=](Code const targetId) -> CrossSectionType { FourMomentum const targetP4( @@ -110,7 +111,7 @@ namespace corsika { NuclearComposition const& composition = currentLogicalNode->getModelProperties().getNuclearComposition(); - // determine sqrtS per nucleon pair, sqrtS_NN + // determine projectile HEPEnergyType const Elab = particle.getEnergy(); FourMomentum const projectileP4{Elab, particle.getMomentum()}; @@ -291,7 +292,6 @@ namespace corsika { and Decay! */ if (distance_interact < distance_decay) { - // define boost of NUCLEON-NUCLEON frame interaction(secondaries, projectileP4, composition, total_cx); } else { [[maybe_unused]] auto projectile = secondaries.getProjectile(); diff --git a/corsika/detail/framework/process/ProcessSequence.inl b/corsika/detail/framework/process/ProcessSequence.inl index e27dbc9fd..25a592d52 100644 --- a/corsika/detail/framework/process/ProcessSequence.inl +++ b/corsika/detail/framework/process/ProcessSequence.inl @@ -482,6 +482,7 @@ namespace corsika { decltype(projectile) const&, // template argument decltype(projectile) const&, // parameters Code, FourMomentum const&>; + static_assert((has_signature_cx1 || has_signature_cx2), "TProcess1 has no method with correct signature \"CrossSectionType " "getCrossSection(Code, Code, FourMomentum const&, FourMomentum " diff --git a/corsika/detail/framework/process/SwitchProcessSequence.inl b/corsika/detail/framework/process/SwitchProcessSequence.inl index fdf1e685e..0d26014fd 100644 --- a/corsika/detail/framework/process/SwitchProcessSequence.inl +++ b/corsika/detail/framework/process/SwitchProcessSequence.inl @@ -217,18 +217,39 @@ namespace corsika { if (select_(projectile)) { if constexpr (is_interaction_process_v<process1_type>) { - return A_.getCrossSection(projectile.getPID(), targetId, - {projectile.getEnergy(), projectile.getMomentum()}, - targetP4); + bool constexpr has_signature_cx1 = + has_method_getCrossSection_v<TSequence, // process object + CrossSectionType, // return type + Code, Code, // parameters + FourMomentum const&, FourMomentum const&>; + if constexpr (has_signature_cx1) { + + return A_.getCrossSection(projectile.getPID(), targetId, + {projectile.getEnergy(), projectile.getMomentum()}, + targetP4); + } else { + return A_.getCrossSection(projectile, projectile.getPID(), + {projectile.getEnergy(), projectile.getMomentum()}); + } } else if (process1_type::is_process_sequence) { return A_.getCrossSection(projectile, targetId, targetP4); } } else { if constexpr (is_interaction_process_v<process2_type>) { - return B_.getCrossSection(projectile.getPID(), targetId, - {projectile.getEnergy(), projectile.getMomentum()}, - targetP4); + bool constexpr has_signature_cx1 = + has_method_getCrossSection_v<USequence, // process object + CrossSectionType, // return type + Code, Code, // parameters + FourMomentum const&, FourMomentum const&>; + if constexpr (has_signature_cx1) { + + return B_.getCrossSection(projectile.getPID(), targetId, + {projectile.getEnergy(), projectile.getMomentum()}, + targetP4); + } else { + return B_.getCrossSection(projectile, targetId, targetP4); + } } else if (process2_type::is_process_sequence) { return B_.getCrossSection(projectile, targetId, targetP4); } @@ -259,50 +280,72 @@ namespace corsika { // get cross section vector for all material components // for selected process A - static_assert( + bool constexpr has_signature_cx1 = has_method_getCrossSection_v<TSequence, // process object CrossSectionType, // return type Code, Code, // parameters - FourMomentum const&, FourMomentum const&>, - "TSequence has no method with correct signature \"CrossSectionType " - "getCrossSection(Code, Code, FourMomentum const&, FourMomentum " - "const&)\" required by " - "InteractionProcess<TSequence>. "); - - std::vector<CrossSectionType> const weightedCrossSections = - composition.getWeighted([=](Code const targetId) -> CrossSectionType { - FourMomentum const targetP4( - get_mass(targetId), - MomentumVector(projectile.getMomentum().getCoordinateSystem(), - {0_GeV, 0_GeV, 0_GeV})); - return A_.getCrossSection(projectileId, targetId, projectileP4, targetP4); - }); - - cx_sum += std::accumulate(weightedCrossSections.cbegin(), - weightedCrossSections.cend(), CrossSectionType::zero()); - if (cx_select < cx_sum) { + FourMomentum const&, FourMomentum const&>; + bool constexpr has_signature_cx2 = // needed for PROPOSAL interface + has_method_getCrossSectionTemplate_v< + TSequence, // process object + CrossSectionType, // return type + decltype(projectile) const&, // template argument + decltype(projectile) const&, // parameters + Code, FourMomentum const&>; + + static_assert((has_signature_cx1 || has_signature_cx2), + "TSequence has no method with correct signature \"CrossSectionType " + "getCrossSection(Code, Code, FourMomentum const&, FourMomentum " + "const&)\" required by " + "InteractionProcess<TSequence>. "); + + std::vector<CrossSectionType> weightedCrossSections; + if constexpr (has_signature_cx1) { + /*std::vector<CrossSectionType> const*/ weightedCrossSections = + composition.getWeighted([=](Code const targetId) -> CrossSectionType { + FourMomentum const targetP4( + get_mass(targetId), + MomentumVector(projectile.getMomentum().getCoordinateSystem(), + {0_GeV, 0_GeV, 0_GeV})); + return A_.getCrossSection(projectileId, targetId, projectileP4, targetP4); + }); + + cx_sum += + std::accumulate(weightedCrossSections.cbegin(), + weightedCrossSections.cend(), CrossSectionType::zero()); + } else { // this is for PROPOSAL + cx_sum += A_.template getCrossSection(projectile, projectileId, projectileP4); + } - // now also sample targetId from weighted cross sections - Code const targetId = composition.sampleTarget(weightedCrossSections, rng); - FourMomentum const targetP4( - get_mass(targetId), - MomentumVector(projectile.getMomentum().getCoordinateSystem(), - {0_GeV, 0_GeV, 0_GeV})); + if (cx_select < cx_sum) { - // interface checking on TProcess1 - static_assert( - has_method_doInteract_v<TSequence, // process object - void, // return type - TSecondaryView, // template argument - TSecondaryView&, // method parameters - Code, Code, FourMomentum const&, - FourMomentum const&>, - "TSequence has no method with correct signature \"void " - "doInteraction<TSecondaryView>(TSecondaryView&, " - "Code, Code, FourMomentum const&, FourMomentum const&)\" required for " - "InteractionProcess<TSequence>. "); - - A_.template doInteraction(view, projectileId, targetId, projectileP4, targetP4); + if constexpr (has_signature_cx1) { + + // now also sample targetId from weighted cross sections + Code const targetId = composition.sampleTarget(weightedCrossSections, rng); + FourMomentum const targetP4( + get_mass(targetId), + MomentumVector(projectile.getMomentum().getCoordinateSystem(), + {0_GeV, 0_GeV, 0_GeV})); + + // interface checking on TProcess1 + static_assert( + has_method_doInteract_v<TSequence, // process object + void, // return type + TSecondaryView, // template argument + TSecondaryView&, // method parameters + Code, Code, FourMomentum const&, + FourMomentum const&>, + "TSequence has no method with correct signature \"void " + "doInteraction<TSecondaryView>(TSecondaryView&, " + "Code, Code, FourMomentum const&, FourMomentum const&)\" required for " + "InteractionProcess<TSequence>. "); + + A_.template doInteraction(view, projectileId, targetId, projectileP4, + targetP4); + } else { // this is for PROPOSAL + A_.template doInteraction(view, projectileId, projectileP4); + } return ProcessReturn::Interacted; } // end collision branch A @@ -320,51 +363,72 @@ namespace corsika { Code const projectileId = projectile.getPID(); // get cross section vector for all material components, for selected process B - static_assert(has_method_getCrossSection_v<USequence, // process object - CrossSectionType, // return type - Code, Code, FourMomentum const&, - FourMomentum const&>, // parameters + bool constexpr has_signature_cx1 = + has_method_getCrossSection_v<USequence, // process object + CrossSectionType, // return type + Code, Code, // parameters + FourMomentum const&, FourMomentum const&>; + bool constexpr has_signature_cx2 = // needed for PROPOSAL interface + has_method_getCrossSectionTemplate_v< + USequence, // process object + CrossSectionType, // return type + decltype(projectile) const&, // template argument + decltype(projectile) const&, // parameters + Code, FourMomentum const&>; + + static_assert((has_signature_cx1 || has_signature_cx2), "USequence has no method with correct signature \"CrossSectionType " "getCrossSection(Code, Code, FourMomentum const&, FourMomentum " "const&)\" required by " "InteractionProcess<USequence>. "); - std::vector<CrossSectionType> const weightedCrossSections = - composition.getWeighted([=](Code const targetId) -> CrossSectionType { - FourMomentum const targetP4( - get_mass(targetId), - MomentumVector(projectile.getMomentum().getCoordinateSystem(), - {0_GeV, 0_GeV, 0_GeV})); - return B_.getCrossSection(projectileId, targetId, projectileP4, targetP4); - }); - - cx_sum += std::accumulate(weightedCrossSections.begin(), - weightedCrossSections.end(), CrossSectionType::zero()); + std::vector<CrossSectionType> weightedCrossSections; + if constexpr (has_signature_cx1) { + /* std::vector<CrossSectionType> const*/ weightedCrossSections = + composition.getWeighted([=](Code const targetId) -> CrossSectionType { + FourMomentum const targetP4( + get_mass(targetId), + MomentumVector(projectile.getMomentum().getCoordinateSystem(), + {0_GeV, 0_GeV, 0_GeV})); + return B_.getCrossSection(projectileId, targetId, projectileP4, targetP4); + }); + + cx_sum += + std::accumulate(weightedCrossSections.begin(), weightedCrossSections.end(), + CrossSectionType::zero()); + } else { // this is for PROPOSAL + cx_sum += B_.template getCrossSection(projectile, projectileId, projectileP4); + } // check if we should execute THIS process and then EXIT if (cx_select <= cx_sum) { - // now also sample targetId from weighted cross sections - Code const targetId = composition.sampleTarget(weightedCrossSections, rng); - FourMomentum const targetP4( - get_mass(targetId), - MomentumVector(projectile.getMomentum().getCoordinateSystem(), - {0_GeV, 0_GeV, 0_GeV})); - - // interface checking on TProcess2 - static_assert( - has_method_doInteract_v<USequence, // process object - void, // return type - TSecondaryView, // template argument - TSecondaryView&, // method parameters - Code, Code, FourMomentum const&, - FourMomentum const&>, - "USequence has no method with correct signature \"void " - "doInteraction<TSecondaryView>(TSecondaryView&, " - "Code, Code, FourMomentum const&, FourMomentum const&)\" required for " - "InteractionProcess<USequence>. "); - - B_.doInteraction(view, projectileId, targetId, projectileP4, targetP4); + if constexpr (has_signature_cx1) { + + // now also sample targetId from weighted cross sections + Code const targetId = composition.sampleTarget(weightedCrossSections, rng); + FourMomentum const targetP4( + get_mass(targetId), + MomentumVector(projectile.getMomentum().getCoordinateSystem(), + {0_GeV, 0_GeV, 0_GeV})); + + // interface checking on TProcess2 + static_assert( + has_method_doInteract_v<USequence, // process object + void, // return type + TSecondaryView, // template argument + TSecondaryView&, // method parameters + Code, Code, FourMomentum const&, + FourMomentum const&>, + "USequence has no method with correct signature \"void " + "doInteraction<TSecondaryView>(TSecondaryView&, " + "Code, Code, FourMomentum const&, FourMomentum const&)\" required for " + "InteractionProcess<USequence>. "); + + B_.doInteraction(view, projectileId, targetId, projectileP4, targetP4); + } else { // this is for PROPOSAL + B_.doInteraction(view, projectileId, projectileP4); + } return ProcessReturn::Interacted; } // end collision in branch B @@ -372,7 +436,7 @@ namespace corsika { } // end branch B_ return ProcessReturn::Ok; - } + } // namespace corsika template <typename TCondition, typename TSequence, typename USequence, int IndexStart, int IndexProcess1, int IndexProcess2> diff --git a/corsika/detail/media/NuclearComposition.inl b/corsika/detail/media/NuclearComposition.inl index 0237d73e9..c499a593d 100644 --- a/corsika/detail/media/NuclearComposition.inl +++ b/corsika/detail/media/NuclearComposition.inl @@ -109,12 +109,8 @@ namespace corsika { } std::discrete_distribution channelDist( - WeightProviderIterator //<decltype(numberFractions_.begin()), - // decltype(sigma.begin())> - (numberFractions_.begin(), sigma.begin()), - WeightProviderIterator //<decltype(numberFractions_.begin()), - // decltype(sigma.end())> - (numberFractions_.end(), sigma.end())); + WeightProviderIterator(numberFractions_.begin(), sigma.begin()), + WeightProviderIterator(numberFractions_.end(), sigma.end())); auto const iChannel = channelDist(randomStream); return components_[iChannel]; diff --git a/corsika/detail/modules/pythia8/Interaction.inl b/corsika/detail/modules/pythia8/Interaction.inl index 5c495e693..a716b156d 100644 --- a/corsika/detail/modules/pythia8/Interaction.inl +++ b/corsika/detail/modules/pythia8/Interaction.inl @@ -80,6 +80,28 @@ namespace corsika::pythia8 { Pythia8::Pythia::particleData.mayDecay(static_cast<int>(get_PDG(pCode)), false); } + inline void Interaction::isValid(Code const projectileId, Code const targetId, + HEPEnergyType const sqrtS) const { + + if ((10_GeV > sqrtS) || (sqrtS > 1_PeV)) { + throw std::runtime_error("energy out of bounds for PYTHIA"); + } + + if (targetId != Code::Hydrogen && targetId != Code::Neutron && + targetId != Code::Proton) { + throw std::runtime_error("wrong target for PYTHIA"); + } + + if (is_nucleus(projectileId)) { + // nuclei handled by different process, this should not happen + throw std::runtime_error("Nuclear projectile are not handled by PYTHIA!"); + } + + if (!canInteract(projectileId)) { + throw std::runtime_error("Projectile not supported by PYTHIA!"); + } + } + inline void Interaction::configureLabFrameCollision(Code const projectileId, Code const targetId, HEPEnergyType const BeamEnergy) { @@ -128,180 +150,117 @@ namespace corsika::pythia8 { HEPEnergyType const CoMenergy = (projectileP4 + targetP4).getNorm(); - // interaction possible in pythia? - if (targetId == Code::Proton || targetId == Code::Hydrogen) { - if (canInteract(projectileId) && isValidCoMEnergy(CoMenergy)) { - // input particle PDG - auto const pdgCodeBeam = static_cast<int>(get_PDG(projectileId)); - auto const pdgCodeTarget = static_cast<int>(get_PDG(targetId)); - double const ecm = CoMenergy / 1_GeV; - - //! @todo: remove this const_cast, when Pythia8 becomes const-correct! CHECK! - Pythia8::SigmaTotal& sigma = *const_cast<Pythia8::SigmaTotal*>(&sigma_); - - // calculate cross section - sigma.calc(pdgCodeBeam, pdgCodeTarget, ecm); - if (sigma.hasSigmaTot()) { - double const sigEla = sigma.sigmaEl(); - double const sigProd = sigma.sigmaTot() - sigEla; - - return std::make_tuple(sigProd * (1_fm * 1_fm), sigEla * (1_fm * 1_fm)); - - } else { - // we can't test pythia8 internals, LCOV_EXCL_START - throw std::runtime_error("pythia cross section init failed"); - // we can't test pythia8 internals, LCOV_EXCL_STOP - } - } else { - return std::make_tuple(std::numeric_limits<double>::infinity() * 1_mb, - std::numeric_limits<double>::infinity() * 1_mb); - } + isValid(projectileId, targetId, CoMenergy); // throws + + // input particle PDG + auto const pdgCodeBeam = static_cast<int>(get_PDG(projectileId)); + auto const pdgCodeTarget = static_cast<int>(get_PDG(targetId)); + double const ecm = CoMenergy / 1_GeV; + + //! @todo: remove this const_cast, when Pythia8 becomes const-correct! CHECK! + Pythia8::SigmaTotal& sigma = *const_cast<Pythia8::SigmaTotal*>(&sigma_); + + // calculate cross section + sigma.calc(pdgCodeBeam, pdgCodeTarget, ecm); + if (sigma.hasSigmaTot()) { + double const sigEla = sigma.sigmaEl(); + double const sigProd = sigma.sigmaTot() - sigEla; + + return std::make_tuple(sigProd * (1_fm * 1_fm), sigEla * (1_fm * 1_fm)); + } else { - throw std::runtime_error("invalid target for pythia"); + // we can't test pythia8 internals, LCOV_EXCL_START + throw std::runtime_error("pythia cross section init failed"); + // we can't test pythia8 internals, LCOV_EXCL_STOP } } template <class TView> inline void Interaction::doInteraction(TView& view, Code const projectileId, - Code const targetId, FourMomentum const&, - FourMomentum const&) { + Code const targetId, + FourMomentum const& projectileP4, + FourMomentum const& targetP4) { auto projectile = view.getProjectile(); CORSIKA_LOG_DEBUG( "Pythia::Interaction: " - "DoInteraction: {} interaction? ", + "doInteraction: {} interaction? ", projectileId, corsika::pythia8::Interaction::canInteract(projectileId)); - if (is_nucleus(projectileId)) { - // nuclei handled by different process, this should not happen - throw std::runtime_error("Nuclear projectile are not handled by PYTHIA!"); + // define system + auto const sqrtS2 = (projectileP4 + targetP4).getNormSqr(); + HEPEnergyType const sqrtS = sqrt(sqrtS2); + HEPEnergyType const eProjectileLab = (sqrtS2 - static_pow<2>(get_mass(projectileId)) - + static_pow<2>(get_mass(targetId))) / + (2 * get_mass(targetId)); + + isValid(projectileId, targetId, sqrtS); // throws + + // position and time of interaction + Point pOrig = projectile.getPosition(); + TimeType tOrig = projectile.getTime(); + + CORSIKA_LOG_DEBUG("Interaction: ebeam lab: {} GeV", eProjectileLab / 1_GeV); + + // define target kinematics in lab frame + // define boost to and from CoM frame + // CoM frame definition in Pythia projectile: +z + COMBoost const boost(projectileP4, constants::nucleonMass); + auto const& labCS = boost.getOriginalCS(); + + CORSIKA_LOG_DEBUG("Interaction: position of interaction: ", pOrig.getCoordinates()); + CORSIKA_LOG_DEBUG("Interaction: time: {}", tOrig); + + CORSIKA_LOG_DEBUG( + "Interaction: " + " doInteraction: E(GeV): {}" + " Ecm(GeV): {}", + eProjectileLab / 1_GeV, sqrtS / 1_GeV); + + count_++; + + configureLabFrameCollision(projectileId, targetId, eProjectileLab); + + // create event in pytia. LCOV_EXCL_START: we don't validate pythia8 internals + if (!Pythia8::Pythia::next()) + throw std::runtime_error("Pythia::DoInteraction: failed!"); + // LCOV_EXCL_STOP + + // link to pythia stack + Pythia8::Event& event = Pythia8::Pythia::event; + + // LCOV_EXCL_START, we don't validate pythia8 internals + if (print_listing_) { + // print final state + event.list(); } + // LCOV_EXCL_STOP + + 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 const& p8p = event[i]; + // skip particles that have decayed in pythia + if (!p8p.isFinal()) continue; - if (corsika::pythia8::Interaction::canInteract(projectileId)) { - - // 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 = projectile.getPosition(); - TimeType tOrig = projectile.getTime(); - - // define target - // FOR NOW: target is always at rest - auto const eTargetLab = 0_GeV + constants::nucleonMass; - auto const pTargetLab = MomentumVector(labCS, 0_GeV, 0_GeV, 0_GeV); - FourVector const PtargLab(eTargetLab, pTargetLab); - - CORSIKA_LOG_DEBUG( - "Interaction: ebeam lab: {} GeV" - "Interaction: pbeam lab: {} GeV", - eProjectileLab / 1_GeV, pProjectileLab.getComponents() / 1_GeV); - - CORSIKA_LOG_DEBUG( - "Interaction: etarget lab: {} GeV" - "Interaction: ptarget lab: {} GeV ", - eTargetLab / 1_GeV, pTargetLab.getComponents() / 1_GeV); - - FourVector const PprojLab(eProjectileLab, pProjectileLab); - - // define target kinematics in lab frame - // define boost to and from CoM frame - // CoM frame definition in Pythia projectile: +z - COMBoost const boost(PprojLab, constants::nucleonMass); - - // just for show: - // boost projecticle - auto const PprojCoM = boost.toCoM(PprojLab); - - // boost target - auto const PtargCoM = boost.toCoM(PtargLab); - - CORSIKA_LOG_DEBUG( - "Interaction: ebeam CoM: {} GeV" - "Interaction: pbeam CoM: {} GeV", - PprojCoM.getTimeLikeComponent() / 1_GeV, - PprojCoM.getSpaceLikeComponents().getComponents() / 1_GeV); - - CORSIKA_LOG_DEBUG( - "Interaction: etarget CoM: {} GeV" - "Interaction: ptarget CoM: {} GeV", - PtargCoM.getTimeLikeComponent() / 1_GeV, - PtargCoM.getSpaceLikeComponents().getComponents() / 1_GeV); - - CORSIKA_LOG_DEBUG("Interaction: position of interaction: ", pOrig.getCoordinates()); - CORSIKA_LOG_DEBUG("Interaction: time: {}", tOrig); - - HEPEnergyType Etot = eProjectileLab + eTargetLab; - MomentumVector Ptot = projectile.getMomentum(); - // invariant mass, i.e. cm. energy - HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.getSquaredNorm()); - - if (targetId != Code::Hydrogen && targetId != Code::Neutron && - targetId != Code::Proton) - throw std::runtime_error("DoInteraction: wrong target for PYTHIA"); - - CORSIKA_LOG_DEBUG( - "Interaction: " - " DoInteraction: E(GeV): {}" - " Ecm(GeV): {}", - eProjectileLab / 1_GeV, Ecm / 1_GeV); - - if (eProjectileLab < 8.5_GeV || !isValidCoMEnergy(Ecm)) { - CORSIKA_LOG_DEBUG( - "Interaction: " - " DoInteraction: should have dropped particle.. " - "THIS IS AN ERROR"); - throw std::runtime_error("energy too low for PYTHIA"); - - } else { - count_++; - - configureLabFrameCollision(projectileId, targetId, eProjectileLab); - - // create event in pytia. LCOV_EXCL_START: we don't validate pythia8 internals - if (!Pythia8::Pythia::next()) - throw std::runtime_error("Pythia::DoInteraction: failed!"); - // LCOV_EXCL_STOP - - // link to pythia stack - Pythia8::Event& event = Pythia8::Pythia::event; - - // LCOV_EXCL_START, we don't validate pythia8 internals - if (print_listing_) { - // print final state - event.list(); - } - // LCOV_EXCL_STOP - - 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 = convert_from_PDG(static_cast<PDGCode>(p8p.id())); - - MomentumVector const pyPlab( - labCS, {p8p.px() * 1_GeV, p8p.py() * 1_GeV, p8p.pz() * 1_GeV}); - - // add to corsika stack - auto pnew = - projectile.addSecondary(std::make_tuple(pyId, pyPlab, pOrig, tOrig)); - - Plab_final += pnew.getMomentum(); - Elab_final += pnew.getEnergy(); - } - CORSIKA_LOG_DEBUG( - "conservation (all GeV): " - "Elab_final= {}" - ", Plab_final= {}", - Elab_final / 1_GeV, (Plab_final / 1_GeV).getComponents()); - } + auto const pyId = convert_from_PDG(static_cast<PDGCode>(p8p.id())); + + MomentumVector const pyPlab(labCS, + {p8p.px() * 1_GeV, p8p.py() * 1_GeV, p8p.pz() * 1_GeV}); + + // add to corsika stack + auto pnew = projectile.addSecondary(std::make_tuple(pyId, pyPlab, pOrig, tOrig)); + + Plab_final += pnew.getMomentum(); + Elab_final += pnew.getEnergy(); } + + CORSIKA_LOG_DEBUG( + "conservation (all GeV): " + "Elab_final= {}" + ", Plab_final= {}", + Elab_final / 1_GeV, (Plab_final / 1_GeV).getComponents()); } } // namespace corsika::pythia8 diff --git a/corsika/framework/process/ProcessSequence.hpp b/corsika/framework/process/ProcessSequence.hpp index 3b647ec82..74dad4f2f 100644 --- a/corsika/framework/process/ProcessSequence.hpp +++ b/corsika/framework/process/ProcessSequence.hpp @@ -141,7 +141,7 @@ namespace corsika { * the static version of the * ProcessSequence and all Process * types are based on the CRTP C++ - * design pattern) + * design pattern). * * Template parameters: * @tparam TProcess1 is of type BaseProcess, either a dedicatd process, or a @@ -177,7 +177,7 @@ namespace corsika { static bool const is_process_sequence = true; /** - * Only valid user constructor will create fully initialized object + * Only valid user constructor will create fully initialized object. * * ProcessSequence supports and encourages move semantics. You can * use object, l-value references or r-value references to @@ -339,10 +339,10 @@ namespace corsika { * @fn make_sequence * @ingroup Processes * - * Factory function to create a ProcessSequence + * Factory function to create a ProcessSequence. * * to construct ProcessSequences in a flexible and dynamic way the - * `sequence` factory functions are provided + * `sequence` factory functions are provided. * * Any objects of type * - BaseProcess @@ -373,34 +373,34 @@ namespace corsika { } /** - * @fn make_sequence - * @ingroup Processes - * - * Factory function to create ProcessSequence - * - specialization for two input objects (no paramter pack in vB). - - @tparam TProcess1 another BaseProcess - @tparam TProcess2 another BaseProcess - @param vA needs to derive from BaseProcess - @param vB needs to derive BaseProcess - */ + * @fn make_sequence + * @ingroup Processes + * + * Factory function to create ProcessSequence. + * + * specialization for two input objects (no paramter pack in vB). + * + * @tparam TProcess1 another BaseProcess + * @tparam TProcess2 another BaseProcess + * @param vA needs to derive from BaseProcess + * @param vB needs to derive BaseProcess + */ template <typename TProcess1, typename TProcess2> ProcessSequence<TProcess1, TProcess2> make_sequence(TProcess1&& vA, TProcess2&& vB) { return ProcessSequence<TProcess1, TProcess2>(vA, vB); } /** - @fn make_sequence - @ingroup Processes - - Factory function to create ProcessSequence from a single BaseProcess - - also allow a single Process in ProcessSequence, accompany by - `NullModel` - - @tparam TProcess1 another BaseProcess - @param vA needs to derive from BaseProcess + * @fn make_sequence + * @ingroup Processes + * + * Factory function to create ProcessSequence from a single BaseProcess. + * + * also allow a single Process in ProcessSequence, accompany by + * `NullModel`. + * + * @tparam TProcess1 another BaseProcess + * @param vA needs to derive from BaseProcess */ template <typename TProcess> ProcessSequence<TProcess, NullModel> make_sequence(TProcess&& vA) { diff --git a/corsika/media/IMediumPropertyModel.hpp b/corsika/media/IMediumPropertyModel.hpp index 860fa22da..94e80fb51 100644 --- a/corsika/media/IMediumPropertyModel.hpp +++ b/corsika/media/IMediumPropertyModel.hpp @@ -16,10 +16,9 @@ namespace corsika { /** - * An interface for type of media, needed e.g. to determine energy losses + * An interface for type of media, needed e.g. to determine energy losses. * * This is the base interface for media types. - * */ template <typename TModel> class IMediumPropertyModel : public TModel { diff --git a/corsika/media/MediumPropertyModel.hpp b/corsika/media/MediumPropertyModel.hpp index ab89a8a54..97bce6ff8 100644 --- a/corsika/media/MediumPropertyModel.hpp +++ b/corsika/media/MediumPropertyModel.hpp @@ -14,7 +14,6 @@ namespace corsika { /** * A model for the energy loss property of a medium. - * */ template <typename T> class MediumPropertyModel : public T { diff --git a/corsika/modules/pythia8/Interaction.hpp b/corsika/modules/pythia8/Interaction.hpp index 63376ab17..02a5313b7 100644 --- a/corsika/modules/pythia8/Interaction.hpp +++ b/corsika/modules/pythia8/Interaction.hpp @@ -21,20 +21,22 @@ namespace corsika::pythia8 { class Interaction : public InteractionProcess<Interaction>, public Pythia8::Pythia { public: - Interaction(const bool print_listing = false); + Interaction(bool const print_listing = false); ~Interaction(); void setStable(std::vector<Code> const&); - void setUnstable(const Code); - void setStable(const Code); + void setUnstable(Code const); + void setStable(Code const); bool isValidCoMEnergy(HEPEnergyType const ecm) const { return (10_GeV < ecm) && (ecm < 1_PeV); } - bool canInteract(const Code) const; - void configureLabFrameCollision(const Code, const Code, const HEPEnergyType); + bool canInteract(Code const) const; + void configureLabFrameCollision(Code const, Code const, HEPEnergyType const); + void isValid(Code const projectileId, Code const targetId, + HEPEnergyType const sqrtS) const; /** * Returns inelastic AND elastic cross sections. * @@ -88,7 +90,7 @@ namespace corsika::pythia8 { private: default_prng_type& RNG_ = RNGManager<>::getInstance().getRandomStream("pythia"); Pythia8::SigmaTotal sigma_; - const bool internalDecays_ = true; + bool const internalDecays_ = true; int count_ = 0; bool print_listing_ = false; }; diff --git a/corsika/modules/sibyll/NuclearInteractionModel.hpp b/corsika/modules/sibyll/NuclearInteractionModel.hpp index 1c4d9c7e9..753cabf98 100644 --- a/corsika/modules/sibyll/NuclearInteractionModel.hpp +++ b/corsika/modules/sibyll/NuclearInteractionModel.hpp @@ -10,7 +10,6 @@ #include <corsika/framework/core/ParticleProperties.hpp> #include <corsika/framework/random/RNGManager.hpp> -#include <corsika/framework/utility/COMBoost.hpp> #include <corsika/framework/geometry/FourVector.hpp> namespace corsika::sibyll { diff --git a/corsika/stack/VectorStack.hpp b/corsika/stack/VectorStack.hpp index df1b020a2..22873790c 100644 --- a/corsika/stack/VectorStack.hpp +++ b/corsika/stack/VectorStack.hpp @@ -66,7 +66,6 @@ namespace corsika { * Set data of new particle. * * @param v tuple containing: PID, kinetic Energy, Direction Vector, Position, Time - * */ void setParticleData(particle_data_momentum_type const& v); @@ -75,7 +74,6 @@ namespace corsika { * * @param parent parent particle * @param v tuple containing: PID, kinetic Energy, Direction Vector, Position, Time - * */ void setParticleData(ParticleInterface<TStackIterator> const& parent, particle_data_momentum_type const& v); @@ -97,9 +95,9 @@ namespace corsika { } /** - The MomentumVector v is used to determine the DirectionVector, and to update the - particle energy. - */ + * The MomentumVector v is used to determine the DirectionVector, and to update the + * particle energy. + */ void setMomentum(MomentumVector const& v) { HEPMomentumType const P = v.getNorm(); if (P == 0_eV) { diff --git a/tests/modules/testPythia8.cpp b/tests/modules/testPythia8.cpp index 2ccc5407d..06121eeec 100644 --- a/tests/modules/testPythia8.cpp +++ b/tests/modules/testPythia8.cpp @@ -183,17 +183,17 @@ TEST_CASE("Pythia8Interface", "modules") { std::tuple<CrossSectionType, CrossSectionType> xs_test = collision.getCrossSectionInelEla( Code::Proton, Code::Hydrogen, - {sqrt(static_pow<2>(Iron::mass) + static_pow<2>(100_GeV)), + {sqrt(static_pow<2>(Proton::mass) + static_pow<2>(100_GeV)), {rootCS, {0_eV, 0_eV, 100_GeV}}}, {Hydrogen::mass, {rootCS, {0_eV, 0_eV, 0_eV}}}); - CHECK(std::get<0>(xs_test) / 1_mb == Approx(353).margin(2)); - CHECK(std::get<1>(xs_test) / 1_mb == Approx(75).margin(2)); + CHECK(std::get<0>(xs_test) / 1_mb == Approx(314).margin(2)); + CHECK(std::get<1>(xs_test) / 1_mb == Approx(69).margin(2)); collision.doInteraction(view, Code::Proton, Code::Hydrogen, - {sqrt(static_pow<2>(Iron::mass) + static_pow<2>(100_GeV)), + {sqrt(static_pow<2>(Proton::mass) + static_pow<2>(100_GeV)), {rootCS, {0_eV, 0_eV, 100_GeV}}}, {Hydrogen::mass, {rootCS, {0_eV, 0_eV, 0_eV}}}); - CHECK(view.getSize() == 38); + CHECK(view.getSize() == 12); } SECTION("pythia too low energy") { @@ -207,8 +207,8 @@ TEST_CASE("Pythia8Interface", "modules") { CHECK_THROWS(collision.doInteraction( view, Code::Neutron, Code::Hydrogen, - {sqrt(static_pow<2>(Neutron::mass) + static_pow<2>(100_GeV)), - {rootCS, {0_eV, 0_eV, 100_GeV}}}, + {sqrt(static_pow<2>(Neutron::mass) + static_pow<2>(1_GeV)), + {rootCS, {0_eV, 0_eV, 1_GeV}}}, {Hydrogen::mass, {rootCS, {0_eV, 0_eV, 0_eV}}})); } -- GitLab