diff --git a/corsika/detail/framework/core/Cascade.inl b/corsika/detail/framework/core/Cascade.inl index f3e5938fe0573d96ddb61df91b996373f575d6a2..f11427148c96e927176168f6d9d8c1ee3dc9fc15 100644 --- a/corsika/detail/framework/core/Cascade.inl +++ b/corsika/detail/framework/core/Cascade.inl @@ -47,7 +47,7 @@ namespace corsika { auto pNext = stack_.getNextParticle(); CORSIKA_LOG_TRACE( - "============== next particle : count={}, pid={}, " + "============== next particle : count={}, pid={}" ", stack entries={}" ", stack deleted={}", count_, pNext.getPID(), stack_.getEntries(), stack_.getErased()); @@ -134,11 +134,9 @@ namespace corsika { ExponentialDistribution expDist(total_lambda); GrammageType const next_interact = expDist(rng_); - CORSIKA_LOG_DEBUG( - "total_lambda={} g/cm2, " - ", next_interact={} g/cm2", - double(total_lambda / 1_g * 1_cm * 1_cm), - double(next_interact / 1_g * 1_cm * 1_cm)); + CORSIKA_LOG_DEBUG("total_lambda={} g/cm2, next_interact={} g/cm2", + double(total_lambda / 1_g * 1_cm * 1_cm), + double(next_interact / 1_g * 1_cm * 1_cm)); // determine combined total inverse decay time InverseTimeType const total_inv_lifetime = sequence_.getInverseLifetime(particle); @@ -147,10 +145,8 @@ namespace corsika { ExponentialDistribution expDistDecay(1 / total_inv_lifetime); TimeType const next_decay = expDistDecay(rng_); - CORSIKA_LOG_DEBUG( - "total_lifetime={} s" - ", next_decay={} s", - (1 / total_inv_lifetime) / 1_s, next_decay / 1_s); + CORSIKA_LOG_DEBUG("total_lifetime={} ns, next_decay={} ns", + (1 / total_inv_lifetime) / 1_ns, next_decay / 1_ns); // convert next_decay from time to length [m] LengthType const distance_decay = next_decay * particle.getMomentum().getNorm() / @@ -198,10 +194,6 @@ namespace corsika { // move particle along the trajectory to new position // also update momentum/direction/time step.setLength(min_distance); - particle.setPosition(step.getPosition(1)); - // assumption: tracking does not change absolute momentum (continuous physics can and - // will): - particle.setMomentum(step.getDirection(1) * particle.getMomentum().getNorm()); // apply all continuous processes on particle + track if (sequence_.doContinuous(particle, step, limitingId) == @@ -215,9 +207,12 @@ namespace corsika { } else { particle.erase(); } - return; + return; // particle is gone -> return } particle.setTime(particle.getTime() + step.getDuration()); + particle.setPosition(step.getPosition(1)); + particle.setMomentum(step.getDirection(1) * particle.getMomentum().getNorm()); + if (isContinuous) { return; // there is nothing further, step is finished } diff --git a/corsika/detail/modules/pythia8/Interaction.inl b/corsika/detail/modules/pythia8/Interaction.inl index a716b156d5e5b052b62dcf0bc771d41a1ea2fb8e..fe55d587412537f86dff4ca4f0ca0f9dd5ef99ab 100644 --- a/corsika/detail/modules/pythia8/Interaction.inl +++ b/corsika/detail/modules/pythia8/Interaction.inl @@ -80,26 +80,20 @@ namespace corsika::pythia8 { Pythia8::Pythia::particleData.mayDecay(static_cast<int>(get_PDG(pCode)), false); } - inline void Interaction::isValid(Code const projectileId, Code const targetId, + inline bool 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 ((10_GeV > sqrtS) || (sqrtS > 1_PeV)) { return false; } if (targetId != Code::Hydrogen && targetId != Code::Neutron && targetId != Code::Proton) { - throw std::runtime_error("wrong target for PYTHIA"); + return false; } - 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 (is_nucleus(projectileId)) { return false; } - if (!canInteract(projectileId)) { - throw std::runtime_error("Projectile not supported by PYTHIA!"); - } + if (!canInteract(projectileId)) { return false; } + return true; } inline void Interaction::configureLabFrameCollision(Code const projectileId, @@ -150,7 +144,9 @@ namespace corsika::pythia8 { HEPEnergyType const CoMenergy = (projectileP4 + targetP4).getNorm(); - isValid(projectileId, targetId, CoMenergy); // throws + if (!isValid(projectileId, targetId, CoMenergy)) { + return {CrossSectionType::zero(), CrossSectionType::zero()}; + } // input particle PDG auto const pdgCodeBeam = static_cast<int>(get_PDG(projectileId)); @@ -195,11 +191,13 @@ namespace corsika::pythia8 { static_pow<2>(get_mass(targetId))) / (2 * get_mass(targetId)); - isValid(projectileId, targetId, sqrtS); // throws + if (!isValid(projectileId, targetId, sqrtS)) { + throw std::runtime_error("invalid target,projectile,energy combination."); + } // position and time of interaction - Point pOrig = projectile.getPosition(); - TimeType tOrig = projectile.getTime(); + Point const& pOrig = projectile.getPosition(); + TimeType const tOrig = projectile.getTime(); CORSIKA_LOG_DEBUG("Interaction: ebeam lab: {} GeV", eProjectileLab / 1_GeV); diff --git a/corsika/detail/modules/qgsjetII/InteractionModel.inl b/corsika/detail/modules/qgsjetII/InteractionModel.inl index 0b9bb370ac0cfb32721b9c9718cf7fe1c4c1d700..b65d5b3f72a64e576711aeee639514bfdc4d355f 100644 --- a/corsika/detail/modules/qgsjetII/InteractionModel.inl +++ b/corsika/detail/modules/qgsjetII/InteractionModel.inl @@ -41,44 +41,32 @@ namespace corsika::qgsjetII { CORSIKA_LOG_DEBUG("QgsjetII::InteractionModel n= {}", count_); } - inline void InteractionModel::isValid(Code const projectileId, + inline bool InteractionModel::isValid(Code const projectileId, Code const targetId) const { if (is_nucleus(targetId)) { size_t iTarget = get_nucleus_A(targetId); - if (iTarget > int(maxMassNumber_) || iTarget <= 0) { - std::ostringstream txt; - txt << "QgsjetII target outside range. Atarget=" << iTarget; - throw std::runtime_error(txt.str().c_str()); - } + if (iTarget > int(maxMassNumber_) || iTarget <= 0) { return false; } } else if (targetId != Proton::code) { - std::ostringstream txt; - txt << "QgsjetII not valid target=" << targetId; - throw std::runtime_error(txt.str().c_str()); + return false; } if (is_nucleus(projectileId)) { size_t iProjectile = get_nucleus_A(projectileId); - if (iProjectile > int(maxMassNumber_) || iProjectile <= 0) { - std::ostringstream txt; - txt << "QgsjetII projectile outside range. Aprojectile=" << iProjectile; - throw std::runtime_error(txt.str().c_str()); - } + if (iProjectile > int(maxMassNumber_) || iProjectile <= 0) { return false; } } else if (!is_hadron(projectileId)) { - std::ostringstream txt; - txt << "QgsjetII projectile can only be hadrons. Is=" << projectileId; - throw std::runtime_error(txt.str().c_str()); + return false; } + return true; } inline CrossSectionType InteractionModel::getCrossSection( Code const projectileId, Code const targetId, FourMomentum const& projectileP4, FourMomentum const& targetP4) const { - double sigProd = std::numeric_limits<double>::infinity(); - - if (!corsika::qgsjetII::canInteract(projectileId)) { return sigProd * 1_mb; } - - isValid(projectileId, targetId); // throws + if (!corsika::qgsjetII::canInteract(projectileId)) { + return CrossSectionType::zero(); + } + if (!isValid(projectileId, targetId)) { return CrossSectionType::zero(); } // define projectile, in lab frame auto const sqrtS2 = (projectileP4 + targetP4).getNormSqr(); @@ -97,9 +85,8 @@ namespace corsika::qgsjetII { "QgsjetII::getCrossSection Elab= {} GeV iBeam= {}" " iProjectile= {} iTarget= {}", Elab / 1_GeV, iBeam, iProjectile, iTarget); - sigProd = qgsect_(Elab / 1_GeV, iBeam, iProjectile, iTarget); + double sigProd = qgsect_(Elab / 1_GeV, iBeam, iProjectile, iTarget); CORSIKA_LOG_DEBUG("QgsjetII::getCrossSection sigProd= {} mb", sigProd); - return sigProd * 1_mb; } @@ -114,9 +101,10 @@ namespace corsika::qgsjetII { "doInteraction: {} interaction possible? {}", projectileId, corsika::qgsjetII::canInteract(projectileId)); - if (!corsika::qgsjetII::canInteract(projectileId)) return; - - isValid(projectileId, targetId); // throws + if (!corsika::qgsjetII::canInteract(projectileId) || + !isValid(projectileId, targetId)) { + throw std::runtime_error("invalid target/projectile/energy combination."); + } CoordinateSystemPtr const& rootCS = get_root_CoordinateSystem(); diff --git a/corsika/detail/modules/sibyll/Decay.inl b/corsika/detail/modules/sibyll/Decay.inl index 6b8ae281d4a4be07408785e1a846c376c8b4bc0f..ab0114182b41f5db321f19ec6d91458cc9b5000d 100644 --- a/corsika/detail/modules/sibyll/Decay.inl +++ b/corsika/detail/modules/sibyll/Decay.inl @@ -174,7 +174,7 @@ namespace corsika::sibyll { count_++; // remember position - Point const decayPoint = projectile.getPosition(); + Point const& decayPoint = projectile.getPosition(); TimeType const t0 = projectile.getTime(); // switch on decay for this particle setUnstable(pCode); diff --git a/corsika/detail/modules/sibyll/InteractionModel.inl b/corsika/detail/modules/sibyll/InteractionModel.inl index 38acb4b3d457bef02f81270761f7fc82716d5821..9ecb434bc62cb5a0bbccc6a13ce889032b4bdcda 100644 --- a/corsika/detail/modules/sibyll/InteractionModel.inl +++ b/corsika/detail/modules/sibyll/InteractionModel.inl @@ -36,26 +36,24 @@ namespace corsika::sibyll { CORSIKA_LOG_DEBUG("Sibyll::Model n={}, Nnuc={}", count_, nucCount_); } - inline void constexpr InteractionModel::isValid(Code const projectileId, + inline bool constexpr InteractionModel::isValid(Code const projectileId, Code const targetId, HEPEnergyType const sqrtSnn) const { - if ((minEnergyCoM_ > sqrtSnn) || (sqrtSnn > maxEnergyCoM_)) { - // i.e. nuclei handled by different process, this should not happen - throw std::runtime_error("CoM energy out of bounds for SIBYLL"); - } + if ((minEnergyCoM_ > sqrtSnn) || (sqrtSnn > maxEnergyCoM_)) { return false; } if (is_nucleus(targetId)) { - unsigned int const targA = get_nucleus_A(targetId); + size_t const targA = get_nucleus_A(targetId); if (targA != 1 && (targA < minNuclearTargetA_ || targA >= maxTargetMassNumber_)) { - throw std::runtime_error("Target outside of allowed range for SIBYLL"); + return false; } } else if (targetId != Code::Proton && targetId != Code::Neutron && targetId != Code::Hydrogen) { - throw std::runtime_error("Target cannot be handled by SIBYLL"); + return false; } if (is_nucleus(projectileId) || !corsika::sibyll::canInteract(projectileId)) { - throw std::runtime_error("Projectile cannot be handled by SIBYLL"); + return false; } + return true; } inline std::tuple<CrossSectionType, CrossSectionType> @@ -68,6 +66,10 @@ namespace corsika::sibyll { // sqrtS per target nucleon HEPEnergyType const sqrtSnn = (projectileP4 + targetP4 / targetSibCode).getNorm(); + if (!isValid(projectileId, targetId, sqrtSnn)) { + return {CrossSectionType::zero(), CrossSectionType::zero()}; + } + double dummy, dum1, dum3, dum4, dumdif[3]; // dummies needed for fortran call int const iBeam = corsika::sibyll::getSibyllXSCode( projectileId); // 0 (can not interact, 1: proton-like, 2: pion-like, @@ -109,7 +111,9 @@ namespace corsika::sibyll { HEPEnergyType const sqrtSnn = (projectileP4 + targetP4 / targetSibCode).getNorm(); COMBoost const boost(projectileP4, targetP4 / targetSibCode); - isValid(projectileId, targetId, sqrtSnn); // throws + if (!isValid(projectileId, targetId, sqrtSnn)) { + throw std::runtime_error("Invalid target/projectile/energy combination"); + } CORSIKA_LOG_DEBUG("pId={} tId={} sqrtSnn={}GeV", projectileId, targetId, sqrtSnn); @@ -135,10 +139,9 @@ namespace corsika::sibyll { // add particles from sibyll to stack // position and time of interaction, not used in Sibyll - Point const pOrig = Point(csPrime, {0_m, 0_m, 0_m}); - TimeType const tOrig = 0_s; // no time in sibyll - CORSIKA_LOG_DEBUG("position of interaction: {}, time {} ", pOrig.getCoordinates(), - tOrig); + auto const& projectile = secondaries.parent(); + Point const& pOrig = projectile.getPosition(); + TimeType const tOrig = projectile.getTime(); // no time in sibyll // link to sibyll stack SibStack ss; diff --git a/corsika/detail/modules/sibyll/NuclearInteractionModel.inl b/corsika/detail/modules/sibyll/NuclearInteractionModel.inl index e9ad447f33e0d25bd4d14fa735ed630d083662d9..bda2996b5a1c2eacd9d2f9a5e81c2f85e3e91987 100644 --- a/corsika/detail/modules/sibyll/NuclearInteractionModel.inl +++ b/corsika/detail/modules/sibyll/NuclearInteractionModel.inl @@ -40,20 +40,17 @@ namespace corsika::sibyll { } template <typename TEnvironment, typename TNucleonModel> - inline void constexpr NuclearInteractionModel<TEnvironment, TNucleonModel>::isValid( + inline bool constexpr NuclearInteractionModel<TEnvironment, TNucleonModel>::isValid( Code const projectileId, Code const targetId, HEPEnergyType const sqrtSnn) const { // also depends on underlying model, for Proton/Neutron projectile - hadronicInteraction_.isValid(Code::Proton, targetId, sqrtSnn); // throws + if (!hadronicInteraction_.isValid(Code::Proton, targetId, sqrtSnn)) { return false; } // projectile limits: - if (!is_nucleus(projectileId)) { - throw std::runtime_error("can only handle nuclear projectile"); - } + if (!is_nucleus(projectileId)) { return false; } unsigned int projectileA = get_nucleus_A(projectileId); - if (projectileA > getMaxNucleusAProjectile() || projectileA < 2) { - throw std::runtime_error("projectile mass A out of bounds"); - } + if (projectileA > getMaxNucleusAProjectile() || projectileA < 2) { return false; } + return true; } // namespace corsika::sibyll template <typename TEnvironment, typename TNucleonModel> @@ -114,28 +111,35 @@ namespace corsika::sibyll { for (Code const ptarg : allElementsInUniverse) { if (ptarg == Code::Argon) continue; // NEED TO IGNORE Argon .... ++k; - CORSIKA_LOG_DEBUG("init target component: {}", ptarg); + CORSIKA_LOG_DEBUG("init target component: {} A={}", ptarg, get_nucleus_A(ptarg)); int const ib = get_nucleus_A(ptarg); - hadronicInteraction_.isValid(Code::Proton, ptarg, 100_GeV); // throws + if (!hadronicInteraction_.isValid(Code::Proton, ptarg, 100_GeV)) { + throw std::runtime_error("Invalid target type."); + } targetComponentsIndex_.insert(std::pair<Code, int>(ptarg, k)); // loop over energies, fNEnBins log. energy bins - for (unsigned int i = 0; i < getNEnergyBins(); ++i) { + for (size_t i = 0; i < getNEnergyBins(); ++i) { // hard coded energy grid, has to be aligned to definition in signuc2!!, no // comment.. HEPEnergyType const Ecm = pow(10., 1. + 1. * i) * 1_GeV; + // head-on pp collision: + HEPEnergyType const EcmHalve = Ecm / 2; + HEPMomentumType const pcm = + sqrt(EcmHalve * EcmHalve - Proton::mass * Proton::mass); CoordinateSystemPtr cs = get_root_CoordinateSystem(); - HEPMomentumType const pcm = sqrt(Ecm * Ecm - Proton::mass * Proton::mass); - FourMomentum projectileP4(Ecm, - {cs, pcm, 0_eV, 0_eV}); // this is ONLY needd for sqrtS - FourMomentum targetP4(0_eV, {cs, 0_eV, 0_eV, 0_eV}); + FourMomentum projectileP4(EcmHalve, {cs, pcm, 0_eV, 0_eV}); + FourMomentum targetP4(EcmHalve, {cs, -pcm, 0_eV, 0_eV}); // get p-p cross sections - auto const protonId = Code::Proton; + if (!hadronicInteraction_.isValid(Code::Proton, Code::Proton, Ecm)) { + throw std::runtime_error("invalid projectile,target,ecm combination"); + } auto const [siginel, sigela] = hadronicInteraction_.getCrossSectionInelEla( - protonId, protonId, projectileP4, targetP4); - const double dsig = siginel / 1_mb; - const double dsigela = sigela / 1_mb; + Code::Proton, Code::Proton, projectileP4, targetP4); + double const dsig = siginel / 1_mb; + double const dsigela = sigela / 1_mb; // loop over projectiles, mass numbers from 2 to fMaxNucleusAProjectile - for (unsigned int j = 1; j < gMaxNucleusAProjectile_; ++j) { + CORSIKA_LOG_TRACE("Ecm={} siginel={} sigela={}", Ecm / 1_GeV, dsig, dsigela); + for (size_t j = 1; j < gMaxNucleusAProjectile_; ++j) { const int jj = j + 1; double sig_out, dsig_out, sigqe_out, dsigqe_out; sigma_mc_(jj, ib, dsig, dsigela, gNSample_, sig_out, dsig_out, sigqe_out, @@ -143,6 +147,7 @@ namespace corsika::sibyll { // write to table cnucsignuc_.sigma[j][k][i] = sig_out; cnucsignuc_.sigqe[j][k][i] = sigqe_out; + CORSIKA_LOG_TRACE("nuc A={} sig={} qe={}", j, sig_out, sigqe_out); } } } @@ -177,7 +182,7 @@ namespace corsika::sibyll { FourMomentum const& targetP4) const { HEPEnergyType const sqrtSnn = (projectileP4 + targetP4).getNorm(); - isValid(projectileId, targetId, sqrtSnn); // throws + if (!isValid(projectileId, targetId, sqrtSnn)) { return CrossSectionType::zero(); } HEPEnergyType const LabEnergyPerNuc = static_pow<2>(sqrtSnn) / (2 * constants::nucleonMass); auto const sigProd = @@ -199,7 +204,9 @@ namespace corsika::sibyll { // this is center-of-mass for projectile_nucleon - target FourMomentum const nucleonP4 = projectileP4 / projectileA; HEPEnergyType const sqrtSnucleon = (nucleonP4 + targetP4).getNorm(); - isValid(projectileId, targetId, sqrtSnucleon); // throws + if (!isValid(projectileId, targetId, sqrtSnucleon)) { + throw std::runtime_error("Invalid projectile/target/energy combination."); + } // projectile is always nucleus! // Elab corresponding to sqrtSnucleon -> fixed target projectile COMBoost const boost(nucleonP4, targetP4); @@ -287,8 +294,8 @@ namespace corsika::sibyll { Point const& pOrig = projectile.getPosition(); TimeType const delay = projectile.getTime(); - CORSIKA_LOG_DEBUG("Interaction: position of interaction: {} {}", - pOrig.getCoordinates(), delay / 1_s); + CORSIKA_LOG_DEBUG("Interaction: position of interaction: {}, {} ns", + pOrig.getCoordinates(), delay / 1_ns); CORSIKA_LOG_DEBUG("number of fragments: {}", nFragments); CORSIKA_LOG_DEBUG("adding nuclear fragments to particle stack.."); // put nuclear fragments on corsika stack diff --git a/corsika/detail/modules/urqmd/UrQMD.inl b/corsika/detail/modules/urqmd/UrQMD.inl index b8393b0e91da8c63cae6ddf5015df605abee4762..1bf0f0d59a42428df231717f2df869f72c30bd45 100644 --- a/corsika/detail/modules/urqmd/UrQMD.inl +++ b/corsika/detail/modules/urqmd/UrQMD.inl @@ -37,14 +37,13 @@ namespace corsika::urqmd { ::urqmd::iniurqmdc8_(); } - inline void UrQMD::isValid(Code const projectileId, Code const targetId) const { + inline bool UrQMD::isValid(Code const projectileId, Code const targetId) const { if (!is_hadron(projectileId) || !corsika::urqmd::canInteract(projectileId)) { - throw std::runtime_error("UrQMD projectile is not a compatible hadron."); - } - if (!is_nucleus(targetId)) { - throw std::runtime_error("UrQMD target is not a nucleus ."); + return false; } + if (!is_nucleus(targetId)) { return false; } + return true; } inline CrossSectionType UrQMD::getTabulatedCrossSection( @@ -141,7 +140,7 @@ namespace corsika::urqmd { FourMomentum const& projectileP4, FourMomentum const& targetP4) const { - if (is_nucleus(projectileId)) { + if (!isValid(projectileId, targetId)) { /* * unfortunately unavoidable at the moment until we have tools to get the actual * inealstic cross-section from UrQMD @@ -149,8 +148,6 @@ namespace corsika::urqmd { return CrossSectionType::zero(); } - isValid(projectileId, targetId); // throws - // define projectile, in lab frame auto const sqrtS2 = (projectileP4 + targetP4).getNormSqr(); HEPEnergyType const Elab = (sqrtS2 - static_pow<2>(get_mass(projectileId)) - @@ -200,7 +197,9 @@ namespace corsika::urqmd { static_pow<2>(get_mass(targetId))) / (2 * get_mass(targetId)); - isValid(projectileId, targetId); // throws + if (!isValid(projectileId, targetId)) { + throw std::runtime_error("invalid target,projectile,energy combination"); + } size_t const targetA = get_nucleus_A(targetId); size_t const targetZ = get_nucleus_Z(targetId); diff --git a/corsika/framework/process/ProcessSequence.hpp b/corsika/framework/process/ProcessSequence.hpp index 74dad4f2ff1f71049efde8198ccbaaa94ff84910..e6d3600b8cff72e305a1b57f64a526a39772341f 100644 --- a/corsika/framework/process/ProcessSequence.hpp +++ b/corsika/framework/process/ProcessSequence.hpp @@ -273,7 +273,7 @@ namespace corsika { FourMomentum const& targetP4) const; template <typename TParticle> - TimeType getLifetime(TParticle&& particle) { + TimeType getLifetime(TParticle& particle) { return 1. / getInverseLifetime(particle); } diff --git a/corsika/modules/pythia8/Interaction.hpp b/corsika/modules/pythia8/Interaction.hpp index 02a5313b70c752a6680cf462ab4aee1e0c2be187..25ebf826b3f886065d5759fffa4eaa94f3e659ac 100644 --- a/corsika/modules/pythia8/Interaction.hpp +++ b/corsika/modules/pythia8/Interaction.hpp @@ -35,7 +35,7 @@ namespace corsika::pythia8 { bool canInteract(Code const) const; void configureLabFrameCollision(Code const, Code const, HEPEnergyType const); - void isValid(Code const projectileId, Code const targetId, + bool isValid(Code const projectileId, Code const targetId, HEPEnergyType const sqrtS) const; /** * Returns inelastic AND elastic cross sections. diff --git a/corsika/modules/qgsjetII/InteractionModel.hpp b/corsika/modules/qgsjetII/InteractionModel.hpp index 4ec1bf6a279a51e8e0c2f2fbd0aa4857d14be3eb..45e9f8ef083b5af9d8ee2c270c9629db2c010260 100644 --- a/corsika/modules/qgsjetII/InteractionModel.hpp +++ b/corsika/modules/qgsjetII/InteractionModel.hpp @@ -33,7 +33,7 @@ namespace corsika::qgsjetII { * @param beamId * @param targetId */ - void isValid(Code const beamId, Code const targetId) const; + bool isValid(Code const beamId, Code const targetId) const; /** * Return the QGSJETII inelastic/production cross section. diff --git a/corsika/modules/sibyll/InteractionModel.hpp b/corsika/modules/sibyll/InteractionModel.hpp index 0f65dcab7d8b38581e141807d5eff1a234f8818d..177e77857b305d385da162a3c0b705a8c5c276f9 100644 --- a/corsika/modules/sibyll/InteractionModel.hpp +++ b/corsika/modules/sibyll/InteractionModel.hpp @@ -45,7 +45,7 @@ namespace corsika::sibyll { * sibyll only accepts nuclei with 4<=A<=18 as targets, or protons aka Hydrogen or * neutrons (p,n == nucleon). */ - void constexpr isValid(Code const projectileId, Code const targetId, + bool constexpr isValid(Code const projectileId, Code const targetId, HEPEnergyType const sqrtSnn) const; /** @@ -96,7 +96,7 @@ namespace corsika::sibyll { */ template <typename TSecondaries> - void doInteraction(TSecondaries&, Code const projectile, Code const target, + void doInteraction(TSecondaries& view, Code const projectile, Code const target, FourMomentum const& projectileP4, FourMomentum const& targetP4); private: diff --git a/corsika/modules/sibyll/NuclearInteractionModel.hpp b/corsika/modules/sibyll/NuclearInteractionModel.hpp index 753cabf98f471832c8e2b315aecf62a7cf9bf0d3..2d7d81c2ce0717e33567715b554b93fb93ce15c9 100644 --- a/corsika/modules/sibyll/NuclearInteractionModel.hpp +++ b/corsika/modules/sibyll/NuclearInteractionModel.hpp @@ -29,7 +29,7 @@ namespace corsika::sibyll { NuclearInteractionModel(TNucleonModel&, TEnvironment const&); ~NuclearInteractionModel(); - void constexpr isValid(Code const projectileId, Code const targetId, + bool constexpr isValid(Code const projectileId, Code const targetId, HEPEnergyType const sqrtSnn) const; void initializeNuclearCrossSections(); diff --git a/corsika/modules/urqmd/UrQMD.hpp b/corsika/modules/urqmd/UrQMD.hpp index 86d238e0fa736027803c8712d4a68df47b6da140..1ae0ff80af53f99ce31bbb383a459510e362a3e1 100644 --- a/corsika/modules/urqmd/UrQMD.hpp +++ b/corsika/modules/urqmd/UrQMD.hpp @@ -35,7 +35,7 @@ namespace corsika::urqmd { UrQMD(boost::filesystem::path const path = corsika_data("UrQMD/UrQMD-1.3.1-xs.dat"), int const retryFlag = 0); - void isValid(Code const projectileId, Code const targetId) const; + bool isValid(Code const projectileId, Code const targetId) const; CrossSectionType getTabulatedCrossSection(Code const, Code const, HEPEnergyType const) const; diff --git a/examples/cascade_example.cpp b/examples/cascade_example.cpp index 06a3756f4b0adbdc8161ad122987b737476f956a..cf01b33ca499cf8d1df3d61bcc142f0aee921cdf 100644 --- a/examples/cascade_example.cpp +++ b/examples/cascade_example.cpp @@ -146,11 +146,8 @@ int main() { BetheBlochPDG eLoss{showerAxis}; // assemble all processes into an ordered process list - auto sequence = make_sequence( - stackInspect, - make_select([](auto const& particle) { return is_nucleus(particle.getPID()); }, - sibyllNuc, sibyll), - decay, eLoss, cut, trackWriter); + auto sequence = make_sequence(stackInspect, make_sequence(sibyllNuc, sibyll), decay, + eLoss, cut, trackWriter); // define air shower object, run simulation Cascade EAS(env, tracking, sequence, output, stack); diff --git a/examples/corsika.cpp b/examples/corsika.cpp index dbf99a5cba85272435cfd0827862981698a23e39..7df6dcbde54c0d40190da9a377c166d9472c588b 100644 --- a/examples/corsika.cpp +++ b/examples/corsika.cpp @@ -286,8 +286,7 @@ int main(int argc, char** argv) { InteractionCounter sibyllCounted(sibyll); corsika::sibyll::NuclearInteraction sibyllNuc(sibyll, env); InteractionCounter sibyllNucCounted(sibyllNuc); - auto heModelCounted = make_select([](auto const& p) { return is_nucleus(p.getPID()); }, - sibyllNucCounted, sibyllCounted); + auto heModelCounted = make_sequence(sibyllNucCounted, sibyllCounted); corsika::pythia8::Decay decayPythia; diff --git a/examples/mars.cpp b/examples/mars.cpp index a284f1ecd85580ace4ec82867bf5ad8573ea5b05..afa8c71b70b8e2526785312acc38e1c7b684484c 100644 --- a/examples/mars.cpp +++ b/examples/mars.cpp @@ -313,8 +313,7 @@ int main(int argc, char** argv) { InteractionCounter sibyllCounted(sibyll); corsika::sibyll::NuclearInteraction sibyllNuc(sibyll, env); InteractionCounter sibyllNucCounted(sibyllNuc); - auto heModelCounted = make_select([](auto const& p) { return is_nucleus(p.getPID()); }, - sibyllNucCounted, sibyllCounted); + auto heModelCounted = make_sequence(sibyllNucCounted, sibyllCounted); corsika::pythia8::Decay decayPythia; diff --git a/examples/vertical_EAS.cpp b/examples/vertical_EAS.cpp index d6c1af1dd4dada9e68f4adb4d2cec4f92facb42b..6bb97291aa2b2d7d3106fcf68a6b887aaf99c7d9 100644 --- a/examples/vertical_EAS.cpp +++ b/examples/vertical_EAS.cpp @@ -238,10 +238,8 @@ int main(int argc, char** argv) { : cutE_(cutE) {} bool operator()(const Particle& p) const { return (p.getEnergy() < cutE_); } }; - auto hadronSequence = - make_select(EnergySwitch(55_GeV), urqmdCounted, - make_select([](auto const& p) { return is_nucleus(p.getPID()); }, - sibyllNucCounted, sibyllCounted)); + auto hadronSequence = make_select(EnergySwitch(55_GeV), urqmdCounted, + make_sequence(sibyllNucCounted, sibyllCounted)); auto decaySequence = make_sequence(decayPythia, decaySibyll); // directory for outputs diff --git a/tests/modules/testPythia8.cpp b/tests/modules/testPythia8.cpp index 06121eeec3e6c317871320e05a6cfb5b0dcf28c6..d54324be5dc00409defa1fc183c2f545f5263350 100644 --- a/tests/modules/testPythia8.cpp +++ b/tests/modules/testPythia8.cpp @@ -231,11 +231,13 @@ TEST_CASE("Pythia8Interface", "modules") { corsika::pythia8::Interaction collision; - CHECK_THROWS(collision.getCrossSection( - Code::Proton, Code::Iron, - {sqrt(static_pow<2>(Proton::mass) + static_pow<2>(100_GeV)), - {rootCS, {0_eV, 0_eV, 100_GeV}}}, - {Iron::mass, {rootCS, {0_eV, 0_eV, 0_eV}}})); + CHECK(collision.getCrossSection( + Code::Proton, Code::Iron, + {sqrt(static_pow<2>(Proton::mass) + static_pow<2>(100_GeV)), + {rootCS, {0_eV, 0_eV, 100_GeV}}}, + {Iron::mass, {rootCS, {0_eV, 0_eV, 0_eV}}}) / + 1_mb == + Approx(0)); CHECK_THROWS(collision.doInteraction( view, Code::Proton, Code::Iron, diff --git a/tests/modules/testQGSJetII.cpp b/tests/modules/testQGSJetII.cpp index 2a8cd57a8d93f938f75fd0447eb6abae465663b8..40f544798157268b20e02bef6eff04b3f28ec323 100644 --- a/tests/modules/testQGSJetII.cpp +++ b/tests/modules/testQGSJetII.cpp @@ -96,8 +96,8 @@ TEST_CASE("QgsjetII", "[processes]") { corsika::qgsjetII::InteractionModel model; - CHECK_THROWS(model.isValid(Code::Electron, Code::Proton)); - CHECK_THROWS(model.isValid(Code::Proton, Code::Electron)); + CHECK_FALSE(model.isValid(Code::Electron, Code::Proton)); + CHECK_FALSE(model.isValid(Code::Proton, Code::Electron)); } } @@ -193,9 +193,12 @@ TEST_CASE("QgsjetIIInterface", "interaction,processes") { FourMomentum const aP4(100_GeV, {cs, 99_GeV, 0_GeV, 0_GeV}); FourMomentum const bP4(1_TeV, {cs, 0.9_TeV, 0_GeV, 0_GeV}); - CHECK_THROWS(model.getCrossSection(get_nucleus_code(10, 5), - get_nucleus_code(1000, 500), aP4, bP4)); - CHECK_THROWS(model.getCrossSection(Code::Nucleus, Code::Nucleus, aP4, bP4)); + CHECK(model.getCrossSection(get_nucleus_code(10, 5), get_nucleus_code(1000, 500), aP4, + bP4) / + 1_mb == + Approx(0)); + CHECK(model.getCrossSection(Code::Nucleus, Code::Nucleus, aP4, bP4) / 1_mb == + Approx(0)); CHECK_THROWS( model.doInteraction(view, get_nucleus_code(1000, 500), Code::Oxygen, aP4, bP4)); } diff --git a/tests/modules/testSibyll.cpp b/tests/modules/testSibyll.cpp index 957ddac0fe3cde92357934ac0d9f60961b6f0b87..2a19a030b7272d88c2912a7ce163bb0a81e64645 100644 --- a/tests/modules/testSibyll.cpp +++ b/tests/modules/testSibyll.cpp @@ -137,22 +137,22 @@ TEST_CASE("SibyllInterface", "modules") { corsika::sibyll::InteractionModel model; // sibyll only accepts protons or nuclei with 4<=A<=18 as targets - CHECK_THROWS(model.isValid(Code::Proton, Code::Electron, 100_GeV)); - CHECK_NOTHROW(model.isValid(Code::Proton, Code::Hydrogen, 100_GeV)); - CHECK_THROWS(model.isValid(Code::Proton, Code::Deuterium, 100_GeV)); - CHECK_NOTHROW(model.isValid(Code::Proton, Code::Helium, 100_GeV)); - CHECK_THROWS(model.isValid(Code::Proton, Code::Helium3, 100_GeV)); - CHECK_THROWS(model.isValid(Code::Proton, Code::Iron, 100_GeV)); - CHECK_NOTHROW(model.isValid(Code::Proton, Code::Oxygen, 100_GeV)); + CHECK_FALSE(model.isValid(Code::Proton, Code::Electron, 100_GeV)); + CHECK(model.isValid(Code::Proton, Code::Hydrogen, 100_GeV)); + CHECK_FALSE(model.isValid(Code::Proton, Code::Deuterium, 100_GeV)); + CHECK(model.isValid(Code::Proton, Code::Helium, 100_GeV)); + CHECK_FALSE(model.isValid(Code::Proton, Code::Helium3, 100_GeV)); + CHECK_FALSE(model.isValid(Code::Proton, Code::Iron, 100_GeV)); + CHECK(model.isValid(Code::Proton, Code::Oxygen, 100_GeV)); // beam particles - CHECK_THROWS(model.isValid(Code::Electron, Code::Oxygen, 100_GeV)); - CHECK_THROWS(model.isValid(Code::Iron, Code::Oxygen, 100_GeV)); + CHECK_FALSE(model.isValid(Code::Electron, Code::Oxygen, 100_GeV)); + CHECK_FALSE(model.isValid(Code::Iron, Code::Oxygen, 100_GeV)); // energy too low - CHECK_THROWS(model.isValid(Code::Proton, Code::Proton, 9_GeV)); - CHECK_NOTHROW(model.isValid(Code::Proton, Code::Proton, 11_GeV)); + CHECK_FALSE(model.isValid(Code::Proton, Code::Proton, 9_GeV)); + CHECK(model.isValid(Code::Proton, Code::Proton, 11_GeV)); // energy too high - CHECK_THROWS(model.isValid(Code::Proton, Code::Proton, 1000001_GeV)); - CHECK_NOTHROW(model.isValid(Code::Proton, Code::Proton, 999999_GeV)); + CHECK_FALSE(model.isValid(Code::Proton, Code::Proton, 1000001_GeV)); + CHECK(model.isValid(Code::Proton, Code::Proton, 999999_GeV)); // hydrogen target == proton target == neutron target FourMomentum const aP4(100_GeV, {cs, 99_GeV, 0_GeV, 0_GeV}); @@ -262,6 +262,11 @@ TEST_CASE("SibyllInterface", "modules") { MomentumVector const plab = MomentumVector(cs, {P0, 0_eV, 0_eV}); corsika::sibyll::InteractionModel hmodel; NuclearInteractionModel model(hmodel, *env); + + CHECK(model.isValid(Code::Helium, Code::Oxygen, 100_GeV)); + CHECK_FALSE(model.isValid(Code::PiPlus, Code::Oxygen, 100_GeV)); + CHECK_FALSE(model.isValid(Code::Electron, Code::Oxygen, 100_GeV)); + Code const pid = Code::Oxygen; HEPEnergyType const Elab = sqrt(static_pow<2>(P0) + static_pow<2>(get_mass(pid))); FourMomentum const P4(Elab, plab); diff --git a/tests/modules/testUrQMD.cpp b/tests/modules/testUrQMD.cpp index 0cabc8b726a16a133f0c40e8a12f4ac0a689c23b..3b3da197bf501a9fdf73b11fcf851c39fe953182 100644 --- a/tests/modules/testUrQMD.cpp +++ b/tests/modules/testUrQMD.cpp @@ -75,13 +75,13 @@ TEST_CASE("UrQMD") { SECTION("valid") { // this is how it is currently done - CHECK_THROWS(urqmd.isValid(Code::K0, Code::Proton)); - CHECK_THROWS(urqmd.isValid(Code::DPlus, Code::Proton)); - CHECK_THROWS(urqmd.isValid(Code::Electron, Code::Proton)); - CHECK_THROWS(urqmd.isValid(Code::Proton, Code::Electron)); - CHECK_THROWS(urqmd.isValid(Code::Oxygen, Code::Oxygen)); - CHECK_THROWS(urqmd.isValid(Code::PiPlus, Code::Omega)); - CHECK_THROWS( + CHECK_FALSE(urqmd.isValid(Code::K0, Code::Proton)); + CHECK_FALSE(urqmd.isValid(Code::DPlus, Code::Proton)); + CHECK_FALSE(urqmd.isValid(Code::Electron, Code::Proton)); + CHECK_FALSE(urqmd.isValid(Code::Proton, Code::Electron)); + CHECK_FALSE(urqmd.isValid(Code::Oxygen, Code::Oxygen)); + CHECK_FALSE(urqmd.isValid(Code::PiPlus, Code::Omega)); + CHECK_FALSE( urqmd.isValid(Code::PiPlus, Code::Proton)); // Proton is not a valid target.... CHECK_NOTHROW(urqmd.isValid(Code::Proton, Code::Oxygen));