diff --git a/corsika/detail/modules/epos/Interaction.inl b/corsika/detail/modules/epos/Interaction.inl index a28c6c8ac5e421172177ffd13ea958a89c1afa19..34e6031090473d070e615107ab90fe3f1fe51072 100644 --- a/corsika/detail/modules/epos/Interaction.inl +++ b/corsika/detail/modules/epos/Interaction.inl @@ -28,8 +28,10 @@ using SetupParticle = setup::Stack::stack_iterator_type; namespace corsika::epos { - inline Interaction::Interaction(const std::string& dataPath, const bool epos_printout_on) - : data_path_(dataPath), epos_listing_(epos_printout_on) { + inline Interaction::Interaction(const std::string& dataPath, + const bool epos_printout_on) + : data_path_(dataPath) + , epos_listing_(epos_printout_on) { if (dataPath == "") { if (std::getenv("CORSIKA_DATA")) { data_path_ = std::string(std::getenv("CORSIKA_DATA")) + "/EPOS/"; @@ -44,6 +46,20 @@ namespace corsika::epos { initialize_eposlhc_c7(); initialized = true; } + set_particles_stable(); + } + + inline void Interaction::set_particles_stable() const { + CORSIKA_LOGGER_DEBUG(logger_, + "set all particles known to CORSIKA stable inside EPOS.."); + for (auto& p : get_all_particles()) { + if (!is_hadron(p)) continue; + int const eid = convertToEposRaw(p); + if (eid != 0) { + ::epos::nodcy_.nrnody = ::epos::nodcy_.nrnody + 1; + ::epos::nodcy_.nody[::epos::nodcy_.nrnody - 1] = eid; + } + } } inline void Interaction::initialize_eposlhc_c7() const { @@ -55,7 +71,7 @@ namespace corsika::epos { ::epos::aaset_(iarg); //::epos::atitle_(); - ::epos::prnt1_.ish = 0; // debug level in epos + ::epos::prnt1_.ish = 0; // debug level in epos ::epos::files_.ifch = 6; // output unit //::epos::prnt1_.iecho = 1; @@ -114,8 +130,6 @@ namespace corsika::epos { strcpy(::epos::fname_.fncs, CS.data); ::epos::nfname_.nfncs = CS.length; - - // dummy event // ::epos::hadr25_.idprojin = 1120; // ::epos::hadr25_.idtargin = 1120; @@ -133,10 +147,13 @@ namespace corsika::epos { //::epos::ainit_(); // dummy event (prepare commons) - initialize_event_Lab(Code::Proton, Code::Argon, 100_GeV); + initialize_event_Lab(Code::Iron, Iron::nucleus_A, Iron::nucleus_Z, Code::Argon, + Argon::nucleus_A, Argon::nucleus_Z, 100_GeV); } - inline void Interaction::initialize_event_CoM(Code const idBeam, Code const idTarget, + inline void Interaction::initialize_event_CoM(Code const idBeam, int const iBeamA, + int const iBeamZ, Code const idTarget, + int const iTargetA, int const iTargetZ, HEPEnergyType const Ecm) const { CORSIKA_LOGGER_TRACE(logger_, "initialize event in CoM frame!" @@ -156,11 +173,13 @@ namespace corsika::epos { "Elab={}", ::epos::enrgy_.ecms, ::epos::enrgy_.elab); - configure_particles(idBeam, idTarget); + configure_particles(idBeam, iBeamA, iBeamZ, idTarget, iTargetA, iTargetZ); ::epos::ainit_(); } - inline void Interaction::initialize_event_Lab(Code const idBeam, Code const idTarget, + inline void Interaction::initialize_event_Lab(Code const idBeam, int const iBeamA, + int const iBeamZ, Code const idTarget, + int const iTargetA, int const iTargetZ, HEPEnergyType const Plab) const { CORSIKA_LOGGER_TRACE(logger_, "initialize event in lab. frame!" @@ -171,7 +190,7 @@ namespace corsika::epos { ::epos::enrgy_.elab = -1.; ::epos::enrgy_.ekin = -1.; ::epos::hadr1_.pnll = -1.; - + // hadron-nucleon momentum ::epos::hadr1_.pnll = float(Plab / 1_GeV); @@ -182,43 +201,34 @@ namespace corsika::epos { "Pnll={}", ::epos::enrgy_.ecms, ::epos::enrgy_.elab, ::epos::hadr1_.pnll); - configure_particles(idBeam, idTarget); + configure_particles(idBeam, iBeamA, iBeamZ, idTarget, iTargetA, iTargetZ); ::epos::ainit_(); } - inline void Interaction::configure_particles(Code const idBeam, - Code const idTarget) const { + inline void Interaction::configure_particles(Code const idBeam, int const iBeamA, + int const iBeamZ, Code const idTarget, + int const iTargetA, + int const iTargetZ) const { CORSIKA_LOGGER_TRACE(logger_, "configure_particles: setting " "Beam={} " "Target={}", idBeam, idTarget); - // idprojin = idtrafo("pdg","nxs",idpro) - // if (idpro.ne.2212) izpro = -1 - // laproj = izpro !proj Z - // maproj = iapro !proj A - if(is_nucleus(idBeam)){ + if (is_nucleus(idBeam)) { ::epos::hadr25_.idprojin = convertToEposRaw(Code::Proton); - ::epos::nucl1_.laproj = get_nucleus_Z(idBeam); - ::epos::nucl1_.maproj = get_nucleus_A(idBeam); + ::epos::nucl1_.laproj = iBeamZ; // get_nucleus_Z(idBeam); + ::epos::nucl1_.maproj = iBeamA; // get_nucleus_A(idBeam); } else { ::epos::hadr25_.idprojin = convertToEposRaw(idBeam); - // if(idBeam!=Code::Proton) - // ::epos::nucl1_.laproj = -1; - // else - // ::epos::nucl1_.laproj = 1; ::epos::nucl1_.laproj = -1; - ::epos::nucl1_.maproj = 1; + ::epos::nucl1_.maproj = 1; } - - // idtargin = idtrafo("pdg","nxs",idtar) - // latarg = iztar !targ Z - // matarg = iatar !targ A + if (is_nucleus(idTarget)) { ::epos::hadr25_.idtargin = convertToEposRaw(Code::Proton); - ::epos::nucl1_.matarg = get_nucleus_A(idTarget); - ::epos::nucl1_.latarg = get_nucleus_Z(idTarget); + ::epos::nucl1_.matarg = iTargetA; // get_nucleus_A(idTarget); + ::epos::nucl1_.latarg = iTargetZ; // get_nucleus_Z(idTarget); } else if (idTarget == Code::Proton || idTarget == Code::Hydrogen) { ::epos::hadr25_.idtargin = convertToEposRaw(Code::Proton); ::epos::nucl1_.matarg = 1; @@ -243,12 +253,22 @@ namespace corsika::epos { ::epos::nucl1_.latarg, ::epos::nucl1_.matarg); } - inline Interaction::~Interaction() { - CORSIKA_LOGGER_DEBUG(logger_, "n={} ", count_); + inline Interaction::~Interaction() { CORSIKA_LOGGER_DEBUG(logger_, "n={} ", count_); } + + inline std::tuple<corsika::CrossSectionType, corsika::CrossSectionType> + Interaction::getCrossSection(corsika::Code const BeamId, corsika::Code const TargetId, + const corsika::HEPEnergyType EnergyCOM) const { + if (!is_nucleus(BeamId)) + return getCrossSection(BeamId, 1, 1, TargetId, get_nucleus_A(TargetId), + get_nucleus_Z(TargetId), EnergyCOM); + else + throw("nuclear projecile, call getCrossSection with : BeamId, BeamA, BeamZ, ..."); } inline std::tuple<corsika::CrossSectionType, corsika::CrossSectionType> - Interaction::getCrossSection(const corsika::Code BeamId, const corsika::Code TargetId, + Interaction::getCrossSection(corsika::Code const BeamId, int const BeamA, + int const BeamZ, corsika::Code const TargetId, + int const TargetA, int const TargetZ, const corsika::HEPEnergyType EnergyCOM) const { CORSIKA_LOGGER_DEBUG(logger_, "getCrossSection: input:" @@ -266,29 +286,36 @@ namespace corsika::epos { // reset beam particle // (1: proton-like, 2: pion-like, 3:kaon-like) if (iBeam == 1) - initialize_event_CoM(Code::Proton, TargetId, EnergyCOM); + initialize_event_CoM(Code::Proton, BeamA, BeamZ, TargetId, TargetA, TargetZ, + EnergyCOM); else if (iBeam == 2) - initialize_event_CoM(Code::PiPlus, TargetId, EnergyCOM); + initialize_event_CoM(Code::PiPlus, BeamA, BeamZ, TargetId, TargetA, TargetZ, + EnergyCOM); + else if (iBeam == 3) + initialize_event_CoM(Code::KPlus, BeamA, BeamZ, TargetId, TargetA, TargetZ, + EnergyCOM); else - initialize_event_CoM(Code::KPlus, TargetId, EnergyCOM); + throw std::runtime_error( + "getCrossSection: interaction of beam hadron not defined in " + "Epos!"); //::epos::xsigma_(); double sigProd, sigEla = 0; float sigTot1, sigProd1, sigEla1, sigCut1 = 0; - if (is_nucleus(TargetId) || is_nucleus(BeamId)) { - ::epos::crseaaepos_(sigTot1, sigProd1, sigCut1, sigEla1); - //sigProd = ::epos::hadr5_.sigineaa; - //sigEla = ::epos::hadr5_.sigelaaa; - sigProd = sigProd1; - sigEla = sigEla1; - } else { + if (!is_nucleus(TargetId) && !is_nucleus(BeamId)) { sigProd = ::epos::hadr5_.sigine; sigEla = ::epos::hadr5_.sigela; + } else { + ::epos::crseaaepos_(sigTot1, sigProd1, sigCut1, sigEla1); + // sigProd = ::epos::hadr5_.sigineaa; + // sigEla = ::epos::hadr5_.sigelaaa; + sigProd = sigProd1; + sigEla = sigEla1; } // calculate cross section - //float sigTot, sigProd, sigEla, sigCut = 0; + // float sigTot, sigProd, sigEla, sigCut = 0; //::epos::crseaaepos_(sigTot, sigProd, sigCut, sigEla); CORSIKA_LOGGER_DEBUG(logger_, @@ -300,7 +327,7 @@ namespace corsika::epos { return std::make_tuple(sigProd * 1_mb, sigEla * 1_mb); // read cross section from epos internal tables - + // int Abeam; // int iBeamId; // if(is_nucleus(BeamId)){ @@ -312,9 +339,9 @@ namespace corsika::epos { // } // int Atarget; // if(is_nucleus(TargetId)) - // Atarget = get_nucleus_A(TargetId); + // Atarget = get_nucleus_A(TargetId); // else - + // float Ekin = (EnergyLab-get_mass(BeamId)) / 1_GeV; // float sigProdEpos = ::epos::eposcrse_(Ekin,iBeamId); // float sigElaEpos = ::epos::eposelacrse_(); @@ -336,6 +363,15 @@ namespace corsika::epos { projectile.getPID()); if (kInteraction) { + + // define projectile nuclei + int beamA = 1; + int beamZ = 1; + if (is_nucleus(corsikaBeamId)) { + beamA = projectile.getNuclearA(); + beamZ = projectile.getNuclearZ(); + } + // get target from environment /* the target should be defined by the Environment, @@ -348,7 +384,7 @@ namespace corsika::epos { // assume target is at rest!! MomentumVector pTarget(labCS, {0_GeV, 0_GeV, 0_GeV}); - + // total momentum and energy HEPEnergyType Elab = projectile.getEnergy() + constants::nucleonMass; MomentumVector pTotLab(labCS, {0_GeV, 0_GeV, 0_GeV}); @@ -365,7 +401,9 @@ namespace corsika::epos { si::CrossSectionType weightedProdCrossSection = mediumComposition.getWeightedSum( [=](corsika::Code targetID) -> si::CrossSectionType { - return std::get<0>(this->getCrossSection(corsikaBeamId, targetID, ECoM)); + return std::get<0>(this->getCrossSection(corsikaBeamId, beamA, beamZ, + targetID, get_nucleus_A(targetID), + get_nucleus_Z(targetID), ECoM)); }); CORSIKA_LOGGER_DEBUG(logger_, "InteractionLength: weighted CrossSection (mb): {} ", @@ -389,8 +427,10 @@ namespace corsika::epos { auto const projectile = view.getProjectile(); auto const corsikaBeamId = projectile.getPID(); - if (corsika::epos::canInteract(corsikaBeamId)) { + CORSIKA_LOGGER_DEBUG(logger_, "DoInteraction: {} interaction ", corsikaBeamId); + if (corsika::epos::canInteract(corsikaBeamId)) { + count_ = count_ + 1; // position and time of interaction, not used in Epos Point const pOrig = projectile.getPosition(); TimeType const tOrig = projectile.getTime(); @@ -405,64 +445,21 @@ namespace corsika::epos { CoordinateSystemPtr const zAxisFrame = make_rotationToZ(originalCS, pProjectileLab); int beamA = 1; - if (is_nucleus(corsikaBeamId)) beamA = projectile.getNuclearA(); + int beamZ = 1; + if (is_nucleus(corsikaBeamId)) { + beamA = projectile.getNuclearA(); + beamZ = projectile.getNuclearZ(); + CORSIKA_LOGGER_DEBUG(logger_, "A={}, Z={} ", beamA, beamZ); + } HEPEnergyType const projectileMomentumLabPerNucleon = projectileMomentum / beamA; - CORSIKA_LOGGER_DEBUG(logger_, "DoInteraction: {} interaction ", corsikaBeamId); - // define target - // for Sibyll is always a single nucleon - // FOR NOW: target is always at rest - const auto eTargetLab = 0_GeV + constants::nucleonMass; - const auto pTargetLab = MomentumVector(originalCS, 0_GeV, 0_GeV, 0_GeV); - const FourVector PtargLab(eTargetLab, pTargetLab); - - CORSIKA_LOGGER_DEBUG(logger_, - "Interaction: ebeam lab: {} GeV" - "Interaction: pbeam lab: {} GeV", - eProjectileLab / 1_GeV, pProjectileLab.getComponents()); - CORSIKA_LOGGER_DEBUG(logger_, - "Interaction: etarget lab: {} GeV " - "Interaction: ptarget lab: {} GeV", - eTargetLab / 1_GeV, pTargetLab.getComponents() / 1_GeV); - - const FourVector PprojLab(eProjectileLab, pProjectileLab); - - // define target kinematics in lab frame - // define boost to and from CoM frame - // CoM frame definition in Sibyll projectile: +z - COMBoost const boost(PprojLab, constants::nucleonMass); - auto const& csPrime = boost.getRotatedCS(); - - // just for show: - // boost projecticle - [[maybe_unused]] auto const PprojCoM = boost.toCoM(PprojLab); - - // boost target - [[maybe_unused]] auto const PtargCoM = boost.toCoM(PtargLab); - - CORSIKA_LOGGER_DEBUG( - logger_, - "Interaction: ebeam CoM: {} GeV " - "Interaction: pbeam CoM: {} GeV ", - PprojCoM.getTimeLikeComponent() / 1_GeV, - PprojCoM.getSpaceLikeComponents().getComponents(csPrime) / 1_GeV); - CORSIKA_LOGGER_DEBUG( - logger_, - "Interaction: etarget CoM: {} GeV " - "Interaction: ptarget CoM: {} GeV ", - PtargCoM.getTimeLikeComponent() / 1_GeV, - PtargCoM.getSpaceLikeComponents().getComponents(csPrime) / 1_GeV); - - CORSIKA_LOGGER_DEBUG(logger_, "Interaction: position of interaction: {} ", - pOrig.getCoordinates()); - CORSIKA_LOGGER_DEBUG(logger_, "Interaction: time: {} ", tOrig); - - HEPEnergyType Etot = eProjectileLab + eTargetLab; - MomentumVector Ptot = projectile.getMomentum(); + auto const eTargetLab = 0_GeV + constants::nucleonMass; + HEPEnergyType const Etot = eProjectileLab + eTargetLab; // invariant mass, i.e. cm. energy - HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.getSquaredNorm()); + HEPEnergyType const Ecm = + sqrt((Etot + projectileMomentum) * (Etot - projectileMomentum)); // sample target mass number auto const* currentNode = projectile.getNode(); @@ -480,58 +477,26 @@ namespace corsika::epos { for (size_t i = 0; i < compVec.size(); ++i) { auto const targetId = compVec[i]; [[maybe_unused]] auto const [sigProd, sigEla] = - getCrossSection(corsikaBeamId, targetId, Ecm); + getCrossSection(corsikaBeamId, beamA, beamZ, targetId, + get_nucleus_A(targetId), get_nucleus_Z(targetId), Ecm); cross_section_of_components[i] = sigProd; } const auto targetCode = mediumComposition.sampleTarget(cross_section_of_components, RNG_); - CORSIKA_LOGGER_DEBUG(logger_, "Interaction: target selected: {} ", targetCode); - - initialize_event_Lab(corsikaBeamId, targetCode, projectileMomentumLabPerNucleon); + CORSIKA_LOGGER_DEBUG(logger_, "target selected: {} ", targetCode); // // from corsika7 interface // // NEXLNK-part - // // projectile - // ::epos::hadr25_.idprojin = - // convertToEposRaw(corsikaBeamId); // 1120 ; // id "NEXUS code" - // ::epos::nucl1_.laproj = -1; // Z (-1 for hadron) - // ::epos::nucl1_.maproj = 1; // A - - // // target - // int targetMassNumber = 1; // proton - // if (is_nucleus(targetCode)) { // nucleus - // targetMassNumber = get_nucleus_A(targetCode); - // if (targetMassNumber > maxTargetMassNumber_) - // throw std::runtime_error("Epos target mass outside range."); - // ::epos::nucl1_.matarg = targetMassNumber; - // ::epos::nucl1_.latarg = get_nucleus_Z(targetCode); - // } else { - // if (targetCode != Proton::code && targetCode != Neutron::code) - // throw std::runtime_error("Epos target not possible."); - // // proton or neutron target - // ::epos::hadr25_.idtargin = convertToEposRaw(targetCode); - // if (targetCode == Proton::code) - // ::epos::nucl1_.latarg = 1; // Z - // else - // ::epos::nucl1_.latarg = -1; // Z (-1 with id 1220 for neutron) - // ::epos::nucl1_.matarg = 1; // A - // } - // CORSIKA_LOG_DEBUG("Interaction: target epos code/A: {}", targetMassNumber); - - // // hadron-nucleon momentum - // ::epos::hadr1_.pnll = float(projectileMomentumLabPerNucleon / 1_GeV); // float(200); - - // // C SET ENGY NEGATIVE TO FORCE CALCULATION IN LAB FRAME - // ::epos::lept1_.engy = -1.; - // ::epos::enrgy_.ecms = -1.; - // ::epos::enrgy_.elab = -1.; - // ::epos::enrgy_.ekin = -1.; - - // // C INTIALIZE ENERGY AND PARTICLE DEPENDENT PORTION OF EPOS/NEXUS - // // C AT THE FIRST CALL: READ ALSO DATA SETS - // ::epos::ainit_(); + int targetA = 1; + int targetZ = 1; + if (is_nucleus(targetCode)) { + targetA = get_nucleus_A(targetCode); + targetZ = get_nucleus_Z(targetCode); + } + initialize_event_Lab(corsikaBeamId, beamA, beamZ, targetCode, targetA, targetZ, + projectileMomentumLabPerNucleon); // create event int iarg = 1; @@ -549,27 +514,16 @@ namespace corsika::epos { // secondaries EposStack es; CORSIKA_LOGGER_DEBUG(logger_, "number of particles: {}", es.getSize()); - // int i=-1; for (auto& psec : es) { - //++i; if (!psec.isFinal()) continue; - // CORSIKA_LOG_DEBUG("EPOS: i, id, energy, mass, type, state: {} {} {} {} {}", i, - // ::epos::cptl_.idptl[i], ::epos::cptl_.pptl[3][i], - // ::epos::cptl_.pptl[4][i], ::epos::cptl_.ityptl[i], - // ::epos::cptl_.istptl[i]); - // CORSIKA_LOG_DEBUG("id, energy: {} {}", psec.getPID(), psec.getEnergy()); - // int id = abs(static_cast<int>(psec.getPID())); - // CORSIKA_LOG_DEBUG("epos id to pdg: {}", - // ::epos::idtrafo_("nxs", "pdg", id)); - auto momentum = psec.getMomentum(zAxisFrame); auto const energy = psec.getEnergy(); momentum.rebase(originalCS); // transform back into standard lab frame auto const pid = corsika::epos::convertFromEpos(psec.getPID()); - CORSIKA_LOGGER_DEBUG(logger_, + CORSIKA_LOGGER_TRACE(logger_, " id= {}" " p= {}", pid, momentum.getComponents() / 1_GeV); @@ -584,63 +538,8 @@ namespace corsika::epos { ", Elab_final={}" ", Plab_final={}", Elab_final / 1_GeV, (Plab_final / 1_GeV).getComponents()); - } - - /* - maproj=maprojxs - laproj=laprojxs - matarg=matargxs - latarg=latargxs - idproj=idprojxs - idtarg=idtargxs - amproj=xsamproj - amtarg=xsamtarg - call idspin(idproj,ispin,jspin,istra) - isoproj=sign(1,idproj)*ispin - call idspin(idtarg,ispin,jspin,istra) - isotarg=sign(1,idtarg)*ispin - - engy=sngl(xsengy) - elab=sngl(xselab) - ecms=sngl(xsecms) - ekin=sngl(xsekin) - pnll=sngl(xspnll) - pnullx=sngl(xspnullx) - yhaha=sngl(xsyhaha) - ypjtl=sngl(xsypjtl) - detap=xsdetap - detat=xsdetat - tpro=xstpro - zpro=xszpro - ttar=xsttar - ztar=xsztar - -c xsbminim=dble(bminim) !not needed and can interfer with other MC -c xsbmaxim=dble(bmaxim) - - call iclass(idproj,iclpro) - call iclass(idtarg,icltar) - call emsini(engy,idproj,idtarg) - call paramini(1) - bkmxndif=conbmxndif() - bkmx=conbmx() - xsbkmx=dble(bkmx) - - if(maproj.gt.1.or.matarg.gt.1)then - xsbmax=xsrmproj+xsrmtarg - else - xsbmax=xsbkmx - endif - - bimevt=-1 - bmax=sngl(xsbmax) - rmproj=sngl(xsrmproj) - rmtarg=sngl(xsrmtarg) - rcproj=xsrcproj - rctarg=xsrctarg - call xsigma !set some variabkle according to xs - if(idtarg.eq.0)idtarg=1120 !air = nucleus - - */ + } else + CORSIKA_LOGGER_WARN( + logger_, "Projectile not configured for interaction! This is likely an error!"); } } // namespace corsika::epos diff --git a/corsika/modules/epos/Interaction.hpp b/corsika/modules/epos/Interaction.hpp index e3ed357b3a830d5e3f8e6f78f7351484816f7029..65838d5df3fac706f547769769ed8b494a392803 100644 --- a/corsika/modules/epos/Interaction.hpp +++ b/corsika/modules/epos/Interaction.hpp @@ -28,6 +28,10 @@ namespace corsika::epos { //! returns production and elastic cross section for hadrons in epos. Inputs are: //! CorsikaId of beam particle, CorsikaId of target particle, center-of-mass energy. //! Allowed targets are: nuclei or single nucleons (p,n,hydrogen). + std::tuple<CrossSectionType, CrossSectionType> getCrossSection( + Code const, int const, int const, Code const, int const, int const, + HEPEnergyType const) const; + std::tuple<CrossSectionType, CrossSectionType> getCrossSection( Code const, Code const, HEPEnergyType const) const; @@ -51,10 +55,14 @@ namespace corsika::epos { } void initialize_eposlhc_c7() const; - void initialize_event_CoM(Code const, Code const, HEPEnergyType const) const; - void initialize_event_Lab(Code const, Code const, HEPEnergyType const) const; - void configure_particles(Code const, Code const) const; - + void initialize_event_CoM(Code const, int const, int const, Code const, int const, + int const, HEPEnergyType const) const; + void initialize_event_Lab(Code const, int const, int const, Code const, int const, + int const, HEPEnergyType const) const; + void configure_particles(Code const, int const, int const, Code const, int const, + int const) const; + void set_particles_stable() const; + private: default_prng_type& RNG_ = RNGManager::getInstance().getRandomStream("epos"); std::shared_ptr<spdlog::logger> logger_ = get_logger("corsika_epos_Interaction"); diff --git a/modules/epos/epos.hpp b/modules/epos/epos.hpp index 8b299204630e36a255174c44f95d7c80b0115a91..d8b77d3593c4eac1725a994b1a019ce3805e9d9b 100644 --- a/modules/epos/epos.hpp +++ b/modules/epos/epos.hpp @@ -480,19 +480,27 @@ namespace epos { float sigdd; } hadr5_; - - /** - Small helper class to provide a data-directory name in the format eposlhc expects - */ - class datadir { - private: - datadir operator=(const std::string& dir); - datadir operator=(const datadir&); - - public: - datadir(const std::string& dir); - char data[500]; - int length; + // integer mxnody,nrnody,nody + // parameter(mxnody=200) + // common/nodcy/nrnody,nody(mxnody) + unsigned int constexpr mxnody = 200; + extern struct { + int nrnody; + int nody[mxnody]; + } nodcy_; + + /** + Small helper class to provide a data-directory name in the format eposlhc expects + */ + class datadir { + private: + datadir operator=(const std::string& dir); + datadir operator=(const datadir&); + + public: + datadir(const std::string& dir); + char data[500]; + int length; }; } } // namespace epos diff --git a/src/modules/epos/code_generator.py b/src/modules/epos/code_generator.py index a47b4ec93a4a6de15f257c576566b390e26d8ea2..74d2e05e20c869028e0f474290442f0735852907 100755 --- a/src/modules/epos/code_generator.py +++ b/src/modules/epos/code_generator.py @@ -41,8 +41,28 @@ def read_epos_codes(filename, particle_db): except KeyError as e: raise Exception("Identifier '{:s}' not found in particle_db".format(identifier)) + +def set_default_epos_definition(particle_db): + ''' + Also particles not explicitly known by QGSJetII may in fact interact via mapping + to cross section types (xsType) and hadron type (hadronType) + + This is achieved here. + The function return nothing, but modified the input particle_db by adding the + fields 'xsType' and 'hadronType' + ''' + for identifier, pData in particle_db.items(): + # the cross-section types + xsType = "CannotInteract" + hadronType = "UndefinedType" + if (pData['isNucleus']): + xsType = "Baryon" + hadronType = "NucleusType" + pData['epos_xsType'] = xsType + pData['epos_hadronType'] = hadronType + def generate_epos_enum(particle_db): ''' @@ -127,6 +147,7 @@ if __name__ == "__main__": particle_db = load_particledb(sys.argv[1]) read_epos_codes(sys.argv[2], particle_db) + set_default_epos_definition(particle_db) with open("Generated.inc", "w") as f: print("// this file is automatically generated\n// edit at your own risk!\n", file=f) diff --git a/tests/modules/testEpos.cpp b/tests/modules/testEpos.cpp index d1632b16ab5168dc0a70f37ea4f282da8d43ae60..7d52d5e71eae07820b47d91d1c4d85c6134f99ff 100644 --- a/tests/modules/testEpos.cpp +++ b/tests/modules/testEpos.cpp @@ -64,6 +64,8 @@ TEST_CASE("Epos", "[processes]") { CHECK(corsika::epos::getEposXSCode(Code::KMinus) == 3); CHECK(corsika::epos::getEposXSCode(Code::PiMinus) == 2); CHECK(corsika::epos::getEposXSCode(Code::Proton) == 1); + CHECK(corsika::epos::getEposXSCode(Code::Helium) == 4); + CHECK(corsika::epos::getEposXSCode(Code::Nucleus) == 4); } SECTION("epos mass") { @@ -154,7 +156,7 @@ TEST_CASE("EposInterface", "[processes]") { auto const [xs_prod_pn, xs_ela_pn] = model.getCrossSection(Code::Proton, Code::Neutron, 100_GeV); auto const [xs_prod_pHydrogen, xs_ela_pHydrogen] = - model.getCrossSection(Code::Proton, Code::Hydrogen, 100_GeV); + model.getCrossSection(Code::Proton, 1, 1, Code::Hydrogen, 1, 1, 100_GeV); CHECK(xs_prod_pp == xs_prod_pHydrogen); CHECK(xs_prod_pp == xs_prod_pn); CHECK(xs_ela_pp == xs_ela_pHydrogen); @@ -217,7 +219,36 @@ TEST_CASE("EposInterface", "[processes]") { CHECK(pSum.getNorm() / P0 == Approx(1).margin(0.05)); [[maybe_unused]] const GrammageType length = model.getInteractionLength(particle); - CHECK(length / 1_g * 1_cm * 1_cm == Approx(93.2).margin(0.1)); + CHECK(length / 1_g * 1_cm * 1_cm == Approx(93.3).margin(0.1)); + + } + + SECTION("InteractionInterface - nuclear projectile") { + + const HEPEnergyType P0 = 60_TeV; + auto [stack, viewPtr] = setup::testing::setup_stack( + Code::Nucleus, 56, 26, P0, (setup::Environment::BaseNodeType* const)nodePtr, cs); + MomentumVector plab = + MomentumVector(cs, {P0, 0_eV, 0_eV}); // this is secret knowledge about setupStack + setup::StackView& view = *viewPtr; + + auto particle = stack->first(); + + Interaction model; + model.doInteraction(view); + + auto const pSum = sumMomentum(view, cs); + + CHECK(pSum.getComponents(cs).getX() / P0 == Approx(1).margin(0.05)); + CHECK(pSum.getComponents(cs).getY() / 1_GeV == Approx(0).margin(1e-4)); + CHECK(pSum.getComponents(cs).getZ() / 1_GeV == Approx(0).margin(1e-4)); + + CHECK((pSum - plab).getNorm() / 1_GeV == + Approx(0).margin(plab.getNorm() * 0.05 / 1_GeV)); + CHECK(pSum.getNorm() / P0 == Approx(1).margin(0.05)); + + [[maybe_unused]] const GrammageType length = model.getInteractionLength(particle); + CHECK(length / 1_g * 1_cm * 1_cm == Approx(75.2).margin(0.1)); }