diff --git a/corsika/detail/modules/proposal/InteractionModel.inl b/corsika/detail/modules/proposal/InteractionModel.inl index 0c92b39b9684fa244d1bcb5fb1ae611f9f073194..2838c1676035cdb672313b48dea43f7bbfcaac1b 100644 --- a/corsika/detail/modules/proposal/InteractionModel.inl +++ b/corsika/detail/modules/proposal/InteractionModel.inl @@ -22,9 +22,9 @@ namespace corsika::proposal { template <typename THadronicModel> template <typename TEnvironment> inline InteractionModel<THadronicModel>::InteractionModel(TEnvironment const& _env, - THadronicModel& hadint) + THadronicModel& _hadint) : ProposalProcessBase(_env) - , hadronicInteraction_(hadint) {} + , HadronicPhotonModel<THadronicModel>(_hadint) {} template <typename THadronicModel> inline void InteractionModel<THadronicModel>::buildCalculator( @@ -107,14 +107,11 @@ namespace corsika::proposal { auto const photonEnergy = projectile.getEnergy() * v; - if (type == PROPOSAL::InteractionType::Photonuclear) + if (type == PROPOSAL::InteractionType::Photonuclear) { CORSIKA_LOG_INFO( "HE photo-hadronic interaction! Energy = " "{} GeV, v = {}, v * E = {}", projectile.getEnergy() / 1_GeV, v, photonEnergy); - - if (type == PROPOSAL::InteractionType::Photonuclear && - photonEnergy > heHadronicModelThresholdLab_) { auto const photonDirection = projectileP4.getSpaceLikeComponents() .normalized(); // photon collinear with projectile @@ -143,45 +140,54 @@ namespace corsika::proposal { return ProcessReturn::Ok; } + template <typename THadronicModel> + inline HadronicPhotonModel<THadronicModel>::HadronicPhotonModel(THadronicModel& _hadint) + : heHadronicInteraction_(_hadint){}; + template <typename THadronicModel> template <typename TStackView> - inline ProcessReturn InteractionModel<THadronicModel>::doHadronicPhotonInteraction( + inline ProcessReturn HadronicPhotonModel<THadronicModel>::doHadronicPhotonInteraction( TStackView& view, CoordinateSystemPtr const& labCS, FourMomentum const& photonP4, Code const& targetId) { - CORSIKA_LOG_INFO( - "HE photo-hadronic interaction! calling hadronic interaction model.."); - - // copy from sibyll::NuclearInteractionModel - // temporarily add to stack, will be removed after interaction in DoInteraction - typename TStackView::inner_stack_value_type photonStack; - Point const pDummy(labCS, {0_m, 0_m, 0_m}); - TimeType const tDummy = 0_ns; - Code const hadPhotonCode = Code::Rho0; // stand in for hadronic-photon - // target at rest - FourMomentum const targetP4(get_mass(targetId), - MomentumVector(labCS, {0_GeV, 0_GeV, 0_GeV})); - auto hadronicPhoton = photonStack.addParticle( - std::make_tuple(hadPhotonCode, photonP4.getTimeLikeComponent(), - photonP4.getSpaceLikeComponents().normalized(), pDummy, tDummy)); - hadronicPhoton.setNode(view.getProjectile().getNode()); - // create inelastic interaction of the hadronic photon - // create new StackView for the photon - TStackView photon_secondaries(hadronicPhoton); - - // call inner hadronic event generator - CORSIKA_LOG_TRACE("calling HadronicInteraction..."); - CORSIKA_LOG_INFO("{} + {} interactions. Ekinlab = {}", hadPhotonCode, targetId, - photonP4.getTimeLikeComponent() / 1_GeV); - hadronicInteraction_.doInteraction(photon_secondaries, hadPhotonCode, targetId, - photonP4, targetP4); - for (const auto& pSec : photon_secondaries) { - auto const p3lab = pSec.getMomentum(); - Code const pid = pSec.getPID(); - HEPEnergyType const secEkin = - calculate_kinetic_energy(p3lab.getNorm(), get_mass(pid)); - view.addSecondary(std::make_tuple(pid, secEkin, p3lab.normalized())); + if (photonP4.getTimeLikeComponent() > heHadronicModelThresholdLab_) { + CORSIKA_LOG_INFO( + "HE photo-hadronic interaction! calling hadronic interaction model.."); + + // copy from sibyll::NuclearInteractionModel + // temporarily add to stack, will be removed after interaction in DoInteraction + typename TStackView::inner_stack_value_type photonStack; + Point const pDummy(labCS, {0_m, 0_m, 0_m}); + TimeType const tDummy = 0_ns; + Code const hadPhotonCode = Code::Rho0; // stand in for hadronic-photon + // target at rest + FourMomentum const targetP4(get_mass(targetId), + MomentumVector(labCS, {0_GeV, 0_GeV, 0_GeV})); + auto hadronicPhoton = photonStack.addParticle(std::make_tuple( + hadPhotonCode, photonP4.getTimeLikeComponent(), + photonP4.getSpaceLikeComponents().normalized(), pDummy, tDummy)); + hadronicPhoton.setNode(view.getProjectile().getNode()); + // create inelastic interaction of the hadronic photon + // create new StackView for the photon + TStackView photon_secondaries(hadronicPhoton); + + // call inner hadronic event generator + CORSIKA_LOG_TRACE("calling HadronicInteraction..."); + CORSIKA_LOG_INFO("{} + {} interactions. Ekinlab = {}", hadPhotonCode, targetId, + photonP4.getTimeLikeComponent() / 1_GeV); + heHadronicInteraction_.doInteraction(photon_secondaries, hadPhotonCode, targetId, + photonP4, targetP4); + for (const auto& pSec : photon_secondaries) { + auto const p3lab = pSec.getMomentum(); + Code const pid = pSec.getPID(); + HEPEnergyType const secEkin = + calculate_kinetic_energy(p3lab.getNorm(), get_mass(pid)); + view.addSecondary(std::make_tuple(pid, secEkin, p3lab.normalized())); + } + CORSIKA_LOG_INFO("number of particles produced: {}", view.getEntries()); + } else { + CORSIKA_LOG_INFO( + "LE photo-hadronic interaction! production of secondaries not implemented.."); } - CORSIKA_LOG_INFO("number of particles produced: {}", view.getEntries()); return ProcessReturn::Ok; } diff --git a/corsika/modules/proposal/InteractionModel.hpp b/corsika/modules/proposal/InteractionModel.hpp index e5663108d194b824ada0f08f2009622484976169..9c3381db2a527d4fbbd010599e65a7025214168d 100644 --- a/corsika/modules/proposal/InteractionModel.hpp +++ b/corsika/modules/proposal/InteractionModel.hpp @@ -33,7 +33,26 @@ namespace corsika::proposal { //! template <class THadronicModel> - class InteractionModel : public ProposalProcessBase { + class HadronicPhotonModel { + public: + HadronicPhotonModel(THadronicModel&); + //! + //! Calculate produce the hadronic secondaries in a hadronic photon interaction and + //! store them on the particle stack. + //! + template <typename TSecondaryView> + ProcessReturn doHadronicPhotonInteraction(TSecondaryView&, CoordinateSystemPtr const&, + FourMomentum const&, Code const&); + + private: + THadronicModel& heHadronicInteraction_; + static HEPEnergyType constexpr heHadronicModelThresholdLab_ = + 80. * 1e9 * electronvolt; + }; + + template <class THadronicModel> + class InteractionModel : public ProposalProcessBase, + public HadronicPhotonModel<THadronicModel> { enum { eSECONDARIES, eINTERACTION }; using calculator_t = std::tuple<std::unique_ptr<PROPOSAL::SecondariesCalculator>, @@ -64,25 +83,12 @@ namespace corsika::proposal { ProcessReturn doInteraction(TSecondaryView&, Code const projectileId, FourMomentum const& projectileP4); - //! - //! Calculate produce the hadronic secondaries in a hadronic photon interaction and - //! store them on the particle stack. - //! - template <typename TSecondaryView> - ProcessReturn doHadronicPhotonInteraction(TSecondaryView&, CoordinateSystemPtr const&, - FourMomentum const&, Code const&); - //! //! Calculates and returns the cross section. //! template <typename TParticle> CrossSectionType getCrossSection(TParticle const& p, Code const projectileId, FourMomentum const& projectileP4); - - private: - THadronicModel& hadronicInteraction_; - static HEPEnergyType constexpr heHadronicModelThresholdLab_ = - 80. * 1e9 * electronvolt; }; } // namespace corsika::proposal diff --git a/tests/modules/testProposal.cpp b/tests/modules/testProposal.cpp index 4575eeb08f32fbf0e4063fec81606834d5412c2a..8718f1c52966ef52791bfa66b6e24b50351a0711 100644 --- a/tests/modules/testProposal.cpp +++ b/tests/modules/testProposal.cpp @@ -70,7 +70,20 @@ TEST_CASE("ProposalInterface", "modules") { CHECK(emModel.getCrossSection(particle, Code::Proton, P4) == 0_mb); } - SECTION("InteractionInterface - hadronic photon interaction") { + SECTION("InteractionInterface - LE hadronic photon interaction") { + auto& stack = *stackPtr; + // auto particle = stack.first(); + FourMomentum P4(10_GeV, {cs, {10_GeV, 0_eV, 0_eV}}); + // finish successfully + CHECK(emModel.doHadronicPhotonInteraction(view, cs, P4, Code::Oxygen) == + ProcessReturn::Ok); + // no LE interactions + CHECK(stack.getEntries() == 1); + CORSIKA_LOG_INFO("Number of particles produced in hadronic photon interaction: {}", + stack.getEntries()-1); + } + + SECTION("InteractionInterface - HE hadronic photon interaction") { auto& stack = *stackPtr; // auto particle = stack.first(); FourMomentum P4(100_TeV, {cs, {100_TeV, 0_eV, 0_eV}}); @@ -79,6 +92,6 @@ TEST_CASE("ProposalInterface", "modules") { ProcessReturn::Ok); CHECK(stack.getEntries() > 1); CORSIKA_LOG_INFO("Number of particles produced in hadronic photon interaction: {}", - stack.getEntries()); + stack.getEntries()-1); } } \ No newline at end of file