diff --git a/corsika/framework/core/detail/ParticleProperties.cc b/corsika/framework/core/detail/ParticleProperties.cc deleted file mode 100644 index a52883bf83b14a97a7a732a700db59eaf502cd8b..0000000000000000000000000000000000000000 --- a/corsika/framework/core/detail/ParticleProperties.cc +++ /dev/null @@ -1,30 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/particles/ParticleProperties.h> -#include <iostream> - -namespace corsika::particles { - - std::ostream& operator<<(std::ostream& stream, corsika::particles::Code const p) { - return stream << corsika::particles::GetName(p); - } - - Code ConvertFromPDG(PDGCode p) { - static_assert(detail::conversionArray.size() % 2 == 1); - // this will fail, for the strange case where the maxPDG is negative... - unsigned int constexpr maxPDG{(detail::conversionArray.size() - 1) >> 1}; - auto k = static_cast<PDGCodeType>(p); - if ((unsigned int)abs(k) <= maxPDG) { - return detail::conversionArray[k + maxPDG]; - } else { - return detail::conversionMap.at(p); - } - } - -} // namespace corsika::particles diff --git a/corsika/framework/geometry/detail/CoordinateSystem.cc b/corsika/framework/geometry/detail/CoordinateSystem.cc deleted file mode 100644 index e822267277f9542ba64d7e745691aee986eac62d..0000000000000000000000000000000000000000 --- a/corsika/framework/geometry/detail/CoordinateSystem.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/geometry/CoordinateSystem.h> -#include <stdexcept> - -using namespace corsika::geometry; - -/** - * returns the transformation matrix necessary to transform primitives with coordinates - * in \a pFrom to \a pTo, e.g. - * \f$ \vec{v}^{\text{(to)}} = \mathcal{M} \vec{v}^{\text{(from)}} \f$ - * (\f$ \vec{v}^{(.)} \f$ denotes the coordinates/components of the component in - * the indicated CoordinateSystem). - */ -EigenTransform CoordinateSystem::GetTransformation(CoordinateSystem const& pFrom, - CoordinateSystem const& pTo) { - CoordinateSystem const* a{&pFrom}; - CoordinateSystem const* b{&pTo}; - CoordinateSystem const* commonBase{nullptr}; - - while (a != b && b != nullptr) { - a = &pFrom; - - while (a != b && a != nullptr) { a = a->GetReference(); } - - if (a == b) break; - - b = b->GetReference(); - } - - if (a == b && a != nullptr) { - commonBase = a; - - } else { - throw std::runtime_error("no connection between coordinate systems found!"); - } - - EigenTransform t = EigenTransform::Identity(); - auto* p = &pFrom; - - while (p != commonBase) { - t = p->GetTransform() * t; - p = p->GetReference(); - } - - p = &pTo; - - while (p != commonBase) { - t = t * p->GetTransform().inverse(Eigen::TransformTraits::Isometry); - p = p->GetReference(); - } - - return t; -} diff --git a/corsika/framework/utility/detail/COMBoost.cc b/corsika/framework/utility/detail/COMBoost.cc deleted file mode 100644 index 5bb4be9da2a2784dc70efa0a7b6b5b1233d3b3f4..0000000000000000000000000000000000000000 --- a/corsika/framework/utility/detail/COMBoost.cc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/geometry/CoordinateSystem.h> -#include <corsika/geometry/FourVector.h> -#include <corsika/geometry/Vector.h> -#include <corsika/units/PhysicalUnits.h> -#include <corsika/utl/COMBoost.h> -#include <corsika/utl/sgn.h> -#include <corsika/logging/Logging.h> - -#include <cmath> - -using namespace corsika::utl; -using namespace corsika::units::si; -using namespace corsika::geometry; - -COMBoost::COMBoost(FourVector<HEPEnergyType, Vector<hepmomentum_d>> const& Pprojectile, - const HEPMassType massTarget) - : originalCS_{Pprojectile.GetSpaceLikeComponents().GetCoordinateSystem()} - , rotatedCS_{originalCS_.RotateToZ(Pprojectile.GetSpaceLikeComponents())} { - auto const pProjectile = Pprojectile.GetSpaceLikeComponents(); - auto const pProjNormSquared = pProjectile.squaredNorm(); - auto const pProjNorm = sqrt(pProjNormSquared); - - auto const eProjectile = Pprojectile.GetTimeLikeComponent(); - auto const massProjectileSquared = eProjectile * eProjectile - pProjNormSquared; - auto const s = - massTarget * massTarget + massProjectileSquared + 2 * eProjectile * massTarget; - - auto const sqrtS = sqrt(s); - auto const sinhEta = -pProjNorm / sqrtS; - auto const coshEta = sqrt(1 + pProjNormSquared / s); - - setBoost(coshEta, sinhEta); - - C8LOG_TRACE("COMBoost (1-beta)={}, gamma={}, det={}", 1 - sinhEta / coshEta, coshEta, - boost_.determinant() - 1); -} - -COMBoost::COMBoost(geometry::Vector<units::si::hepmomentum_d> const& momentum, - units::si::HEPEnergyType mass) - : originalCS_{momentum.GetCoordinateSystem()} - , rotatedCS_{originalCS_.RotateToZ(momentum)} { - auto const squaredNorm = momentum.squaredNorm(); - auto const norm = sqrt(squaredNorm); - auto const sinhEta = -norm / mass; - auto const coshEta = sqrt(1 + squaredNorm / (mass * mass)); - setBoost(coshEta, sinhEta); -} - -void COMBoost::setBoost(double coshEta, double sinhEta) { - boost_ << coshEta, sinhEta, sinhEta, coshEta; - inverseBoost_ << coshEta, -sinhEta, -sinhEta, coshEta; -} - -CoordinateSystem const& COMBoost::GetRotatedCS() const { return rotatedCS_; } diff --git a/corsika/framework/utility/detail/CorsikaFenvDefault.cc b/corsika/framework/utility/detail/CorsikaFenvDefault.cc deleted file mode 100644 index 4d3426ad6b6c2b3c40e51d7103cec38b5ec12b87..0000000000000000000000000000000000000000 --- a/corsika/framework/utility/detail/CorsikaFenvDefault.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -// do nothing, functions exist in system libraries diff --git a/corsika/modules/Sibyll/Decay.cc b/corsika/modules/Sibyll/Decay.cc deleted file mode 100644 index 844f3fdab9c1f497b87ef0e874ac6c56866f741a..0000000000000000000000000000000000000000 --- a/corsika/modules/Sibyll/Decay.cc +++ /dev/null @@ -1,235 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/sibyll/Decay.h> - -#include <corsika/process/sibyll/ParticleConversion.h> -#include <corsika/process/sibyll/SibStack.h> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using std::make_tuple; -using std::tuple; -using std::vector; - -using namespace corsika; -using namespace corsika; - -using SetupView = corsika::StackView; -using SetupProjectile = corsika::StackView::ParticleType; -using SetupParticle = corsika::Stack::ParticleType; - -namespace corsika::sibyll { - - Decay::Decay(const bool sibyll_printout_on) - : sibyll_listing_(sibyll_printout_on) { - // switch off decays to avoid internal decay chains - SetAllStable(); - // handle all decays by default - handleAllDecays_ = true; - } - - Decay::Decay(std::set<particles::Code> vHandled) - : handleAllDecays_(false) - , handledDecays_(vHandled) { - SetAllStable(); - } - - Decay::~Decay() { C8LOG_DEBUG("Sibyll::Decay n={}", count_); } - - bool Decay::CanHandleDecay(const particles::Code vParticleCode) { - using namespace corsika::particles; - // if known to sibyll and not proton or neutrino it can decay - if (vParticleCode == Code::Proton || vParticleCode == Code::AntiProton || - vParticleCode == Code::NuE || vParticleCode == Code::NuMu || - vParticleCode == Code::NuTau || vParticleCode == Code::NuEBar || - vParticleCode == Code::NuMuBar || vParticleCode == Code::NuTauBar || - vParticleCode == Code::Electron || vParticleCode == Code::Positron) - return false; - else if (process::sibyll::ConvertToSibyllRaw( - vParticleCode)) // non-zero for particles known to sibyll - return true; - else - return false; - } - - void Decay::SetHandleDecay(const particles::Code vParticleCode) { - handleAllDecays_ = false; - C8LOG_DEBUG("Sibyll::Decay: set to handle decay of {}", vParticleCode); - if (Decay::CanHandleDecay(vParticleCode)) - handledDecays_.insert(vParticleCode); - else - throw std::runtime_error("this decay can not be handled by sibyll!"); - } - - void Decay::SetHandleDecay(const vector<particles::Code> vParticleList) { - handleAllDecays_ = false; - for (auto p : vParticleList) Decay::SetHandleDecay(p); - } - - bool Decay::IsDecayHandled(const corsika::particles::Code vParticleCode) { - if (handleAllDecays_ && Decay::CanHandleDecay(vParticleCode)) - return true; - else - return Decay::handledDecays_.find(vParticleCode) != Decay::handledDecays_.end() - ? true - : false; - } - - void Decay::SetStable(const vector<particles::Code> vParticleList) { - for (auto p : vParticleList) Decay::SetStable(p); - } - - void Decay::SetUnstable(const vector<particles::Code> vParticleList) { - for (auto p : vParticleList) Decay::SetUnstable(p); - } - - bool Decay::IsStable(const particles::Code vCode) { - return abs(process::sibyll::ConvertToSibyllRaw(vCode)) <= 0 ? true : false; - } - - bool Decay::IsUnstable(const particles::Code vCode) { - return abs(process::sibyll::ConvertToSibyllRaw(vCode)) > 0 ? true : false; - } - - void Decay::SetDecay(const particles::Code vCode, const bool vMakeUnstable) { - vMakeUnstable ? SetUnstable(vCode) : SetStable(vCode); - } - - void Decay::SetUnstable(const particles::Code vCode) { - C8LOG_DEBUG("Sibyll::Decay: setting {} unstable. ", vCode); - const int s_id = abs(process::sibyll::ConvertToSibyllRaw(vCode)); - s_csydec_.idb[s_id - 1] = abs(s_csydec_.idb[s_id - 1]); - } - - void Decay::SetStable(const particles::Code vCode) { - C8LOG_DEBUG("Sibyll::Decay: setting {} stable. ", vCode); - const int s_id = abs(process::sibyll::ConvertToSibyllRaw(vCode)); - s_csydec_.idb[s_id - 1] = (-1) * abs(s_csydec_.idb[s_id - 1]); - } - - void Decay::SetAllStable() { - for (int i = 0; i < 99; ++i) s_csydec_.idb[i] = -1 * abs(s_csydec_.idb[i]); - } - - void Decay::SetAllUnstable() { - for (int i = 0; i < 99; ++i) s_csydec_.idb[i] = abs(s_csydec_.idb[i]); - } - - void Decay::PrintDecayConfig([[maybe_unused]] const particles::Code vCode) { - [[maybe_unused]] const int sibCode = process::sibyll::ConvertToSibyllRaw(vCode); - [[maybe_unused]] const int absSibCode = abs(sibCode); - C8LOG_DEBUG("Decay: Sibyll decay configuration: {} is {}", vCode, - (s_csydec_.idb[absSibCode - 1] <= 0) ? "stable" : "unstable"); - } - - void Decay::PrintDecayConfig() { - C8LOG_DEBUG("Sibyll::Decay: decay configuration:"); - if (handleAllDecays_) { - C8LOG_DEBUG(" all particles known to Sibyll are handled by Sibyll::Decay!"); - } else { - for ([[maybe_unused]] auto& pCode : handledDecays_) { - C8LOG_DEBUG(" Decay of {} is handled by Sibyll!", pCode); - } - } - } - - template <> - units::si::TimeType Decay::GetLifetime(Particle const& vP) { - using namespace units::si; - - const particles::Code pid = vP.GetPID(); - if (Decay::IsDecayHandled(pid)) { - HEPEnergyType E = vP.GetEnergy(); - HEPMassType m = vP.GetMass(); - - const double gamma = E / m; - - const TimeType t0 = particles::GetLifetime(vP.GetPID()); - auto const lifetime = gamma * t0; - - [[maybe_unused]] const auto mkin = - (E * E - vP.GetMomentum().squaredNorm()); // delta_mass(vP.GetMomentum(), E, m); - C8LOG_DEBUG("Sibyll::Decay: code: {} ", vP.GetPID()); - C8LOG_DEBUG("Sibyll::Decay: MinStep: t0: {} ", t0); - C8LOG_DEBUG("Sibyll::Decay: MinStep: energy: {} GeV ", E / 1_GeV); - C8LOG_DEBUG("Sibyll::Decay: momentum: {} GeV ", - vP.GetMomentum().GetComponents() / 1_GeV); - C8LOG_DEBUG("Sibyll::Decay: momentum: shell mass-kin. inv. mass {} {}", - mkin / 1_GeV / 1_GeV, m / 1_GeV * m / 1_GeV); - [[maybe_unused]] auto sib_id = process::sibyll::ConvertToSibyllRaw(vP.GetPID()); - C8LOG_DEBUG("Sibyll::Decay: sib mass: {}", get_sibyll_mass2(sib_id)); - C8LOG_DEBUG("Sibyll::Decay: MinStep: gamma: {}", gamma); - C8LOG_DEBUG("Sibyll::Decay: MinStep: tau {} s: ", lifetime / 1_s); - - return lifetime; - } else - return std::numeric_limits<double>::infinity() * 1_s; - } - - template <> - void Decay::DoDecay(SetupView& view) { - using geometry::Point; - using namespace units::si; - - auto const projectile = view.GetProjectile(); - - const particles::Code pCode = projectile.GetPID(); - // check if sibyll is configured to handle this decay! - if (!IsDecayHandled(pCode)) - throw std::runtime_error("STOP! Sibyll not configured to execute this decay!"); - - count_++; - SibStack ss; - ss.Clear(); - - // copy particle to sibyll stack - ss.AddParticle(process::sibyll::ConvertToSibyllRaw(pCode), projectile.GetEnergy(), - projectile.GetMomentum(), - // setting particle mass with Corsika values, may be inconsistent - // with sibyll internal values - particles::GetMass(pCode)); - // remember position - Point const decayPoint = projectile.GetPosition(); - TimeType const t0 = projectile.GetTime(); - // remember if particles is unstable - // auto const priorIsUnstable = IsUnstable(pCode); - // switch on decay for this particle - SetUnstable(pCode); - PrintDecayConfig(pCode); - - // call sibyll decay - C8LOG_DEBUG("Decay: calling Sibyll decay routine.."); - decsib_(); - - if (sibyll_listing_) { - // print output - int print_unit = 6; - sib_list_(print_unit); - } - - // reset to stable - SetStable(pCode); - - // copy particles from sibyll stack to corsika - for (auto& psib : ss) { - // FOR NOW: skip particles that have decayed in Sibyll, move to iterator? - if (psib.HasDecayed()) continue; - // add to corsika stack - vP.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, corsika::MomentumVector, - geometry::Point, units::si::TimeType>{ - process::sibyll::ConvertFromSibyll(psib.GetPID()), psib.GetEnergy(), - psib.GetMomentum(), decayPoint, t0}); - } - // empty sibyll stack - ss.Clear(); - } - -} // namespace corsika::sibyll diff --git a/corsika/modules/Sibyll/Interaction.cc b/corsika/modules/Sibyll/Interaction.cc deleted file mode 100644 index 219494e057c4e1a1eb9fba63131ee529905383da..0000000000000000000000000000000000000000 --- a/corsika/modules/Sibyll/Interaction.cc +++ /dev/null @@ -1,361 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/sibyll/Interaction.h> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/NuclearComposition.hpp> -#include <corsika/framework/geometry/FourVector.hpp> -#include <corsika/process/sibyll/ParticleConversion.h> -#include <corsika/process/sibyll/SibStack.h> -#include <corsika/process/sibyll/sibyll2.3c.h> -#include <corsika/framework/utility/COMBoost.hpp> - -#include <tuple> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using std::cout; -using std::endl; -using std::tuple; - -using namespace corsika; -using namespace corsika; -using SetupParticle = setup::Stack::StackIterator; -using SetupProjectile = setup::StackView::StackIterator; -using Track = Trajectory; - -namespace corsika::sibyll { - - bool Interaction::initialized_ = false; - - Interaction::Interaction(const bool sibyll_printout_on) - : sibyll_listing_(sibyll_printout_on) { - using random::RNGManager; - - // initialize Sibyll - if (!initialized_) { - sibyll_ini_(); - initialized_ = true; - } - } - - Interaction::~Interaction() { - C8LOG_DEBUG(fmt::format("Sibyll::Interaction n={}, Nnuc={}", count_, nucCount_)); - } - - void Interaction::SetAllStable() { - for (int i = 0; i < 99; ++i) s_csydec_.idb[i] = -1 * abs(s_csydec_.idb[i]); - } - - tuple<units::si::CrossSectionType, units::si::CrossSectionType> - Interaction::GetCrossSection(const particles::Code BeamId, - const particles::Code TargetId, - const units::si::HEPEnergyType CoMenergy) const { - using namespace units::si; - double sigProd, sigEla, dummy, dum1, dum3, dum4; - double dumdif[3]; - const int iBeam = process::sibyll::GetSibyllXSCode(BeamId); - if (!IsValidCoMEnergy(CoMenergy)) { - throw std::runtime_error( - "Interaction: GetCrossSection: CoM energy outside range for Sibyll!"); - } - const double dEcm = CoMenergy / 1_GeV; - if (particles::IsNucleus(TargetId)) { - const int iTarget = particles::GetNucleusA(TargetId); - if (iTarget > maxTargetMassNumber_ || iTarget == 0) - throw std::runtime_error( - "Sibyll target outside range. Only nuclei with A<18 are allowed."); - sib_sigma_hnuc_(iBeam, iTarget, dEcm, sigProd, dummy, sigEla); - } else if (TargetId == particles::Proton::GetCode()) { - sib_sigma_hp_(iBeam, dEcm, dum1, sigEla, sigProd, dumdif, dum3, dum4); - } else { - // no interaction in sibyll possible, return infinite cross section? or throw? - sigProd = std::numeric_limits<double>::infinity(); - sigEla = std::numeric_limits<double>::infinity(); - } - return std::make_tuple(sigProd * 1_mb, sigEla * 1_mb); - } - - template <> - units::si::GrammageType Interaction::GetInteractionLength(Particle const& vP) const { - - using namespace units; - using namespace units::si; - using namespace geometry; - - // coordinate system, get global frame of reference - CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - - const particles::Code corsikaBeamId = vP.GetPID(); - - // beam particles for sibyll : 1, 2, 3 for p, pi, k - // read from cross section code table - const bool kInteraction = process::sibyll::CanInteract(corsikaBeamId); - - // FOR NOW: assume target is at rest - MomentumVector pTarget(rootCS, {0_GeV, 0_GeV, 0_GeV}); - - // total momentum and energy - HEPEnergyType Elab = vP.GetEnergy() + constants::nucleonMass; - MomentumVector pTotLab(rootCS, {0_GeV, 0_GeV, 0_GeV}); - pTotLab += vP.GetMomentum(); - pTotLab += pTarget; - auto const pTotLabNorm = pTotLab.norm(); - // calculate cm. energy - const HEPEnergyType ECoM = sqrt( - (Elab + pTotLabNorm) * (Elab - pTotLabNorm)); // binomial for numerical accuracy - - C8LOG_DEBUG( - fmt::format("Interaction: LambdaInt: \n" - " input energy: {} GeV " - " beam can interact: {} " - " beam pid: {}", - vP.GetEnergy() / 1_GeV, kInteraction, vP.GetPID())); - - // TODO: move limits into variables - // FR: removed && Elab >= 8.5_GeV - if (kInteraction && IsValidCoMEnergy(ECoM)) { - - // get target from environment - /* - the target should be defined by the Environment, - ideally as full particle object so that the four momenta - and the boosts can be defined.. - */ - - auto const* currentNode = vP.GetNode(); - const auto& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - - si::CrossSectionType weightedProdCrossSection = mediumComposition.WeightedSum( - [=](particles::Code targetID) -> si::CrossSectionType { - return std::get<0>(this->GetCrossSection(corsikaBeamId, targetID, ECoM)); - }); - - C8LOG_DEBUG( - fmt::format("Interaction: " - "IntLength: weighted CrossSection (mb): {} ", - weightedProdCrossSection / 1_mb)); - - // calculate interaction length in medium - GrammageType const int_length = mediumComposition.GetAverageMassNumber() * - units::constants::u / weightedProdCrossSection; - C8LOG_DEBUG( - fmt::format("Interaction: " - "interaction length (g/cm2): {} ", - int_length / (0.001_kg) * 1_cm * 1_cm)); - - return int_length; - } - - return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); - } - - /** - In this function SIBYLL is called to produce one event. The - event is copied (and boosted) into the shower lab frame. - */ - - template <> - process::EProcessReturn Interaction::DoInteraction(SetupView& view) { - using namespace utl; - using namespace units; - using namespace units::si; - using namespace geometry; - - auto const projectile = view.GetProjectile(); - - const auto corsikaBeamId = projectile.GetPID(); - - if (particles::IsNucleus(corsikaBeamId)) { - // nuclei handled by different process, this should not happen - throw std::runtime_error("Nuclear projectile are not handled by SIBYLL!"); - } - - // position and time of interaction, not used in Sibyll - Point const pOrig = projectile.GetPosition(); - TimeType const tOrig = projectile.GetTime(); - - // define projectile - HEPEnergyType const eProjectileLab = projectile.GetEnergy(); - auto const pProjectileLab = projectile.GetMomentum(); - const CoordinateSystem& originalCS = pProjectileLab.GetCoordinateSystem(); - - C8LOG_DEBUG( - "ProcessSibyll: " - "DoInteraction: pid {} 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); - - C8LOG_DEBUG( - "Interaction: ebeam lab: {} GeV" - "Interaction: pbeam lab: {} GeV", - eProjectileLab / 1_GeV, pProjectileLab.GetComponents()); - C8LOG_DEBUG( - "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); - - C8LOG_DEBUG( - "Interaction: ebeam CoM: {} GeV " - "Interaction: pbeam CoM: {} GeV ", - PprojCoM.GetTimeLikeComponent() / 1_GeV, - PprojCoM.GetSpaceLikeComponents().GetComponents(csPrime) / 1_GeV); - C8LOG_DEBUG( - "Interaction: etarget CoM: {} GeV " - "Interaction: ptarget CoM: {} GeV ", - PtargCoM.GetTimeLikeComponent() / 1_GeV, - PtargCoM.GetSpaceLikeComponents().GetComponents(csPrime) / 1_GeV); - - C8LOG_DEBUG("Interaction: position of interaction: {} ", pOrig.GetCoordinates()); - C8LOG_DEBUG("Interaction: time: {} ", tOrig); - - HEPEnergyType Etot = eProjectileLab + eTargetLab; - MomentumVector Ptot = projectile.GetMomentum(); - // invariant mass, i.e. cm. energy - HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.squaredNorm()); - - // sample target mass number - auto const* currentNode = projectile.GetNode(); - auto const& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - // get cross sections for target materials - /* - Here we read the cross section from the interaction model again, - should be passed from GetInteractionLength if possible - */ - //#warning reading interaction cross section again, should not be necessary - auto const& compVec = mediumComposition.GetComponents(); - std::vector<CrossSectionType> cross_section_of_components(compVec.size()); - - for (size_t i = 0; i < compVec.size(); ++i) { - auto const targetId = compVec[i]; - const auto [sigProd, sigEla] = GetCrossSection(corsikaBeamId, targetId, Ecm); - [[maybe_unused]] const auto& dummy_sigEla = sigEla; - cross_section_of_components[i] = sigProd; - } - - const auto targetCode = - mediumComposition.SampleTarget(cross_section_of_components, RNG_); - C8LOG_DEBUG("Interaction: target selected: {} ", targetCode); - /* - FOR NOW: allow nuclei with A<18 or protons only. - when medium composition becomes more complex, approximations will have to be - allowed air in atmosphere also contains some Argon. - */ - int targetSibCode = -1; - if (IsNucleus(targetCode)) targetSibCode = GetNucleusA(targetCode); - if (targetCode == particles::Proton::GetCode()) targetSibCode = 1; - C8LOG_DEBUG("Interaction: sibyll code: {}", targetSibCode); - if (targetSibCode > maxTargetMassNumber_ || targetSibCode < 1) - throw std::runtime_error( - "Sibyll target outside range. Only nuclei with A<18 or protons are " - "allowed."); - - // beam id for sibyll - const int kBeam = process::sibyll::ConvertToSibyllRaw(corsikaBeamId); - - C8LOG_DEBUG( - "Interaction: " - " DoInteraction: E(GeV): {} " - " Ecm(GeV): {} ", - eProjectileLab / 1_GeV, Ecm / 1_GeV); - if (Ecm > GetMaxEnergyCoM()) - throw std::runtime_error("Interaction::DoInteraction: CoM energy too high!"); - // FR: removed eProjectileLab < 8.5_GeV || - if (Ecm < GetMinEnergyCoM()) { - C8LOG_DEBUG( - "Interaction: " - " DoInteraction: should have dropped particle.. " - "THIS IS AN ERROR"); - throw std::runtime_error("energy too low for SIBYLL"); - } else { - count_++; - // Sibyll does not know about units.. - const double sqs = Ecm / 1_GeV; - // running sibyll, filling stack - sibyll_(kBeam, targetSibCode, sqs); - - if (sibyll_listing_) { - // print final state - int print_unit = 6; - sib_list_(print_unit); - nucCount_ += get_nwounded() - 1; - } - - // add particles from sibyll to stack - // link to sibyll stack - SibStack ss; - - MomentumVector Plab_final(originalCS, {0.0_GeV, 0.0_GeV, 0.0_GeV}); - HEPEnergyType Elab_final = 0_GeV, Ecm_final = 0_GeV; - for (auto& psib : ss) { - - // abort on particles that have decayed in Sibyll. Should not happen! - if (psib.HasDecayed()) - throw std::runtime_error("found particle that decayed in SIBYLL!"); - - // transform 4-momentum to lab. frame - // note that the momentum needs to be rotated back - auto const tmp = psib.GetMomentum().GetComponents(); - auto const pCoM = Vector<hepmomentum_d>(csPrime, tmp); - HEPEnergyType const eCoM = psib.GetEnergy(); - auto const Plab = boost.fromCoM(FourVector(eCoM, pCoM)); - auto const p3lab = Plab.GetSpaceLikeComponents(); - assert(p3lab.GetCoordinateSystem() == originalCS); // just to be sure! - - // add to corsika stack - auto pnew = view.AddSecondary( - make_tuple(process::sibyll::ConvertFromSibyll(psib.GetPID()), - Plab.GetTimeLikeComponent(), p3lab, pOrig, tOrig)); - - Plab_final += pnew.GetMomentum(); - Elab_final += pnew.GetEnergy(); - Ecm_final += psib.GetEnergy(); - } - C8LOG_DEBUG( - "conservation (all GeV):" - "Ecm_initial(per nucleon)={}, Ecm_final(per nucleon)={}, " - "Elab_initial={}, Elab_final={}, " - "diff (%)={}, " - "E in nucleons={}, " - "Plab_initial={}, " - "Plab_final={} ", - Ecm / 1_GeV, Ecm_final * 2. / (get_nwounded() + 1) / 1_GeV, Etot / 1_GeV, - Elab_final / 1_GeV, (Elab_final / Etot / get_nwounded() - 1) * 100, - constants::nucleonMass * get_nwounded() / 1_GeV, - (pProjectileLab / 1_GeV).GetComponents(), (Plab_final / 1_GeV).GetComponents()); - } - return process::EProcessReturn::eOk; - } - -} // namespace corsika::sibyll diff --git a/corsika/modules/Sibyll/NuclearInteraction.cc b/corsika/modules/Sibyll/NuclearInteraction.cc deleted file mode 100644 index 2ec18ed40d8f7b8a915978e6be0a6e39ab9d3162..0000000000000000000000000000000000000000 --- a/corsika/modules/Sibyll/NuclearInteraction.cc +++ /dev/null @@ -1,612 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/sibyll/Interaction.h> -#include <corsika/process/sibyll/NuclearInteraction.h> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/NuclearComposition.hpp> -#include <corsika/framework/geometry/FourVector.hpp> -#include <corsika/process/sibyll/nuclib.h> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include <corsika/framework/utility/COMBoost.hpp> - -#include <set> -#include <sstream> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using std::cout; -using std::endl; -using std::tuple; -using std::vector; - -using namespace corsika; -using namespace corsika; -using Particle = Stack::ParticleType; // StackIterator; // ParticleType; -using Projectile = StackView::StackIterator; // StackView::ParticleType; -using Track = Trajectory; - -namespace corsika::sibyll { - - template <> - NuclearInteraction<setup::Environment>::~NuclearInteraction() { - C8LOG_DEBUG( - fmt::format("Nuclib::NuclearInteraction n={} Nnuc={}", count_, nucCount_)); - } - - template <> - void NuclearInteraction<SetupEnvironment>::PrintCrossSectionTable( - corsika::Code pCode) { - using namespace corsika; - const int k = targetComponentsIndex_.at(pCode); - Code pNuclei[] = {Code::Helium, Code::Lithium7, Code::Oxygen, - Code::Neon, Code::Argon, Code::Iron}; - std::ostringstream table; - table << "Nuclear CrossSectionTable pCode=" << pCode << " :\n en/A "; - for (auto& j : pNuclei) table << std::setw(9) << j; - table << "\n"; - - // loop over energy bins - for (unsigned int i = 0; i < GetNEnergyBins(); ++i) { - table << " " << i << " "; - for (auto& n : pNuclei) { - auto const j = GetNucleusA(n); - table << " " << std::setprecision(5) << std::setw(8) - << cnucsignuc_.sigma[j - 1][k][i]; - } - table << "\n"; - } - C8LOG_DEBUG(table.str()); - } - - template <> - void NuclearInteraction<SetupEnvironment>::InitializeNuclearCrossSections() { - using namespace corsika; - using namespace units::si; - - auto& universe = *(environment_.GetUniverse()); - - auto const allElementsInUniverse = std::invoke([&]() { - std::set<particles::Code> allElementsInUniverse; - auto collectElements = [&](auto& vtn) { - if (vtn.HasModelProperties()) { - auto const& comp = - vtn.GetModelProperties().GetNuclearComposition().GetComponents(); - for (auto const c : comp) allElementsInUniverse.insert(c); - } - }; - universe.walk(collectElements); - return allElementsInUniverse; - }); - - C8LOG_DEBUG("NuclearInteraction: initializing nuclear cross sections..."); - - // loop over target components, at most 4!! - int k = -1; - for (auto& ptarg : allElementsInUniverse) { - ++k; - C8LOG_DEBUG(fmt::format("NuclearInteraction: init target component: {}", ptarg)); - const int ib = GetNucleusA(ptarg); - if (!hadronicInteraction_.IsValidTarget(ptarg)) { - C8LOG_DEBUG(fmt::format( - "NuclearInteraction::InitializeNuclearCrossSections: target nucleus? id={}", - ptarg)); - throw std::runtime_error( - " target can not be handled by hadronic interaction model! "); - } - targetComponentsIndex_.insert(std::pair<Code, int>(ptarg, k)); - // loop over energies, fNEnBins log. energy bins - for (unsigned int i = 0; i < GetNEnergyBins(); ++i) { - // hard coded energy grid, has to be aligned to definition in signuc2!!, no - // comment.. - const units::si::HEPEnergyType Ecm = pow(10., 1. + 1. * i) * 1_GeV; - // get p-p cross sections - auto const protonId = Code::Proton; - auto const [siginel, sigela] = - hadronicInteraction_.GetCrossSection(protonId, protonId, Ecm); - const double dsig = siginel / 1_mb; - const double dsigela = sigela / 1_mb; - // loop over projectiles, mass numbers from 2 to fMaxNucleusAProjectile - for (unsigned int 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, - dsigqe_out); - // write to table - cnucsignuc_.sigma[j][k][i] = sig_out; - cnucsignuc_.sigqe[j][k][i] = sigqe_out; - } - } - } - C8LOG_DEBUG( - fmt::format("NuclearInteraction: cross sections for {} " - " components initialized!", - targetComponentsIndex_.size())); - for (auto& ptarg : allElementsInUniverse) { PrintCrossSectionTable(ptarg); } - } - - template <> - units::si::CrossSectionType - NuclearInteraction<setup::Environment>::ReadCrossSectionTable( - const int ia, particles::Code pTarget, units::si::HEPEnergyType elabnuc) { - using namespace corsika; - using namespace units::si; - const int ib = targetComponentsIndex_.at(pTarget) + 1; // table index in fortran - auto const ECoMNuc = sqrt(2. * corsika::units::constants::nucleonMass * elabnuc); - if (ECoMNuc < GetMinEnergyPerNucleonCoM() || ECoMNuc > GetMaxEnergyPerNucleonCoM()) - throw std::runtime_error("NuclearInteraction: energy outside tabulated range!"); - const double e0 = elabnuc / 1_GeV; - double sig; - C8LOG_DEBUG(fmt::format("ReadCrossSectionTable: {} {} {}", ia, ib, e0)); - signuc2_(ia, ib, e0, sig); - C8LOG_DEBUG(fmt::format("ReadCrossSectionTable: sig={}", sig)); - return sig * 1_mb; - } - - // TODO: remove elastic cross section? - template <> - template <> - tuple<units::si::CrossSectionType, units::si::CrossSectionType> - NuclearInteraction<setup::Environment>::GetCrossSection( - Particle const& vP, const particles::Code TargetId) { - using namespace units::si; - if (vP.GetPID() != particles::Code::Nucleus) - throw std::runtime_error( - "NuclearInteraction: GetCrossSection: particle not a nucleus!"); - - const unsigned int iBeamA = vP.GetNuclearA(); - HEPEnergyType LabEnergyPerNuc = vP.GetEnergy() / iBeamA; - C8LOG_DEBUG( - fmt::format("NuclearInteraction: GetCrossSection: called with: beamNuclA={} " - " TargetId={} LabEnergyPerNuc={}GeV ", - iBeamA, TargetId, LabEnergyPerNuc / 1_GeV)); - - // use nuclib to calc. nuclear cross sections - // TODO: for now assumes air with hard coded composition - // extend to arbitrary mixtures, requires smarter initialization - // get nuclib projectile code: nucleon number - if (iBeamA > GetMaxNucleusAProjectile() || iBeamA < 2) { - C8LOG_DEBUG( - "NuclearInteraction: beam nucleus outside allowed range for NUCLIB!" - "A=" + - std::to_string(iBeamA)); - throw std::runtime_error( - "NuclearInteraction: GetCrossSection: beam nucleus outside allowed range for " - "NUCLIB!"); - } - - if (hadronicInteraction_.IsValidTarget(TargetId)) { - auto const sigProd = ReadCrossSectionTable(iBeamA, TargetId, LabEnergyPerNuc); - C8LOG_DEBUG("cross section (mb): " + std::to_string(sigProd / 1_mb)); - return std::make_tuple(sigProd, 0_mb); - } else { - throw std::runtime_error("target outside range."); - } - return std::make_tuple(std::numeric_limits<double>::infinity() * 1_mb, - std::numeric_limits<double>::infinity() * 1_mb); - } - - template <> - template <> - units::si::GrammageType NuclearInteraction<setup::Environment>::GetInteractionLength( - Particle const& vP) { - - using namespace units; - using namespace units::si; - using namespace geometry; - - // coordinate system, get global frame of reference - CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - - const particles::Code corsikaBeamId = vP.GetPID(); - - if (corsikaBeamId != particles::Code::Nucleus) { - // check if target-style nucleus (enum), these are not allowed as projectile - if (particles::IsNucleus(corsikaBeamId)) - throw std::runtime_error( - "NuclearInteraction: GetInteractionLength: Wrong nucleus type. Nuclear " - "projectiles should use NuclearStackExtension!"); - else { - // no nuclear interaction - return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); - } - } - - // read from cross section code table - - // FOR NOW: assume target is at rest - corsika::MomentumVector pTarget(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV}); - - // total momentum and energy - HEPEnergyType Elab = vP.GetEnergy() + constants::nucleonMass; - unsigned int const nuclA = vP.GetNuclearA(); - auto const ElabNuc = vP.GetEnergy() / nuclA; - - corsika::MomentumVector pTotLab(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV}); - pTotLab += vP.GetMomentum(); - pTotLab += pTarget; - auto const pTotLabNorm = pTotLab.norm(); - // calculate cm. energy - [[maybe_unused]] const HEPEnergyType ECoM = sqrt( - (Elab + pTotLabNorm) * (Elab - pTotLabNorm)); // binomial for numerical accuracy - auto const ECoMNN = sqrt(2. * ElabNuc * constants::nucleonMass); - C8LOG_DEBUG( - fmt::format("NuclearInteraction: LambdaInt: \n" - " input energy: {}GeV\n" - " input energy CoM: {}GeV\n" - " beam pid: {}\n" - " beam A: {}\n" - " input energy per nucleon: {}GeV\n" - " input energy CoM per nucleon: {}GeV ", - Elab / 1_GeV, ECoM / 1_GeV, particles::GetName(corsikaBeamId), nuclA, - ElabNuc / 1_GeV, ECoMNN / 1_GeV)); - // throw std::runtime_error("stop here"); - - // energy limits - // TODO: values depend on hadronic interaction model !! this is sibyll specific - if (ElabNuc >= 8.5_GeV && ECoMNN >= gMinEnergyPerNucleonCoM_ && - ECoMNN < gMaxEnergyPerNucleonCoM_) { - - // get target from environment - /* - the target should be defined by the Environment, - ideally as full particle object so that the four momenta - and the boosts can be defined.. - */ - auto const* const currentNode = vP.GetNode(); - auto const& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - // determine average interaction length - // weighted sum - int i = -1; - si::CrossSectionType weightedProdCrossSection = 0_mb; - // get weights of components from environment/medium - const auto& w = mediumComposition.GetFractions(); - // loop over components in medium - for (auto const targetId : mediumComposition.GetComponents()) { - i++; - C8LOG_DEBUG("NuclearInteraction: get interaction length for target: " + - particles::GetName(targetId)); - auto const [productionCrossSection, elaCrossSection] = - GetCrossSection(vP, targetId); - [[maybe_unused]] auto& dummy_elaCrossSection = elaCrossSection; - - C8LOG_DEBUG( - "NuclearInteraction: " - "IntLength: nuclib return (mb): " + - std::to_string(productionCrossSection / 1_mb)); - weightedProdCrossSection += w[i] * productionCrossSection; - } - C8LOG_DEBUG( - "NuclearInteraction: " - "IntLength: weighted CrossSection (mb): " + - std::to_string(weightedProdCrossSection / 1_mb)); - - // calculate interaction length in medium - GrammageType const int_length = mediumComposition.GetAverageMassNumber() * - units::constants::u / weightedProdCrossSection; - C8LOG_DEBUG( - "NuclearInteraction: " - "interaction length (g/cm2): " + - std::to_string(int_length * (1_cm * 1_cm / (0.001_kg)))); - - return int_length; - } else { - return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); - } - } - - template <> - template <> - process::EProcessReturn NuclearInteraction<setup::Environment>::DoInteraction( - View& view) { - - // this routine superimposes different nucleon-nucleon interactions - // in a nucleus-nucleus interaction, based the SIBYLL routine SIBNUC - - using namespace units; - using namespace utl; - using namespace units::si; - using namespace geometry; - - auto projectile = view.GetProjectile(); - - const auto ProjId = projectile.GetPID(); - // TODO: calculate projectile mass in nuclearStackExtension - // const auto ProjMass = projectile.GetMass(); - C8LOG_DEBUG("NuclearInteraction: DoInteraction: called with:" + - particles::GetName(ProjId)); - - // check if target-style nucleus (enum) - if (ProjId != particles::Code::Nucleus) - throw std::runtime_error( - "NuclearInteraction: DoInteraction: Wrong nucleus type. Nuclear projectiles " - "should use NuclearStackExtension!"); - - auto const ProjMass = projectile.GetNuclearZ() * particles::Proton::GetMass() + - (projectile.GetNuclearA() - projectile.GetNuclearZ()) * - particles::Neutron::GetMass(); - C8LOG_DEBUG("NuclearInteraction: projectile mass: " + - std::to_string(ProjMass / 1_GeV)); - - count_++; - - const CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - - // position and time of interaction, not used in NUCLIB - Point pOrig = projectile.GetPosition(); - TimeType tOrig = projectile.GetTime(); - - C8LOG_DEBUG( - fmt::format("Interaction: position of interaction: {}", pOrig.GetCoordinates())); - C8LOG_DEBUG("Interaction: time: " + std::to_string(tOrig / 1_s)); - - // projectile nucleon number - const unsigned int kAProj = projectile.GetNuclearA(); - if (kAProj > GetMaxNucleusAProjectile()) - throw std::runtime_error("Projectile nucleus too large for NUCLIB!"); - - // kinematics - // define projectile nucleus - HEPEnergyType const eProjectileLab = projectile.GetEnergy(); - auto const pProjectileLab = projectile.GetMomentum(); - const FourVector PprojLab(eProjectileLab, pProjectileLab); - - C8LOG_DEBUG( - fmt::format("NuclearInteraction: eProj lab: {} " - "pProj lab: {} ", - eProjectileLab / 1_GeV, pProjectileLab.GetComponents() / 1_GeV)); - ; - - // define projectile nucleon - HEPEnergyType const eProjectileNucLab = projectile.GetEnergy() / kAProj; - auto const pProjectileNucLab = projectile.GetMomentum() / kAProj; - const FourVector PprojNucLab(eProjectileNucLab, pProjectileNucLab); - - C8LOG_DEBUG(fmt::format( - "NuclearInteraction: eProjNucleon lab (GeV): {} " - "pProjNucleon lab (GeV): {}", - eProjectileNucLab / 1_GeV, pProjectileNucLab.GetComponents() / 1_GeV)); - - // define target - // always a nucleon - // target is always at rest - const auto eTargetNucLab = 0_GeV + constants::nucleonMass; - const auto pTargetNucLab = - corsika::MomentumVector(rootCS, 0_GeV, 0_GeV, 0_GeV); - const FourVector PtargNucLab(eTargetNucLab, pTargetNucLab); - - C8LOG_DEBUG( - fmt::format("NuclearInteraction: etarget lab(GeV): {}" - "NuclearInteraction: ptarget lab(GeV): {} ", - eTargetNucLab / 1_GeV, pTargetNucLab.GetComponents() / 1_GeV)); - - // center-of-mass energy in nucleon-nucleon frame - auto const PtotNN4 = PtargNucLab + PprojNucLab; - HEPEnergyType EcmNN = PtotNN4.GetNorm(); - C8LOG_DEBUG("NuclearInteraction: nuc-nuc cm energy: " + - std::to_string(EcmNN / 1_GeV)); - - if (!hadronicInteraction_.IsValidCoMEnergy(EcmNN)) { - C8LOG_DEBUG( - "NuclearInteraction: nuc-nuc. CoM energy too low for hadronic " - "interaction model!"); - throw std::runtime_error("NuclearInteraction: DoInteraction: energy too low!"); - } - - // define boost to NUCLEON-NUCLEON frame - COMBoost const boost(PprojNucLab, constants::nucleonMass); - // boost projecticle - [[maybe_unused]] auto const PprojNucCoM = boost.toCoM(PprojNucLab); - - // boost target - [[maybe_unused]] auto const PtargNucCoM = boost.toCoM(PtargNucLab); - - C8LOG_DEBUG( - fmt::format("Interaction: ebeam CoM: {} " - ", pbeam CoM: {}", - PprojNucCoM.GetTimeLikeComponent() / 1_GeV, - PprojNucCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV)); - C8LOG_DEBUG( - fmt::format("Interaction: etarget CoM: {}" - ", ptarget CoM: {}", - PtargNucCoM.GetTimeLikeComponent() / 1_GeV, - PtargNucCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV)); - - // sample target nucleon number - // - // proton stand-in for nucleon - const auto beamId = particles::Proton::GetCode(); - auto const* const currentNode = projectile.GetNode(); - const auto& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - C8LOG_DEBUG("get nucleon-nucleus cross sections for target materials.."); - // get cross sections for target materials - // using nucleon-target-nucleus cross section!!! - /* - Here we read the cross section from the interaction model again, - should be passed from GetInteractionLength if possible - */ - auto const& compVec = mediumComposition.GetComponents(); - vector<si::CrossSectionType> cross_section_of_components(compVec.size()); - - for (size_t i = 0; i < compVec.size(); ++i) { - auto const targetId = compVec[i]; - C8LOG_DEBUG("target component: " + particles::GetName(targetId)); - C8LOG_DEBUG("beam id: " + particles::GetName(beamId)); - const auto [sigProd, sigEla] = - hadronicInteraction_.GetCrossSection(beamId, targetId, EcmNN); - cross_section_of_components[i] = sigProd; - [[maybe_unused]] auto sigElaCopy = sigEla; // ONLY TO AVOID COMPILER WARNINGS - } - - const auto targetCode = - mediumComposition.SampleTarget(cross_section_of_components, RNG_); - C8LOG_DEBUG("Interaction: target selected: " + particles::GetName(targetCode)); - /* - FOR NOW: allow nuclei with A<18 or protons only. - when medium composition becomes more complex, approximations will have to be - allowed air in atmosphere also contains some Argon. - */ - int kATarget = -1; - if (IsNucleus(targetCode)) kATarget = GetNucleusA(targetCode); - if (targetCode == particles::Proton::GetCode()) kATarget = 1; - C8LOG_DEBUG("NuclearInteraction: nuclib target code: " + std::to_string(kATarget)); - if (!hadronicInteraction_.IsValidTarget(targetCode)) - throw std::runtime_error("target outside range. "); - // end of target sampling - - // superposition - C8LOG_DEBUG("NuclearInteraction: sampling nuc. multiple interaction structure.. "); - // get nucleon-nucleon cross section - // (needed to determine number of nucleon-nucleon scatterings) - const auto protonId = particles::Proton::GetCode(); - const auto [prodCrossSection, elaCrossSection] = - hadronicInteraction_.GetCrossSection(protonId, protonId, EcmNN); - const double sigProd = prodCrossSection / 1_mb; - const double sigEla = elaCrossSection / 1_mb; - // sample number of interactions (only input variables, output in common cnucms) - // nuclear multiple scattering according to glauber (r.i.p.) - int_nuc_(kATarget, kAProj, sigProd, sigEla); - - C8LOG_DEBUG( - fmt::format("number of nucleons in target : {}\n" - "number of wounded nucleons in target : {}\n" - "number of nucleons in projectile : {}\n" - "number of wounded nucleons in project. : {}\n" - "number of inel. nuc.-nuc. interactions : {}\n" - "number of elastic nucleons in target : {}\n" - "number of elastic nucleons in project. : {}\n" - "impact parameter: {}", - kATarget, cnucms_.na, kAProj, cnucms_.nb, cnucms_.ni, cnucms_.nael, - cnucms_.nbel, cnucms_.b)); - - // calculate fragmentation - C8LOG_DEBUG("calculating nuclear fragments.."); - // number of interactions - // include elastic - const int nElasticNucleons = cnucms_.nbel; - const int nInelNucleons = cnucms_.nb; - const int nIntProj = nInelNucleons + nElasticNucleons; - const double impactPar = cnucms_.b; // only needed to avoid passing common var. - int nFragments = 0; - // number of fragments is limited to 60 - int AFragments[60]; - // call fragmentation routine - // input: target A, projectile A, number of int. nucleons in projectile, impact - // parameter (fm) output: nFragments, AFragments in addition the momenta ar stored - // in pf in common fragments, neglected - fragm_(kATarget, kAProj, nIntProj, impactPar, nFragments, AFragments); - - // this should not occur but well :) - if (nFragments > (int)GetMaxNFragments()) - throw std::runtime_error("Number of nuclear fragments in NUCLIB exceeded!"); - - C8LOG_DEBUG("number of fragments: " + std::to_string(nFragments)); - for (int j = 0; j < nFragments; ++j) - C8LOG_DEBUG(fmt::format("fragment {}: A={} px={} py={} pz={}", j, AFragments[j], - fragments_.ppp[j][0], fragments_.ppp[j][1], - fragments_.ppp[j][2])); - - C8LOG_DEBUG("adding nuclear fragments to particle stack.."); - // put nuclear fragments on corsika stack - for (int j = 0; j < nFragments; ++j) { - particles::Code specCode; - const int nuclA = AFragments[j]; - // get Z from stability line - const int nuclZ = int(nuclA / 2.15 + 0.7); - - // TODO: do we need to catch single nucleons?? - if (nuclA == 1) - // TODO: sample neutron or proton - specCode = particles::Code::Proton; - else - specCode = particles::Code::Nucleus; - - // TODO: mass of nuclei? - const HEPMassType mass = - particles::Proton::GetMass() * nuclZ + - (nuclA - nuclZ) * particles::Neutron::GetMass(); // this neglects binding energy - - C8LOG_DEBUG("NuclearInteraction: adding fragment: " + particles::GetName(specCode)); - C8LOG_DEBUG("NuclearInteraction: A,Z: " + std::to_string(nuclA) + ", " + - std::to_string(nuclZ)); - C8LOG_DEBUG("NuclearInteraction: mass: " + std::to_string(mass / 1_GeV)); - - // CORSIKA 7 way - // spectators inherit momentum from original projectile - const double mass_ratio = mass / ProjMass; - - C8LOG_DEBUG("NuclearInteraction: mass ratio " + std::to_string(mass_ratio)); - - auto const Plab = PprojLab * mass_ratio; - - C8LOG_DEBUG(fmt::format("NuclearInteraction: fragment momentum: {}", - Plab.GetSpaceLikeComponents().GetComponents() / 1_GeV)); - - if (nuclA == 1) - // add nucleon - projectile.AddSecondary(make_tuple(specCode, Plab.GetTimeLikeComponent(), - Plab.GetSpaceLikeComponents(), pOrig, tOrig)); - else - // add nucleus - vP.AddSecondary(tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, - units::si::TimeType, unsigned short, unsigned short>{ - specCode, Plab.GetTimeLikeComponent(), Plab.GetSpaceLikeComponents(), pOrig, - tOrig, nuclA, nuclZ}); - } - - // add elastic nucleons to corsika stack - // TODO: the elastic interaction could be external like the inelastic interaction, - // e.g. use existing ElasticModel - C8LOG_DEBUG("adding elastically scattered nucleons to particle stack.."); - for (int j = 0; j < nElasticNucleons; ++j) { - // TODO: sample proton or neutron - auto const elaNucCode = particles::Code::Proton; - - // CORSIKA 7 way - // elastic nucleons inherit momentum from original projectile - // neglecting momentum transfer in interaction - const double mass_ratio = particles::GetMass(elaNucCode) / ProjMass; - auto const Plab = PprojLab * mass_ratio; - - vP.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, corsika::MomentumVector, - geometry::Point, units::si::TimeType>{ - elaNucCode, Plab.GetTimeLikeComponent(), Plab.GetSpaceLikeComponents(), - pOrig, tOrig}); - } - - // add inelastic interactions - C8LOG_DEBUG("calculate inelastic nucleon-nucleon interactions.."); - for (int j = 0; j < nInelNucleons; ++j) { - // TODO: sample neutron or proton - auto pCode = particles::Proton::GetCode(); - // temporarily add to stack, will be removed after interaction in DoInteraction - cout << "inelastic interaction no. " << j << endl; - auto inelasticNucleon = vP.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, corsika::MomentumVector, - geometry::Point, units::si::TimeType>{ - pCode, PprojNucLab.GetTimeLikeComponent(), - PprojNucLab.GetSpaceLikeComponents(), pOrig, tOrig}); - // create inelastic interaction - cout << "calling HadronicInteraction..." << endl; - hadronicInteraction_.DoInteraction(inelasticNucleon); - } - - C8LOG_DEBUG("NuclearInteraction: DoInteraction: done"); - - return process::EProcessReturn::eOk; - } - -} // namespace corsika::sibyll diff --git a/corsika/modules/Sibyll/ParticleConversion.cc b/corsika/modules/Sibyll/ParticleConversion.cc deleted file mode 100644 index 2e73f3a66373bb16d8dfe3b2cf330c2f52d6d1ad..0000000000000000000000000000000000000000 --- a/corsika/modules/Sibyll/ParticleConversion.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/process/sibyll/ParticleConversion.h> - -using namespace corsika::sibyll; - -corsika::units::si::HEPMassType corsika::process::sibyll::GetSibyllMass( - corsika::particles::Code const pCode) { - using namespace corsika::units; - using namespace corsika::units::si; - if (pCode == corsika::particles::Code::Nucleus) - throw std::runtime_error("Cannot GetMass() of particle::Nucleus -> unspecified"); - auto sCode = ConvertToSibyllRaw(pCode); - if (sCode == 0) - throw std::runtime_error("GetSibyllMass: unknown particle!"); - else - return sqrt(get_sibyll_mass2(sCode)) * 1_GeV; -} diff --git a/corsika/modules/Sibyll/code_generator.py b/corsika/modules/Sibyll/code_generator.py deleted file mode 100755 index 22cb11022741597b6807c844766dcf0158f24365..0000000000000000000000000000000000000000 --- a/corsika/modules/Sibyll/code_generator.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python3 - -# (c) Copyright 2018-2019 CORSIKA Project, corsika-project@lists.kit.edu -# -# See file AUTHORS for a list of contributors. -# -# This software is distributed under the terms of the GNU General Public -# Licence version 3 (GPL Version 3). See file LICENSE for a full version of -# the license. - - -import pickle, sys, itertools - - - -def load_particledb(filename): - ''' - loads the pickled particle_db (which is an OrderedDict) - ''' - with open(filename, "rb") as f: - particle_db = pickle.load(f) - return particle_db - - - -def read_sibyll_codes(filename, particle_db): - ''' - reads to sibyll codes data file - - For particls known to sibyll, add 'sibyll_code' and 'sibyll_xsType' to particle_db - ''' - with open(filename) as f: - for line in f: - line = line.strip() - if len(line)==0 or line[0] == '#': - continue - identifier, sib_code, canInteractFlag, xsType = line.split() - try: - particle_db[identifier]["sibyll_code"] = int(sib_code) - particle_db[identifier]["sibyll_xsType"] = xsType - except KeyError as e: - raise Exception("Identifier '{:s}' not found in particle_db".format(identifier)) - - - - -def generate_sibyll_enum(particle_db): - ''' - generates the enum to access sibyll particles by readable names - ''' - output = "enum class SibyllCode : int8_t {\n" - for identifier, pData in particle_db.items(): - if 'sibyll_code' in pData: - output += " {:s} = {:d},\n".format(identifier, pData['sibyll_code']) - output += "};\n" - return output - - - -def generate_corsika2sibyll(particle_db): - ''' - generates the look-up table to convert corsika codes to sibyll codes - ''' - string = "std::array<SibyllCode, {:d}> constexpr corsika2sibyll = {{\n".format(len(particle_db)) - for identifier, pData in particle_db.items(): - if 'sibyll_code' in pData: - string += " SibyllCode::{:s}, \n".format(identifier) - else: - string += " SibyllCode::Unknown, // {:s}\n".format(identifier + ' not implemented in SIBYLL') - string += "};\n" - return string - - - -def generate_corsika2sibyll_xsType(particle_db): - ''' - generates the look-up table to convert corsika codes to sibyll codes - ''' - string = "std::array<SibyllXSClass, {:d}> constexpr corsika2sibyllXStype = {{\n".format(len(particle_db)) - for identifier, pData in particle_db.items(): - if 'sibyll_xsType' in pData: - string += " SibyllXSClass::{:s}, // {:s}\n".format(pData['sibyll_xsType'], identifier) - else: - string += " SibyllXSClass::CannotInteract, // {:s}\n".format(identifier + ' not implemented in SIBYLL') - string += "};\n" - return string - - -def generate_sibyll2corsika(particle_db) : - ''' - generates the look-up table to convert sibyll codes to corsika codes - ''' - string = "" - - minID = 0 - for identifier, pData in particle_db.items() : - if 'sibyll_code' in pData: - minID = min(minID, pData['sibyll_code']) - - string += "SibyllCodeIntType constexpr minSibyll = {:d};\n\n".format(minID) - - pDict = {} - for identifier, pData in particle_db.items() : - if 'sibyll_code' in pData: - sib_code = pData['sibyll_code'] - minID - pDict[sib_code] = identifier - - nPart = max(pDict.keys()) - min(pDict.keys()) + 1 - string += "std::array<corsika::Code, {:d}> constexpr sibyll2corsika = {{\n".format(nPart) - - for iPart in range(nPart) : - if iPart in pDict: - identifier = pDict[iPart] - else: - identifier = "Unknown" - string += " corsika::Code::{:s}, \n".format(identifier) - - string += "};\n" - return string - -if __name__ == "__main__": - if len(sys.argv) != 3: - print("usage: {:s} <particle_db.pkl> <sibyll_codes.dat>".format(sys.argv[0]), file=sys.stderr) - sys.exit(1) - - print("code_generator.py for SIBYLL") - - particle_db = load_particledb(sys.argv[1]) - read_sibyll_codes(sys.argv[2], particle_db) - - with open("Generated.inc", "w") as f: - print("// this file is automatically generated\n// edit at your own risk!\n", file=f) - print(generate_sibyll_enum(particle_db), file=f) - print(generate_corsika2sibyll(particle_db), file=f) - print(generate_sibyll2corsika(particle_db), file=f) - print(generate_corsika2sibyll_xsType(particle_db), file=f) diff --git a/corsika/modules/Sibyll/sibyll_codes.dat b/corsika/modules/Sibyll/sibyll_codes.dat deleted file mode 100644 index d8cce42e494585023d460a0a50635a12d44139fd..0000000000000000000000000000000000000000 --- a/corsika/modules/Sibyll/sibyll_codes.dat +++ /dev/null @@ -1,132 +0,0 @@ -# input file for particle conversion to/from SIBYLL -# the format of this file is: "corsika-identifier" "sibyll-id" "can-interact-in-sibyll" "cross-section-type" - -# The unknown particle is to handle all particles that are not known to SIBYLL. -# It is important that sibyll-id does not overlap with any existing sibyll particle! -# Be careful -Unknown 0 0 CannotInteract - -# Here is the list of particles known to sibyll -Electron 3 0 CannotInteract -Positron 2 0 CannotInteract -NuE 15 0 CannotInteract -NuEBar 16 0 CannotInteract -MuMinus 5 0 CannotInteract -MuPlus 4 0 CannotInteract -NuMu 17 0 CannotInteract -NuMuBar 18 0 CannotInteract -TauMinus 91 0 CannotInteract -TauPlus 90 0 CannotInteract -NuTau 92 0 CannotInteract -NuTauBar 93 0 CannotInteract -Gamma 1 0 CannotInteract -Pi0 6 1 Pion -# rho0 could interact but sibyll has no cross section/interaction length. was used for gamma had int -Rho0 27 0 CannotInteract -K0Long 11 1 Kaon -K0 21 0 Kaon -K0Bar 22 0 Kaon -PiPlus 7 1 Pion -PiMinus 8 1 Pion -RhoPlus 25 0 CannotInteract -RhoMinus 26 0 CannotInteract -Eta 23 0 CannotInteract -EtaPrime 24 0 CannotInteract -Pi1300Plus 62 0 CannotInteract -Pi1300Minus 63 0 CannotInteract -Pi1300_0 61 0 CannotInteract -Omega 32 0 CannotInteract -K0Short 12 1 Kaon -KStar0 30 0 CannotInteract -KStar0Bar 31 0 CannotInteract -KPlus 9 1 Kaon -KMinus 10 1 Kaon -KStarPlus 28 0 CannotInteract -KStarMinus 29 0 CannotInteract -KStar0_1430_0 66 0 CannotInteract -KStar0_1430_0Bar 67 0 CannotInteract -KStar0_1430_Plus 64 0 CannotInteract -KStar0_1430_MinusBar 65 0 CannotInteract -DPlus 59 1 Kaon -DMinus 60 1 Kaon -DStarPlus 78 0 CannotInteract -DStarMinus 79 0 CannotInteract -D0 71 1 Kaon -D0Bar 72 1 Kaon -DStar0 80 0 CannotInteract -DStar0Bar 81 0 CannotInteract -DsPlus 74 1 Kaon -DsMinus 75 1 Kaon -DStarSPlus 76 0 CannotInteract -DStarSMinus 77 0 CannotInteract -EtaC 73 0 CannotInteract -Neutron 14 1 Baryon -AntiNeutron -14 1 Baryon -Delta0 42 0 CannotInteract -Delta0Bar -42 0 CannotInteract -DeltaMinus 43 0 CannotInteract -DeltaPlusBar -43 0 CannotInteract -Proton 13 1 Baryon -AntiProton -13 1 Baryon -N1440Plus 51 0 CannotInteract -N1440MinusBar -51 0 CannotInteract -N1440_0 52 0 CannotInteract -N1440_0Bar -52 0 CannotInteract -N1710Plus 53 0 CannotInteract -N1710MinusBar -53 0 CannotInteract -N1710_0 54 0 CannotInteract -N1710_0Bar -54 0 CannotInteract -DeltaPlus 41 0 CannotInteract -DeltaMinusBar -41 0 CannotInteract -DeltaPlusPlus 40 0 CannotInteract -DeltaMinusMinusBar -40 0 CannotInteract -SigmaMinus 36 1 Baryon -SigmaPlusBar -36 1 Baryon -SigmaStarMinus 46 0 CannotInteract -SigmaStarPlusBar -46 0 CannotInteract -SigmaStarPlus 44 0 CannotInteract -SigmaStarMinusBar -44 0 CannotInteract -SigmaStar0 45 0 CannotInteract -SigmaStar0Bar -45 0 CannotInteract -Lambda0 39 1 Baryon -Lambda0Bar -39 1 Baryon -Sigma0 35 1 Baryon -Sigma0Bar -35 1 Baryon -SigmaPlus 34 1 Baryon -SigmaMinusBar -34 1 Baryon -XiMinus 38 1 Baryon -XiPlusBar -38 1 Baryon -Xi0 37 1 Baryon -Xi0Bar -37 1 Baryon -XiStarMinus 48 0 CannotInteract -XiStarPlusBar -48 0 CannotInteract -XiStar0 47 0 CannotInteract -XiStar0Bar -47 0 CannotInteract -OmegaMinus 49 0 CannotInteract -OmegaPlusBar -49 0 CannotInteract -SigmaC0 86 0 CannotInteract -SigmaC0Bar -86 0 CannotInteract -SigmaStarC0 96 0 CannotInteract -SigmaStarC0Bar -96 0 CannotInteract -LambdaCPlus 89 1 Baryon -LambdaCMinusBar -89 1 Baryon -XiC0 88 1 Baryon -XiC0Bar -88 1 Baryon -SigmaCPlus 85 0 CannotInteract -SigmaCMinusBar -85 0 CannotInteract -SigmaStarCPlus 95 0 CannotInteract -SigmaStarCMinusBar -95 0 CannotInteract -SigmaCPlusPlus 84 0 CannotInteract -SigmaCMinusMinusBar -84 0 CannotInteract -SigmaStarCPlusPlus 94 0 CannotInteract -SigmaStarCMinusMinusBar -94 0 CannotInteract -XiCPlus 87 1 Baryon -XiCMinusBar -87 1 Baryon -XiStarCPlus 97 0 CannotInteract -XiStarCMinusBar -97 0 CannotInteract -XiStarC0 98 0 CannotInteract -XiStarC0Bar -98 0 CannotInteract -OmegaC0 99 0 CannotInteract -OmegaC0Bar -99 0 CannotInteract -Jpsi 83 0 CannotInteract -Phi 33 0 CannotInteract diff --git a/corsika/modules/Sibyll/testSibyll.cc b/corsika/modules/Sibyll/testSibyll.cc deleted file mode 100644 index cc9245629639004dd9bec1551faeec4eb0c9127e..0000000000000000000000000000000000000000 --- a/corsika/modules/Sibyll/testSibyll.cc +++ /dev/null @@ -1,273 +0,0 @@ -/* - * (c) Copyright 2019 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/sibyll/Decay.h> -#include <corsika/process/sibyll/Interaction.h> -#include <corsika/process/sibyll/NuclearInteraction.h> -#include <corsika/process/sibyll/ParticleConversion.h> - -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/core/ParticleProperties.hpp> - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <catch2/catch.hpp> -#include <tuple> - -using namespace corsika; -using namespace corsika::sibyll; - -TEST_CASE("Sibyll", "[processes]") { - - SECTION("Sibyll -> Corsika") { - CHECK(particles::Electron::GetCode() == - process::sibyll::ConvertFromSibyll(process::sibyll::SibyllCode::Electron)); - } - - SECTION("Corsika -> Sibyll") { - CHECK(process::sibyll::ConvertToSibyll(particles::Electron::GetCode()) == - process::sibyll::SibyllCode::Electron); - CHECK(process::sibyll::ConvertToSibyllRaw(particles::Proton::GetCode()) == 13); - CHECK(process::sibyll::ConvertToSibyll(particles::XiStarC0::GetCode()) == - process::sibyll::SibyllCode::XiStarC0); - } - - SECTION("canInteractInSibyll") { - - CHECK(process::sibyll::CanInteract(particles::Proton::GetCode())); - CHECK(process::sibyll::CanInteract(particles::Code::XiCPlus)); - - CHECK_FALSE(process::sibyll::CanInteract(particles::Electron::GetCode())); - CHECK_FALSE(process::sibyll::CanInteract(particles::SigmaC0::GetCode())); - - CHECK_FALSE(process::sibyll::CanInteract(particles::Nucleus::GetCode())); - CHECK_FALSE(process::sibyll::CanInteract(particles::Helium::GetCode())); - } - - SECTION("cross-section type") { - - CHECK(process::sibyll::GetSibyllXSCode(particles::Code::Electron) == 0); - CHECK(process::sibyll::GetSibyllXSCode(particles::Code::K0Long) == 3); - CHECK(process::sibyll::GetSibyllXSCode(particles::Code::SigmaPlus) == 1); - CHECK(process::sibyll::GetSibyllXSCode(particles::Code::PiMinus) == 2); - } - - SECTION("sibyll mass") { - - CHECK_FALSE(process::sibyll::GetSibyllMass(particles::Code::Electron) == 0_GeV); - } -} - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> - -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/framework/core/ParticleProperties.hpp> -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -#include <corsika/media/Environment.hpp> -#include <corsika/media/HomogeneousMedium.hpp> -#include <corsika/media/NuclearComposition.hpp> -#include <corsika/process/sibyll/sibyll2.3c.h> - -using namespace corsika::units::si; -using namespace corsika::units; - -template <typename TStackView> -auto sumMomentum(TStackView const& view, geometry::CoordinateSystem const& vCS) { - geometry::Vector<hepenergy_d> sum{vCS, 0_eV, 0_eV, 0_eV}; - for (auto const& p : view) { sum += p.GetMomentum(); } - return sum; -} - -TEST_CASE("SibyllInterface", "[processes]") { - - auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen); - auto const& cs = *csPtr; - [[maybe_unused]] auto const& env_dummy = env; - [[maybe_unused]] auto const& node_dummy = nodePtr; - - random::RNGManager::GetInstance().RegisterRandomStream("sibyll"); - - SECTION("InteractionInterface - low energy") { - - const HEPEnergyType P0 = 60_GeV; - auto [stack, viewPtr] = - setup::testing::setupStack(particles::Code::Proton, 0, 0, P0, nodePtr, cs); - const auto plab = corsika::stack::MomentumVector( - cs, {P0, 0_eV, 0_eV}); // this is secret knowledge about setupStack - setup::StackView& view = *viewPtr; - - setup::Stack stack; - const HEPEnergyType E0 = 100_GeV; - HEPMomentumType P0 = - sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass()); - auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0}); - geometry::Point pos(cs, 0_m, 0_m, 0_m); - auto particle = stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - particles::Code::Proton, E0, plab, pos, 0_ns}); - particle.SetNode(nodePtr); - corsika::SecondaryView view(particle); - auto projectile = view.GetProjectile(); - - Interaction model; - - [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(view); - auto const pSum = sumMomentum(view, cs); - - /* - Interactions between hadrons (h) and nuclei (A) in Sibyll are treated in the - hadron-nucleon center-of-mass frame (hnCoM). The incoming hadron (h) and - nucleon (N) are assumed massless, such that the energy and momentum in the hnCoM are - : E_i_cm = 0.5 * SQS and P_i_cm = +- 0.5 * SQS where i is either the projectile - hadron or the target nucleon and SQS is the hadron-nucleon center-of-mass energy. - - The true energies and momenta, accounting for the hadron masses, are: E_i = ( S + - m_i**2 - m_j**2 ) / (2 * SQS) and Pcm = +- - sqrt( (S-(m_j+m_i)**2) * (s-(m_j-m_i)**2) ) / (2*SQS) where m_i is the projectiles - mass and m_j is the target particles mass. In terms of lab. frame variables Pcm = - m_j * Plab_i / SQS, where Plab_i is the momentum of the projectile (i) in the lab. - and m_j is the mass of the target, i.e. the particle at rest (usually a nucleon). - - Any hadron-nucleus event can contain several nucleon interactions. In case of Nw - (number of wounded nucleons) nucleons interacting in the hadron-nucleus interaction, - the total energy and momentum in the hadron(i)-nucleon(N) center-of-mass frame are: - momentum: p_projectile + p_nucleon_1 + p_nucleon_2 + .... p_nucleon_Nw = -(Nw-1) * - Pcm with center-of-mass momentum Pcm = p_projectile = - p_nucleon_i. For the energy: - E_projectile + E_nucleon_1 + ... E_nucleon_Nw = E_projectile + Nw * E_nucleon. - - Using the above definitions of center-of-mass energies and momenta this leads to the - total energy: E_tot = SQS/2 * (1+Nw) + (m_N**2-m_i**2)/(2*SQS) * (Nw-1) and P_tot - = -m_N * Plab_i / SQS * (Nw-1). - - A Lorentztransformation of these quantities to the lab. frame recovers Plab_i for - the total momentum, so momentum is exactly conserved, and Elab_i + Nw * m_N for the - total energy. Not surprisingly the total energy differs from the total energy before - the collision by the mass of the additional nucleons (Nw-1)*m_N. In relative terms - the additional energy is entirely negligible and as it is not kinetic energy there - is zero influence on the shower development. - - Due to the ommission of the hadron masses in Sibyll, the total energy and momentum - in the center-of-mass system after the collision are just: E_tot = SQS/2 * (1+Nw) - and P_tot = SQS/2 * (1-Nw). After the Lorentztransformation the total momentum in - the lab. thus differs from the initial value by (1-Nw)/2 * ( m_N + m_i**2 / (2 * - Plab_i) ) and momentum is NOT conserved. Note however that the second term quickly - vanishes as the lab. momentum of the projectile increases. The first term is fixed - as it depends only on the number of additional nucleons, in relative terms it is - always small at high energies. - - For this reason the numerical precision in these tests is limited to 5% to still - pass at low energies and no absolute check is implemented, e.g. - - CHECK(pSum.GetComponents(cs).GetX() / P0 == Approx(1).margin(0.05)); - CHECK((pSum - plab).norm()/1_GeV == Approx(0).margin(plab.norm() * 0.05/1_GeV)); - - /FR'2020 - - See also: - - Issue 272 / MR 204 - https://gitlab.ikp.kit.edu/AirShowerPhysics/corsika/-/merge_requests/204 - - */ - - 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).norm() / 1_GeV == Approx(0).margin(plab.norm() * 0.05 / 1_GeV)); - CHECK(pSum.norm() / P0 == Approx(1).margin(0.05)); - [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle); - CHECK(length / 1_g * 1_cm * 1_cm == Approx(88.7).margin(0.1)); - // CHECK(view.getSize() == 20); // also sibyll not stable wrt. to compiler changes - } - - SECTION("NuclearInteractionInterface") { - - setup::Stack stack; - const HEPEnergyType E0 = 400_GeV; - HEPMomentumType P0 = - sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass()); - auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0}); - geometry::Point pos(cs, 0_m, 0_m, 0_m); - - auto particle = - stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, - units::si::TimeType, unsigned short, unsigned short>{ - particles::Code::Nucleus, E0, plab, pos, 0_ns, 4, 2}); - particle.SetNode(nodePtr); - corsika::SecondaryView view(particle); - auto projectile = view.GetProjectile(); - - Interaction hmodel; - NuclearInteraction model(hmodel, *env); - - [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(view); - [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle); - CHECK(length / 1_g * 1_cm * 1_cm == Approx(44.2).margin(.1)); - // CHECK(view.getSize() == 11); // also sibyll not stable wrt. to compiler changes - } - - SECTION("DecayInterface") { - - setup::Stack stack; - const HEPEnergyType E0 = 10_GeV; - HEPMomentumType P0 = - sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass()); - auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0}); - geometry::Point pos(cs, 0_m, 0_m, 0_m); - auto particle = stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - particles::Code::Lambda0, E0, plab, pos, 0_ns}); - corsika::SecondaryView view(particle); - auto projectile = view.GetProjectile(); - - Decay model; - model.PrintDecayConfig(); - [[maybe_unused]] const TimeType time = model.GetLifetime(particle); - - /*[[maybe_unused]] const process::EProcessReturn ret =*/model.DoDecay(view); - // run checks - // lambda decays into proton and pi- or neutron and pi+ - CHECK(stack.getEntries() == 3); - } - - SECTION("DecayConfiguration") { - - Decay model({particles::Code::PiPlus, particles::Code::PiMinus}); - CHECK(model.IsDecayHandled(particles::Code::PiPlus)); - CHECK(model.IsDecayHandled(particles::Code::PiMinus)); - CHECK_FALSE(model.IsDecayHandled(particles::Code::KPlus)); - - const std::vector<particles::Code> particleTestList = { - particles::Code::PiPlus, particles::Code::PiMinus, particles::Code::KPlus, - particles::Code::Lambda0Bar, particles::Code::D0Bar}; - - // setup decays - model.SetHandleDecay(particleTestList); - for (auto& pCode : particleTestList) CHECK(model.IsDecayHandled(pCode)); - - // individually - model.SetHandleDecay(particles::Code::KMinus); - - // possible decays - CHECK_FALSE(model.CanHandleDecay(particles::Code::Proton)); - CHECK_FALSE(model.CanHandleDecay(particles::Code::Electron)); - CHECK(model.CanHandleDecay(particles::Code::PiPlus)); - CHECK(model.CanHandleDecay(particles::Code::MuPlus)); - } -} diff --git a/corsika/modules/UrQMD/UrQMD.cc b/corsika/modules/UrQMD/UrQMD.cc deleted file mode 100644 index a433088454a218c29075975f7bbe673fb35bc9da..0000000000000000000000000000000000000000 --- a/corsika/modules/UrQMD/UrQMD.cc +++ /dev/null @@ -1,385 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/framework/geometry/QuantityVector.hpp> -#include <corsika/framework/geometry/Vector.hpp> -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/process/urqmd/UrQMD.h> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <algorithm> -#include <array> -#include <cassert> -#include <cmath> -#include <fstream> -#include <functional> -#include <random> -#include <sstream> - -using namespace corsika::UrQMD; -using namespace corsika::units::si; - -UrQMD::UrQMD() { iniurqmd_(); } - -using SetupStack = corsika::Stack; -using SetupParticle = corsika::Stack::StackIterator; -using SetupProjectile = corsika::StackView::StackIterator; - -CrossSectionType UrQMD::GetCrossSection(particles::Code vProjectileCode, - corsika::Code vTargetCode, - HEPEnergyType vLabEnergy, int vAProjectile = 1) { - // the following is a translation of ptsigtot() into C++ - if (vProjectileCode != particles::Code::Nucleus && - !IsNucleus(vTargetCode)) { // both particles are "special" - auto const mProj = particles::GetMass(vProjectileCode); - auto const mTar = particles::GetMass(vTargetCode); - double sqrtS = sqrt(units::si::detail::static_pow<2>(mProj) + - units::si::detail::static_pow<2>(mTar) + 2 * vLabEnergy * mTar) * - (1 / 1_GeV); - - // we must set some UrQMD globals first... - auto const [ityp, iso3] = ConvertToUrQMD(projectileCode); - inputs_.spityp[0] = ityp; - inputs_.spiso3[0] = iso3; - - auto const [itypTar, iso3Tar] = ConvertToUrQMD(targetCode); - inputs_.spityp[1] = itypTar; - inputs_.spiso3[1] = iso3Tar; - - int one = 1; - int two = 2; - int three = 3; - - double const totalXS = sigtot_(one, two, sqrtS); - - // subtract elastic cross-section as in ptsigtot() - int itypmn, itypmx, iso3mn, iso3mx; - if (ityp < itypTar) { - itypmn = ityp; - itypmx = itypTar; - - iso3mn = iso3; - iso3mx = iso3Tar; - } else { - itypmx = ityp; - itypmn = itypTar; - - iso3mx = iso3; - iso3mn = iso3Tar; - } - - int isigline = collclass_(itypmx, iso3mx, itypmn, iso3mn); - int iline = readsigmaln_(three, one, isigline); - double sigEl; - double massProj = mProj / 1_GeV; - double massTar = mTar / 1_GeV; - - crossx_(iline, sqrtS, ityp, iso3, massProj, itypTar, iso3Tar, massTar, sigEl); - - if (totalXS > sigEl) { - return (totalXS - sigEl) * 1_mb; - } else { - return sigEl * 0_mb; - } - } else { - int const Ap = projectileA; - int const At = IsNucleus(targetCode) ? particles::GetNucleusA(targetCode) : 1; - - double const maxImpact = nucrad_(Ap) + nucrad_(At) + 2 * options_.CTParam[30 - 1]; - return 10_mb * M_PI * units::static_pow<2>(maxImpact); - // is a constant cross-section really reasonable? - } -} - -template <typename TParticle> // need template here, as this is called both with - // SetupParticle as well as SetupProjectile -CrossSectionType UrQMD::GetCrossSection(TParticle const& vProjectile, - corsika::Code vTargetCode) const { - // TODO: return 0 for non-hadrons? - - auto const projectileCode = vProjectile.GetPID(); - auto const projectileEnergyLab = vProjectile.GetEnergy(); - - if (projectileCode == particles::Code::K0Long) { - return 0.5 * - (GetCrossSection(particles::Code::K0, vTargetCode, projectileEnergyLab) + - GetCrossSection(particles::Code::K0Bar, vTargetCode, projectileEnergyLab)); - } - - return GetTabulatedCrossSection(projectileCode, targetCode, projectileEnergyLab); -} - -bool UrQMD::CanInteract(particles::Code code) const { - // According to the manual, UrQMD can use all mesons, baryons and nucleons - // which are modeled also as input particles. I think it is safer to accept - // only the usual long-lived species as input. - - // Interactions with nucleus projectiles are possible in principle with UrQMD - // but right now we don't have access to the inelastic (production) cross-section, - // so we unfortunately have to forbid these interactions for the time being. - - static particles::Code const validProjectileCodes[] = { - particles::Code::Proton, particles::Code::AntiProton, particles::Code::Neutron, - particles::Code::AntiNeutron, particles::Code::PiPlus, particles::Code::PiMinus, - particles::Code::KPlus, particles::Code::KMinus, particles::Code::K0Short, - particles::Code::K0Long}; - - return std::find(std::cbegin(validProjectileCodes), std::cend(validProjectileCodes), - code) != std::cend(validProjectileCodes); -} - -GrammageType UrQMD::GetInteractionLength(SetupParticle const& particle) const { - if (!CanInteract(particle.GetPID())) { - // we could do the canInteract check in GetCrossSection, too but if - // we do it here we have the advantage of avoiding the loop - return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); - } - - auto const& mediumComposition = - particle.GetNode()->GetModelProperties().GetNuclearComposition(); - using namespace std::placeholders; - - CrossSectionType const weightedProdCrossSection = mediumComposition.WeightedSum( - std::bind(&UrQMD::GetCrossSection<decltype(particle)>, this, particle, _1)); - - return mediumComposition.GetAverageMassNumber() * units::constants::u / - weightedProdCrossSection; -} - -corsika::EProcessReturn UrQMD::DoInteraction(SetupProjectile& vProjectile) { - using namespace units::si; - - auto const projectile = view.GetProjectile(); - - auto projectileCode = projectile.GetPID(); - auto const projectileEnergyLab = projectile.GetEnergy(); - auto const& projectileMomentumLab = projectile.GetMomentum(); - auto const& projectilePosition = projectile.GetPosition(); - auto const projectileTime = projectile.GetTime(); - - C8LOG_DEBUG("UrQMD::DoInteraction pid={} E={} GeV", projectileCode, - projectileEnergyLab / 1_GeV); - - // sample target particle - auto const& mediumComposition = - projectile.GetNode()->GetModelProperties().GetNuclearComposition(); - auto const componentCrossSections = std::invoke([&]() { - auto const& components = mediumComposition.GetComponents(); - std::vector<CrossSectionType> crossSections; - crossSections.reserve(components.size()); - - for (auto const c : components) { - crossSections.push_back(GetCrossSection(projectile, c)); - } - - return crossSections; - }); - - auto const targetCode = mediumComposition.SampleTarget(componentCrossSections, rng_); - auto const targetA = particles::GetNucleusA(targetCode); - auto const targetZ = particles::GetNucleusZ(targetCode); - - inputs_.nevents = 1; - sys_.eos = 0; // could be configurable in principle - inputs_.outsteps = 1; - sys_.nsteps = 1; - - // initialization regarding projectile - if (particles::Code::Nucleus == projectileCode) { - // is this everything? - inputs_.prspflg = 0; - - sys_.Ap = projectile.GetNuclearA(); - sys_.Zp = projectile.GetNuclearZ(); - rsys_.ebeam = (projectileEnergyLab - projectile.GetMass()) * (1 / 1_GeV) / - projectile.GetNuclearA(); - - rsys_.bdist = nucrad_(targetA) + nucrad_(sys_.Ap) + 2 * options_.CTParam[30 - 1]; - - int const id = 1; - cascinit_(sys_.Zp, sys_.Ap, id); - } else { - inputs_.prspflg = 1; - sys_.Ap = 1; // even for non-baryons this has to be set, see vanilla UrQMD.f - rsys_.bdist = nucrad_(targetA) + nucrad_(1) + 2 * options_.CTParam[30 - 1]; - rsys_.ebeam = (projectileEnergyLab - projectile.GetMass()) * (1 / 1_GeV); - - if (projectileCode == particles::Code::K0Long || - projectileCode == particles::Code::K0Short) { - projectileCode = booleanDist_(rng_) ? particles::Code::K0 : particles::Code::K0Bar; - } - - auto const [ityp, iso3] = ConvertToUrQMD(projectileCode); - // todo: conversion of K_long/short into strong eigenstates; - inputs_.spityp[0] = ityp; - inputs_.spiso3[0] = iso3; - } - - // initilazation regarding target - if (particles::IsNucleus(targetCode)) { - sys_.Zt = targetZ; - sys_.At = targetA; - inputs_.trspflg = 0; // nucleus as target - int const id = 2; - cascinit_(sys_.Zt, sys_.At, id); - } else { - inputs_.trspflg = 1; // special particle as target - auto const [ityp, iso3] = ConvertToUrQMD(targetCode); - inputs_.spityp[1] = ityp; - inputs_.spiso3[1] = iso3; - } - - int iflb = 0; // flag for retrying interaction in case of empty event, 0 means retry - urqmd_(iflb); - - // now retrieve secondaries from UrQMD - auto const& originalCS = projectileMomentumLab.GetCoordinateSystem(); - geometry::CoordinateSystem const zAxisFrame = - originalCS.RotateToZ(projectileMomentumLab); - - for (int i = 0; i < sys_.npart; ++i) { - auto code = ConvertFromUrQMD(isys_.ityp[i], isys_.iso3[i]); - if (code == particles::Code::K0 || code == particles::Code::K0Bar) { - code = booleanDist_(rng_) ? particles::Code::K0Short : particles::Code::K0Long; - } - - // "coor_.p0[i] * 1_GeV" is likely off-shell as UrQMD doesn't preserve masses well - auto momentum = geometry::Vector( - zAxisFrame, - geometry::QuantityVector<dimensionless_d>{coor_.px[i], coor_.py[i], coor_.pz[i]} * - 1_GeV); - - auto const energy = sqrt(momentum.squaredNorm() + square(particles::GetMass(code))); - - momentum.rebase(originalCS); // transform back into standard lab frame - C8LOG_DEBUG(" Secondary {} code {} p={} GeV", i, code, - momentum.GetComponents() / 1_GeV); - - view.AddSecondary( - std::make_tuple(code, energy, momentum, projectilePosition, projectileTime)); - } - - C8LOG_DEBUG("UrQMD generated {} secondaries!", sys_.npart); - - return process::EProcessReturn::eOk; -} - -/** - * the random number generator function of UrQMD - */ -double corsika::UrQMD::ranf_(int&) { - static corsika::RNG& rng = - corsika::RNGManager::GetInstance().GetRandomStream("UrQMD"); - static std::uniform_real_distribution<double> dist; - - return dist(rng); -} - -corsika::Code corsika::UrQMD::ConvertFromUrQMD(int vItyp, int vIso3) { - int const pdgInt = - pdgid_(vItyp, vIso3); // use the conversion function provided by UrQMD - if (pdgInt == 0) { // pdgid_ returns 0 on error - throw std::runtime_error("UrQMD pdgid() returned 0"); - } - auto const pdg = static_cast<particles::PDGCode>(pdgInt); - return particles::ConvertFromPDG(pdg); -} - -std::pair<int, int> corsika::UrQMD::ConvertToUrQMD( - corsika::Code code) { - static const std::map<int, std::pair<int, int>> mapPDGToUrQMD{ - // data mostly from github.com/afedynitch/ParticleDataTool - {22, {100, 0}}, // gamma - {111, {101, 0}}, // pi0 - {211, {101, 2}}, // pi+ - {-211, {101, -2}}, // pi- - {321, {106, 1}}, // K+ - {-321, {-106, -1}}, // K- - {311, {106, -1}}, // K0 - {-311, {-106, 1}}, // K0bar - {2212, {1, 1}}, // p - {2112, {1, -1}}, // n - {-2212, {-1, -1}}, // pbar - {-2112, {-1, 1}}, // nbar - {221, {102, 0}}, // eta - {213, {104, 2}}, // rho+ - {-213, {104, -2}}, // rho- - {113, {104, 0}}, // rho0 - {323, {108, 2}}, // K*+ - {-323, {108, -2}}, // K*- - {313, {108, 0}}, // K*0 - {-313, {-108, 0}}, // K*0-bar - {223, {103, 0}}, // omega - {333, {109, 0}}, // phi - {3222, {40, 2}}, // Sigma+ - {3212, {40, 0}}, // Sigma0 - {3112, {40, -2}}, // Sigma- - {3322, {49, 0}}, // Xi0 - {3312, {49, -1}}, // Xi- - {3122, {27, 0}}, // Lambda0 - {2224, {17, 4}}, // Delta++ - {2214, {17, 2}}, // Delta+ - {2114, {17, 0}}, // Delta0 - {1114, {17, -2}}, // Delta- - {3224, {41, 2}}, // Sigma*+ - {3214, {41, 0}}, // Sigma*0 - {3114, {41, -2}}, // Sigma*- - {3324, {50, 0}}, // Xi*0 - {3314, {50, -1}}, // Xi*- - {3334, {55, 0}}, // Omega- - {411, {133, 2}}, // D+ - {-411, {133, -2}}, // D- - {421, {133, 0}}, // D0 - {-421, {-133, 0}}, // D0-bar - {441, {107, 0}}, // etaC - {431, {138, 1}}, // Ds+ - {-431, {138, -1}}, // Ds- - {433, {139, 1}}, // Ds*+ - {-433, {139, -1}}, // Ds*- - {413, {134, 1}}, // D*+ - {-413, {134, -1}}, // D*- - {10421, {134, 0}}, // D*0 - {-10421, {-134, 0}}, // D*0-bar - {443, {135, 0}}, // jpsi - }; - - return mapPDGToUrQMD.at(static_cast<int>(GetPDG(code))); -} - -void UrQMD::readXSFile(std::string const& filename) { - std::ifstream file(filename, std::ios::in); - - if (!file.is_open()) { throw std::runtime_error(filename + " could not be opened."); } - - std::string line; - - std::getline(file, line); - std::stringstream ss(line); - - char dummy; - int nTargets, nProjectiles, nSupports; - ss >> dummy >> nTargets >> nProjectiles >> nSupports; - - decltype(xs_interp_support_table_)::extent_gen extents; - xs_interp_support_table_.resize(extents[nProjectiles][nTargets][nSupports]); - - for (int i = 0; i < nTargets; ++i) { - for (int j = 0; j < nProjectiles; ++j) { - for (int k = 0; k < nSupports; ++k) { - std::getline(file, line); - std::stringstream s(line); - double energy, sigma; - s >> energy >> sigma; - xs_interp_support_table_[j][i][k] = sigma * 1_mb; - } - - std::getline(file, line); - std::getline(file, line); - } - } -} diff --git a/corsika/modules/UrQMD/UrQMD.h b/corsika/modules/UrQMD/UrQMD.h deleted file mode 100644 index 61a23b0ef876be1fd48d746a8f1cd3c451eec6d4..0000000000000000000000000000000000000000 --- a/corsika/modules/UrQMD/UrQMD.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/InteractionProcess.hpp> -#include <corsika/framework/random/RNGManager.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <array> -#include <random> -#include <string> -#include <utility> -#include "../../corsika/setup/SetupStack.hpp" - -namespace corsika::UrQMD { - class UrQMD : public corsika::InteractionProcess<UrQMD> { - public: - UrQMD(std::string const& path = utl::CorsikaData("UrQMD/UrQMD-1.3.1-xs.dat")); - corsika::units::si::GrammageType GetInteractionLength( - corsika::Stack::StackIterator&) const; - - template <typename TParticle> - corsika::units::si::CrossSectionType GetCrossSection(TParticle const&, - corsika::Code) const; - - corsika::EProcessReturn DoInteraction( - corsika::StackView::StackIterator&); - - bool CanInteract(particles::Code) const; - - private: - static corsika::units::si::CrossSectionType GetCrossSection( - particles::Code, particles::Code, corsika::units::si::HEPEnergyType, int); - corsika::RNG& fRNG = - corsika::RNGManager::GetInstance().GetRandomStream("UrQMD"); - - corsika::random::RNG& rng_ = - corsika::random::RNGManager::GetInstance().GetRandomStream("urqmd"); - - std::uniform_int_distribution<int> booleanDist_{0, 1}; - boost::multi_array<corsika::units::si::CrossSectionType, 3> xs_interp_support_table_; - }; - - namespace details::constants { - // from coms.f - int constexpr nmax = 500; - - // from options.f - int constexpr numcto = 400; - int constexpr numctp = 400; - - // from inputs.f - int constexpr aamax = 300; - - } // namespace details::constants - - template <typename T> - using nmaxArray = std::array<T, details::constants::nmax>; - using nmaxIntArray = nmaxArray<int>; - using nmaxDoubleArray = nmaxArray<double>; - - extern "C" { - // FORTRAN functions defined in UrQMD - void iniurqmdc8_(); - double ranf_(int&); - void cascinit_(int const&, int const&, int const&); - double nucrad_(int const&); - void urqmd_(int&); - int pdgid_(int const&, int const&); - double sigtot_(int&, int&, double&); - int collclass_(int&, int&, int&, int&); - double crossx_(int const&, double const&, int const&, int const&, double const&, - int const&, int const&, double const&, double&); - int readsigmaln_(int const&, int const&, int const&); - - // defined in coms.f - extern struct { - int npart, nbar, nmes, ctag, nsteps, uid_cnt, ranseed, event; - int Ap; // projectile mass number (in case of nucleus) - int At; // target mass number (in case of nucleus) - int Zp; // projectile charge number (in case of nucleus) - int Zt; // target charge number (in case of nucleus) - int eos, dectag, NHardRes, NSoftRes, NDecRes, NElColl, NBlColl; - } sys_; - - extern struct { - double time, acttime, bdist, bimp, bmin; - double ebeam; // lab-frame energy of projectile - double ecm; - } rsys_; - - // defined in coms.f - extern struct { - nmaxIntArray spin, ncoll, charge, ityp, lstcoll, iso3, origin, strid, uid; - } isys_; - - // defined in coor.f - extern struct { - nmaxDoubleArray r0, rx, ry, rz, p0, px, py, pz, fmass, rww, dectime; - } coor_; - - // defined in inputs.f - extern struct { - int nevents; - std::array<int, 2> spityp; // particle codes of: [0]: projectile, [1]: target - int prspflg; // projectile special flag - int trspflg; // target special flag, set to 1 unless target is nucleus > H - std::array<int, 2> spiso3; // particle codes of: [0]: projectile, [1]: target - int outsteps, bflag, srtflag, efuncflag, nsrt, npb, firstev; - } inputs_; - - // defined in inputs.f - extern struct { - double srtmin, srtmax, pbeam, betann, betatar, betapro, pbmin, pbmax; - } input2_; - - // defined in options.f - extern struct { - std::array<double, details::constants::numcto> CTOption; - std::array<double, details::constants::numctp> CTParam; - } options_; - - extern struct { - int fixedseed, bf13, bf14, bf15, bf16, bf17, bf18, bf19, bf20; - } loptions_; - - // defined in urqmdInterface.F - extern struct { std::array<double, 3> xs, bim; } cxs_u2_; - } - - /** - * convert CORSIKA code to UrQMD code tuple - * - * In the current implementation a detour via the PDG code is made. - */ - std::pair<int, int> ConvertToUrQMD(particles::Code); - particles::Code ConvertFromUrQMD(int vItyp, int vIso3); - -} // namespace corsika::UrQMD - -#endif diff --git a/corsika/modules/UrQMD/testUrQMD.cc b/corsika/modules/UrQMD/testUrQMD.cc deleted file mode 100644 index 8bcfd651c5b386be18c119d94fe09455229a8c66..0000000000000000000000000000000000000000 --- a/corsika/modules/UrQMD/testUrQMD.cc +++ /dev/null @@ -1,238 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/urqmd/UrQMD.h> -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> - -#include <corsika/framework/core/PhysicalConstants.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/framework/utility/CorsikaFenv.hpp> - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/media/Environment.hpp> -#include <corsika/media/HomogeneousMedium.hpp> -#include <corsika/media/NuclearComposition.hpp> - -#include <tuple> -#include <utility> - -#include <catch2/catch.hpp> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using namespace corsika; -using namespace corsika::UrQMD; -using namespace corsika::units::si; - -template <typename TStackView> -auto sumCharge(TStackView const& view) { - int totalCharge = 0; - - for (auto const& p : view) { totalCharge += particles::GetChargeNumber(p.GetPID()); } - - return totalCharge; -} - -template <typename TStackView> -auto sumMomentum(TStackView const& view, geometry::CoordinateSystem const& vCS) { - geometry::Vector<hepenergy_d> sum{vCS, 0_eV, 0_eV, 0_eV}; - - for (auto const& p : view) { sum += p.GetMomentum(); } - - return sum; -} - -auto setupEnvironment(particles::Code vTargetCode) { - // setup environment, geometry - auto env = std::make_unique<environment::Environment<environment::IMediumModel>>(); - auto& universe = *(env->GetUniverse()); - const geometry::CoordinateSystem& cs = env->GetCoordinateSystem(); - - auto theMedium = - environment::Environment<environment::IMediumModel>::CreateNode<geometry::Sphere>( - geometry::Point{cs, 0_m, 0_m, 0_m}, - 1_km * std::numeric_limits<double>::infinity()); - - using MyHomogeneousModel = environment::HomogeneousMedium<environment::IMediumModel>; - theMedium->SetModelProperties<MyHomogeneousModel>( - 1_kg / (1_m * 1_m * 1_m), - environment::NuclearComposition(std::vector<particles::Code>{vTargetCode}, - std::vector<float>{1.})); - - auto const* nodePtr = theMedium.get(); - universe.AddChild(std::move(theMedium)); - - return std::make_tuple(std::move(env), &cs, nodePtr); -} - -template <typename TNodeType> -auto setupStack(int vA, int vZ, HEPEnergyType vMomentum, TNodeType* vNodePtr, - geometry::CoordinateSystem const& cs) { - auto stack = std::make_unique<setup::Stack>(); - auto constexpr mN = corsika::units::constants::nucleonMass; - - geometry::Point const origin(cs, {0_m, 0_m, 0_m}); - corsika::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV}); - - HEPEnergyType const E0 = - sqrt(units::si::detail::static_pow<2>(mN * vA) + pLab.squaredNorm()); - auto particle = - stack->AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, - units::si::TimeType, unsigned short, unsigned short>{ - particles::Code::Nucleus, E0, pLab, origin, 0_ns, vA, vZ}); - - particle.SetNode(vNodePtr); - return std::make_tuple( - std::move(stack), - std::make_unique<decltype(corsika::SecondaryView(particle))>(particle)); -} - -template <typename TNodeType> -auto setupStack(particles::Code vProjectileType, HEPEnergyType vMomentum, - TNodeType* vNodePtr, geometry::CoordinateSystem const& cs) { - auto stack = std::make_unique<setup::Stack>(); - - geometry::Point const origin(cs, {0_m, 0_m, 0_m}); - corsika::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV}); - - HEPEnergyType const E0 = - sqrt(units::si::detail::static_pow<2>(particles::GetMass(vProjectileType)) + - pLab.squaredNorm()); - auto particle = stack->AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - vProjectileType, E0, pLab, origin, 0_ns}); - - particle.SetNode(vNodePtr); - return std::make_tuple( - std::move(stack), - std::make_unique<decltype(corsika::SecondaryView(particle))>(particle)); -} - -TEST_CASE("UrQMD") { - SECTION("conversion") { - REQUIRE_THROWS(process::UrQMD::ConvertFromUrQMD(106, 0)); - REQUIRE(process::UrQMD::ConvertFromUrQMD(101, 0) == particles::Code::Pi0); - REQUIRE(process::UrQMD::ConvertToUrQMD(particles::Code::PiPlus) == - std::make_pair<int, int>(101, 2)); - } - - feenableexcept(FE_INVALID); - corsika::RNGManager::GetInstance().RegisterRandomStream("UrQMD"); - UrQMD urqmd; - - SECTION("interaction length") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Nitrogen); - auto const& cs = *csPtr; - [[maybe_unused]] auto const& env_dummy = env; - [[maybe_unused]] auto const& node_dummy = nodePtr; - - particles::Code validProjectileCodes[] = { - particles::Code::PiPlus, particles::Code::PiMinus, particles::Code::Proton, - particles::Code::Neutron, particles::Code::KPlus, particles::Code::KMinus, - particles::Code::K0, particles::Code::K0Bar, particles::Code::K0Long}; - - for (auto code : validProjectileCodes) { - auto [stack, view] = setup::testing::setupStack(code, 0, 0, 100_GeV, nodePtr, cs); - REQUIRE(stack->getEntries() == 1); - REQUIRE(view->getEntries() == 0); - - // simple check whether the cross-section is non-vanishing - // only nuclei with available tabluated data so far - REQUIRE(urqmd.GetInteractionLength(stack->GetNextParticle()) > 1_g / square(1_cm)); - } - } - - SECTION("nucleus projectile") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Oxygen); - [[maybe_unused]] auto const& env_dummy = env; // against warnings - [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings - - unsigned short constexpr A = 14, Z = 7; - auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::Nucleus, A, - Z, 400_GeV, nodePtr, *csPtr); - REQUIRE(stackPtr->getEntries() == 1); - REQUIRE(secViewPtr->getEntries() == 0); - - // must be assigned to variable, cannot be used as rvalue?! - auto projectile = secViewPtr->GetProjectile(); - auto const projectileMomentum = projectile.GetMomentum(); - [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr); - - REQUIRE(sumCharge(*secViewPtr) == - Z + particles::GetChargeNumber(particles::Code::Oxygen)); - - auto const secMomSum = - sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem()); - REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() == - Approx(0).margin(1e-2)); - } - - SECTION("\"special\" projectile") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Oxygen); - [[maybe_unused]] auto const& env_dummy = env; // against warnings - [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings - - auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::PiPlus, 0, - 0, 400_GeV, nodePtr, *csPtr); - REQUIRE(stackPtr->getEntries() == 1); - REQUIRE(secViewPtr->getEntries() == 0); - - // must be assigned to variable, cannot be used as rvalue?! - auto projectile = secViewPtr->GetProjectile(); - auto const projectileMomentum = projectile.GetMomentum(); - - [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr); - - REQUIRE(sumCharge(*secViewPtr) == - particles::GetChargeNumber(particles::Code::PiPlus) + - particles::GetChargeNumber(particles::Code::Oxygen)); - - auto const secMomSum = - sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem()); - REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() == - Approx(0).margin(1e-2)); - } - - SECTION("K0Long projectile") { - auto [env, csPtr, nodePtr] = - setup::testing::setupEnvironment(particles::Code::Oxygen); - [[maybe_unused]] auto const& env_dummy = env; // against warnings - [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings - - auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::K0Long, 0, - 0, 400_GeV, nodePtr, *csPtr); - REQUIRE(stackPtr->getEntries() == 1); - REQUIRE(secViewPtr->getEntries() == 0); - - // must be assigned to variable, cannot be used as rvalue?! - auto projectile = secViewPtr->GetProjectile(); - auto const projectileMomentum = projectile.GetMomentum(); - - [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr); - - REQUIRE(sumCharge(*secViewPtr) == - particles::GetChargeNumber(particles::Code::K0Long) + - particles::GetChargeNumber(particles::Code::Oxygen)); - - auto const secMomSum = - sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem()); - REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() == - Approx(0).margin(1e-2)); - } -} diff --git a/corsika/modules/UrQMD/urqmdInterface.F b/corsika/modules/UrQMD/urqmdInterface.F deleted file mode 100644 index ec2bd092a8386393368a6789df73b3efa3253160..0000000000000000000000000000000000000000 --- a/corsika/modules/UrQMD/urqmdInterface.F +++ /dev/null @@ -1,447 +0,0 @@ -c 18.11.2011 Link routines between UrQMD 1.3 and CONEX. -c author T. Pierog based on CORSIKA and EPOS link to UrQMD - -c adapted by M. Reininghaus for linking UrQMD to CORSIKA 8 (Apr 2019) - -#ifdef __STD__ -#define __GHEISHA__ -#define __QGSJET__ -#define __ANALYSIS__ -#endif - - -c----------------------------------------------------------------------- - subroutine IniUrQMDC8 -c----------------------------------------------------------------------- -c Primary initialization for UrQMD 1.31 -c----------------------------------------------------------------------- - implicit none -c CONEX includes -c~ #include "conex.h" -c~ #include "conex.incnex" -#ifndef __CXCORSIKA__ -c~ character*500 furqdat -c~ integer ifurqdat, nfurqdat -c~ common/urqfname/ furqdat, ifurqdat, nfurqdat - - include 'boxinc.f' - include 'inputs.f' - include 'options.f' - -c commons from coms.f - integer Ap, At, Zp, Zt, npart, nbar, nmes, ctag - integer nsteps,ranseed,event,eos,dectag,uid_cnt - integer NHardRes,NSoftRes,NDecRes,NElColl,NBlColl - common /sys/ npart, nbar, nmes, ctag,nsteps,uid_cnt, - + ranseed,event,Ap,At,Zp,Zt,eos,dectag, - + NHardRes,NSoftRes,NDecRes,NElColl,NBlColl - -c local - INTEGER i,io,ia,ie,id - CHARACTER CTPStrg(numctp)*60, CTOStrng(numcto)*60 - integer mxie,mxid,mxia - parameter (mxie=41,mxid=10,mxia=3) - character adum - double precision sig_u1,ekdummy - integer iamaxu,idmaxu,iemaxu -c~ common /cxs_u1/ sig_u1(mxie,mxid,mxia),iamaxu,idmaxu,iemaxu -c~ double precision xs(3),bim(3) -c~ c M.R.: bim added to cxs_u2 -c~ common /cxs_u2/ xs,bim - integer iudebug -c~ data bim/6.d0,6.d0,7.d0/ - integer init - data init/0/ - SAVE - - if(init.ge.1)return - init=init+1 -#ifdef __CXDEBUG__ - call utisx1('iniurqmd ',4) - write(*,'(a)')'initialize URQMD ...' -#endif - -C----------------------------------------------------------------------- - -c~ IF ( isx.ge.2 ) THEN -c~ IUDEBUG = isx-1 -c~ ELSE -c~ IUDEBUG = 0 -c~ ENDIF - - WRITE (*,*) - $ '############################################################' - WRITE (*,*) - $ '## ##' - WRITE (*,*) - $ '## UrQMD 1.3.1 University of Frankfurt ##' - WRITE (*,*) - $ '## urqmd@th.physik.uni-frankfurt.de ##' - WRITE (*,*) - $ '## ##' - WRITE (*,*) - $ '############################################################' - WRITE (*,*) - $ '## ##' - WRITE (*,*) - $ '## please cite when using this model: ##' - WRITE (*,*) - $ '## S.A.Bass et al. Prog.Part.Nucl.Phys. 41 (1998) 225 ##' - WRITE (*,*) - $ '## M.Bleicher et al. J.Phys. G25 (1999) 1859 ##' - WRITE (*,*) - $ '## ##' - WRITE (*,*) - $ '############################################################' - -C SET THE 'LARGE' CROSS-SECTIONS FOR ALL 3 TARGET ELEMENTS -c~ DO I = 1, 3 -c~ XS(I) = 10.D0 * PI * BIM(I)**2 -c~ ENDDO - -C SET NMAX TO DEFAULT VALUE - call set0 - call params - -C THIS IS THE SUBSTITUE FOR THE URQMD INPUT ROUTINE -C INITIALIZE COUNTERS - boxflag = 0 - mbflag = 0 - edens = 0.d0 - para = 0 - solid = 0 - mbox = 0 - io = 0 - -C THE FOLLOWING FLAGS CHECK, WHETHER ALL NECESSARY INPUT IS GIVEN -C PROJECTILE - prspflg = 0 -C TARGET - trspflg = 0 -C - srtflag = 0 - firstev = 0 -C EXCITATION FUNCTION - nsrt = 1 - npb = 1 - efuncflag = 0 -C DEFAULT NUMBER OF EVENTS - nevents = 1 -C DEFAULT NUMBER OF TIMESTEPS - nsteps = 1000 - -C SKIP CONDITIONS ON UNIT 13, 14, 15, 16 & 18 -C SUPPRESS ALL OUTPUT - bf13 = .true. - bf14 = .true. - bf15 = .true. - bf16 = .true. - bf18 = .true. - bf19 = .true. - bf20 = .true. -C SET DEBUG OUTPUT DEPENDING ON CHOSEN DEBUG LEVEL -C SET THE OUTPUT OF UNITS 13, 14, 15 TO THE DEBUG OUTPUT UNIT -c~ IF ( IUDEBUG .EQ. 1 ) THEN -c~ bf13 = .true. -c~ bf14 = .false. -c~ call uounit(14,IFCK) -c~ bf15 = .true. -c~ ELSEIF ( IUDEBUG .EQ. 2 ) THEN -c~ bf13 = .false. -c~ call uounit(13,IFCK) -c~ bf14 = .true. -c~ bf15 = .true. -c~ ELSEIF ( IUDEBUG .GT. 2 ) THEN -c~ bf13 = .true. -c~ bf14 = .true. -c~ bf15 = .false. -c~ call uounit(15,IFCK) -c~ ENDIF - do i = 1, numcto - CTOdc(i) = ' ' - enddo - do i = 1, numctp - CTPdc(i) = ' ' - enddo - do i = 1, maxstables - stabvec(i) = 0 - enddo - nstable = 0 - -C DEFAULT SETTINGS FOR CTParam AND CTOption -C DEFAULT SETTINGS FOR CTParam - CTParam(1)=1.d0 - CTPStrg(1)='scaling factor for decay-width' - CTParam(2)=0.52d0 - CTPStrg(2)='used for minimal stringmass & el/inel cut in makestr' - CTParam(3)=2.d0 - CTPStrg(3)='velocity exponent for modified AQM' - CTParam(4)=0.3d0 - CTPStrg(4)='transverse pion mass, used in make22 & strexct' - CTParam(5)=0.d0 - CTPStrg(5)='probabil. for quark rearrangement in cluster' - CTParam(6)=0.37d0 - CTPstrg(6)='strangeness probability' - CTParam(7)=0.d0 - CTPStrg(7)='charm probability (not yet implemented in UQMD)' - CTParam(8)=0.093d0 - CTPStrg(8)='probability to create a diquark' - CTParam(9)=0.35d0 - CTPStrg(9)='kinetic energy cut off for last string break' - CTParam(10)=0.25d0 - CTPStrg(10)='min. kinetic energy for hadron in string' - CTParam(11)=0.d0 - CTPStrg(11)='fraction of non groundstate resonances' - CTParam(12)=.5d0 - CTPStrg(12)='probability for rho 770 in String' - CTParam(13)=.27d0 - CTPStrg(13)='probability for rho 1450 (rest->rho1700)' - CTParam(14)=.49d0 - CTPStrg(14)='probability for omega 782' - CTParam(15)=.27d0 - CTPStrg(15)='probability for omega 1420(rest->om1600)' - CTParam(16)=1.0d0 - CTPStrg(16)='mass cut betw. rho770 and rho 1450' - CTParam(17)=1.6d0 - CTPSTRG(17)='mass cut betw. rho1450 and rho1700' - CTParam(18)=.85d0 - CTPStrg(18)='mass cut betw. om 782 and om1420' - CTParam(19)=1.55d0 - CTPStrg(19)='mass cut betw. om1420 and om1600' - CTParam(20)=0.0d0 - CTPStrg(20)=' distance for second projectile' - CTParam(21)=0.0d0 - CTPStrg(21)=' deformation parameter' - - CTParam(25)=.9d0 - CTPStrg(25)=' probability for diquark not to break' - CTParam(26)=50.d0 - CTPStrg(26)=' maximum trials to get string masses' - CTParam(27)=1.d0 - CTPStrg(27)=' scaling factor for xmin in string excitation' - CTParam(28)=1.d0 - CTPStrg(28)=' scaling factor for transverse fermi motion' - CTParam(29)=0.4d0 - CTPStrg(29)=' single strange di-quark suppression factor ' - CTParam(30)=1.5d0 - CTPStrg(30)=' radius offset for initialization ' - CTParam(31)=1.6d0 - CTPStrg(31)=' sigma of gaussian for tranverse momentum tranfer ' - CTParam(32)=0.d0 - CTPStrg(32)=' alpha-1 for valence quark distribution ' - CTParam(33)=2.5d0 - CTPStrg(33)=' betav for valence quark distribution (DPM)' - CTParam(34)=0.1d0 - CTPStrg(34)=' minimal x multiplied with ecm ' - CTParam(35)=3.0d0 - CTPStrg(35)=' offset for cut for the FSM ' - CTParam(36)=0.275d0 - CTPStrg(36)=' fragmentation function parameter a ' - CTParam(37)=0.42d0 - CTPStrg(37)=' fragmentation function parameter b ' - CTParam(38)=1.08d0 - CTPStrg(38)=' diquark pt scaling factor ' - CTParam(39)=0.8d0 - CTPStrg(39)=' strange quark pt scaling factor ' - CTParam(40)=0.5d0 - CTPStrg(40)=' betas-1 for valence quark distribution (LEM)' - CTParam(41)=0.d0 - CTPStrg(41)=' distance of initialization' - CTParam(42)=0.55d0 - CTPStrg(42)=' width of gaussian -> pt in string-fragmentation ' - CTParam(43)=5.d0 - CTPStrg(43)=' maximum kinetic energy in mesonic clustr ' - CTParam(44)=0.8d0 - CTPStrg(44)=' prob. of double vs. single excitation for AQM inel.' - CTParam(45)=0.5d0 - CTPStrg(45)=' offset for minimal mass generation of strings' - CTParam(46)=800000.d0 - CTPStrg(46)=' maximal number of rejections for initialization' - CTParam(47)=1.0d0 - CTPStrg(47)=' field feynman fragmentation funct. param. a' - CTParam(48)=2.0d0 - CTPStrg(48)=' field feynman fragmentation funct. param. b' - - CTParam(50)=1.d0 - CTPStrg(50)=' enhancement factor for 0- mesons' - CTParam(51)=1.d0 - CTPStrg(51)=' enhancement factor for 1- mesons' - CTParam(52)=1.d0 - CTPStrg(52)=' enhancement factor for 0+ mesons' - CTParam(53)=1.d0 - CTPStrg(53)=' enhancement factor for 1+ mesons' - CTParam(54)=1.d0 - CTPStrg(54)=' enhancement factor for 2+ mesons' - CTParam(55)=1.d0 - CTPStrg(55)=' enhancement factor for 1+-mesons' - CTParam(56)=1.d0 - CTPStrg(56)=' enhancement factor for 1-*mesons' - CTParam(57)=1.d0 - CTPStrg(57)=' enhancement factor for 1-*mesons' - CTParam(58)=1.d0 - CTPStrg(58)=' scaling factor for DP time-delay' - -C DEFAULT SETTINGS FOR CTOption - CTOption(1)=1 ! hjd1 - CTOStrng(1)=' resonance widths are mass dependent ' - CTOption(2)=0 - CTOStrng(2)=' conservation of scattering plane' - CTOption(3)=0 - CTOStrng(3)=' use modified detailed balance' - CTOption(4)=0 - CTOStrng(4)=' no initial conf. output ' - CTOption(5)=0 - CTOStrng(5)=' fixed random impact parameter' - CTOption(6)=0 - CTOStrng(6)=' no first collisions inside proj/target' - CTOption(7)=0 - CTOStrng(7)=' elastic cross-section enabled (<>0:total=inelast)' - CTOption(8)=0 - CTOStrng(8)=' extrapolate branching ratios ' - CTOption(9)=0 - CTOStrng(9)=' use tabulated pp cross-sections ' - CTOption(10)=0 - CTOStrng(10)=' enable Pauli Blocker' - CTOption(11)=0 - CTOStrng(11)=' mass reduction for cascade initialization' - CTOption(12)=0 - CTOStrng(12)=' string condition =0 (.ne.0 no strings)' - CTOption(13)=0 - CTOStrng(13)=' enhanced file16 output ' - CTOption(14)=0 - CTOStrng(14)=' cos(the) is distributet between -1..1 ' - CTOption(15)=0 - CTOStrng(15)=' allow mm&mb-scattering' - CTOption(16)=0 - CTOStrng(16)=' propagate without collisions' - CTOption(17)=0 - CTOStrng(17)=' colload after every timestep ' - CTOption(18)=0 - CTOStrng(18)=' final decay of unstable particles' - CTOption(19)=0 - CTOStrng(19)=' allow bbar annihilaion' - CTOption(20)=0 - CTOStrng(20)=' dont generate e+e- instead of bbar' - CTOption(21)=0 - CTOStrng(21)=' use field feynman frgm. function' - CTOption(22)=1 - CTOStrng(22)=' use lund excitation function' - CTOption(23)=0 - CTOStrng(23)=' lorentz contraction of projectile & targed' - CTOption(24)=2 ! 1 is default 2 means fast method - CTOStrng(24)=' Wood-Saxon initialization' - CTOption(25)=0 - CTOStrng(25)=' phase space corrections for resonance mass' - CTOption(26)=0 - CTOStrng(26)=' use z -> 1-z for diquark-pairs' - CTOption(27)=1 ! hjd1 - CTOStrng(27)=' reference frame (1=target, 2=projectile, else=cms)' - CTOption(28)=1 ! M.R. 2019-04-15 - CTOStrng(28)=' propagate spectators also ' - CTOption(29)=2 - CTOStrng(29)=' no transverse momentum in clustr ' - CTOption(30)=1 - CTOStrng(30)=' frozen fermi motion ' - CTOption(31)=0 - CTOStrng(31)=' reduced mass spectrum in string' - CTOption(32)=0 - CTOStrng(32)=' masses are distributed acc. to m-dep. widths' - CTOption(33)=0 - CTOStrng(33)=' use tables & m-dep. for pmean in fprwdt & fwidth' - CTOption(34)=1 - CTOStrng(34)=' lifetme according to m-dep. width' - CTOption(35)=1 - CTOStrng(35)=' generate high precision tables' - CTOption(36)=0 - CTOStrng(36)=' normalize Breit-Wigners with m.dep. widths ' - CTOption(37)=0 - CTOStrng(37)=' heavy quarks form di-quark clusters' - CTOption(38)=0 - CTOStrng(38)=' scale p-pbar to b-bbar with equal p_lab ' - CTOption(39)=0 - CTOStrng(39)=' dont call pauliblocker' - CTOption(40)=0 - CTOStrng(40)=' read old fort.14 file ' - CTOption(41)=0 - CTOStrng(41)=' generate extended output for cto40' - CTOption(42)=0 - CTOStrng(42)=' hadrons now have color fluctuations' - CTOption(43)=0 - CTOStrng(43)=' dont generate dimuon intead of dielectron output' - CTOption(44)=0 - CTOStrng(44)=' not used at the moment' - CTOption(45)=0 - CTOStrng(45)=' not used at the moment' - -C INITIALIZE ARRAYS FOR SPECIAL PRO/TAR COMBINATIONS - do i = 1, 2 - spityp(i) = 0 - spiso3(i) = 0 - enddo - -C INITIALIZE ARRAYS FOR SPECIAL PARTICLES - EoS = 0 - -C READ CROSS-SECTION FILES -Cdh CALL URQREC() - -C INITIALIZES SOME ARRAYS - call strini ! initialize mixing angles for meson-multipletts - call loginit - - IF ( CTOption(33) .EQ. 0 .OR. CTOption(9) .EQ. 0 ) THEN - call loadwtab(io) -c~ IF ( IUDEBUG .GT. 0 ) WRITE(IFCK,*) 'URQINI: AFTER LOADWTAB' - ENDIF - -C READ URQMD TOTAL CROSS SECTION TABLE -c -c ie=1..41 E=10.0**(float(ie)/10-1.0-0.05) (bin-middle) -c id=1..9 p,ap,n,an,pi+,pi-,K+,K-,KS -c ia=1..3 N,O,Ar -c -c~ if(ifurqdat.eq.1)then -c~ OPEN(UNIT=76,FILE=furqdat(1:nfurqdat),STATUS='OLD') -c~ else -c~ OPEN(UNIT=76,FILE='UrQMD-1.3.1-xs.dat',STATUS='OLD') -c~ endif -c~ read(76,*) adum,iamaxu,idmaxu,iemaxu -c~ do ia=1,iamaxu -c~ do id=1,idmaxu -c~ do ie=1,iemaxu -c~ read(76,*) ekdummy,sig_u1(ie,id,ia) -c~ enddo -c~ read(76,*) -c~ read(76,*) -c~ enddo -c~ enddo -c~ close(76) - -C IN CASE OF CASCADE MODE, THE POTENTIALS NEED NOT BE CALCULATED - -C CALCULATE NORMALIZATION OF RESONANCES DISTRIBUTION... - call norm_init -#endif - - -c~ xsegymin=0.25d0 - -#ifdef __CXDEBUG__ - call utisx2 -#endif - - end - -c -c M. Reininghaus, 2020-04-08 -c - integer function ReadSigmaLn(ia, ib, ic) - implicit none - - include 'comres.f' - - integer :: ia, ib, ic - - ReadSigmaLn = SigmaLn(ia, ib, ic) - - end function ReadSigmaLn diff --git a/corsika/process/EnergyLoss.hpp b/corsika/process/EnergyLoss.hpp deleted file mode 100644 index 656f644c0c93ff98ac2d322de7a7ce6f678d45af..0000000000000000000000000000000000000000 --- a/corsika/process/EnergyLoss.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/Vector.hpp> -#include <corsika/framework/sequence/ContinuousProcess.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <map> - -#include <corsika/setup/SetupStack.hpp> -#include <corsika/setup/SetupTrajectory.hpp> - -namespace corsika { - - class EnergyLoss : public corsika::ContinuousProcess<EnergyLoss> { - - using MeVgcm2 = decltype(1e6 * units::si::electronvolt / units::si::gram * - units::si::square(1e-2 * units::si::meter)); - - void MomentumUpdate(setup::Stack::ParticleType&, units::si::HEPEnergyType Enew); - - public: - template <typename TDim> - EnergyLoss(geometry::Point const& injectionPoint, - geometry::Vector<TDim> const& direction) - : InjectionPoint_(injectionPoint) - , ShowerAxisDirection_(direction.normalized()) {} - - EnergyLoss(setup::Trajectory const& trajectory) - : EnergyLoss(trajectory.GetPosition(0), trajectory.GetV0()){}; - - process::EProcessReturn DoContinuous(setup::Stack::ParticleType&, - setup::Trajectory const&); - units::si::LengthType MaxStepLength(setup::Stack::ParticleType const&, - setup::Trajectory const&) const; - units::si::HEPEnergyType GetTotal() const; - void PrintProfile() const; - static units::si::HEPEnergyType BetheBloch(setup::Stack::ParticleType const&, - const units::si::GrammageType); - static units::si::HEPEnergyType RadiationLosses(setup::Stack::ParticleType const&, - const units::si::GrammageType); - static units::si::HEPEnergyType TotalEnergyLoss(setup::Stack::ParticleType const&, - const units::si::GrammageType); - - void showResults() const; - void reset(); - corsika::units::si::HEPEnergyType energyLost() const { return energy_lost_; } - - private: - void FillProfile(setup::Trajectory const&, units::si::HEPEnergyType); - - units::si::GrammageType const dX_ = std::invoke([]() { - using namespace units::si; - return 10_g / square(1_cm); - }); // profile binning - - private: - environment::ShowerAxis const& shower_axis_; - corsika::units::si::HEPEnergyType emCut_; - std::vector<units::si::HEPEnergyType> profile_; // longitudinal profile - units::si::HEPEnergyType energy_lost_ = 0 * units::si::electronvolt; - }; - - units::si::GrammageType const dX_threshold_ = std::invoke([]() { - using namespace units::si; - return 0.0001_g / square(1_cm); - }); -} // namespace corsika diff --git a/corsika/process/HadronicElasticModel.hpp b/corsika/process/HadronicElasticModel.hpp deleted file mode 100644 index 0466a037ec5fed6339ebd43f8b339746e65bdd2a..0000000000000000000000000000000000000000 --- a/corsika/process/HadronicElasticModel.hpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/InteractionProcess.hpp> -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/core/PhysicalConstants.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -namespace corsika::HadronicElasticModel { - /** - * A simple model for elastic hadronic interactions based on the formulas - * in Gaisser, Engel, Resconi, Cosmic Rays and Particle Physics (Cambridge Univ. Press, - * 2016), section 4.2 and Donnachie, Landshoff, Phys. Lett. B 296, 227 (1992) - * - * Currently only \f$p\f$ projectiles are supported and cross-sections are assumed to be - * \f$pp\f$-like even for nuclei. - */ - class HadronicElasticInteraction - : public corsika::InteractionProcess<HadronicElasticInteraction> { - private: - corsika::units::si::CrossSectionType const fX, fY; - - static double constexpr gfEpsilon = 0.0808; - static double constexpr gfEta = 0.4525; - // Froissart-Martin is not violated up for sqrt s < 10^32 eV with these values [DL]. - - using SquaredHEPEnergyType = decltype(corsika::units::si::HEPEnergyType() * - corsika::units::si::HEPEnergyType()); - - using eV2 = decltype(units::si::square(units::si::electronvolt)); - using inveV2 = decltype(1 / units::si::square(units::si::electronvolt)); - - corsika::RNG& fRNG = - corsika::RNGManager::GetInstance().GetRandomStream("HadronicElasticModel"); - - inveV2 B(eV2 s) const; - corsika::units::si::CrossSectionType CrossSection(SquaredHEPEnergyType s) const; - - public: - HadronicElasticInteraction( // x & y values taken from DL for pp collisions - units::si::CrossSectionType x = 0.0217 * units::si::barn, - units::si::CrossSectionType y = 0.05608 * units::si::barn); - - template <typename Particle> - corsika::units::si::GrammageType GetInteractionLength(Particle const& p); - - template <typename Particle> - corsika::EProcessReturn DoInteraction(Particle&); - }; - -} // namespace corsika::HadronicElasticModel diff --git a/corsika/process/ObservationPlane.hpp b/corsika/process/ObservationPlane.hpp deleted file mode 100644 index 3ac64e263539824e439544409d28aeb94cccafa7..0000000000000000000000000000000000000000 --- a/corsika/process/ObservationPlane.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * (c) Copyright 2019 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/geometry/Plane.hpp> -#include <corsika/framework/sequence/ContinuousProcess.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <fstream> - -#include "corsika/setup/SetupStack.hpp" -#include "corsika/setup/SetupTrajectory.hpp" - -namespace corsika::observation_plane { - - /** - * The ObservationPlane writes PDG codes, energies, and distances of particles to the - * central point of the plane into its output file. The particles are considered - * "absorbed" afterwards. - */ - class ObservationPlane : public corsika::ContinuousProcess<ObservationPlane> { - - public: - ObservationPlane(geometry::Plane const&, - geometry::Vector<units::si::dimensionless_d> const&, - std::string const&, bool = true); - - corsika::EProcessReturn DoContinuous(corsika::Stack::ParticleType const& vParticle, - corsika::Trajectory const& vTrajectory); - - corsika::units::si::LengthType MaxStepLength(corsika::Stack::ParticleType const&, - corsika::Trajectory const& vTrajectory); - - void ShowResults() const; - void Reset(); - corsika::units::si::HEPEnergyType GetEnergyGround() const { return energy_ground_; } - - private: - geometry::Plane const plane_; - std::ofstream outputStream_; - bool const deleteOnHit_; - - units::si::HEPEnergyType energy_ground_ = 0 * units::si::electronvolt; - unsigned int count_ground_ = 0; - geometry::Vector<units::si::dimensionless_d> const xAxis_, yAxis_; - }; -} // namespace corsika::observation_plane diff --git a/corsika/process/ParticleCut.hpp b/corsika/process/ParticleCut.hpp deleted file mode 100644 index 435eb09f3eca7bc731ae7f3916e61c263beb78f4..0000000000000000000000000000000000000000 --- a/corsika/process/ParticleCut.hpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/SecondariesProcess.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include "corsika/setup/SetupStack.hpp" - -namespace corsika { - namespace particle_cut { - class ParticleCut : public process::SecondariesProcess<ParticleCut>, - public corsika::process::ContinuousProcess<ParticleCut> { - - units::si::HEPEnergyType const energy_cut_; - bool bCutEm; - bool bCutInv; - - units::si::HEPEnergyType fEnergy = 0 * units::si::electronvolt; - units::si::HEPEnergyType fEmEnergy = 0 * units::si::electronvolt; - unsigned int uiEmCount = 0; - units::si::HEPEnergyType fInvEnergy = 0 * units::si::electronvolt; - unsigned int uiInvCount = 0; - - public: - ParticleCut(const units::si::HEPEnergyType vCut) - : fECut(vCut) {} - - bool ParticleIsInvisible(particles::Code) const; - EProcessReturn DoSecondaries(corsika::StackView&); - - void DoSecondaries(corsika::setup::StackView&); - - EProcessReturn DoContinuous(corsika::setup::Stack::ParticleType& vParticle, - corsika::setup::Trajectory const& vTrajectory); - - corsika::units::si::LengthType MaxStepLength( - corsika::setup::Stack::ParticleType const&, corsika::setup::Trajectory const&) { - return units::si::meter * std::numeric_limits<double>::infinity(); - } - - units::si::HEPEnergyType GetECut() const { return energy_cut_; } - units::si::HEPEnergyType GetInvEnergy() const { return fInvEnergy; } - units::si::HEPEnergyType GetCutEnergy() const { return fEnergy; } - units::si::HEPEnergyType GetEmEnergy() const { return fEmEnergy; } - unsigned int GetNumberEmParticles() const { return uiEmCount; } - unsigned int GetNumberInvParticles() const { return uiInvCount; } - - void ShowResults() const; - void Reset(); - - protected: - template <typename TParticle> - bool checkCutParticle(const TParticle& p); - - template <typename TParticle> - bool ParticleIsBelowEnergyCut(TParticle const&) const; - - bool ParticleIsEmParticle(particles::Code) const; - bool ParticleIsInvisible(particles::Code) const; - }; - } // namespace particle_cut -} // namespace corsika diff --git a/corsika/process/Pythia/Decay.hpp b/corsika/process/Pythia/Decay.hpp deleted file mode 100644 index 20bbf96943e9d48aee30e876c676e3dc2ae25bd6..0000000000000000000000000000000000000000 --- a/corsika/process/Pythia/Decay.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <Pythia8/Pythia.h> - -#include <iostream> -#include <vector> -#include <tuple> -#include <corsika/setup/SetupStack.hpp> -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/DecayProcess.hpp> - -namespace corsika { - - namespace pythia { - - typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector; - - class Decay : public corsika::DecayProcess<Decay> { - - const std::vector<particles::Code> fTrackedParticles; - int fCount = 0; - - public: - Decay(std::vector<corsika::Code>); - ~Decay(); - - void SetParticleListStable(std::vector<particles::Code> const&); - void SetUnstable(const corsika::Code); - void SetStable(const corsika::Code); - - corsika::units::si::TimeType GetLifetime(corsika::Stack::ParticleType const&); - - void DoDecay(corsika::StackView::ParticleType&); - - private: - void SetUnstable(const corsika::particles::Code); - void SetStable(const corsika::particles::Code); - void SetStable(const std::vector<particles::Code>); - bool IsStable(const corsika::particles::Code); - - Pythia8::Pythia fPythia; - std::set<particles::Code> handledDecays_; - }; - - } // namespace pythia -} // namespace corsika - -#include <corsika/detail/process/Pythia/Decay.inl> diff --git a/corsika/process/Pythia/Interaction.hpp b/corsika/process/Pythia/Interaction.hpp deleted file mode 100644 index e5d473f98904c64362eeaea7f3812981a686c978..0000000000000000000000000000000000000000 --- a/corsika/process/Pythia/Interaction.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <Pythia8/Pythia.h> - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/InteractionProcess.hpp> -#include <corsika/framework/random/RNGManager.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include <tuple> - -namespace corsika::pythia { - - class Interaction : public corsika::InteractionProcess<Interaction> { - - int fCount = 0; - bool fInitialized = false; - bool print_listing_ = false; - - public: - Interaction(const bool print_listing = false); - ~Interaction() = default; - - void SetParticleListStable(std::vector<particles::Code> const&); - void SetUnstable(const corsika::Code); - void SetStable(const corsika::Code); - - bool WasInitialized() { return fInitialized; } - bool ValidCoMEnergy(corsika::units::si::HEPEnergyType ecm) { - using namespace corsika::units::si; - return (10_GeV < ecm) && (ecm < 1_PeV); - } - - bool CanInteract(const corsika::Code); - void ConfigureLabFrameCollision(const corsika::Code, const corsika::Code, - const corsika::units::si::HEPEnergyType); - std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType> - GetCrossSection(const corsika::Code BeamId, const corsika::Code TargetId, - const corsika::units::si::HEPEnergyType CoMenergy); - - template <typename TParticle> - corsika::units::si::GrammageType GetInteractionLength(const TParticle&); - - /** - In this function PYTHIA is called to produce one event. The - event is copied (and boosted) into the shower lab frame. - */ - - template <typename TProjectile> - corsika::EProcessReturn DoInteraction(TProjectile&); - - private: - corsika::RNG& fRNG = corsika::RNGManager::GetInstance().GetRandomStream("pythia"); - Pythia8::Pythia fPythia; - Pythia8::SigmaTotal fSigma; - const bool fInternalDecays = true; - }; - -} // namespace corsika::pythia - -#endif diff --git a/corsika/process/Pythia/Random.hpp b/corsika/process/Pythia/Random.hpp deleted file mode 100644 index 3858be7933eafae27d2c8f5cfe8d9527478da65b..0000000000000000000000000000000000000000 --- a/corsika/process/Pythia/Random.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <Pythia8/Pythia.h> -#include <corsika/framework/random/RNGManager.hpp> - -namespace corsika { - - namespace pythia { - - class Random : public Pythia8::RndmEngine { - double flat(); - - private: - std::uniform_real_distribution<double> fDist; - corsika::RNG& fRNG = corsika::RNGManager::GetInstance().GetRandomStream("pythia"); - }; - - } // namespace pythia -} // namespace corsika - -#endif diff --git a/corsika/process/QGSJetII/Interaction.hpp b/corsika/process/QGSJetII/Interaction.hpp deleted file mode 100644 index fd331d75aac0bb42dca79c03dc520258317a3ba0..0000000000000000000000000000000000000000 --- a/corsika/process/QGSJetII/Interaction.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/InteractionProcess.hpp> -#include <corsika/framework/random/RNGManager.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <string> - -namespace corsika::qgsjetII { - - class Interaction : public corsika::InteractionProcess<Interaction> { - - std::string data_path_; - int count_ = 0; - bool initialized_ = false; - QgsjetIIHadronType alternate_ = - QgsjetIIHadronType::PiPlusType; // for pi0, rho0 projectiles - - public: - Interaction(const std::string& dataPath = ""); - ~Interaction(); - - bool WasInitialized() { return initialized_; } - int GetMaxTargetMassNumber() const { return maxMassNumber_; } - bool IsValidTarget(corsika::Code TargetId) const { - return (corsika::GetNucleusA(TargetId) < maxMassNumber_) && - corsika::IsNucleus(TargetId); - } - - corsika::units::si::CrossSectionType GetCrossSection( - const corsika::Code, const corsika::Code, const corsika::units::si::HEPEnergyType, - const unsigned int Abeam = 0, const unsigned int Atarget = 0) const; - - template <typename TParticle> - corsika::units::si::GrammageType GetInteractionLength(TParticle const&) const; - - /** - In this function QGSJETII is called to produce one event. The - event is copied (and boosted) into the shower lab frame. - */ - - template <typename TProjectile> - corsika::EProcessReturn DoInteraction(TProjectile&); - - private: - corsika::RNG& fRNG = corsika::RNGManager::GetInstance().GetRandomStream("qgran"); - const int maxMassNumber_ = 208; - }; - -} // namespace corsika::qgsjetII - -#endif diff --git a/corsika/process/QGSJetII/ParticleConversion.hpp b/corsika/process/QGSJetII/ParticleConversion.hpp deleted file mode 100644 index aef660ee28ab3261320d44d386d9bb835100e29b..0000000000000000000000000000000000000000 --- a/corsika/process/QGSJetII/ParticleConversion.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> - -#include <string> - -namespace corsika::qgsjetII { - - /** - These are the possible secondaries produced by QGSJetII - */ - enum class QgsjetIICode : int8_t; - using QgsjetIICodeIntType = std::underlying_type<QgsjetIICode>::type; - - /** - These are the possible projectile for which QGSJetII knwos cross section - */ - enum class QgsjetIIXSClass : int8_t { - CannotInteract = 0, - LightMesons = 1, - Baryons = 2, - Kaons = 3, - }; - using QgsjetIIXSClassIntType = std::underlying_type<QgsjetIIXSClass>::type; - - /** - These are the only possible projectile types in QGSJetII - */ - enum class QgsjetIIHadronType : int8_t { - UndefinedType = 0, - PiPlusType = +1, - PiMinusType = -1, - ProtonType = +2, - AntiProtonType = -2, - NeutronType = +3, - AntiNeutronType = -3, - KaonPlusType = +4, - KaonMinusType = -4, - Kaon0LType = +5, - Kaon0SType = -5, - // special codes, not in QGSJetII - NucleusType = 100, - NeutralLightMesonType = 101, - }; - using QgsjetIIHadronTypeIntType = std::underlying_type<QgsjetIIHadronType>::type; - -#include <corsika/process/qgsjetII/Generated.inc> - - QgsjetIICode constexpr ConvertToQgsjetII(corsika::Code pCode) { - return static_cast<QgsjetIICode>( - corsika2qgsjetII[static_cast<corsika::CodeIntType>(pCode)]); - } - - corsika::Code constexpr ConvertFromQgsjetII(QgsjetIICode pCode) { - auto const pCodeInt = static_cast<QgsjetIICodeIntType>(pCode); - auto const corsikaCode = qgsjetII2corsika[pCodeInt - minQgsjetII]; - if (corsikaCode == corsika::Code::Unknown) { - throw std::runtime_error(std::string("QGSJETII/CORSIKA conversion of pCodeInt=") - .append(std::to_string(pCodeInt)) - .append(" impossible")); - } - return corsikaCode; - } - - int constexpr ConvertToQgsjetIIRaw(corsika::Code pCode) { - return static_cast<int>(ConvertToQgsjetII(pCode)); - } - - int constexpr GetQgsjetIIXSCode(corsika::Code pCode) { - if (pCode == corsika::Code::Nucleus) return 2; - return corsika2qgsjetIIXStype[static_cast<corsika::CodeIntType>(pCode)]; - } - - bool constexpr CanInteract(corsika::Code pCode) { - return (GetQgsjetIIXSCode(pCode) > 0) && (ConvertToQgsjetIIRaw(pCode) <= 5); - } - -} // namespace corsika::qgsjetII - -} // namespace corsika::process::qgsjetII diff --git a/corsika/process/QGSJetII/QGSJetIIFragmentsStack.hpp b/corsika/process/QGSJetII/QGSJetIIFragmentsStack.hpp deleted file mode 100644 index bbb852f245cbeec06a8c8043de741e6232aa4a6e..0000000000000000000000000000000000000000 --- a/corsika/process/QGSJetII/QGSJetIIFragmentsStack.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> -#include <corsika/process/QGSJetII/ParticleConversion.hpp> -#include <corsika/process/QGSJetII/qgsjet-II-04.h> -#include <corsika/framework/stack/Stack.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -namespace corsika::qgsjetII { - - class QGSJetIIFragmentsStackData { - - public: - void Dump() const {} - - void Clear() { - qgarr13_.nsf = 0; - qgarr55_.nwt = 0; - } - unsigned int GetSize() const { return qgarr13_.nsf; } - unsigned int GetCapacity() const { return iapmax; } - - static unsigned int GetWoundedNucleonsTarget() { return qgarr55_.nwt; } - static unsigned int GetWoundedNucleonsProjectile() { return qgarr55_.nwp; } - - int GetFragmentSize(const unsigned int i) const { return qgarr13_.iaf[i]; } - void SetFragmentSize(const unsigned int i, const int v) { qgarr13_.iaf[i] = v; } - - void Copy(const unsigned int i1, const unsigned int i2) { - qgarr13_.iaf[i2] = qgarr13_.iaf[i1]; - } - - void Swap(const unsigned int i1, const unsigned int i2) { - std::swap(qgarr13_.iaf[i1], qgarr13_.iaf[i2]); - } - - void IncrementSize() { qgarr13_.nsf++; } - void DecrementSize() { - if (qgarr13_.nsf > 0) { qgarr13_.nsf--; } - } - }; - - template <typename StackIteratorInterface> - class FragmentsInterface : public corsika::ParticleBase<StackIteratorInterface> { - - using corsika::ParticleBase<StackIteratorInterface>::GetStackData; - using corsika::ParticleBase<StackIteratorInterface>::GetIndex; - - public: - void SetParticleData(const int vSize) { SetFragmentSize(vSize); } - - void SetParticleData(FragmentsInterface<StackIteratorInterface>& /*parent*/, - const int vSize) { - SetFragmentSize(vSize); - } - - void SetFragmentSize(const int v) { GetStackData().SetFragmentSize(GetIndex(), v); } - - double GetFragmentSize() const { return GetStackData().GetFragmentSize(GetIndex()); } - }; - - typedef corsika::Stack<QGSJetIIFragmentsStackData, FragmentsInterface> - QGSJetIIFragmentsStack; - -} // end namespace corsika::qgsjetII - -#endif diff --git a/corsika/process/QGSJetII/QGSJetIIStack.hpp b/corsika/process/QGSJetII/QGSJetIIStack.hpp deleted file mode 100644 index 403fa90322c13f3e8bd2da2a3abfd3d5a035456f..0000000000000000000000000000000000000000 --- a/corsika/process/QGSJetII/QGSJetIIStack.hpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/geometry/CoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> -#include <corsika/process/QGSJetII/ParticleConversion.hpp> -#include <corsika/process/QGSJetII/qgsjet-II-04.h> -#include <corsika/framework/stack/Stack.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -namespace corsika::qgsjetII { - - typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector; - - class QGSJetIIStackData { - - public: - void Dump() const {} - - void Clear() { - qgarr12_.nsp = 0; - qgarr13_.nsf = 0; - qgarr55_.nwt = 0; - } - unsigned int GetSize() const { return qgarr12_.nsp; } - unsigned int GetCapacity() const { return nptmax; } - - void SetId(const unsigned int i, const int v) { qgarr14_.ich[i] = v; } - void SetEnergy(const unsigned int i, const corsika::units::si::HEPEnergyType v) { - using namespace corsika::units::si; - qgarr14_.esp[i][0] = v / 1_GeV; - } - - void SetMomentum(const unsigned int i, const MomentumVector& v) { - using namespace corsika::units::si; - auto tmp = v.GetComponents(); - qgarr14_.esp[i][2] = tmp[0] / 1_GeV; - qgarr14_.esp[i][3] = tmp[1] / 1_GeV; - qgarr14_.esp[i][1] = tmp[2] / 1_GeV; - } - - int GetId(const unsigned int i) const { return qgarr14_.ich[i]; } - corsika::units::si::HEPEnergyType GetEnergy(const int i) const { - using namespace corsika::units::si; - return qgarr14_.esp[i][0] * 1_GeV; - } - MomentumVector GetMomentum(const unsigned int i, - const corsika::CoordinateSystem& CS) const { - using namespace corsika::units::si; - geometry::QuantityVector<hepmomentum_d> components = {qgarr14_.esp[i][2] * 1_GeV, - qgarr14_.esp[i][3] * 1_GeV, - qgarr14_.esp[i][1] * 1_GeV}; - return MomentumVector(CS, components); - } - - void Copy(const unsigned int i1, const unsigned int i2) { - qgarr14_.ich[i2] = qgarr14_.ich[i1]; - for (unsigned int i = 0; i < 4; ++i) qgarr14_.esp[i2][i] = qgarr14_.esp[i1][i]; - } - - void Swap(const unsigned int i1, const unsigned int i2) { - std::swap(qgarr14_.ich[i1], qgarr14_.ich[i2]); - for (unsigned int i = 0; i < 4; ++i) - std::swap(qgarr14_.esp[i1][i], qgarr14_.esp[i2][i]); - } - - void IncrementSize() { qgarr12_.nsp++; } - void DecrementSize() { - if (qgarr12_.nsp > 0) { qgarr12_.nsp--; } - } - }; - - template <typename StackIteratorInterface> - class ParticleInterface : public corsika::ParticleBase<StackIteratorInterface> { - - using corsika::ParticleBase<StackIteratorInterface>::GetStackData; - using corsika::ParticleBase<StackIteratorInterface>::GetIndex; - - public: - void SetParticleData(const int vID, const corsika::units::si::HEPEnergyType vE, - const MomentumVector& vP, - const corsika::units::si::HEPMassType) { - SetPID(vID); - SetEnergy(vE); - SetMomentum(vP); - } - - void SetParticleData(ParticleInterface<StackIteratorInterface>& /*parent*/, - const int vID, const corsika::units::si::HEPEnergyType vE, - const MomentumVector& vP, - const corsika::units::si::HEPMassType) { - SetPID(vID); - SetEnergy(vE); - SetMomentum(vP); - } - - void SetEnergy(const corsika::units::si::HEPEnergyType v) { - GetStackData().SetEnergy(GetIndex(), v); - } - - corsika::units::si::HEPEnergyType GetEnergy() const { - return GetStackData().GetEnergy(GetIndex()); - } - - void SetPID(const int v) { GetStackData().SetId(GetIndex(), v); } - - corsika::qgsjetII::QgsjetIICode GetPID() const { - return static_cast<corsika::qgsjetII::QgsjetIICode>( - GetStackData().GetId(GetIndex())); - } - - MomentumVector GetMomentum(const corsika::CoordinateSystem& CS) const { - return GetStackData().GetMomentum(GetIndex(), CS); - } - - void SetMomentum(const MomentumVector& v) { - GetStackData().SetMomentum(GetIndex(), v); - } - }; - - typedef corsika::Stack<QGSJetIIStackData, ParticleInterface> QGSJetIIStack; - -} // end namespace corsika::qgsjetII - -#endif diff --git a/corsika/process/QGSJetII/qgsjet-II-04.h b/corsika/process/QGSJetII/qgsjet-II-04.h deleted file mode 100644 index f9f75d826371873fc9985fb05478c48c81ab17dc..0000000000000000000000000000000000000000 --- a/corsika/process/QGSJetII/qgsjet-II-04.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <string> - -//---------------------------------------------- -// C++ interface for the QGSJetII event generator -//---------------------------------------------- -// wrapper - -extern "C" { - -// data memory layout - -extern struct { int nsp; } qgarr12_; - -const int nptmax = 95000; -const int iapmax = 208; - -extern struct { - double esp[nptmax][4]; - int ich[nptmax]; -} qgarr14_; - -extern struct { - // c nsf - number of secondary fragments; - // c iaf(i) - mass of the i-th fragment - int nsf; - int iaf[iapmax]; -} qgarr13_; - -extern struct { - int nwt; - int nwp; -} qgarr55_; - -/** - Small helper class to provide a data-directory name in the format qgsjetII expects - */ -class datadir { -private: - datadir operator=(const std::string& dir); - datadir operator=(const datadir&); - -public: - datadir(const std::string& dir); - char data[132]; -}; - -// functions -void qgset_(); -void qgaini_( - const char* datdir); // Note: there is a length limiation 132 from fortran-qgsjet here - -/** - @function qgini_ - - additional initialization procedure per event - - @parameter e0n - interaction energy (per hadron/nucleon), - @parameter icp0 - hadron type (+-1 - pi+-, +-2 - p(p~), +-3 - n(n~), +-4 - K+-, +-5 - - K_l/s), - @parameter iap - projectile mass number (1 - for a hadron), - @parameter iat - target mass number -*/ -void qgini_(const double& e0n, const int& icp0, const int& iap, const int& iat); - -/** - @function qgconf_ - - generate one event configuration -*/ -void qgconf_(); - -/** - @function qgsect_ - - hadron-nucleus (hadron-nucleus) particle production cross section - - @parameter e0n lab. energy per projectile nucleon (hadron) - @parameter icz hadron class (1 - pion, 2 - nucleon, 3 - kaon) - @parameter iap projectile mass number (1=<iap<=iapmax), - @parameter iat target mass number (1=<iat<=iapmax) - */ -double qgsect_(const double& e0n, const int& icz, const int& iap0, const int& iat0); - -/** - @function qgran - - link to random number generation - */ -double qgran_(int&); -} diff --git a/corsika/process/Sibyll/Decay.hpp b/corsika/process/Sibyll/Decay.hpp deleted file mode 100644 index dbd009dcfe0a7f0d33c7c0467034e92f4dd38839..0000000000000000000000000000000000000000 --- a/corsika/process/Sibyll/Decay.hpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/process/DecayProcess.h> -#include <corsika/framework/sequence/SecondariesProcess.hpp> - -#include <set> -#include <vector> - -namespace corsika { - - namespace sibyll { - - class Decay : public corsika::DecayProcess<Decay> { - int fCount = 0; - - public: - Decay(const bool sibyll_listing = false); - Decay(std::set<particles::Code>); - ~Decay(); - void Init(); - - void SetStable(const std::vector<particles::Code>); - void SetUnstable(const std::vector<particles::Code>); - void SetUnstable(const corsika::Code); - void SetStable(const corsika::Code); - void SetAllUnstable(); - void SetAllStable(); - bool IsStable(const corsika::Code); - bool IsUnstable(const corsika::Code); - void SetDecay(const particles::Code, const bool); - - void PrintDecayConfig(const corsika::Code); - void SetHadronsUnstable(); - - // is Sibyll::Decay set to handle the decay of this particle? - bool IsDecayHandled(const corsika::particles::Code); - - // is decay possible in principle? - bool CanHandleDecay(const corsika::particles::Code); - - // set Sibyll::Decay to handle the decay of this particle! - void SetHandleDecay(const corsika::particles::Code); - // set Sibyll::Decay to handle the decay of this list of particles! - void SetHandleDecay(const std::vector<particles::Code>); - // set Sibyll::Decay to handle all particle decays - void SetHandleAllDecay(); - - template <typename TParticle> - corsika::units::si::TimeType GetLifetime(TParticle const&); - - /** - In this function SIBYLL is called to produce to decay the input particle. - */ - - template <typename TSecondaryView> - void DoDecay(TSecondaryView&); - - template <typename TParticleView> - EProcessReturn DoSecondaries(TParticleView&); - - private: - // internal routines to set particles stable and unstable in the COMMON blocks in - // sibyll - void SetStable(const std::vector<particles::Code>); - void SetUnstable(const std::vector<particles::Code>); - - void SetStable(const corsika::particles::Code); - void SetUnstable(const corsika::particles::Code); - - // internally set all particles to decay/not to decay - void SetAllUnstable(); - void SetAllStable(); - - // will this particle be stable in sibyll ? - bool IsStable(const corsika::particles::Code); - // will this particle decay in sibyll ? - bool IsUnstable(const corsika::particles::Code); - // set particle with input code to decay or not - void SetDecay(const particles::Code, const bool); - - std::set<particles::Code> handledDecays_; - }; - - } // namespace sibyll - -} // namespace corsika - -#endif diff --git a/corsika/process/Sibyll/Interaction.hpp b/corsika/process/Sibyll/Interaction.hpp deleted file mode 100644 index 9c263aaa59b6dc1f1d617ce6ef9fc70fb21a934c..0000000000000000000000000000000000000000 --- a/corsika/process/Sibyll/Interaction.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/InteractionProcess.hpp> -#include <corsika/framework/random/RNGManager.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include <tuple> - -namespace corsika::sibyll { - - class Interaction : public corsika::InteractionProcess<Interaction> { - - int count_ = 0; - int nucCount_ = 0; - static bool initialized_; ///! flag to assure init is done only once - bool sibyll_listing_; - - public: - Interaction(const bool sibyll_printout_on = false); - ~Interaction(); - - void Init(); - - void SetStable(std::vector<particles::Code> const&); - void SetUnstable(std::vector<particles::Code> const&); - - void SetUnstable(const corsika::Code); - void SetStable(const corsika::Code); - void SetAllUnstable(); - void SetAllStable(); - - static bool WasInitialized() { return initialized_; } - bool IsValidCoMEnergy(corsika::units::si::HEPEnergyType ecm) const { - return (minEnergyCoM_ <= ecm) && (ecm <= maxEnergyCoM_); - } - int GetMaxTargetMassNumber() const { return maxTargetMassNumber_; } - corsika::units::si::HEPEnergyType GetMinEnergyCoM() const { return minEnergyCoM_; } - corsika::units::si::HEPEnergyType GetMaxEnergyCoM() const { return maxEnergyCoM_; } - bool IsValidTarget(corsika::Code TargetId) const { - return (corsika::GetNucleusA(TargetId) < maxTargetMassNumber_) && - corsika::IsNucleus(TargetId); - } - - std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType> - GetCrossSection(const corsika::Code, const corsika::Code, - const corsika::units::si::HEPEnergyType) const; - - template <typename TParticle> - corsika::units::si::GrammageType GetInteractionLength(const TParticle&) const; - - /** - In this function SIBYLL is called to produce one event. The - event is copied (and boosted) into the shower lab frame. - */ - - template <typename TProjectile> - corsika::EProcessReturn DoInteraction(TProjectile&); - - private: - corsika::RNG& RNG_ = corsika::RNGManager::GetInstance().GetRandomStream("s_rndm"); - // FOR NOW keep trackedParticles private, could be configurable - std::vector<particles::Code> const trackedParticles_ = { - particles::Code::PiPlus, particles::Code::PiMinus, - particles::Code::Pi0, particles::Code::KMinus, - particles::Code::KPlus, particles::Code::K0Long, - particles::Code::K0Short, particles::Code::SigmaPlus, - particles::Code::Sigma0, particles::Code::Sigma0Bar, - particles::Code::SigmaMinus, particles::Code::Lambda0, - particles::Code::Xi0, particles::Code::XiMinus, - particles::Code::OmegaMinus, particles::Code::DPlus, - particles::Code::DMinus, particles::Code::D0, - particles::Code::MuMinus, particles::Code::MuPlus, - particles::Code::D0Bar}; - const bool internalDecays_ = true; - const corsika::units::si::HEPEnergyType minEnergyCoM_ = - 10. * 1e9 * corsika::units::si::electronvolt; - const corsika::units::si::HEPEnergyType maxEnergyCoM_ = - 1.e6 * 1e9 * corsika::units::si::electronvolt; - const int maxTargetMassNumber_ = 18; - }; - -} // namespace corsika::sibyll - -#endif diff --git a/corsika/process/Sibyll/NuclearInteraction.hpp b/corsika/process/Sibyll/NuclearInteraction.hpp deleted file mode 100644 index a587bf0f82fa002c089ac4cca36848d669c4ac07..0000000000000000000000000000000000000000 --- a/corsika/process/Sibyll/NuclearInteraction.hpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/sequence/InteractionProcess.hpp> -#include <corsika/framework/random/RNGManager.hpp> - -namespace corsika::sibyll { - - class Interaction; // fwd-decl - - /** - * - * - **/ - template <class TEnvironment> - class NuclearInteraction - : public corsika::InteractionProcess<NuclearInteraction<TEnvironment>> { - - int count_ = 0; - int nucCount_ = 0; - - public: - NuclearInteraction(corsika::sibyll::Interaction&, TEnvironment const&); - ~NuclearInteraction(); - - void InitializeNuclearCrossSections(); - void PrintCrossSectionTable(corsika::Code); - corsika::units::si::CrossSectionType ReadCrossSectionTable( - const int, corsika::Code, corsika::units::si::HEPEnergyType); - corsika::units::si::HEPEnergyType GetMinEnergyPerNucleonCoM() { - return gMinEnergyPerNucleonCoM_; - } - corsika::units::si::HEPEnergyType GetMaxEnergyPerNucleonCoM() { - return gMaxEnergyPerNucleonCoM_; - } - unsigned int constexpr GetMaxNucleusAProjectile() { return gMaxNucleusAProjectile_; } - unsigned int constexpr GetMaxNFragments() { return gMaxNFragments_; } - unsigned int constexpr GetNEnergyBins() { return gNEnBins_; } - - template <typename Particle> - std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType> - GetCrossSection(Particle& p, const corsika::Code TargetId); - - template <typename Particle> - corsika::units::si::GrammageType GetInteractionLength(Particle const&); - - template <typename Projectile> - corsika::EProcessReturn DoInteraction(Projectile&); - - private: - TEnvironment const& environment_; - corsika::sibyll::Interaction& hadronicInteraction_; - std::map<corsika::Code, int> targetComponentsIndex_; - corsika::RNG& RNG_ = corsika::RNGManager::GetInstance().GetRandomStream("s_rndm"); - static constexpr int gNSample_ = - 500; // number of samples in MC estimation of cross section - static constexpr unsigned int gMaxNucleusAProjectile_ = 56; - static constexpr unsigned int gNEnBins_ = 6; - static constexpr unsigned int gMaxNFragments_ = 60; - // energy limits defined by table used for cross section in signuc.f - // 10**1 GeV to 10**6 GeV - static constexpr corsika::units::si::HEPEnergyType gMinEnergyPerNucleonCoM_ = - 10. * 1e9 * corsika::units::si::electronvolt; - static constexpr corsika::units::si::HEPEnergyType gMaxEnergyPerNucleonCoM_ = - 1.e6 * 1e9 * corsika::units::si::electronvolt; - }; - -} // namespace corsika::sibyll - -#endif diff --git a/corsika/process/Sibyll/ParticleConversion.h b/corsika/process/Sibyll/ParticleConversion.h deleted file mode 100644 index a2bc716cafd56e9a1aa8a52c4448f4466510a79b..0000000000000000000000000000000000000000 --- a/corsika/process/Sibyll/ParticleConversion.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/core/ParticleProperties.hpp> - -#include <string> - -namespace corsika::sibyll { - - enum class SibyllCode : int8_t; - using SibyllCodeIntType = std::underlying_type<SibyllCode>::type; - - /** - These are the possible projectile for which Sibyll knows the cross section - */ - enum class SibyllXSClass : int8_t { - CannotInteract = 0, - Baryon = 1, - Pion = 2, - Kaon = 3, - }; - using SibyllXSClassIntType = std::underlying_type<SibyllXSClass>::type; - -#include <corsika/process/sibyll/Generated.inc> - - SibyllCode constexpr ConvertToSibyll(corsika::Code pCode) { - return static_cast<SibyllCode>( - corsika2sibyll[static_cast<corsika::CodeIntType>(pCode)]); - } - - corsika::Code constexpr ConvertFromSibyll(SibyllCode pCode) { - auto const s = static_cast<SibyllCodeIntType>(pCode); - auto const corsikaCode = sibyll2corsika[s - minSibyll]; - if (corsikaCode == corsika::Code::Unknown) { - throw std::runtime_error(std::string("SIBYLL/CORSIKA conversion of ") - .append(std::to_string(s)) - .append(" impossible")); - } - return corsikaCode; - } - - int constexpr ConvertToSibyllRaw(corsika::Code pCode) { - return static_cast<int>(ConvertToSibyll(pCode)); - } - - int constexpr GetSibyllXSCode(corsika::Code pCode) { - return corsika2sibyllXStype[static_cast<corsika::CodeIntType>(pCode)]; - } - - bool constexpr CanInteract(corsika::Code pCode) { - return GetSibyllXSCode(pCode) > 0; - } - -} // namespace corsika::sibyll - -} // namespace corsika::process::sibyll diff --git a/corsika/process/Sibyll/SibStack.hpp b/corsika/process/Sibyll/SibStack.hpp deleted file mode 100644 index 1217468313febf5f11782e01ed67c0980f6179b4..0000000000000000000000000000000000000000 --- a/corsika/process/Sibyll/SibStack.hpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> -#include <corsika/process/sibyll/ParticleConversion.h> -#include <corsika/process/sibyll/sibyll2.3c.h> -#include <corsika/framework/stack/Stack.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -namespace corsika::sibyll { - - typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector; - - class SibStackData { - - public: - void Dump() const {} - - void Clear() { s_plist_.np = 0; } - unsigned int GetSize() const { return s_plist_.np; } - unsigned int GetCapacity() const { return 8000; } - - void SetId(const unsigned int i, const int v) { s_plist_.llist[i] = v; } - void SetEnergy(const unsigned int i, const corsika::units::si::HEPEnergyType v) { - using namespace corsika::units::si; - s_plist_.p[3][i] = v / 1_GeV; - } - void SetMass(const unsigned int i, const corsika::units::si::HEPMassType v) { - using namespace corsika::units::si; - s_plist_.p[4][i] = v / 1_GeV; - } - void SetMomentum(const unsigned int i, const MomentumVector& v) { - using namespace corsika::units::si; - auto tmp = v.GetComponents(); - for (int idx = 0; idx < 3; ++idx) s_plist_.p[idx][i] = tmp[idx] / 1_GeV; - } - - int GetId(const unsigned int i) const { return s_plist_.llist[i]; } - corsika::units::si::HEPEnergyType GetEnergy(const int i) const { - using namespace corsika::units::si; - return s_plist_.p[3][i] * 1_GeV; - } - corsika::units::si::HEPEnergyType GetMass(const unsigned int i) const { - using namespace corsika::units::si; - return s_plist_.p[4][i] * 1_GeV; - } - MomentumVector GetMomentum(const unsigned int i) const { - using corsika::CoordinateSystem; - using corsika::QuantityVector; - using corsika::RootCoordinateSystem; - using namespace corsika::units::si; - CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - QuantityVector<hepmomentum_d> components = { - s_plist_.p[0][i] * 1_GeV, s_plist_.p[1][i] * 1_GeV, s_plist_.p[2][i] * 1_GeV}; - return MomentumVector(rootCS, components); - } - - void Copy(const unsigned int i1, const unsigned int i2) { - s_plist_.llist[i2] = s_plist_.llist[i1]; - for (unsigned int i = 0; i < 5; ++i) s_plist_.p[i][i2] = s_plist_.p[i][i1]; - } - - void Swap(const unsigned int i1, const unsigned int i2) { - std::swap(s_plist_.llist[i1], s_plist_.llist[i2]); - for (unsigned int i = 0; i < 5; ++i) - std::swap(s_plist_.p[i][i1], s_plist_.p[i][i2]); - } - - void IncrementSize() { s_plist_.np++; } - void DecrementSize() { - if (s_plist_.np > 0) { s_plist_.np--; } - } - }; - - template <typename StackIteratorInterface> - class ParticleInterface : public corsika::ParticleBase<StackIteratorInterface> { - - using corsika::ParticleBase<StackIteratorInterface>::GetStackData; - using corsika::ParticleBase<StackIteratorInterface>::GetIndex; - - public: - void SetParticleData(const int vID, // corsika::sibyll::SibyllCode vID, - const corsika::units::si::HEPEnergyType vE, - const MomentumVector& vP, - const corsika::units::si::HEPMassType vM) { - SetPID(vID); - SetEnergy(vE); - SetMomentum(vP); - SetMass(vM); - } - - void SetParticleData(ParticleInterface<StackIteratorInterface>& /*parent*/, - const int vID, // corsika::sibyll::SibyllCode vID, - const corsika::units::si::HEPEnergyType vE, - const MomentumVector& vP, - const corsika::units::si::HEPMassType vM) { - SetPID(vID); - SetEnergy(vE); - SetMomentum(vP); - SetMass(vM); - } - - void SetEnergy(const corsika::units::si::HEPEnergyType v) { - GetStackData().SetEnergy(GetIndex(), v); - } - - corsika::units::si::HEPEnergyType GetEnergy() const { - return GetStackData().GetEnergy(GetIndex()); - } - - bool HasDecayed() const { return abs(GetStackData().GetId(GetIndex())) > 100; } - - void SetMass(const corsika::units::si::HEPMassType v) { - GetStackData().SetMass(GetIndex(), v); - } - - corsika::units::si::HEPEnergyType GetMass() const { - return GetStackData().GetMass(GetIndex()); - } - - void SetPID(const int v) { GetStackData().SetId(GetIndex(), v); } - - corsika::sibyll::SibyllCode GetPID() const { - return static_cast<corsika::sibyll::SibyllCode>(GetStackData().GetId(GetIndex())); - } - - MomentumVector GetMomentum() const { return GetStackData().GetMomentum(GetIndex()); } - - void SetMomentum(const MomentumVector& v) { - GetStackData().SetMomentum(GetIndex(), v); - } - }; - - typedef corsika::Stack<SibStackData, ParticleInterface> SibStack; - -} // end namespace corsika::sibyll - -#endif diff --git a/corsika/process/StackInspector.hpp b/corsika/process/StackInspector.hpp deleted file mode 100644 index ff9169d4d5ddd00efe9929d882b646cf4e214dfd..0000000000000000000000000000000000000000 --- a/corsika/process/StackInspector.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/sequence/StackProcess.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <chrono> -#include "corsika/setup/SetupTrajectory.hpp" - -namespace corsika { - - namespace stack_inspector { - - template <typename TStack> - class StackInspector : public corsika::StackProcess<StackInspector<TStack>> { - - typedef typename TStack::ParticleType Particle; - - using corsika::StackProcess<StackInspector<TStack>>::GetStep; - - public: - StackInspector(const int vNStep, const bool vReportStack, - const corsika::units::si::HEPEnergyType vE0); - ~StackInspector(); - - void DoStack(const TStack&); - - /** - * To set a new E0, for example when a new shower event is started - */ - void SetE0(const corsika::units::si::HEPEnergyType vE0) { E0_ = vE0; } - - private: - bool ReportStack_; - corsika::units::si::HEPEnergyType E0_; - const corsika::units::si::HEPEnergyType dE_threshold_ = std::invoke([]() { - using namespace units::si; - return 1_eV; - }); - decltype(std::chrono::system_clock::now()) StartTime_; - }; - - } // namespace stack_inspector - -} // namespace corsika diff --git a/corsika/process/SwitchProcess.hpp b/corsika/process/SwitchProcess.hpp deleted file mode 100644 index 2c08016fd5c89c83ca1ed9d3dad89a2e0b9033b5..0000000000000000000000000000000000000000 --- a/corsika/process/SwitchProcess.hpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/sequence/InteractionProcess.hpp> -#include <corsika/framework/sequence/ProcessSequence.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include "corsika/setup/SetupStack.hpp" - -namespace corsika::switch_process { - - /** - * This process provides an energy-based switch between two interaction processes P1 and - * P2. For energies below the threshold, P1 is invoked, otherwise P2. Both can be either - * single interaction processes or multiple ones combined in a ProcessSequence. A - * SwitchProcess itself will always be regarded as a distinct case when assembled into a - * (greater) ProcessSequence. - */ - - template <class TLowEProcess, class THighEProcess> - class SwitchProcess : public BaseProcess<SwitchProcess<TLowEProcess, THighEProcess>> { - TLowEProcess& fLowEProcess; - THighEProcess& fHighEProcess; - units::si::HEPEnergyType const fThresholdEnergy; - - public: - SwitchProcess(TLowEProcess& vLowEProcess, THighEProcess& vHighEProcess, - units::si::HEPEnergyType vThresholdEnergy) - : fLowEProcess(vLowEProcess) - , fHighEProcess(vHighEProcess) - , fThresholdEnergy(vThresholdEnergy) {} - - template <typename TParticle> - corsika::units::si::InverseGrammageType GetInverseInteractionLength(TParticle& p) { - return 1 / GetInteractionLength(p); - } - - template <typename TParticle> - units::si::GrammageType GetInteractionLength(TParticle& vParticle) { - if (vParticle.GetEnergy() < fThresholdEnergy) { - if constexpr (is_process_sequence_v<TLowEProcess>) { - return fLowEProcess.GetTotalInteractionLength(vParticle); - } else { - return fLowEProcess.GetInteractionLength(vParticle); - } - } else { - if constexpr (is_process_sequence_v<THighEProcess>) { - return fHighEProcess.GetTotalInteractionLength(vParticle); - } else { - return fHighEProcess.GetInteractionLength(vParticle); - } - } - } - - // required to conform to ProcessSequence interface. We cannot just - // implement DoInteraction() because we want to call SelectInteraction - // in case a member process is a ProcessSequence. - template <typename TParticle, typename TSecondaries> - EProcessReturn SelectInteraction( - TParticle& vP, TSecondaries& vS, - [[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select, - corsika::units::si::InverseGrammageType& lambda_inv_count) { - if (vP.GetEnergy() < fThresholdEnergy) { - if constexpr (is_process_sequence_v<TLowEProcess> || - is_switch_process_v<TLowEProcess>) { - return fLowEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); - } else { - lambda_inv_count += fLowEProcess.GetInverseInteractionLength(vP); - // check if we should execute THIS process and then EXIT - if (lambda_select < lambda_inv_count) { - fLowEProcess.DoInteraction(vS); - return EProcessReturn::eInteracted; - } else { - return EProcessReturn::eOk; - } - } - } else { - if constexpr (is_process_sequence_v<THighEProcess> || - is_switch_process_v<THighEProcess>) { - return fHighEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count); - } else { - lambda_inv_count += fHighEProcess.GetInverseInteractionLength(vP); - // check if we should execute THIS process and then EXIT - if (lambda_select < lambda_inv_count) { - fHighEProcess.DoInteraction(vS); - return EProcessReturn::eInteracted; - } else { - return EProcessReturn::eOk; - } - } - } - } - }; -} // namespace corsika::switch_process diff --git a/corsika/process/TrackWriter.hpp b/corsika/process/TrackWriter.hpp deleted file mode 100644 index d0f9d84622b2c6726daae7f43ae3522806e46a9f..0000000000000000000000000000000000000000 --- a/corsika/process/TrackWriter.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/framework/sequence/ContinuousProcess.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <fstream> -#include <string> - -namespace corsika::track_writer { - - class TrackWriter : public corsika::ContinuousProcess<TrackWriter> { - - public: - TrackWriter(std::string const& filename); - - template <typename Particle, typename Track> - corsika::EProcessReturn DoContinuous(Particle&, Track&); - - template <typename Particle, typename Track> - corsika::units::si::LengthType MaxStepLength(Particle&, Track&) { - return units::si::meter * std::numeric_limits<double>::infinity(); - } - - private: - std::string const fFilename; - std::ofstream fFile; - - int width = 14; - int precision = 6; - }; - -} // namespace corsika::track_writer diff --git a/corsika/process/detail/EnergyLoss.cc b/corsika/process/detail/EnergyLoss.cc deleted file mode 100644 index 6e6d44ac7305f3cb58ad95b301355c8b0fabf8b0..0000000000000000000000000000000000000000 --- a/corsika/process/detail/EnergyLoss.cc +++ /dev/null @@ -1,303 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/energy_loss/EnergyLoss.h> - -#include <corsika/framework/core/ParticleProperties.hpp> - -#include <corsika/framework/geometry/Line.hpp> - -#include <cmath> -#include <fstream> -#include <iostream> -#include <limits> -#include <numeric> - -#include "../corsika/setup/SetupStack.hpp" -#include "../corsika/setup/SetupTrajectory.hpp" - -using namespace std; - -using namespace corsika; -using namespace corsika::units::si; -using SetupParticle = corsika::Stack::ParticleType; -using SetupTrack = corsika::Trajectory; - -namespace corsika { - - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt((Elab - m) * (Elab + m)); - }; - - /** - * PDG2018, passage of particles through matter - * - * Note, that \f$I_{\mathrm{eff}}\f$ of composite media a determined from \f$ \ln I = - * \sum_i a_i \ln(I_i) \f$ where \f$ a_i \f$ is the fraction of the electron population - * (\f$\sim Z_i\f$) of the \f$i\f$-th element. This can also be used for shell - * corrections or density effects. - * - * The \f$I_{\mathrm{eff}}\f$ of compounds is not better than a few percent, if not - * measured explicitly. - * - * For shell correction, see Sec 6 of https://www.nap.edu/read/20066/chapter/8#115 - * - */ - HEPEnergyType EnergyLoss::BetheBloch(SetupParticle const& p, GrammageType const dX) { - - // all these are material constants and have to come through Environment - // right now: values for nitrogen_D - // 7 nitrogen_gas 82.0 0.49976 D E 0.0011653 0.0 1.7378 4.1323 0.15349 3.2125 10.54 - auto Ieff = 82.0_eV; - [[maybe_unused]] auto Zmat = 7; - auto ZoverA = 0.49976_mol / 1_g; - const double x0 = 1.7378; - const double x1 = 4.1323; - const double Cbar = 10.54; - const double delta0 = 0.0; - const double aa = 0.15349; - const double sk = 3.2125; - // end of material constants - - // this is the Bethe-Bloch coefficiet 4pi N_A r_e^2 m_e c^2 - auto constexpr K = 0.307075_MeV / 1_mol * square(1_cm); - HEPEnergyType const E = p.GetEnergy(); - HEPMassType const m = p.GetMass(); - double const gamma = E / m; - int const Z = p.GetChargeNumber(); - int const Z2 = Z * Z; - HEPMassType constexpr me = particles::Electron::GetMass(); - auto const m2 = m * m; - auto constexpr me2 = me * me; - double const gamma2 = gamma * gamma; - - double const beta2 = (gamma2 - 1) / gamma2; // 1-1/gamma2 (1-1/gamma)*(1+1/gamma); - // (gamma_2-1)/gamma_2 = (1-1/gamma2); - double constexpr c2 = 1; // HEP convention here c=c2=1 - cout << "BetheBloch beta2=" << beta2 << " gamma2=" << gamma2 << endl; - [[maybe_unused]] double const eta2 = beta2 / (1 - beta2); - HEPMassType const Wmax = - 2 * me * c2 * beta2 * gamma2 / (1 + 2 * gamma * me / m + me2 / m2); - // approx, but <<1% HEPMassType const Wmax = 2*me*c2*beta2*gamma2; for HEAVY - // PARTICLES Wmax ~ 2me v2 for non-relativistic particles - cout << "BetheBloch Wmax=" << Wmax << endl; - - // Sternheimer parameterization, density corrections towards high energies - // NOTE/TODO: when Cbar is 0 it needs to be approximated from parameterization -> - // MISSING - cout << "BetheBloch p.GetMomentum().GetNorm()/m=" << p.GetMomentum().GetNorm() / m - << endl; - double const x = log10(p.GetMomentum().GetNorm() / m); - double delta = 0; - if (x >= x1) { - delta = 2 * (log(10)) * x - Cbar; - } else if (x < x1 && x >= x0) { - delta = 2 * (log(10)) * x - Cbar + aa * pow((x1 - x), sk); - } else if (x < x0) { // and IF conductor (otherwise, this is 0) - delta = delta0 * pow(100, 2 * (x - x0)); - } - cout << "BetheBloch delta=" << delta << endl; - - // with further low energies correction, accurary ~1% down to beta~0.05 (1MeV for p) - - // shell correction, <~100MeV - // need more clarity about formulas and units - const double Cadj = 0; - /* - // https://www.nap.edu/read/20066/chapter/8#104 - HEPEnergyType Iadj = 12_eV * Z + 7_eV; // Iadj<163eV - if (Iadj>=163_eV) - Iadj = 9.76_eV * Z + 58.8_eV * pow(Z, -0.19); // Iadj>=163eV - double const Cadj = (0.422377/eta2 + 0.0304043/(eta2*eta2) - - 0.00038106/(eta2*eta2*eta2)) * 1e-6 * Iadj*Iadj + (3.858019/eta2 - - 0.1667989/(eta2*eta2) + 0.00157955/(eta2*eta2*eta2)) * 1e-9 * Iadj*Iadj*Iadj; - */ - - // Barkas correction O(Z3) higher-order Born approximation - // see Appl. Phys. 85 (1999) 1249 - // double A = 1; - // if (p.GetPID() == particles::Code::Nucleus) A = p.GetNuclearA(); - // double const Erel = (p.GetEnergy()-p.GetMass()) / A / 1_keV; - // double const Llow = 0.01 * Erel; - // double const Lhigh = 1.5/pow(Erel, 0.4) + 45000./Zmat * pow(Erel, 1.6); - // double const barkas = Z * Llow*Lhigh/(Llow+Lhigh); // RU, I think the Z was - // missing... - double const barkas = 1; // does not work yet - - // Bloch correction for O(Z4) higher-order Born approximation - // see Appl. Phys. 85 (1999) 1249 - const double alpha = 1. / 137.035999173; - double const y2 = Z * Z * alpha * alpha / beta2; - double const bloch = -y2 * (1.202 - y2 * (1.042 - 0.855 * y2 + 0.343 * y2 * y2)); - - // cout << "BetheBloch Erel=" << Erel << " barkas=" << barkas << " bloch=" << bloch << - // endl; - - double const aux = 2 * me * c2 * beta2 * gamma2 * Wmax / (Ieff * Ieff); - return -K * Z2 * ZoverA / beta2 * - (0.5 * log(aux) - beta2 - Cadj / Z - delta / 2 + barkas + bloch) * dX; - } - -EnergyLoss::EnergyLoss(environment::ShowerAxis const& shower_axis, - corsika::units::si::HEPEnergyType emCut) - : shower_axis_(shower_axis) - , emCut_(emCut) - , profile_(int(shower_axis.maximumX() / dX_) + 1) {} - -auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt((Elab - m) * (Elab + m)); -}; - -/** - * PDG2018, passage of particles through matter - * - * Note, that \f$I_{\mathrm{eff}}\f$ of composite media a determined from \f$ \ln I = - * \sum_i a_i \ln(I_i) \f$ where \f$ a_i \f$ is the fraction of the electron population - * (\f$\sim Z_i\f$) of the \f$i\f$-th element. This can also be used for shell - * corrections or density effects. - * - * The \f$I_{\mathrm{eff}}\f$ of compounds is not better than a few percent, if not - * measured explicitly. - * - * For shell correction, see Sec 6 of https://www.nap.edu/read/20066/chapter/8#115 - * - */ -HEPEnergyType EnergyLoss::BetheBloch(SetupParticle const& p, GrammageType const dX) { - - // all these are material constants and have to come through Environment - // right now: values for nitrogen_D - // 7 nitrogen_gas 82.0 0.49976 D E 0.0011653 0.0 1.7378 4.1323 0.15349 3.2125 10.54 - auto Ieff = 82.0_eV; - [[maybe_unused]] auto Zmat = 7; - auto ZoverA = 0.49976_mol / 1_g; - const double x0 = 1.7378; - const double x1 = 4.1323; - const double Cbar = 10.54; - const double delta0 = 0.0; - const double aa = 0.15349; - const double sk = 3.2125; - // end of material constants - - // this is the Bethe-Bloch coefficiet 4pi N_A r_e^2 m_e c^2 - auto constexpr K = 0.307075_MeV / 1_mol * square(1_cm); - HEPEnergyType const E = p.GetEnergy(); - HEPMassType const m = p.GetMass(); - double const gamma = E / m; - int const Z = p.GetChargeNumber(); - int const Z2 = Z * Z; - HEPMassType constexpr me = particles::Electron::GetMass(); - auto const m2 = m * m; - auto constexpr me2 = me * me; - double const gamma2 = gamma * gamma; - - double const beta2 = (gamma2 - 1) / gamma2; // 1-1/gamma2 (1-1/gamma)*(1+1/gamma); - // (gamma_2-1)/gamma_2 = (1-1/gamma2); - double constexpr c2 = 1; // HEP convention here c=c2=1 - C8LOG_DEBUG("BetheBloch beta2={}, gamma2={}", beta2, gamma2); - [[maybe_unused]] double const eta2 = beta2 / (1 - beta2); - HEPMassType const Wmax = - 2 * me * c2 * beta2 * gamma2 / (1 + 2 * gamma * me / m + me2 / m2); - // approx, but <<1% HEPMassType const Wmax = 2*me*c2*beta2*gamma2; for HEAVY - // PARTICLES Wmax ~ 2me v2 for non-relativistic particles - C8LOG_DEBUG("BetheBloch Wmax={}", Wmax); - - // Sternheimer parameterization, density corrections towards high energies - // NOTE/TODO: when Cbar is 0 it needs to be approximated from parameterization -> - // MISSING - C8LOG_DEBUG("BetheBloch p.GetMomentum().GetNorm()/m{}=", p.GetMomentum().GetNorm() / m); - double const x = log10(p.GetMomentum().GetNorm() / m); - double delta = 0; - if (x >= x1) { - delta = 2 * (log(10)) * x - Cbar; - } else if (x < x1 && x >= x0) { - delta = 2 * (log(10)) * x - Cbar + aa * pow((x1 - x), sk); - } else if (x < x0) { // and IF conductor (otherwise, this is 0) - delta = delta0 * pow(100, 2 * (x - x0)); - } - - void EnergyLoss::MomentumUpdate(corsika::Stack::ParticleType& vP, - corsika::units::si::HEPEnergyType Enew) { - HEPMomentumType Pnew = elab2plab(Enew, vP.GetMass()); - auto pnew = vP.GetMomentum(); - vP.SetMomentum(pnew * Pnew / pnew.GetNorm()); - } - - void EnergyLoss::FillProfile(SetupParticle const& vP, SetupTrack const& vTrack, - const HEPEnergyType dE) { - - using namespace corsika; - - auto const toStart = vTrack.GetPosition(0) - InjectionPoint_; - auto const toEnd = vTrack.GetPosition(1) - InjectionPoint_; - - auto const v1 = (toStart * 1_Hz).dot(ShowerAxisDirection_); - auto const v2 = (toEnd * 1_Hz).dot(ShowerAxisDirection_); - geometry::Line const lineToStartBin(InjectionPoint_, ShowerAxisDirection_ * v1); - geometry::Line const lineToEndBin(InjectionPoint_, ShowerAxisDirection_ * v2); - - SetupTrack const trajToStartBin(lineToStartBin, 1_s); - SetupTrack const trajToEndBin(lineToEndBin, 1_s); - - GrammageType const grammageStart = - vP.GetNode()->GetModelProperties().IntegratedGrammage(trajToStartBin, - trajToStartBin.GetLength()); - GrammageType const grammageEnd = - vP.GetNode()->GetModelProperties().IntegratedGrammage(trajToEndBin, - trajToEndBin.GetLength()); - - const int binStart = grammageStart / dX_; - const int binEnd = grammageEnd / dX_; - - std::cout << "energy deposit of " << -dE << " between " << grammageStart << " and " - << grammageEnd << std::endl; - - auto energyCount = HEPEnergyType::zero(); - - auto fill = [&](int bin, GrammageType weight) { - const auto dX = grammageEnd - grammageStart; - if (dX > dX_threshold_) { - auto const increment = -dE * weight / (grammageEnd - grammageStart); - Profile_[bin] += increment; - energyCount += increment; - - std::cout << "filling bin " << bin << " with weight " << weight << ": " - << increment << std::endl; - } - }; - - // fill longitudinal profile - fill(binStart, (1 + binStart) * dX_ - grammageStart); - fill(binEnd, grammageEnd - binEnd * dX_); - - if (binStart == binEnd) { fill(binStart, -dX_); } - - for (int bin = binStart + 1; bin < binEnd; ++bin) { fill(bin, dX_); } - - // fill longitudinal profile - if (binStart == binEnd) { - fill(binStart, 1); - } else { - fill(binStart, ((1 + binStart) * dX_ - grammageStart) / deltaX); - fill(binEnd, (grammageEnd - binEnd * dX_) / deltaX); - for (int bin = binStart + 1; bin < binEnd; ++bin) { fill(bin, 1); } - } - - C8LOG_DEBUG("total energy added to histogram: {} ", energyCount); -} - -void EnergyLoss::PrintProfile() const { - std::ofstream file("EnergyLossProfile.dat"); - file << "# EnergyLoss profile" << std::endl - << "# lower X bin edge [g/cm2] dE/dX [GeV/g/cm2]" << endl; - double const deltaX = dX_ / 1_g * square(1_cm); - for (size_t i = 0; i < profile_.size(); ++i) { - file << std::scientific << std::setw(15) << i * deltaX << std::setw(15) - << profile_.at(i) / (deltaX * 1_GeV) << endl; - } - -} // namespace corsika diff --git a/corsika/process/detail/HadronicElasticModel.cc b/corsika/process/detail/HadronicElasticModel.cc deleted file mode 100644 index a7fad5814c73ce63029c04575beb48e9c4d14ed5..0000000000000000000000000000000000000000 --- a/corsika/process/detail/HadronicElasticModel.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/hadronic_elastic_model/HadronicElasticModel.h> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/NuclearComposition.hpp> -#include <corsika/framework/geometry/FourVector.hpp> -#include <corsika/framework/random/ExponentialDistribution.hpp> -#include <corsika/framework/utility/COMBoost.hpp> - -#include <iomanip> -#include <iostream> -#include "../corsika/setup/SetupStack.hpp" - -using namespace corsika; -using SetupParticle = corsika::Stack::ParticleType; - -namespace corsika::HadronicElasticModel { - - void HadronicElasticInteraction::Init() {} - - HadronicElasticInteraction::HadronicElasticInteraction(units::si::CrossSectionType x, - units::si::CrossSectionType y) - : fX(x) - , fY(y) {} - - template <> - units::si::GrammageType HadronicElasticInteraction::GetInteractionLength( - SetupParticle const& p) { - using namespace units::si; - if (p.GetPID() == particles::Code::Proton) { - auto const* currentNode = p.GetNode(); - auto const& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - - auto const& components = mediumComposition.GetComponents(); - auto const& fractions = mediumComposition.GetFractions(); - - auto const projectileMomentum = p.GetMomentum(); - auto const projectileMomentumSquaredNorm = projectileMomentum.squaredNorm(); - auto const projectileEnergy = p.GetEnergy(); - -HadronicElasticInteraction::HadronicElasticInteraction(units::si::CrossSectionType x, - units::si::CrossSectionType y) - : fX(x) - , fY(y) {} - -template <> -units::si::GrammageType HadronicElasticInteraction::GetInteractionLength( - SetupParticle const& p) { - using namespace units::si; - if (p.GetPID() == particles::Code::Proton) { - auto const* currentNode = p.GetNode(); - auto const& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - - auto const& components = mediumComposition.GetComponents(); - auto const& fractions = mediumComposition.GetFractions(); - - auto const projectileMomentum = p.GetMomentum(); - auto const projectileMomentumSquaredNorm = projectileMomentum.squaredNorm(); - auto const projectileEnergy = p.GetEnergy(); - - auto const avgCrossSection = [&]() { - CrossSectionType avgCrossSection = 0_b; - - for (size_t i = 0; i < fractions.size(); ++i) { - auto const targetMass = particles::GetMass(components[i]); - auto const s = units::static_pow<2>(projectileEnergy + targetMass) - - projectileMomentumSquaredNorm; - avgCrossSection += CrossSection(s) * fractions[i]; - } - - std::cout << "avgCrossSection: " << avgCrossSection / 1_mb << " mb" << std::endl; - - return avgCrossSection; - }(); - - auto const avgTargetMassNumber = mediumComposition.GetAverageMassNumber(); - - GrammageType const interactionLength = - avgTargetMassNumber * units::constants::u / avgCrossSection; - - return interactionLength; - } else { - return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); - } -} - -template <> -process::EProcessReturn HadronicElasticInteraction::DoInteraction(SetupView& view) { - using namespace units::si; - using namespace units::constants; - - auto p = view.GetProjectile(); - if (p.GetPID() != particles::Code::Proton) { return process::EProcessReturn::eOk; } - - const auto* currentNode = p.GetNode(); - const auto& composition = currentNode->GetModelProperties().GetNuclearComposition(); - const auto& components = composition.GetComponents(); - - std::vector<units::si::CrossSectionType> cross_section_of_components( - composition.GetComponents().size()); - - auto const projectileMomentum = p.GetMomentum(); - auto const projectileMomentumSquaredNorm = projectileMomentum.squaredNorm(); - auto const projectileEnergy = p.GetEnergy(); - - for (size_t i = 0; i < components.size(); ++i) { - auto const targetMass = particles::GetMass(components[i]); - auto const s = units::static_pow<2>(projectileEnergy + targetMass) - - projectileMomentumSquaredNorm; - cross_section_of_components[i] = CrossSection(s); - } - -} // namespace corsika::HadronicElasticModel diff --git a/corsika/process/detail/ObservationPlane.cc b/corsika/process/detail/ObservationPlane.cc deleted file mode 100644 index 402d9c0f303ce3f21155c9f57a93926c14a22a67..0000000000000000000000000000000000000000 --- a/corsika/process/detail/ObservationPlane.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* - * (c) Copyright 2019 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/observation_plane/ObservationPlane.hpp> - -#include <fstream> - -using namespace corsika::observation_plane; -using namespace corsika::units::si; - -ObservationPlane::ObservationPlane( - geometry::Plane const& obsPlane, - geometry::Vector<units::si::dimensionless_d> const& x_axis, - std::string const& filename, bool deleteOnHit) - : plane_(obsPlane) - , outputStream_(filename) - , deleteOnHit_(deleteOnHit) - , energy_ground_(0_GeV) - , count_ground_(0) - , xAxis_(x_axis.normalized()) - , yAxis_(obsPlane.GetNormal().cross(xAxis_)) { - outputStream_ << "#PDG code, energy / eV, x distance / m, y distance / m" << std::endl; -} - -corsika::EProcessReturn ObservationPlane::DoContinuous( - setup::Stack::ParticleType const& particle, setup::Trajectory const& trajectory) { - TimeType const timeOfIntersection = - (plane_.GetCenter() - trajectory.GetLine().GetR0()).dot(plane_.GetNormal()) / - trajectory.GetLine().GetV0().dot(plane_.GetNormal()); - - if (timeOfIntersection < TimeType::zero()) { return process::EProcessReturn::eOk; } - - if (plane_.IsAbove(trajectory.GetLine().GetR0()) == - plane_.IsAbove(trajectory.GetPosition(1))) { - return process::EProcessReturn::eOk; - } - - const auto energy = particle.GetEnergy(); - auto const displacement = trajectory.GetPosition(1) - plane_.GetCenter(); - - outputStream_ << static_cast<int>(particles::GetPDG(particle.GetPID())) << ' ' - << energy / 1_eV << ' ' << displacement.dot(xAxis_) / 1_m << ' ' - << displacement.dot(yAxis_) / 1_m - << (trajectory.GetPosition(1) - plane_.GetCenter()).norm() / 1_m - << std::endl; - - if (deleteOnHit_) { - count_ground_++; - energy_ground_ += energy; - particle.Delete(); - return process::EProcessReturn::eParticleAbsorbed; - } else { - return process::EProcessReturn::eOk; - } -} - -LengthType ObservationPlane::MaxStepLength(setup::Stack::ParticleType const& vParticle, - setup::Trajectory const& trajectory) { - int chargeNumber; - if (corsika::particles::IsNucleus(vParticle.GetPID())) { - chargeNumber = vParticle.GetNuclearZ(); - } else { - chargeNumber = corsika::particles::GetChargeNumber(vParticle.GetPID()); - } - auto const* currentLogicalVolumeNode = vParticle.GetNode(); - auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField( - vParticle.GetPosition()); - auto direction = trajectory.GetLine().GetV0().normalized(); - - if (chargeNumber != 0 && - abs(plane_.GetNormal().dot(trajectory.GetLine().GetV0().cross(magneticfield))) * - 1_s / 1_m / 1_T > - 1e-6) { - auto const* currentLogicalVolumeNode = vParticle.GetNode(); - auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField( - vParticle.GetPosition()); - auto k = chargeNumber * corsika::units::constants::c * 1_eV / - (vParticle.GetMomentum().norm() * 1_V); - - if (direction.dot(plane_.GetNormal()) * direction.dot(plane_.GetNormal()) - - (plane_.GetNormal().dot(trajectory.GetLine().GetR0() - plane_.GetCenter()) * - plane_.GetNormal().dot(direction.cross(magneticfield)) * 2 * k) < - 0) { - return std::numeric_limits<double>::infinity() * 1_m; - } - - LengthType MaxStepLength1 = - (sqrt(direction.dot(plane_.GetNormal()) * direction.dot(plane_.GetNormal()) - - (plane_.GetNormal().dot(trajectory.GetLine().GetR0() - plane_.GetCenter()) * - plane_.GetNormal().dot(direction.cross(magneticfield)) * 2 * k)) - - direction.dot(plane_.GetNormal()) / direction.GetNorm()) / - (plane_.GetNormal().dot(direction.cross(magneticfield)) * k); - - LengthType MaxStepLength2 = - (-sqrt( - direction.dot(plane_.GetNormal()) * direction.dot(plane_.GetNormal()) - - (plane_.GetNormal().dot(trajectory.GetLine().GetR0() - plane_.GetCenter()) * - plane_.GetNormal().dot(direction.cross(magneticfield)) * 2 * k)) - - direction.dot(plane_.GetNormal()) / direction.GetNorm()) / - (plane_.GetNormal().dot(direction.cross(magneticfield)) * k); - - if (MaxStepLength1 <= 0_m && MaxStepLength2 <= 0_m) { - return std::numeric_limits<double>::infinity() * 1_m; - } else if (MaxStepLength1 <= 0_m || MaxStepLength2 < MaxStepLength1) { - std::cout << " steplength to obs plane 2: " << MaxStepLength2 << std::endl; - return MaxStepLength2 * - (direction + direction.cross(magneticfield) * MaxStepLength2 * k / 2) - .norm() * - 1.001; - } else if (MaxStepLength2 <= 0_m || MaxStepLength1 < MaxStepLength2) { - std::cout << " steplength to obs plane 1: " << MaxStepLength1 << std::endl; - return MaxStepLength1 * - (direction + direction.cross(magneticfield) * MaxStepLength2 * k / 2) - .norm() * - 1.001; - } - } - TimeType const timeOfIntersection = - (plane_.GetCenter() - trajectory.GetLine().GetR0()).dot(plane_.GetNormal()) / - trajectory.GetLine().GetV0().dot(plane_.GetNormal()); - - if (timeOfIntersection < TimeType::zero()) { - return std::numeric_limits<double>::infinity() * 1_m; - } - - auto const pointOfIntersection = trajectory.GetLine().GetPosition(timeOfIntersection); - std::cout << " obs plane non b-field " << std::endl; - return (trajectory.GetLine().GetR0() - pointOfIntersection).norm() * 1.0001; -} - -void ObservationPlane::ShowResults() const { - C8LOG_INFO( - " ******************************\n" - " ObservationPlane: \n" - " energy in ground (GeV) : {}\n" - " no. of particles in ground : {}\n" - " ******************************", - energy_ground_ / 1_GeV, count_ground_); -} - -void ObservationPlane::Reset() { - energy_ground_ = 0_GeV; - count_ground_ = 0; -} diff --git a/corsika/process/detail/ParticleCut.cc b/corsika/process/detail/ParticleCut.cc deleted file mode 100644 index 5cd87dad75a07b89679bee90efc33e05997620dd..0000000000000000000000000000000000000000 --- a/corsika/process/detail/ParticleCut.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/particle_cut/ParticleCut.hpp> - -using namespace std; - -using namespace corsika; -using namespace corsika; -using namespace corsika::units::si; -using namespace corsika; -using namespace corsika; - -namespace corsika { - namespace particle_cut { - - template <typename TParticle> - bool ParticleCut::ParticleIsBelowEnergyCut(TParticle const& vP) const { - auto const energyLab = vP.GetEnergy(); - // nuclei - if (vP.GetPID() == particles::Code::Nucleus) { - // calculate energy per nucleon - auto const ElabNuc = energyLab / vP.GetNuclearA(); - return (ElabNuc <= energy_cut_); - } else { - return (energyLab <= energy_cut_); - } - } - - bool ParticleCut::ParticleIsEmParticle(Code vCode) const { - switch (vCode) { - case Code::Gamma: - case Code::Electron: - case Code::Positron: - return true; - default: - return false; - } - } - - bool ParticleCut::ParticleIsInvisible(Code vCode) const { - switch (vCode) { - case Code::NuE: - case Code::NuEBar: - case Code::NuMu: - case Code::NuMuBar: - return true; - - default: - return false; - } - } - - EProcessReturn ParticleCut::DoSecondaries(corsika::StackView& vS) { - auto p = vS.begin(); - while (p != vS.end()) { - const Code pid = p.GetPID(); - HEPEnergyType energy = p.GetEnergy(); - cout << "ProcessCut: DoSecondaries: " << pid << " E= " << energy - << ", EcutTot=" << (fEmEnergy + fInvEnergy + fEnergy) / 1_GeV << " GeV" - << endl; - if (ParticleIsEmParticle(pid)) { - cout << "removing em. particle..." << endl; - fEmEnergy += energy; - fEmCount += 1; - p.Delete(); - } else if (ParticleIsInvisible(pid)) { - cout << "removing inv. particle..." << endl; - fInvEnergy += energy; - fInvCount += 1; - p.Delete(); - } else if (ParticleIsBelowEnergyCut(p)) { - cout << "removing low en. particle..." << endl; - fEnergy += energy; - p.Delete(); - } else if (p.GetTime() > 10_ms) { - cout << "removing OLD particle..." << endl; - fEnergy += energy; - p.Delete(); - } else { - ++p; // next entry in SecondaryView - } - } - return false; // this particle will not be removed/cut - } - - void ParticleCut::DoSecondaries(corsika::setup::StackView& vS) { - auto particle = vS.begin(); - while (particle != vS.end()) { - if (checkCutParticle(particle)) { particle.Delete(); } - ++particle; // next entry in SecondaryView - } - } - - process::EProcessReturn ParticleCut::DoContinuous( - corsika::setup::Stack::ParticleType& particle, - corsika::setup::Trajectory const&) { - C8LOG_TRACE("ParticleCut::DoContinuous"); - if (checkCutParticle(particle)) { - C8LOG_TRACE("removing during continuous"); - particle.Delete(); - // signal to upstream code that this particle was deleted - return process::EProcessReturn::eParticleAbsorbed; - } - return process::EProcessReturn::eOk; - } - - ParticleCut::ParticleCut(const units::si::HEPEnergyType eCut, bool em, bool inv) - : energy_cut_(eCut) - , bCutEm(em) - , bCutInv(inv) { - fEmEnergy = 0_GeV; - uiEmCount = 0; - fInvEnergy = 0_GeV; - uiInvCount = 0; - fEnergy = 0_GeV; - } - - // LCOV_EXCL_START - void ParticleCut::ShowResults() const { - C8LOG_INFO(fmt::format( - " ******************************\n" - " ParticleCut: \n" - " energy in em. component (GeV): {}\n" - " no. of em. particles injected: {}\n" - " energy in inv. component (GeV): {}\n" - " no. of inv. particles injected: {}\n" - " energy below particle cut (GeV): {}\n" - " ******************************", - fEmEnergy / 1_GeV, uiEmCount, fInvEnergy / 1_GeV, uiInvCount, fEnergy / 1_GeV)); - } - // LCOV_EXCL_STOP - - void ParticleCut::Reset() { - fEmEnergy = 0_GeV; - uiEmCount = 0; - fInvEnergy = 0_GeV; - uiInvCount = 0; - fEnergy = 0_GeV; - } - - } // namespace particle_cut -} // namespace corsika diff --git a/corsika/process/detail/Pythia/Decay.cc b/corsika/process/detail/Pythia/Decay.cc deleted file mode 100644 index e79d534bd7245c2ad81ab8459f658d4ade4edde3..0000000000000000000000000000000000000000 --- a/corsika/process/detail/Pythia/Decay.cc +++ /dev/null @@ -1,264 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <Pythia8/Pythia.h> -#include <corsika/process/pythia/Decay.h> -#include <corsika/process/pythia/Random.h> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using std::cout; -using std::endl; -using std::tuple; -using std::vector; - -using namespace corsika; -using namespace corsika; -using Projectile = corsika::StackView::ParticleType; -using Particle = corsika::Stack::ParticleType; -using Track = Trajectory; - -namespace corsika::pythia { - - Decay::Decay(const bool print_listing) - : print_listing_(print_listing) { - - // set random number generator in pythia - Pythia8::RndmEngine* rndm = new corsika::pythia::Random(); - fPythia.setRndmEnginePtr(rndm); - - /* - issue xyz: definition of particles and decay channels use the same mechanism in - corsika and pythia we should force pythia to use the file in corsika. - */ - // bool ParticleData::reInit(string startFile, bool xmlFormat = true) - // read in particle data from Corsika 8 - // fPythia.particleData.reInit("/home/felix/ngcorsika/corsika-build/include/corsika/particles/ParticleData.xml"); - // fPythia.particleData.checkTable(); - - fPythia.readString("Next:numberShowInfo = 0"); - fPythia.readString("Next:numberShowProcess = 0"); - fPythia.readString("Next:numberShowEvent = 0"); - - fPythia.readString("Print:quiet = on"); - fPythia.readString("Check:particleData = 0"); - - /* - switching off event check in pythia is needed to allow decays that are off-shell - according to the mass definition in pythia. - the consistency of particle masses between event generators is an unsolved issues - */ - cout << "Pythia::Init: switching off event checking in pythia.." << endl; - fPythia.readString("Check:event = 1"); - - fPythia.readString("ProcessLevel:all = off"); - fPythia.readString("ProcessLevel:resonanceDecays = off"); - - // making sure - SetStable(particles::Code::Pi0); - - // fPythia.particleData.readString("59:m0 = 101.00"); - - if (!fPythia.init()) - throw std::runtime_error("Pythia::Decay: Initialization failed!"); - } - - Decay::Decay(std::set<particles::Code> vHandled) - : handleAllDecays_(false) - , handledDecays_(vHandled) {} - - Decay::~Decay() { cout << "Pythia::Decay n=" << fCount << endl; } - - bool Decay::CanHandleDecay(const particles::Code vParticleCode) { - using namespace corsika::particles; - // if known to pythia and not proton, electron or neutrino it can decay - if (vParticleCode == Code::Proton || vParticleCode == Code::AntiProton || - vParticleCode == Code::NuE || vParticleCode == Code::NuMu || - vParticleCode == Code::NuTau || vParticleCode == Code::NuEBar || - vParticleCode == Code::NuMuBar || vParticleCode == Code::NuTauBar || - vParticleCode == Code::Electron || vParticleCode == Code::Positron) - return false; - else if (CanDecay(vParticleCode)) // non-zero for particles known to sibyll - return true; - else - return false; - } - - void Decay::SetHandleDecay(const particles::Code vParticleCode) { - handleAllDecays_ = false; - cout << "Pythia::Decay: set to handle decay of " << vParticleCode << endl; - if (Decay::CanHandleDecay(vParticleCode)) - handledDecays_.insert(vParticleCode); - else - throw std::runtime_error("this decay can not be handled by pythia!"); - } - - void Decay::SetHandleDecay(const vector<particles::Code> vParticleList) { - handleAllDecays_ = false; - for (auto p : vParticleList) SetHandleDecay(p); - } - - bool Decay::IsDecayHandled(const corsika::particles::Code vParticleCode) { - if (handleAllDecays_ && CanHandleDecay(vParticleCode)) - return true; - else - return handledDecays_.find(vParticleCode) != Decay::handledDecays_.end(); - } - - bool Decay::IsStable(const particles::Code vCode) { - return fPythia.particleData.canDecay(static_cast<int>(particles::GetPDG(vCode))); - } - - void Decay::PrintDecayConfig(const particles::Code vCode) { - cout << "Decay: Pythia decay configuration:" << endl; - cout << vCode << " is "; - if (IsStable(vCode)) - cout << "stable" << endl; - else - cout << "unstable" << endl; - } - - void Decay::PrintDecayConfig() { - cout << "Pythia::Decay: decay configuration:" << endl; - if (handleAllDecays_) - cout << " all particles known to Pythia are handled by Pythia::Decay!" << endl; - else - for (auto& pCode : handledDecays_) - cout << "Decay of " << pCode << " is handled by Pythia!" << endl; - } - - void Decay::SetStable(const vector<particles::Code> particleList) { - for (auto p : particleList) Decay::SetStable(p); - } - - bool Decay::CanDecay(const particles::Code pCode) { - std::cout << "Pythia::Decay: checking if particle: " << pCode - << " can decay in PYTHIA? "; - const bool ans = - fPythia.particleData.canDecay(static_cast<int>(particles::GetPDG(pCode))); - std::cout << ans << std::endl; - return ans; - } - - void Decay::SetUnstable(const particles::Code pCode) { - cout << "Pythia::Decay: setting " << pCode << " unstable.." << endl; - fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), true); - } - - void Decay::SetStable(const particles::Code pCode) { - cout << "Pythia::Decay: setting " << pCode << " stable.." << endl; - fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), false); - } - - template <> - units::si::TimeType Decay::GetLifetime(Particle const& vP) { - using namespace units::si; - - const auto pid = vP.GetPID(); - if (CanDecay(pid)) { - HEPEnergyType E = vP.GetEnergy(); - HEPMassType m = vP.GetMass(); - - const double gamma = E / m; - - const TimeType t0 = particles::GetLifetime(pid); - auto const lifetime = gamma * t0; - cout << "Pythia::Decay: code: " << vP.GetPID() << endl; - cout << "Pythia::Decay: MinStep: t0: " << t0 << endl; - cout << "Pythia::Decay: MinStep: energy: " << E / 1_GeV << " GeV" << endl; - cout << "Pythia::Decay: momentum: " << vP.GetMomentum().GetComponents() / 1_GeV - << " GeV" << endl; - cout << "Pythia::Decay: MinStep: gamma: " << gamma << endl; - cout << "Pythia::Decay: MinStep: tau: " << lifetime << endl; - - return lifetime; - } else - return std::numeric_limits<double>::infinity() * 1_s; - } - - template <> - void Decay::DoDecay(View& view) { - using geometry::Point; - using namespace units; - using namespace units::si; - - auto const projectile = view.GetProjectile(); - - auto const& decayPoint = projectile.GetPosition(); - auto const t0 = projectile.GetTime(); - - auto const& labMomentum = projectile.GetMomentum(); - geometry::CoordinateSystem const& labCS = labMomentum.GetCoordinateSystem(); - - // define target kinematics in lab frame - // define boost to and from CoM frame - // CoM frame definition in Pythia projectile: +z - utl::COMBoost const boost(labMomentum, projectile.GetMass()); - auto const& rotatedCS = boost.GetRotatedCS(); - - fCount++; - - // pythia stack - Pythia8::Event& event = fPythia.event; - event.reset(); - - auto const particleId = projectile.GetPID(); - - // set particle unstable - Decay::SetUnstable(particleId); - - // input particle PDG - auto const pdgCode = static_cast<int>(particles::GetPDG(particleId)); - - double constexpr px = 0; - double constexpr py = 0; - double constexpr pz = 0; - double const en = projectile.GetMass() / 1_GeV; - double const m = en; - - // add particle to pythia stack - event.append(pdgCode, 1, 0, 0, px, py, pz, en, m); - - if (!fPythia.next()) - throw std::runtime_error("Pythia::Decay: decay failed!"); - else - cout << "Pythia::Decay: particles after decay: " << event.size() << endl; - - if (print_listing_) { - // list final state - event.list(); - } - - // loop over final state - for (int i = 0; i < event.size(); ++i) - if (event[i].isFinal()) { - auto const pyId = - particles::ConvertFromPDG(static_cast<particles::PDGCode>(event[i].id())); - HEPEnergyType const Erest = event[i].e() * 1_GeV; - MomentumVector const pRest( - rotatedCS, - {event[i].px() * 1_GeV, event[i].py() * 1_GeV, event[i].pz() * 1_GeV}); - geometry::FourVector const fourMomRest{Erest, pRest}; - auto const fourMomLab = boost.fromCoM(fourMomRest); - - cout << "particle: id=" << pyId << " momentum=" - << fourMomLab.GetSpaceLikeComponents().GetComponents(labCS) / 1_GeV - << " energy=" << fourMomLab.GetTimeLikeComponent() << endl; - - view.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - pyId, pyEn, pyP, decayPoint, t0}); - } - - // set particle stable - Decay::SetStable(particleId); - } - -} // namespace corsika::pythia diff --git a/corsika/process/detail/Pythia/Interaction.cc b/corsika/process/detail/Pythia/Interaction.cc deleted file mode 100644 index 1b22153ef6a5f326eb30b5698a6acaef3c66fc48..0000000000000000000000000000000000000000 --- a/corsika/process/detail/Pythia/Interaction.cc +++ /dev/null @@ -1,405 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/pythia/Interaction.h> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/NuclearComposition.hpp> -#include <corsika/framework/geometry/FourVector.hpp> -#include <corsika/framework/utility/COMBoost.hpp> - -#include <tuple> -#include "../../corsika/setup/SetupStack.hpp" - -using std::cout; -using std::endl; -using std::tuple; - -using namespace corsika; -using namespace corsika; -using Projectile = corsika::StackView::ParticleType; -using Particle = corsika::Stack::ParticleType; - -namespace corsika::pythia { - - typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector; - - Interaction::Interaction(const bool print_listing) - : print_listing_(print_listing) { - - cout << "Pythia::Interaction n=" << fCount << endl; - - using random::RNGManager; - - // initialize Pythia - if (!fInitialized) { - - fPythia.readString("Print:quiet = on"); - // TODO: proper process initialization for MinBias needed - fPythia.readString("HardQCD:all = on"); - fPythia.readString("ProcessLevel:resonanceDecays = off"); - - fPythia.init(); - - // any decays in pythia? if yes need to define which particles - if (fInternalDecays) { - // define which particles are passed to corsika, i.e. which particles make it into - // history even very shortlived particles like charm or pi0 are of interest here - const std::vector<particles::Code> HadronsWeWantTrackedByCorsika = { - particles::Code::PiPlus, particles::Code::PiMinus, - particles::Code::Pi0, particles::Code::KMinus, - particles::Code::KPlus, particles::Code::K0Long, - particles::Code::K0Short, particles::Code::SigmaPlus, - particles::Code::SigmaMinus, particles::Code::Lambda0, - particles::Code::Xi0, particles::Code::XiMinus, - particles::Code::OmegaMinus, particles::Code::DPlus, - particles::Code::DMinus, particles::Code::D0, - particles::Code::D0Bar}; - - Interaction::SetParticleListStable(HadronsWeWantTrackedByCorsika); - } - - // basic initialization of cross section routines - fSigma.init(&fPythia.info, fPythia.settings, &fPythia.particleData, &fPythia.rndm); - - fInitialized = true; - } - } - - void Interaction::SetParticleListStable( - std::vector<particles::Code> const& particleList) { - for (auto p : particleList) Interaction::SetStable(p); - } - - void Interaction::SetUnstable(const particles::Code pCode) { - cout << "Pythia::Interaction: setting " << pCode << " unstable.." << endl; - fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), true); - } - - void Interaction::SetStable(const particles::Code pCode) { - cout << "Pythia::Interaction: setting " << pCode << " stable.." << endl; - fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), false); - } - - void Interaction::ConfigureLabFrameCollision( - const particles::Code BeamId, const particles::Code TargetId, - const units::si::HEPEnergyType BeamEnergy) { - using namespace units::si; - // Pythia configuration of the current event - // very clumsy. I am sure this can be done better.. - - // set beam - // beam id for pythia - auto const pdgBeam = static_cast<int>(particles::GetPDG(BeamId)); - std::stringstream stBeam; - stBeam << "Beams:idA = " << pdgBeam; - fPythia.readString(stBeam.str()); - // set target - auto pdgTarget = static_cast<int>(particles::GetPDG(TargetId)); - // replace hydrogen with proton, otherwise pythia goes into heavy ion mode! - if (TargetId == particles::Code::Hydrogen) - pdgTarget = static_cast<int>(particles::GetPDG(particles::Code::Proton)); - std::stringstream stTarget; - stTarget << "Beams:idB = " << pdgTarget; - fPythia.readString(stTarget.str()); - // set frame to lab. frame - fPythia.readString("Beams:frameType = 2"); - // set beam energy - const double Elab = BeamEnergy / 1_GeV; - std::stringstream stEnergy; - stEnergy << "Beams:eA = " << Elab; - fPythia.readString(stEnergy.str()); - // target at rest - fPythia.readString("Beams:eB = 0."); - // initialize this config - fPythia.init(); - } - - bool Interaction::CanInteract(const corsika::Code pCode) { - return pCode == corsika::Code::Proton || - pCode == corsika::Code::Neutron || - pCode == corsika::Code::AntiProton || - pCode == corsika::Code::AntiNeutron || - pCode == corsika::Code::PiMinus || - pCode == corsika::Code::PiPlus; - } - - tuple<units::si::CrossSectionType, units::si::CrossSectionType> - Interaction::GetCrossSection(const particles::Code BeamId, - const particles::Code TargetId, - const units::si::HEPEnergyType CoMenergy) { - using namespace units::si; - - // interaction possible in pythia? - if (TargetId == particles::Code::Proton || TargetId == particles::Code::Hydrogen) { - if (CanInteract(BeamId) && ValidCoMEnergy(CoMenergy)) { - // input particle PDG - auto const pdgCodeBeam = static_cast<int>(particles::GetPDG(BeamId)); - auto const pdgCodeTarget = static_cast<int>(particles::GetPDG(TargetId)); - const double ecm = CoMenergy / 1_GeV; - - // calculate cross section - fSigma.calc(pdgCodeBeam, pdgCodeTarget, ecm); - if (fSigma.hasSigmaTot()) { - const double sigEla = fSigma.sigmaEl(); - const double sigProd = fSigma.sigmaTot() - sigEla; - - return std::make_tuple(sigProd * (1_fm * 1_fm), sigEla * (1_fm * 1_fm)); - - } else - throw std::runtime_error("pythia cross section init failed"); - - } else { - return std::make_tuple(std::numeric_limits<double>::infinity() * 1_mb, - std::numeric_limits<double>::infinity() * 1_mb); - } - } else { - throw std::runtime_error("invalid target for pythia"); - } - } - - template <> - units::si::GrammageType Interaction::GetInteractionLength(const Particle& p) { - - using namespace units; - using namespace units::si; - using namespace geometry; - - // coordinate system, get global frame of reference - CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - - const particles::Code corsikaBeamId = p.GetPID(); - - // beam particles for pythia : 1, 2, 3 for p, pi, k - // read from cross section code table - const bool kInteraction = CanInteract(corsikaBeamId); - - // FOR NOW: assume target is at rest - process::pythia::MomentumVector pTarget(rootCS, {0_GeV, 0_GeV, 0_GeV}); - - // total momentum and energy - HEPEnergyType Elab = p.GetEnergy() + constants::nucleonMass; - process::pythia::MomentumVector pTotLab(rootCS, {0_GeV, 0_GeV, 0_GeV}); - pTotLab += p.GetMomentum(); - pTotLab += pTarget; - auto const pTotLabNorm = pTotLab.norm(); - // calculate cm. energy - const HEPEnergyType ECoM = sqrt( - (Elab + pTotLabNorm) * (Elab - pTotLabNorm)); // binomial for numerical accuracy - - cout << "Interaction: LambdaInt: \n" - << " input energy: " << p.GetEnergy() / 1_GeV << endl - << " beam can interact:" << kInteraction << endl - << " beam pid:" << p.GetPID() << endl; - - // TODO: move limits into variables - if (kInteraction && Elab >= 8.5_GeV && ValidCoMEnergy(ECoM)) { - - // get target from environment - /* - the target should be defined by the Environment, - ideally as full particle object so that the four momenta - and the boosts can be defined.. - */ - const auto* currentNode = p.GetNode(); - const auto mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - // determine average interaction length - - auto const weightedProdCrossSection = - mediumComposition.WeightedSum([=](auto vTargetID) { - return std::get<0>(this->GetCrossSection(corsikaBeamId, vTargetID, ECoM)); - }); - - cout << "Interaction: IntLength: weighted CrossSection (mb): " - << weightedProdCrossSection / 1_mb << endl - << "Interaction: IntLength: average mass number: " - << mediumComposition.GetAverageMassNumber() << endl; - - // calculate interaction length in medium - GrammageType const int_length = mediumComposition.GetAverageMassNumber() * - units::constants::u / weightedProdCrossSection; - cout << "Interaction: " - << "interaction length (g/cm2): " << int_length / (0.001_kg) * 1_cm * 1_cm - << endl; - - return int_length; - } - - return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); - } - - /** - In this function PYTHIA is called to produce one event. The - event is copied (and boosted) into the shower lab frame. - */ - - template <> - process::EProcessReturn Interaction::DoInteraction(SecondaryView& view) { - - using namespace units; - using namespace utl; - using namespace units::si; - using namespace geometry; - - auto const projectile = view.GetProjectile(); - - const auto corsikaBeamId = projectile.GetPID(); - cout << "Pythia::Interaction: " - << "DoInteraction: " << corsikaBeamId << " interaction? " - << process::pythia::Interaction::CanInteract(corsikaBeamId) << endl; - - if (particles::IsNucleus(corsikaBeamId)) { - // nuclei handled by different process, this should not happen - throw std::runtime_error("Nuclear projectile are not handled by PYTHIA!"); - } - - if (process::pythia::Interaction::CanInteract(corsikaBeamId)) { - - const CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - - // 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 - const auto eTargetLab = 0_GeV + constants::nucleonMass; - const auto pTargetLab = MomentumVector(rootCS, 0_GeV, 0_GeV, 0_GeV); - const FourVector PtargLab(eTargetLab, pTargetLab); - - // define projectile - HEPEnergyType const eProjectileLab = projectile.GetEnergy(); - auto const pProjectileLab = projectile.GetMomentum(); - - cout << "Interaction: ebeam lab: " << eProjectileLab / 1_GeV << endl - << "Interaction: pbeam lab: " << pProjectileLab.GetComponents() / 1_GeV - << endl; - cout << "Interaction: etarget lab: " << eTargetLab / 1_GeV << endl - << "Interaction: ptarget lab: " << pTargetLab.GetComponents() / 1_GeV << endl; - - const FourVector 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); - - cout << "Interaction: ebeam CoM: " << PprojCoM.GetTimeLikeComponent() / 1_GeV - << endl - << "Interaction: pbeam CoM: " - << PprojCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV << endl; - cout << "Interaction: etarget CoM: " << PtargCoM.GetTimeLikeComponent() / 1_GeV - << endl - << "Interaction: ptarget CoM: " - << PtargCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV << endl; - - cout << "Interaction: position of interaction: " << pOrig.GetCoordinates() << endl; - cout << "Interaction: time: " << tOrig << endl; - - HEPEnergyType Etot = eProjectileLab + eTargetLab; - MomentumVector Ptot = projectile.GetMomentum(); - // invariant mass, i.e. cm. energy - HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.squaredNorm()); - - // sample target mass number - const auto* currentNode = projectile.GetNode(); - const auto& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - // get cross sections for target materials - /* - Here we read the cross section from the interaction model again, - should be passed from GetInteractionLength if possible - */ - //#warning reading interaction cross section again, should not be necessary - auto const& compVec = mediumComposition.GetComponents(); - std::vector<si::CrossSectionType> cross_section_of_components(compVec.size()); - - for (size_t i = 0; i < compVec.size(); ++i) { - auto const targetId = compVec[i]; - const auto [sigProd, sigEla] = GetCrossSection(corsikaBeamId, targetId, Ecm); - [[maybe_unused]] const auto& dummy_sigEla = sigEla; - cross_section_of_components[i] = sigProd; - } - - const auto corsikaTargetId = - mediumComposition.SampleTarget(cross_section_of_components, fRNG); - cout << "Interaction: target selected: " << corsikaTargetId << endl; - - if (corsikaTargetId != particles::Code::Hydrogen && - corsikaTargetId != particles::Code::Neutron && - corsikaTargetId != particles::Code::Proton) - throw std::runtime_error("DoInteraction: wrong target for PYTHIA"); - - cout << "Interaction: " - << " DoInteraction: E(GeV):" << eProjectileLab / 1_GeV - << " Ecm(GeV): " << Ecm / 1_GeV << endl; - - if (eProjectileLab < 8.5_GeV || !ValidCoMEnergy(Ecm)) { - cout << "Interaction: " - << " DoInteraction: should have dropped particle.. " - << "THIS IS AN ERROR" << endl; - throw std::runtime_error("energy too low for PYTHIA"); - - } else { - fCount++; - - ConfigureLabFrameCollision(corsikaBeamId, corsikaTargetId, eProjectileLab); - - // create event in pytia - if (!fPythia.next()) throw std::runtime_error("Pythia::DoInteraction: failed!"); - - // link to pythia stack - Pythia8::Event& event = fPythia.event; - - if (print_listing_) { - // list final state - event.list(); - } - - MomentumVector Plab_final(rootCS, {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 = - particles::ConvertFromPDG(static_cast<particles::PDGCode>(p8p.id())); - - const MomentumVector pyPlab( - rootCS, {p8p.px() * 1_GeV, p8p.py() * 1_GeV, p8p.pz() * 1_GeV}); - HEPEnergyType const pyEn = p8p.e() * 1_GeV; - - // add to corsika stack - auto pnew = view.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector, - geometry::Point, units::si::TimeType>{pyId, pyEn, pyPlab, pOrig, - tOrig}); - - Plab_final += pnew.GetMomentum(); - Elab_final += pnew.GetEnergy(); - } - cout << "conservation (all GeV): " - << "Elab_final=" << Elab_final / 1_GeV - << ", Plab_final=" << (Plab_final / 1_GeV).GetComponents() << endl; - } - } - return process::EProcessReturn::eOk; - } - -} // namespace corsika::pythia diff --git a/corsika/process/detail/Pythia/Random.cc b/corsika/process/detail/Pythia/Random.cc deleted file mode 100644 index 0ebfbd85b670637d7339366f60713cf7d26b8c4d..0000000000000000000000000000000000000000 --- a/corsika/process/detail/Pythia/Random.cc +++ /dev/null @@ -1,15 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/pythia/Random.h> - -namespace corsika::pythia { - - double Random::flat() { return fDist(fRNG); } - -} // namespace corsika::pythia diff --git a/corsika/process/detail/QGSJetII/Interaction.cc b/corsika/process/detail/QGSJetII/Interaction.cc deleted file mode 100644 index 086f98a9a592c42633298e9e5ce27f8368d17c2c..0000000000000000000000000000000000000000 --- a/corsika/process/detail/QGSJetII/Interaction.cc +++ /dev/null @@ -1,398 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/qgsjetII/Interaction.h> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/NuclearComposition.hpp> -#include <corsika/framework/geometry/QuantityVector.hpp> -#include <corsika/framework/geometry/FourVector.hpp> -#include <corsika/process/qgsjetII/ParticleConversion.h> -#include <corsika/process/qgsjetII/QGSJetIIFragmentsStack.h> -#include <corsika/process/qgsjetII/QGSJetIIStack.h> -#include <corsika/process/qgsjetII/qgsjet-II-04.h> -#include <corsika/framework/utility/COMBoost.hpp> - -#include <random> -#include <sstream> -#include <string> -#include <tuple> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using std::cout; -using std::endl; -using std::ostringstream; -using std::string; -using std::tuple; - -using namespace corsika; -using namespace corsika; -using SetupParticle = setup::Stack::StackIterator; -using SetupView = setup::StackView; -using Track = Trajectory; - -namespace corsika::qgsjetII { - - Interaction::Interaction(const string& dataPath) - : data_path_(dataPath) { - if (dataPath == "") { - if (std::getenv("CORSIKA_DATA")) { - data_path_ = string(std::getenv("CORSIKA_DATA")) + "/QGSJetII/"; - cout << "Searching for QGSJetII data tables in " << data_path_ << endl; - } - } - - // initialize QgsjetII - if (!initialized_) { - qgset_(); - datadir DIR(data_path_); - qgaini_(DIR.data); - initialized_ = true; - } - } - - Interaction::~Interaction() { cout << "QgsjetII::Interaction n=" << count_ << endl; } - - units::si::CrossSectionType Interaction::GetCrossSection( - const particles::Code beamId, const particles::Code targetId, - const units::si::HEPEnergyType Elab, const unsigned int Abeam, - const unsigned int targetA) const { - using namespace units::si; - double sigProd = std::numeric_limits<double>::infinity(); - - if (process::qgsjetII::CanInteract(beamId)) { - - const int xsCode = process::qgsjetII::GetQgsjetIIXSCodeRaw(beamId); - int iTarget = 1; - if (particles::IsNucleus(targetId)) { - iTarget = targetA; - if (iTarget > maxMassNumber_ || iTarget <= 0) { - std::ostringstream txt; - txt << "QgsjetII target outside range. iTarget=" << iTarget; - throw std::runtime_error(txt.str().c_str()); - } - } - int iProjectile = 1; - if (particles::IsNucleus(beamId)) { - iProjectile = Abeam; - if (iProjectile > maxMassNumber_ || iProjectile <= 0) - throw std::runtime_error("QgsjetII target outside range. "); - } - - cout << "QgsjetII::GetCrossSection Elab=" << Elab << " xs-code=" << xsCode - << " iProjectile=" << iProjectile << " iTarget=" << iTarget << endl; - sigProd = qgsect_(Elab / 1_GeV, xsCode, iProjectile, iTarget); - cout << "QgsjetII::GetCrossSection sigProd=" << sigProd << endl; - } - - return sigProd * 1_mb; - } - - template <> - units::si::GrammageType Interaction::GetInteractionLength( - SetupParticle const& vP) const { - - using namespace units; - using namespace units::si; - using namespace geometry; - - // coordinate system, get global frame of reference - CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - - const particles::Code corsikaBeamId = vP.GetPID(); - - // beam particles for qgsjetII : 1, 2, 3 for p, pi, k - // read from cross section code table - const bool kInteraction = process::qgsjetII::CanInteract(corsikaBeamId); - - // FOR NOW: assume target is at rest - MomentumVector pTarget(rootCS, {0_GeV, 0_GeV, 0_GeV}); - - // total momentum and energy - HEPEnergyType Elab = vP.GetEnergy(); - - cout << "Interaction: LambdaInt: \n" - << " input energy: " << vP.GetEnergy() / 1_GeV << endl - << " beam can interact:" << kInteraction << endl - << " beam pid:" << vP.GetPID() << endl; - - if (kInteraction) { - - int Abeam = 0; - if (particles::IsNucleus(vP.GetPID())) Abeam = vP.GetNuclearA(); - - // get target from environment - /* - the target should be defined by the Environment, - ideally as full particle object so that the four momenta - and the boosts can be defined.. - */ - - auto const* currentNode = vP.GetNode(); - const auto& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - - si::CrossSectionType weightedProdCrossSection = mediumComposition.WeightedSum( - [=](particles::Code targetID) -> si::CrossSectionType { - int targetA = 0; - if (corsika::IsNucleus(targetID)) - targetA = particles::GetNucleusA(targetID); - return GetCrossSection(corsikaBeamId, targetID, Elab, Abeam, targetA); - }); - - cout << "Interaction: " - << "IntLength: weighted CrossSection (mb): " << weightedProdCrossSection / 1_mb - << endl; - - // calculate interaction length in medium - GrammageType const int_length = mediumComposition.GetAverageMassNumber() * - units::constants::u / weightedProdCrossSection; - cout << "Interaction: " - << "interaction length (g/cm2): " << int_length / (0.001_kg) * 1_cm * 1_cm - << endl; - - return int_length; - } - - return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm); - } - - /** - In this function QGSJETII is called to produce one event. The - event is copied (and boosted) into the shower lab frame. - */ - - template <> - process::EProcessReturn Interaction::DoInteraction(SetupView& view) { - - using namespace units; - using namespace utl; - using namespace units::si; - using namespace geometry; - - auto const projectile = view.GetProjectile(); - - const auto corsikaBeamId = projectile.GetPID(); - cout << "ProcessQgsjetII: " - << "DoInteraction: " << corsikaBeamId << " interaction? " - << process::qgsjetII::CanInteract(corsikaBeamId) << endl; - - if (process::qgsjetII::CanInteract(corsikaBeamId)) { - - const CoordinateSystem& rootCS = - RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); - - // position and time of interaction, not used in QgsjetII - Point pOrig = projectile.GetPosition(); - TimeType tOrig = projectile.GetTime(); - - // define target - // for QgsjetII is always a single nucleon - // FOR NOW: target is always at rest - const auto targetEnergyLab = 0_GeV + constants::nucleonMass; - const auto targetMomentumLab = MomentumVector(rootCS, 0_GeV, 0_GeV, 0_GeV); - const FourVector PtargLab(targetEnergyLab, targetMomentumLab); - - // define projectile - HEPEnergyType const projectileEnergyLab = projectile.GetEnergy(); - auto const projectileMomentumLab = projectile.GetMomentum(); - - int beamA = 1; - if (particles::IsNucleus(corsikaBeamId)) beamA = projectile.GetNuclearA(); - - const HEPEnergyType projectileEnergyLabPerNucleon = projectileEnergyLab / beamA; - - cout << "Interaction: ebeam lab: " << projectileEnergyLab / 1_GeV << endl - << "Interaction: pbeam lab: " << projectileMomentumLab.GetComponents() / 1_GeV - << endl; - cout << "Interaction: etarget lab: " << targetEnergyLab / 1_GeV << endl - << "Interaction: ptarget lab: " << targetMomentumLab.GetComponents() / 1_GeV - << endl; - - cout << "Interaction: position of interaction: " << pOrig.GetCoordinates() << endl; - cout << "Interaction: time: " << tOrig << endl; - - // sample target mass number - auto const* currentNode = projectile.GetNode(); - auto const& mediumComposition = - currentNode->GetModelProperties().GetNuclearComposition(); - // get cross sections for target materials - /* - Here we read the cross section from the interaction model again, - should be passed from GetInteractionLength if possible - */ - auto const& compVec = mediumComposition.GetComponents(); - std::vector<si::CrossSectionType> cross_section_of_components(compVec.size()); - - for (size_t i = 0; i < compVec.size(); ++i) { - auto const targetId = compVec[i]; - int targetA = 0; - if (corsika::IsNucleus(targetId)) - targetA = particles::GetNucleusA(targetId); - const auto sigProd = - GetCrossSection(corsikaBeamId, targetId, projectileEnergyLab, beamA, targetA); - cross_section_of_components[i] = sigProd; - } - - const auto targetCode = - mediumComposition.SampleTarget(cross_section_of_components, rng_); - cout << "Interaction: target selected: " << targetCode << endl; - - int targetMassNumber = 1; // proton - if (particles::IsNucleus(targetCode)) { // nucleus - targetMassNumber = particles::GetNucleusA(targetCode); - if (targetMassNumber > maxMassNumber_) - throw std::runtime_error("QgsjetII target mass outside range."); - } else { - if (targetCode != particles::Proton::GetCode()) - throw std::runtime_error("QgsjetII Taget not possible."); - } - cout << "Interaction: target qgsjetII code/A: " << targetMassNumber << endl; - - int projectileMassNumber = 1; // "1" means "hadron" - QgsjetIIHadronType qgsjet_hadron_type = - process::qgsjetII::GetQgsjetIIHadronType(corsikaBeamId); - if (qgsjet_hadron_type == QgsjetIIHadronType::NucleusType) { - projectileMassNumber = projectile.GetNuclearA(); - if (projectileMassNumber > maxMassNumber_) - throw std::runtime_error("QgsjetII projectile mass outside range."); - std::array<QgsjetIIHadronType, 2> constexpr nucleons = { - QgsjetIIHadronType::ProtonType, QgsjetIIHadronType::NeutronType}; - std::uniform_int_distribution select(0, 1); - qgsjet_hadron_type = nucleons[select(rng_)]; - } else { - // from conex: replace pi0 or rho0 with pi+/pi- in alternating sequence - if (qgsjet_hadron_type == QgsjetIIHadronType::NeutralLightMesonType) { - qgsjet_hadron_type = alternate_; - alternate_ = (alternate_ == QgsjetIIHadronType::PiPlusType - ? QgsjetIIHadronType::PiMinusType - : QgsjetIIHadronType::PiPlusType); - } - } - cout << "Interaction: projectile qgsjetII code/A: " << projectileMassNumber << " " - << corsikaBeamId << endl; - - int qgsjet_hadron_type_int = static_cast<QgsjetIICodeIntType>(qgsjet_hadron_type); - - cout << "Interaction: " - << " DoInteraction: E(GeV):" << projectileEnergyLab / 1_GeV << endl; - count_++; - qgini_(projectileEnergyLab / 1_GeV, qgsjet_hadron_type_int, projectileMassNumber, - targetMassNumber); - qgconf_(); - - // bookkeeping - MomentumVector Plab_final(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV}); - HEPEnergyType Elab_final = 0_GeV; - - // to read the secondaries - // define rotation to and from CoM frame - // CoM frame definition in QgsjetII projectile: +z - auto const& originalCS = projectileMomentumLab.GetCoordinateSystem(); - geometry::CoordinateSystem const zAxisFrame = - originalCS.RotateToZ(projectileMomentumLab); - - // nuclear projectile fragments - QGSJetIIFragmentsStack qfs; - for (auto& fragm : qfs) { - particles::Code idFragm = particles::Code::Nucleus; - const int A = fragm.GetFragmentSize(); - int Z = 0; - switch (A) { - case 1: { // proton/neutron - idFragm = particles::Code::Proton; - - auto momentum = geometry::Vector( - zAxisFrame, - corsika::QuantityVector<hepmomentum_d>{0.0_GeV, 0.0_GeV, - sqrt((projectileEnergyLab + particles::Proton::GetMass()) * - (projectileEnergyLab - particles::Proton::GetMass()))}); - - auto const energy = sqrt(momentum.squaredNorm() + square(particles::GetMass(idFragm))); - momentum.rebase(originalCS); // transform back into standard lab frame - std::cout << "secondary fragment> id=" << idFragm << " p=" << momentum.GetComponents() << std::endl; - auto pnew = vP.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector, - geometry::Point, units::si::TimeType>{idFragm, energy, momentum, - pOrig, tOrig}); - Plab_final += pnew.GetMomentum(); - Elab_final += pnew.GetEnergy(); - } break; - case 2: // deuterium - Z = 1; - break; - case 3: // tritium - Z = 1; - break; - case 4: // helium - Z = 2; - break; - default: // nucleus - { - Z = int(A / 2.15 + 0.7); - } - } - - if (idFragm == particles::Code::Nucleus) { // thus: not p or n - const HEPMassType nucleusMass = - particles::Proton::GetMass() * Z + particles::Neutron::GetMass() * (A - Z); - auto momentum = geometry::Vector( - zAxisFrame, geometry::QuantityVector<hepmomentum_d>{ - 0.0_GeV, 0.0_GeV, - sqrt((projectileEnergyLabPerNucleon * A + nucleusMass) * - (projectileEnergyLabPerNucleon * A - nucleusMass))}); - - auto const energy = sqrt(momentum.squaredNorm() + square(nucleusMass)); - momentum.rebase(originalCS); // transform back into standard lab frame - std::cout << "secondary fragment> id=" << idFragm - << " p=" << momentum.GetComponents() << " A=" << A << " Z=" << Z - << std::endl; - auto pnew = view.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector, - geometry::Point, units::si::TimeType, unsigned short, unsigned short>{ - idFragm, energy, momentum, pOrig, tOrig, A, Z}); - Plab_final += pnew.GetMomentum(); - Elab_final += pnew.GetEnergy(); - } - } - - // secondaries - QGSJetIIStack qs; - for (auto& psec : qs) { - - auto momentum = psec.GetMomentum(zAxisFrame); - auto const energy = psec.GetEnergy(); - - momentum.rebase(originalCS); // transform back into standard lab frame - std::cout << "secondary fragment> id=" - << process::qgsjetII::ConvertFromQgsjetII(psec.GetPID()) - << " p=" << momentum.GetComponents() << std::endl; - auto pnew = view.AddSecondary( - tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector, - geometry::Point, units::si::TimeType>{ - process::qgsjetII::ConvertFromQgsjetII(psec.GetPID()), energy, momentum, - pOrig, tOrig}); - Plab_final += pnew.GetMomentum(); - Elab_final += pnew.GetEnergy(); - } - cout << "conservation (all GeV): Ecm_final= n/a" /* << Ecm_final / 1_GeV*/ << endl - << "Elab_final=" << Elab_final / 1_GeV - << ", Plab_final=" << (Plab_final / 1_GeV).GetComponents() - << ", N_wounded,targ=" - << QGSJetIIFragmentsStackData::GetWoundedNucleonsTarget() - << ", N_wounded,proj=" - << QGSJetIIFragmentsStackData::GetWoundedNucleonsProjectile() - << ", N_fragm,proj=" << qfs.getEntries() << endl; - } - return process::EProcessReturn::eOk; - } - -} // namespace corsika::qgsjetII diff --git a/corsika/process/detail/QGSJetII/ParticleConversion.cc b/corsika/process/detail/QGSJetII/ParticleConversion.cc deleted file mode 100644 index b9e40535448c230d80022c82ecfb3089218995e6..0000000000000000000000000000000000000000 --- a/corsika/process/detail/QGSJetII/ParticleConversion.cc +++ /dev/null @@ -1,12 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/process/qgsjetII/ParticleConversion.h> - -using namespace corsika::qgsjetII; diff --git a/corsika/process/detail/QGSJetII/qgsjet-II-04.cc b/corsika/process/detail/QGSJetII/qgsjet-II-04.cc deleted file mode 100644 index d668daf0b025c5361e43b863cb441fcbf2939a68..0000000000000000000000000000000000000000 --- a/corsika/process/detail/QGSJetII/qgsjet-II-04.cc +++ /dev/null @@ -1,33 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/qgsjetII/qgsjet-II-04.h> - -#include <corsika/framework/random/RNGManager.hpp> - -#include <iostream> -#include <random> - -datadir::datadir(const std::string& dir) { - if (dir.length() > 130) { - std::cerr << "QGSJetII error, will cut datadir \"" << dir - << "\" to 130 characters: " << std::endl; - } - int i = 0; - for (i = 0; i < std::min(130, int(dir.length())); ++i) data[i] = dir[i]; - data[i + 0] = ' '; - data[i + 1] = '\0'; -} - -double qgran_(int&) { - static corsika::RNG& rng = - corsika::RNGManager::GetInstance().GetRandomStream("qgran"); - - std::uniform_real_distribution<double> dist; - return dist(rng); -} diff --git a/corsika/process/detail/StackInspector.cc b/corsika/process/detail/StackInspector.cc deleted file mode 100644 index 2a5622b3e67b33c6e9cbb34899ba0d5afca7a2e6..0000000000000000000000000000000000000000 --- a/corsika/process/detail/StackInspector.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/process/stack_inspector/StackInspector.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/logging/Logger.h> - -#include <chrono> -#include <iomanip> -#include <iostream> -#include <limits> - -#include "../corsika/setup/SetupTrajectory.hpp" -using namespace std; - -using namespace corsika; -using namespace corsika; -using namespace corsika::units::si; -using namespace corsika_inspector; - -template <typename TStack> -StackInspector<TStack>::StackInspector(const int vNStep, const bool vReportStack, - const HEPEnergyType vE0) - : StackProcess<StackInspector<TStack>>(vNStep) - , ReportStack_(vReportStack) - , E0_(vE0) - , StartTime_(std::chrono::system_clock::now()) { - - ReportStack_ = false; - StartTime_ = std::chrono::system_clock::now(); -} - -template <typename TStack> -StackInspector<TStack>::~StackInspector() {} - -template <typename TStack> -void StackInspector<TStack>::DoStack(const TStack& vS) { - [[maybe_unused]] int i = 0; - HEPEnergyType Etot = 0_GeV; - - for (const auto& iterP : vS) { - HEPEnergyType E = iterP.GetEnergy(); - Etot += E; - if (ReportStack_) { - geometry::CoordinateSystem& rootCS = geometry::RootCoordinateSystem::GetInstance() - .GetRootCoordinateSystem(); // for printout - auto pos = iterP.GetPosition().GetCoordinates(rootCS); - cout << "StackInspector: i=" << setw(5) << fixed << (i++) << ", id=" << setw(30) - << iterP.GetPID() << " E=" << setw(15) << scientific << (E / 1_GeV) << " GeV, " - << " pos=" << pos << " node = " << iterP.GetNode(); - if (iterP.GetPID() == Code::Nucleus) cout << " nuc_ref=" << iterP.GetNucleusRef(); - cout << endl; - } - } - - auto const now = std::chrono::system_clock::now(); - const std::chrono::duration<double> elapsed_seconds = now - StartTime_; - std::time_t const now_time = std::chrono::system_clock::to_time_t(now); - auto const dE = E0_ - Etot; - if (dE < dE_threshold_) return; - double const progress = dE / E0_; - - double const eta_seconds = elapsed_seconds.count() / progress; - std::time_t const eta_time = std::chrono::system_clock::to_time_t( - StartTime_ + std::chrono::seconds((int)eta_seconds)); - - cout << "StackInspector: " - << " time=" << std::put_time(std::localtime(&now_time), "%T") - << ", running=" << elapsed_seconds.count() << " seconds" - << " (" << setw(3) << int(progress * 100) << "%)" - << ", nStep=" << GetStep() << ", stackEntries=" << vS.getEntries() - << ", Estack=" << Etot / 1_GeV << " GeV" - << ", ETA=" << std::put_time(std::localtime(&eta_time), "%T") << endl; - return; -} - -#include <corsika/cascade/testCascade.h> -#include "../corsika/setup/SetupStack.hpp" - -template class process::stack_inspector::StackInspector<setup::Stack>; -template class process::stack_inspector::StackInspector<TestCascadeStack>; diff --git a/corsika/process/detail/TrackWriter.cc b/corsika/process/detail/TrackWriter.cc deleted file mode 100644 index 7ce08e49d1b8c17604850d45c96ca0d58adbb1d5..0000000000000000000000000000000000000000 --- a/corsika/process/detail/TrackWriter.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/track_writer/TrackWriter.h> - -#include <corsika/framework/core/ParticleProperties.hpp> - -#include <iomanip> -#include <limits> - -#include "../corsika/setup/SetupStack.hpp" -#include "../corsika/setup/SetupTrajectory.hpp" - -using namespace corsika; -using Particle = Stack::ParticleType; -using Track = Trajectory; - -namespace corsika::track_writer { - - TrackWriter::TrackWriter(std::string const& filename) - : fFilename(filename) { - - using namespace std::string_literals; - - fFile.open(fFilename); - fFile - << "# PID, E / eV, start coordinates / m, displacement vector to end / m, steplength / m "s - << '\n'; - } - - template <> - process::EProcessReturn TrackWriter::DoContinuous(Particle& vP, Track& vT) { - using namespace units::si; - auto const start = vT.GetPosition(0).GetCoordinates(); - auto const delta = vT.GetPosition(1).GetCoordinates() - start; - auto const pdg = static_cast<int>(particles::GetPDG(vP.GetPID())); - - // clang-format off - fFile << std::setw(7) << pdg - << std::setw(width) << std::scientific << std::setprecision(precision) << vP.GetEnergy() / 1_eV - << std::setw(width) << std::scientific << std::setprecision(precision) << start[0] / 1_m - << std::setw(width) << std::scientific << std::setprecision(precision) << start[1] / 1_m - << std::setw(width) << std::scientific << std::setprecision(precision) << start[2] / 1_m - << std::setw(width) << std::scientific << std::setprecision(precision) << delta[0] / 1_m - << std::setw(width) << std::scientific << std::setprecision(precision) << delta[1] / 1_m - << std::setw(width) << std::scientific << std::setprecision(precision) << delta[2] / 1_m - << std::setw(width) << std::scientific << std::setprecision(precision) << delta.norm() / 1_m - << '\n'; - // clang-format on - - return process::EProcessReturn::eOk; - } - - template <> - units::si::LengthType TrackWriter::MaxStepLength(Particle&, Track&) { - return units::si::meter * std::numeric_limits<double>::infinity(); - } - -} // namespace corsika::track_writer diff --git a/examples/boundary_example.cc b/examples/boundary_example.cc deleted file mode 100644 index addd6f4a9f5a00b4ea3e33e22f61b6be321c7e43..0000000000000000000000000000000000000000 --- a/examples/boundary_example.cc +++ /dev/null @@ -1,188 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/framework/core/Cascade.hpp> -#include <corsika/framework/sequence/ProcessSequence.hpp> -#include <corsika/process/tracking_line/TrackingLine.hpp> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/HomogeneousMedium.hpp> -#include <corsika/media/NuclearComposition.hpp> - -#include <corsika/framework/geometry/Sphere.hpp> - -#include <corsika/process/sibyll/Decay.h> -#include <corsika/process/sibyll/Interaction.h> -#include <corsika/process/sibyll/NuclearInteraction.h> - -#include <corsika/process/track_writer/TrackWriter.h> - -#include <corsika/process/particle_cut/ParticleCut.hpp> - -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/utility/CorsikaFenv.hpp> - -#include <corsika/logging/Logging.h> - -#include <iostream> -#include <limits> -#include <typeinfo> - -#include "../../corsika/setup/SetupEnvironment.hpp" -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using namespace corsika; -using namespace corsika; -using namespace corsika::units; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika::environment; - -using namespace std; -using namespace corsika::units::si; - -template <bool deleteParticle> -struct MyBoundaryCrossingProcess - : public BoundaryCrossingProcess<MyBoundaryCrossingProcess<deleteParticle>> { - - MyBoundaryCrossingProcess(std::string const& filename) { fFile.open(filename); } - - template <typename Particle> - EProcessReturn DoBoundaryCrossing(Particle& p, - typename Particle::BaseNodeType const& from, - typename Particle::BaseNodeType const& to) { - - C8LOG_INFO("MyBoundaryCrossingProcess: crossing! from: {} to: {} ", fmt::ptr(&from), - fmt::ptr(&to)); - - auto const& name = particles::GetName(p.GetPID()); - auto const start = p.GetPosition().GetCoordinates(); - - fFile << name << " " << start[0] / 1_m << ' ' << start[1] / 1_m << ' ' - << start[2] / 1_m << '\n'; - - if constexpr (deleteParticle) { p.Delete(); } - - return EProcessReturn::eOk; - } - -private: - std::ofstream fFile; -}; - -// -// The example main program for a particle cascade -// -int main() { - - logging::SetLevel(logging::level::trace); - - C8LOG_INFO("boundary_example"); - - feenableexcept(FE_INVALID); - // initialize random number sequence(s) - random::RNGManager::GetInstance().RegisterRandomStream("cascade"); - - // setup environment, geometry - using EnvType = setup::Environment; - EnvType env; - auto& universe = *(env.GetUniverse()); - - const CoordinateSystem& rootCS = env.GetCoordinateSystem(); - - // create "world" as infinite sphere filled with protons - auto world = EnvType::CreateNode<Sphere>( - Point{rootCS, 0_m, 0_m, 0_m}, 100_km); - - using MyHomogeneousModel = - environment::MediumPropertyModel<environment::UniformMagneticField< - environment::HomogeneousMedium<setup::EnvironmentInterface>>>; - - auto const props = world->SetModelProperties<MyHomogeneousModel>( - environment::Medium::AirDry1Atm, Vector(rootCS, 0_T, 0_T, 0_T), - 1_kg / (1_m * 1_m * 1_m), - environment::NuclearComposition( - std::vector<particles::Code>{particles::Code::Proton}, - std::vector<float>{1.f})); - - // add a "target" sphere with 5km readius at 0,0,0 - auto target = EnvType::CreateNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 5_km); - target->SetModelProperties(props); - - world->AddChild(std::move(target)); - universe.AddChild(std::move(world)); - - // setup processes, decays and interactions - setup::Tracking tracking; - - random::RNGManager::GetInstance().RegisterRandomStream("sibyll"); - process::sibyll::Interaction sibyll; - process::sibyll::Decay decay; - - process::particle_cut::ParticleCut cut(50_GeV, true, true); - - process::track_writer::TrackWriter trackWriter("boundary_tracks.dat"); - MyBoundaryCrossingProcess<true> boundaryCrossing("crossings.dat"); - - // assemble all processes into an ordered process list - auto sequence = process::sequence(sibyll, decay, cut, boundaryCrossing, trackWriter); - - // setup particle stack, and add primary particles - setup::Stack stack; - stack.Clear(); - const Code beamCode = Code::MuPlus; - const HEPMassType mass = particles::GetMass(beamCode); - const HEPEnergyType E0 = 100_GeV; - - std::uniform_real_distribution distTheta(0., 180.); - std::uniform_real_distribution distPhi(0., 360.); - std::mt19937 rng; - - for (int i = 0; i < 100; ++i) { - double const theta = distTheta(rng); - double const phi = distPhi(rng); - - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt((Elab - m) * (Elab + m)); - }; - HEPMomentumType P0 = elab2plab(E0, mass); - auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) { - return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi), - -ptot * cos(theta)); - }; - auto const [px, py, pz] = - momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0); - auto plab = corsika::MomentumVector(rootCS, {px, py, pz}); - cout << "input particle: " << beamCode << endl; - cout << "input angles: theta=" << theta << " phi=" << phi << endl; - cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl; - Point pos(rootCS, 0_m, 0_m, 0_m); - stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - beamCode, E0, plab, pos, 0_ns}); - } - - // define air shower object, run simulation - cascade::Cascade EAS(env, tracking, sequence, stack); - - EAS.Run(); - - C8LOG_INFO("Result: E0={}GeV", E0 / 1_GeV); - cut.ShowResults(); - [[maybe_unused]] const HEPEnergyType Efinal = - (cut.GetCutEnergy() + cut.GetInvEnergy() + cut.GetEmEnergy()); - C8LOG_INFO("Total energy (GeV): {} relative difference (%): {}", Efinal / 1_GeV, - (Efinal / E0 - 1.) * 100); -} diff --git a/examples/cascade_example.cc b/examples/cascade_example.cc deleted file mode 100644 index 1915125f1ef422f5ff13811430a7aa214d15fea7..0000000000000000000000000000000000000000 --- a/examples/cascade_example.cc +++ /dev/null @@ -1,173 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - - -#include <corsika/framework/core/Cascade.hpp> -#include <corsika/framework/sequence/ProcessSequence.hpp> -#include <corsika/process/energy_loss/EnergyLoss.h> -#include <corsika/process/stack_inspector/StackInspector.hpp> -#include <corsika/process/tracking_line/TrackingLine.hpp> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/HomogeneousMedium.hpp> -#include <corsika/media/NuclearComposition.hpp> - -#include <corsika/framework/geometry/Sphere.hpp> - -#include <corsika/process/sibyll/Decay.h> -#include <corsika/process/sibyll/Interaction.h> -#include <corsika/process/sibyll/NuclearInteraction.h> - -#include <corsika/process/particle_cut/ParticleCut.hpp> -#include <corsika/process/track_writer/TrackWriter.h> - -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/utility/CorsikaFenv.hpp> - -#include <iostream> -#include <limits> - -#include "../../corsika/setup/SetupEnvironment.hpp" -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using namespace corsika; -using namespace corsika; -using namespace corsika::units; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika::environment; - -using namespace std; -using namespace corsika::units::si; - -// -// The example main program for a particle cascade -// -int main() { - - logging::SetLevel(logging::level::info); - - C8LOG_INFO("vertical_EAS"); - - std::cout << "cascade_example" << std::endl; - - const LengthType height_atmosphere = 112.8_km; - - feenableexcept(FE_INVALID); - // initialize random number sequence(s) - random::RNGManager::GetInstance().RegisterRandomStream("cascade"); - - // setup environment, geometry - setup::Environment env; - auto& universe = *(env.GetUniverse()); - - const CoordinateSystem& rootCS = env.GetCoordinateSystem(); - - auto world = setup::Environment::CreateNode<Sphere>( - Point{rootCS, 0_m, 0_m, 0_m}, 150_km); - - using MyHomogeneousModel = - environment::MediumPropertyModel<environment::UniformMagneticField< - environment::HomogeneousMedium<setup::EnvironmentInterface>>>; - - // fraction of oxygen - const float fox = 0.20946; - auto const props = world->SetModelProperties<MyHomogeneousModel>( - environment::Medium::AirDry1Atm, Vector(rootCS, 0_T, 0_T, 0_T), - 1_kg / (1_m * 1_m * 1_m), - environment::NuclearComposition( - std::vector<particles::Code>{particles::Code::Nitrogen, - particles::Code::Oxygen}, - std::vector<float>{1.f - fox, fox})); - - auto innerMedium = - setup::Environment::CreateNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 5000_m); - - innerMedium->SetModelProperties(props); - world->AddChild(std::move(innerMedium)); - universe.AddChild(std::move(world)); - - // setup particle stack, and add primary particle - setup::Stack stack; - stack.Clear(); - const Code beamCode = Code::Nucleus; - const int nuclA = 4; - const int nuclZ = int(nuclA / 2.15 + 0.7); - const HEPMassType mass = GetNucleusMass(nuclA, nuclZ); - const HEPEnergyType E0 = nuclA * 1_TeV; - double theta = 0.; - double phi = 0.; - - Point const injectionPos( - rootCS, 0_m, 0_m, - height_atmosphere); // this is the CORSIKA 7 start of atmosphere/universe - - ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env}; - - { - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt((Elab - m) * (Elab + m)); - }; - HEPMomentumType P0 = elab2plab(E0, mass); - auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) { - return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi), - -ptot * cos(theta)); - }; - auto const [px, py, pz] = - momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0); - auto plab = corsika::MomentumVector(rootCS, {px, py, pz}); - cout << "input particle: " << beamCode << endl; - cout << "input angles: theta=" << theta << " phi=" << phi << endl; - cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl; - stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, - units::si::TimeType, unsigned short, unsigned short>{ - beamCode, E0, plab, injectionPos, 0_ns, nuclA, nuclZ}); - } - - // setup processes, decays and interactions - setup::Tracking tracking; - stack_inspector::StackInspector<setup::Stack> stackInspect(1, true, E0); - - random::RNGManager::GetInstance().RegisterRandomStream("sibyll"); - random::RNGManager::GetInstance().RegisterRandomStream("pythia"); - process::sibyll::Interaction sibyll; - process::sibyll::NuclearInteraction sibyllNuc(sibyll, env); - process::sibyll::Decay decay; - // cascade with only HE model ==> HE cut - process::particle_cut::ParticleCut cut(80_GeV, true, true); - - process::track_writer::TrackWriter trackWriter("tracks.dat"); - process::energy_loss::EnergyLoss eLoss{showerAxis, cut.GetECut()}; - - // assemble all processes into an ordered process list - auto sequence = - process::sequence(stackInspect, sibyll, sibyllNuc, decay, eLoss, cut, trackWriter); - - // define air shower object, run simulation - cascade::Cascade EAS(env, tracking, sequence, stack); - - EAS.Run(); - - eLoss.PrintProfile(); // print longitudinal profile - - cut.ShowResults(); - const HEPEnergyType Efinal = - cut.GetCutEnergy() + cut.GetInvEnergy() + cut.GetEmEnergy(); - cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl - << "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl; - cout << "total dEdX energy (GeV): " << eLoss.GetTotal() / 1_GeV << endl - << "relative difference (%): " << eLoss.GetTotal() / E0 * 100 << endl; - cut.Reset(); -} diff --git a/examples/cascade_proton_example.cc b/examples/cascade_proton_example.cc deleted file mode 100644 index 3512cac6a14256bb9d5352d16eb9f3f57ceeba52..0000000000000000000000000000000000000000 --- a/examples/cascade_proton_example.cc +++ /dev/null @@ -1,161 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/framework/core/Cascade.hpp> -#include <corsika/framework/sequence/ProcessSequence.hpp> -#include <corsika/process/hadronic_elastic_model/HadronicElasticModel.h> -#include <corsika/process/stack_inspector/StackInspector.hpp> -#include <corsika/process/tracking_line/TrackingLine.hpp> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/HomogeneousMedium.hpp> -#include <corsika/media/NuclearComposition.hpp> - -#include <corsika/framework/geometry/Sphere.hpp> - -#include <corsika/process/sibyll/Decay.h> -#include <corsika/process/sibyll/Interaction.h> -#include <corsika/process/sibyll/NuclearInteraction.h> - -#include <corsika/process/pythia/Decay.h> -#include <corsika/process/pythia/Interaction.h> - -#include <corsika/process/track_writer/TrackWriter.h> - -#include <corsika/process/particle_cut/ParticleCut.hpp> - -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/utility/CorsikaFenv.hpp> - -#include <boost/type_index.hpp> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" -using boost::typeindex::type_id_with_cvr; - -#include <iostream> -#include <limits> -#include <typeinfo> - -using namespace corsika; -using namespace corsika; -using namespace corsika::units; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika::environment; - -using namespace std; -using namespace corsika::units::si; - -// -// The example main program for a particle cascade -// -int main() { - - logging::SetLevel(logging::level::info); - - std::cout << "cascade_proton_example" << std::endl; - - feenableexcept(FE_INVALID); - // initialize random number sequence(s) - random::RNGManager::GetInstance().RegisterRandomStream("cascade"); - - // setup environment, geometry - using EnvType = setup::Environment; - EnvType env; - auto& universe = *(env.GetUniverse()); - const CoordinateSystem& rootCS = env.GetCoordinateSystem(); - - auto world = EnvType::CreateNode<Sphere>( - Point{rootCS, 0_m, 0_m, 0_m}, 150_km); - - using MyHomogeneousModel = - environment::MediumPropertyModel<environment::UniformMagneticField< - environment::HomogeneousMedium<setup::EnvironmentInterface>>>; - - world->SetModelProperties<MyHomogeneousModel>( - environment::Medium::AirDry1Atm, geometry::Vector(rootCS, 0_T, 0_T, 1_T), - 1_kg / (1_m * 1_m * 1_m), - NuclearComposition(std::vector<particles::Code>{particles::Code::Hydrogen}, - std::vector<float>{(float)1.})); - - universe.AddChild(std::move(world)); - - // setup particle stack, and add primary particle - setup::Stack stack; - stack.Clear(); - const Code beamCode = Code::Proton; - const HEPMassType mass = particles::Proton::GetMass(); - const HEPEnergyType E0 = 100_GeV; - double theta = 0.; - double phi = 0.; - - Point injectionPos(rootCS, 0_m, 0_m, 0_m); - { - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt(Elab * Elab - m * m); - }; - HEPMomentumType P0 = elab2plab(E0, mass); - auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) { - return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi), - -ptot * cos(theta)); - }; - auto const [px, py, pz] = - momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0); - auto plab = corsika::MomentumVector(rootCS, {px, py, pz}); - cout << "input particle: " << beamCode << endl; - cout << "input angles: theta=" << theta << " phi=" << phi << endl; - cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl; - stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - beamCode, E0, plab, pos, 0_ns}); - } - - // setup processes, decays and interactions - setup::Tracking tracking; - stack_inspector::StackInspector<setup::Stack> stackInspect(1, true, E0); - - random::RNGManager::GetInstance().RegisterRandomStream("sibyll"); - random::RNGManager::GetInstance().RegisterRandomStream("pythia"); - // process::sibyll::Interaction sibyll(env); - process::pythia::Interaction pythia; - // process::sibyll::NuclearInteraction sibyllNuc(env, sibyll); - // process::sibyll::Decay decay; - process::pythia::Decay decay; - process::particle_cut::ParticleCut cut(60_GeV, true, true); - - // random::RNGManager::GetInstance().RegisterRandomStream("HadronicElasticModel"); - // process::HadronicElasticModel::HadronicElasticInteraction - // hadronicElastic(env); - - process::track_writer::TrackWriter trackWriter("tracks.dat"); - ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env}; - process::energy_loss::EnergyLoss eLoss{showerAxis, cut.GetECut()}; - - // assemble all processes into an ordered process list - // auto sequence = sibyll << decay << hadronicElastic << cut << trackWriter; - auto sequence = process::sequence(pythia, decay, eLoss, cut, trackWriter, stackInspect); - - // define air shower object, run simulation - cascade::Cascade EAS(env, tracking, sequence, stack); - - EAS.Run(); - - cout << "Result: E0=" << E0 / 1_GeV << endl; - cut.ShowResults(); - const HEPEnergyType Efinal = - cut.GetCutEnergy() + cut.GetInvEnergy() + cut.GetEmEnergy(); - cout << "total energy (GeV): " << Efinal / 1_GeV << endl - << "relative difference (%): " << (Efinal / E0 - 1.) * 100 << endl; -} diff --git a/examples/stopping_power.cc b/examples/stopping_power.cc deleted file mode 100644 index d6d5bb89ef7d8ce9a33752d3e78fb6d44bb2dc8d..0000000000000000000000000000000000000000 --- a/examples/stopping_power.cc +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (c) Copyright 2019 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/media/Environment.hpp> -#include <corsika/framework/geometry/Sphere.hpp> -#include <corsika/process/energy_loss/EnergyLoss.h> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include <corsika/framework/utility/CorsikaFenv.hpp> - -#include <fstream> -#include <iostream> -#include <limits> -#include "../../corsika/setup/SetupStack.hpp" - -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika::environment; - -using namespace std; -using namespace corsika::units::si; - -// -// This example demonstrates the energy loss of muons as function of beta*gamma (=p/m) -// -int main() { - - std::cout << "stopping_power" << std::endl; - - feenableexcept(FE_INVALID); - - // setup environment, geometry - using EnvType = Environment<IMediumModel>; - EnvType env; - env.GetUniverse()->SetModelProperties<HomogeneousMedium<IMediumModel>>( - 1_g / cube(1_cm), NuclearComposition{{particles::Code::Unknown}, {1.f}}); - - const CoordinateSystem& rootCS = env.GetCoordinateSystem(); - - Point const injectionPos( - rootCS, 0_m, 0_m, - 112.8_km); // this is the CORSIKA 7 start of atmosphere/universe - - environment::ShowerAxis showerAxis{injectionPos, - Vector<length_d>{rootCS, 0_m, 0_m, 1_m}, env}; - process::energy_loss::EnergyLoss eLoss{showerAxis, 300_MeV}; - - setup::Stack stack; - - std::ofstream file("dEdX.dat"); - file << "# beta*gamma, dE/dX / eV/(g/cm²)" << std::endl; - - for (HEPEnergyType E0 = 300_MeV; E0 < 1_PeV; E0 *= 1.05) { - stack.Clear(); - const Code beamCode = Code::MuPlus; - const HEPMassType mass = GetMass(beamCode); - double theta = 0.; - double phi = 0.; - - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt((Elab - m) * (Elab + m)); - }; - HEPMomentumType P0 = elab2plab(E0, mass); - auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) { - return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi), - -ptot * cos(theta)); - }; - auto const [px, py, pz] = - momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0); - auto plab = corsika::MomentumVector(rootCS, {px, py, pz}); - cout << "input particle: " << beamCode << endl; - cout << "input angles: theta=" << theta << " phi=" << phi << endl; - cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl; - - stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - beamCode, E0, plab, injectionPos, 0_ns}); - - auto const p = stack.GetNextParticle(); - HEPEnergyType dE = eLoss.TotalEnergyLoss(p, 1_g / square(1_cm)); - file << P0 / mass << "\t" << -dE / 1_eV << std::endl; - } -} diff --git a/examples/vertical_EAS.cc b/examples/vertical_EAS.cc deleted file mode 100644 index 50071a8f8729d2ec202a46f4b65524aa568747b6..0000000000000000000000000000000000000000 --- a/examples/vertical_EAS.cc +++ /dev/null @@ -1,285 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/framework/core/Cascade.hpp> -#include <corsika/framework/sequence/ProcessSequence.hpp> -#include <corsika/process/StackProcess.h> -#include <corsika/process/energy_loss/EnergyLoss.h> -#include <corsika/process/observation_plane/ObservationPlane.hpp> -#include <corsika/process/particle_cut/ParticleCut.hpp> -#include <corsika/process/switch_process/SwitchProcess.hpp> -#include <corsika/process/tracking_line/TrackingLine.hpp> - -#include <corsika/media/LayeredSphericalAtmosphereBuilder.hpp> -#include <corsika/media/Environment.hpp> -#include <corsika/media/FlatExponential.hpp> -#include <corsika/media/NuclearComposition.hpp> - -#include <corsika/framework/geometry/Plane.hpp> -#include <corsika/framework/geometry/Sphere.hpp> - -#include <corsika/process/sibyll/Decay.h> -#include <corsika/process/stack_inspector/StackInspector.h> -#include <corsika/process/sibyll/Interaction.h> -#include <corsika/process/sibyll/NuclearInteraction.h> -#include <corsika/process/urqmd/UrQMD.h> - -#include <corsika/process/particle_cut/ParticleCut.hpp> -#include <corsika/process/track_writer/TrackWriter.h> - -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/utility/CorsikaFenv.hpp> - -#include <iomanip> -#include <iostream> -#include <limits> -#include <string> - -#include "../../corsika/setup/SetupStack.hpp" -#include "../../corsika/setup/SetupTrajectory.hpp" - -using namespace corsika; -using namespace corsika; -using namespace corsika::units; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika; -using namespace corsika::environment; - -using namespace std; -using namespace corsika::units::si; - -using Particle = setup::Stack::StackIterator; - -void registerRandomStreams(const int seed) { - random::RNGManager::GetInstance().RegisterRandomStream("cascade"); - random::RNGManager::GetInstance().RegisterRandomStream("qgsjet"); - random::RNGManager::GetInstance().RegisterRandomStream("sibyll"); - random::RNGManager::GetInstance().RegisterRandomStream("pythia"); - random::RNGManager::GetInstance().RegisterRandomStream("urqmd"); - random::RNGManager::GetInstance().RegisterRandomStream("proposal"); - - if (seed == 0) - random::RNGManager::GetInstance().SeedAll(); - else - random::RNGManager::GetInstance().SeedAll(seed); -} - -template <typename T> -using MyExtraEnv = environment::MediumPropertyModel<environment::UniformMagneticField<T>>; - -int main(int argc, char** argv) { - - logging::SetLevel(logging::level::info); - - C8LOG_INFO("vertical_EAS"); - - if (argc < 4) { - std::cerr << "usage: vertical_EAS <A> <Z> <energy/GeV> [seed]" << std::endl; - std::cerr << " if no seed is given, a random seed is chosen" << std::endl; - return 1; - } - feenableexcept(FE_INVALID); - - int seed = 0; - if (argc > 4) seed = std::stoi(std::string(argv[4])); - // initialize random number sequence(s) - registerRandomStreams(seed); - - // setup environment, geometry - using EnvType = setup::Environment; - EnvType env; - const CoordinateSystem& rootCS = env.GetCoordinateSystem(); - Point const center{rootCS, 0_m, 0_m, 0_m}; - auto builder = environment::make_layered_spherical_atmosphere_builder< - setup::EnvironmentInterface, - MyExtraEnv>::create(center, units::constants::EarthRadius::Mean, - environment::Medium::AirDry1Atm, - geometry::Vector{rootCS, 0_T, 50_uT, 0_T}); - builder.setNuclearComposition( - {{particles::Code::Nitrogen, particles::Code::Oxygen}, - {0.7847f, 1.f - 0.7847f}}); // values taken from AIRES manual, Ar removed for now - - builder.addExponentialLayer(1222.6562_g / (1_cm * 1_cm), 994186.38_cm, 4_km); - builder.addExponentialLayer(1144.9069_g / (1_cm * 1_cm), 878153.55_cm, 10_km); - builder.addExponentialLayer(1305.5948_g / (1_cm * 1_cm), 636143.04_cm, 40_km); - builder.addExponentialLayer(540.1778_g / (1_cm * 1_cm), 772170.16_cm, 100_km); - builder.addLinearLayer(1e9_cm, 112.8_km); - builder.assemble(env); - - // setup particle stack, and add primary particle - setup::Stack stack; - stack.Clear(); - const Code beamCode = Code::Nucleus; - unsigned short const A = std::stoi(std::string(argv[1])); - unsigned short Z = std::stoi(std::string(argv[2])); - auto const mass = particles::GetNucleusMass(A, Z); - const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[3])); - double theta = 0.; - auto const thetaRad = theta / 180. * M_PI; - - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt((Elab - m) * (Elab + m)); - }; - HEPMomentumType P0 = elab2plab(E0, mass); - auto momentumComponents = [](double thetaRad, HEPMomentumType ptot) { - return std::make_tuple(ptot * sin(thetaRad), 0_eV, -ptot * cos(thetaRad)); - }; - auto const [px, py, pz] = - momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0); - auto plab = corsika::MomentumVector(rootCS, {px, py, pz}); - cout << "input particle: " << beamCode << endl; - cout << "input angles: theta=" << theta << endl; - cout << "input momentum: " << plab.GetComponents() / 1_GeV << ", norm = " << plab.norm() - << endl; - - auto const observationHeight = 0_km + builder.getEarthRadius(); - auto const injectionHeight = 112.75_km + builder.getEarthRadius(); - auto const t = -observationHeight * cos(thetaRad) + - sqrt(-units::static_pow<2>(sin(thetaRad) * observationHeight) + - units::static_pow<2>(injectionHeight)); - - Point const showerCore{rootCS, 0_m, 0_m, observationHeight}; - Point const injectionPos = - showerCore + - Vector<dimensionless_d>{rootCS, {-sin(thetaRad), 0, cos(thetaRad)}} * t; - - std::cout << "point of injection: " << injectionPos.GetCoordinates() << std::endl; - - if (A != 1) { - stack.AddParticle(std::make_tuple(beamCode, E0, plab, injectionPos, 0_ns, A, Z)); - - } else { - if (Z == 1) { - stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::stack::MomentumVector, geometry::Point, - units::si::TimeType>{particles::Code::Proton, E0, plab, - injectionPos, 0_ns}); - } else if (Z == 0) { - stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::stack::MomentumVector, geometry::Point, - units::si::TimeType>{particles::Code::Neutron, E0, - plab, injectionPos, 0_ns}); - } else { - std::cerr << "illegal parameters" << std::endl; - return EXIT_FAILURE; - } - } - - // we make the axis much longer than the inj-core distance since the - // profile will go beyond the core, depending on zenith angle - std::cout << "shower axis length: " << (showerCore - injectionPos).norm() * 1.5 - << std::endl; - - environment::ShowerAxis const showerAxis{injectionPos, - (showerCore - injectionPos) * 1.5, env}; - - // setup processes, decays and interactions - - stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - beamCode, E0, plab, injectionPos, 0_ns}); - // } - - process::sibyll::Interaction sibyll; - process::interaction_counter::InteractionCounter sibyllCounted(sibyll); - - process::sibyll::NuclearInteraction sibyllNuc(sibyll, env); - process::interaction_counter::InteractionCounter sibyllNucCounted(sibyllNuc); - - process::pythia::Decay decayPythia; - - // use sibyll decay routine for decays of particles unknown to pythia - process::sibyll::Decay decaySibyll{{ - Code::N1440Plus, - Code::N1440MinusBar, - Code::N1440_0, - Code::N1440_0Bar, - Code::N1710Plus, - Code::N1710MinusBar, - Code::N1710_0, - Code::N1710_0Bar, - - Code::Pi1300Plus, - Code::Pi1300Minus, - Code::Pi1300_0, - - Code::KStar0_1430_0, - Code::KStar0_1430_0Bar, - Code::KStar0_1430_Plus, - Code::KStar0_1430_MinusBar, - }}; - - decaySibyll.PrintDecayConfig(); - - process::on_shell_check::OnShellCheck reset_particle_mass(1.e-3, 1.e-1, false); - - process::track_writer::TrackWriter trackWriter("tracks.dat"); - process::longitudinal_profile::LongitudinalProfile longprof{showerAxis}; - - Plane const obsPlane(showerCore, Vector<dimensionless_d>(rootCS, {0., 0., 1.})); - process::observation_plane::ObservationPlane observationLevel( - obsPlane, Vector<dimensionless_d>(rootCS, {1., 0., 0.}), "particles.dat"); - - process::UrQMD::UrQMD urqmd; - process::interaction_counter::InteractionCounter urqmdCounted{urqmd}; - - // assemble all processes into an ordered process list - struct EnergySwitch { - HEPEnergyType cutE_; - EnergySwitch(HEPEnergyType cutE) - : cutE_(cutE) {} - process::SwitchResult operator()(const Particle& p) { - if (p.GetEnergy() < cutE_) - return process::SwitchResult::First; - else - return process::SwitchResult::Second; - } - }; - auto hadronSequence = - process::select(urqmdCounted, process::sequence(sibyllNucCounted, sibyllCounted), - EnergySwitch(55_GeV)); - auto decaySequence = process::sequence(decayPythia, decaySibyll); - stack_inspector::StackInspector<setup::Stack> stackInspect(1000, false, E0); - auto sequence = process::sequence(stackInspect, hadronSequence, reset_particle_mass, - decaySequence, proposalCounted, em_continuous, cut, - trackWriter, observationLevel, longprof); - - // define air shower object, run simulation - setup::Tracking tracking; - cascade::Cascade EAS(env, tracking, sequence, stack); - - // to fix the point of first interaction, uncomment the following two lines: - // EAS.forceInteraction(); - - EAS.Run(); - - cut.ShowResults(); - em_continuous.showResults(); - observationLevel.ShowResults(); - const HEPEnergyType Efinal = cut.GetCutEnergy() + cut.GetInvEnergy() + - cut.GetEmEnergy() + em_continuous.energyLost() + - observationLevel.GetEnergyGround(); - cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl - << "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl; - observationLevel.Reset(); - cut.Reset(); - em_continuous.reset(); - - auto const hists = sibyllCounted.GetHistogram() + sibyllNucCounted.GetHistogram() + - urqmdCounted.GetHistogram() + proposalCounted.GetHistogram(); - - hists.saveLab("inthist_lab_verticalEAS.npz"); - hists.saveCMS("inthist_cms_verticalEAS.npz"); - longprof.save("longprof_verticalEAS.txt"); -} diff --git a/tests/common/testTestStack.h b/tests/common/testTestStack.hpp similarity index 100% rename from tests/common/testTestStack.h rename to tests/common/testTestStack.hpp diff --git a/tests/framework/testCombinedStack.cpp b/tests/framework/testCombinedStack.cpp index 5ea982873f49ebeb9641a9e7453954646ee31f4f..f90f738d191644b21a57107093adda87f02a7832 100644 --- a/tests/framework/testCombinedStack.cpp +++ b/tests/framework/testCombinedStack.cpp @@ -12,7 +12,7 @@ #include <corsika/framework/stack/SecondaryView.hpp> #include <corsika/framework/stack/Stack.hpp> -#include <testTestStack.h> // for testing: simple stack. This is a +#include <testTestStack.hpp> // for testing: simple stack. This is a // test-build, and inluce file is obtained from CMAKE_CURRENT_SOURCE_DIR #include <iomanip> diff --git a/tests/framework/testSecondaryView.cpp b/tests/framework/testSecondaryView.cpp index 197d03825ade6db99a48690db1c9b22cb53620b1..a2a161bd816ab026d67d9b2fff27026325e2c852 100644 --- a/tests/framework/testSecondaryView.cpp +++ b/tests/framework/testSecondaryView.cpp @@ -12,7 +12,7 @@ #include <corsika/framework/stack/Stack.hpp> #include <corsika/framework/logging/Logging.hpp> -#include <testTestStack.h> // for testing: simple stack. This is a +#include <testTestStack.hpp> // for testing: simple stack. This is a // test-build, and inluce file is obtained from CMAKE_CURRENT_SOURCE_DIR #include <iomanip> diff --git a/tests/framework/testStackInterface.cpp b/tests/framework/testStackInterface.cpp index b07e378a95ff3dcde952588e38defa4766b2c07e..0e5b49a1a99781238b5679375c5b57cd2e6d5fff 100644 --- a/tests/framework/testStackInterface.cpp +++ b/tests/framework/testStackInterface.cpp @@ -10,7 +10,7 @@ #include <corsika/framework/stack/Stack.hpp> -#include <testTestStack.h> // from tests/common +#include <testTestStack.hpp> // from tests/common #include <iomanip> #include <tuple> diff --git a/tests/processes/TrackingLine/testTrackingLineStack.h b/tests/processes/TrackingLine/testTrackingLineStack.h deleted file mode 100644 index 96998fe6ec0e5183729bcd09796ff9b4f7ba1677..0000000000000000000000000000000000000000 --- a/tests/processes/TrackingLine/testTrackingLineStack.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#pragma once - -#include <corsika/media/Environment.hpp> -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/Vector.hpp> -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include <corsika/setup/SetupStack.hpp> - -using TestEnvironmentType = - corsika::environment::Environment<corsika::environment::Empty>; - -template <typename T> -using SetupGeometryDataInterface = - corsika::stack::node::GeometryDataInterface<T, TestEnvironmentType>; - -// combine particle data stack with geometry information for tracking -template <typename StackIter> -using StackWithGeometryInterface = corsika::CombinedParticleInterface< - corsika::detail::ParticleDataStack::PIType, SetupGeometryDataInterface, - StackIter>; -using TestTrackingLineStack = corsika::CombinedStack< - typename corsika::detail::ParticleDataStack::StackImpl, - GeometryData<TestEnvironmentType>, StackWithGeometryInterface>; - - diff --git a/tests/processes/testNullModel.cc b/tests/processes/testNullModel.cc deleted file mode 100644 index 853361352819cb59506562578b0ea0c434974770..0000000000000000000000000000000000000000 --- a/tests/processes/testNullModel.cc +++ /dev/null @@ -1,61 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <catch2/catch.hpp> - -#include <corsika/process/NullModel.hpp> - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> - -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/setup/SetupStack.hpp> -#include <corsika/setup/SetupTrajectory.hpp> - -using namespace corsika::units::si; -using namespace corsika::null_model; -using namespace corsika; - -TEST_CASE("NullModel", "[processes]") { - - auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen); - auto const& cs = *csPtr; - [[maybe_unused]] auto const& env_dummy = env; - [[maybe_unused]] auto const& node_dummy = nodePtr; - - auto [stack, view] = - setup::testing::setupStack(particles::Code::Electron, 0, 0, 100_GeV, nodePtr, cs); - [[maybe_unused]] const auto& dummyView = view; - auto particle = stack->first(); - - geometry::Point const origin(cs, {0_m, 0_m, 0_m}); - geometry::Vector<units::si::SpeedType::dimension_type> v(cs, 0_m / second, 0_m / second, - 1_m / second); - geometry::Line line(origin, v); - geometry::Trajectory<geometry::Line> track(line, 10_s); - - setup::Stack stack; - setup::Stack::ParticleType particle = stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - particles::Code::Electron, 100_GeV, - corsika::MomentumVector(dummyCS, {0_GeV, 0_GeV, -1_GeV}), - geometry::Point(dummyCS, {0_m, 0_m, 10_km}), 0_ns}); - SECTION("interface") { - - NullModel model(10_m); - - [[maybe_unused]] const process::EProcessReturn ret = - model.DoContinuous(particle, track); - LengthType const length = model.MaxStepLength(particle, track); - - CHECK((length / 10_m) == Approx(1)); - } -} diff --git a/tests/processes/testObservationPlane.cc b/tests/processes/testObservationPlane.cc deleted file mode 100644 index 243d091ce1165fcc060a07bf30de9d1f0f273bb8..0000000000000000000000000000000000000000 --- a/tests/processes/testObservationPlane.cc +++ /dev/null @@ -1,100 +0,0 @@ -/* - * (c) Copyright 2019 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one - // cpp file -#include <catch2/catch.hpp> - -#include <corsika/process/ObservationPlane.hpp> - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/setup/SetupStack.h> -#include <corsika/setup/SetupTrajectory.h> - -using namespace corsika::units::si; -using namespace corsika::observation_plane; -using namespace corsika; -using namespace corsika; -using namespace corsika; - -TEST_CASE("ContinuousProcess interface", "[proccesses][observation_plane]") { - - auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen); - auto const& cs = *csPtr; - [[maybe_unused]] auto const& env_dummy = env; - [[maybe_unused]] auto const& node_dummy = nodePtr; - - /* - Test with downward going 1_GeV neutrino, starting at 0, 1_m, 10m - - ObservationPlane has origin at 0,0,0 - */ - - auto [stack, viewPtr] = - setup::testing::setupStack(particles::Code::NuE, 0, 0, 1_GeV, nodePtr, cs); - [[maybe_unused]] setup::StackView& view = *viewPtr; - auto particle = stack->GetNextParticle(); - - Point const start(cs, {0_m, 1_m, 10_m}); - Vector<units::si::SpeedType::dimension_type> vec(cs, 0_m / second, 0_m / second, - -units::constants::c); - Line line(start, vec); - Trajectory<Line> track(line, 12_m / units::constants::c); - - // setup particle stack, and add primary particle - setup::Stack stack; - stack.Clear(); - { - auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) { - return sqrt((Elab - m) * (Elab + m)); - }; - stack.AddParticle( - std::tuple<Code, units::si::HEPEnergyType, corsika::MomentumVector, Point, - units::si::TimeType>{ - Code::NuMu, 1_GeV, - corsika::MomentumVector( - rootCS, {0_GeV, 0_GeV, -elab2plab(1_GeV, NuMu::GetMass())}), - Point(rootCS, {1_m, 1_m, 10_m}), 0_ns}); - } - auto particle = stack.GetNextParticle(); - - SECTION("horizontal plane") { - - Plane const obsPlane(Point(cs, {0_m, 0_m, 0_m}), - Vector<dimensionless_d>(cs, {0., 0., 1.})); - ObservationPlane obs(obsPlane, Vector<dimensionless_d>(cs, {1., 0., 0.}), - "particles.dat", true); - - const LengthType length = obs.MaxStepLength(particle, track); - const process::EProcessReturn ret = obs.DoContinuous(particle, track); - - REQUIRE(length / 10_m == Approx(1).margin(1e-4)); - REQUIRE(ret == process::EProcessReturn::eParticleAbsorbed); - } - - SECTION("inclined plane") {} - - SECTION("transparent plane") { - Plane const obsPlane(Point(cs, {0_m, 0_m, 0_m}), - Vector<dimensionless_d>(cs, {0., 0., 1.})); - ObservationPlane obs(obsPlane, Vector<dimensionless_d>(cs, {1., 0., 0.}), - "particles.dat", false); - - const LengthType length = obs.MaxStepLength(particle, track); - const process::EProcessReturn ret = obs.DoContinuous(particle, track); - - REQUIRE(length / 10_m == Approx(1).margin(1e-4)); - REQUIRE(ret == process::EProcessReturn::eOk); - } -} diff --git a/tests/processes/testParticleCut.cc b/tests/processes/testParticleCut.cc deleted file mode 100644 index 7385a82b55973c026872aadc217439c5433fe3aa..0000000000000000000000000000000000000000 --- a/tests/processes/testParticleCut.cc +++ /dev/null @@ -1,189 +0,0 @@ -/* - * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/ParticleCut.hpp> - -#include <corsika/media/Environment.hpp> -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> -#include <corsika/framework/utility/CorsikaFenv.hpp> - -#include <catch2/catch.hpp> -#include <corsika/setup/SetupStack.hpp> - -using namespace corsika; -using namespace corsika::particle_cut; -using namespace corsika::units; -using namespace corsika::units::si; - -TEST_CASE("ParticleCut", "[processes]") { - feenableexcept(FE_INVALID); - using EnvType = setup::Environment; - - EnvType env; - const geometry::CoordinateSystem& rootCS = env.GetCoordinateSystem(); - - // setup empty particle stack - setup::Stack stack; - stack.Clear(); - // two energies - const HEPEnergyType Eabove = 1_TeV; - const HEPEnergyType Ebelow = 10_GeV; - // list of arbitrary particles - const std::vector<particles::Code> particleList = { - particles::Code::PiPlus, particles::Code::PiMinus, particles::Code::KPlus, - particles::Code::KMinus, particles::Code::K0Long, particles::Code::K0Short, - particles::Code::Electron, particles::Code::MuPlus, particles::Code::NuE, - particles::Code::Neutron, particles::Code::NuMu}; - - // common staring point - const geometry::Point point0(rootCS, 0_m, 0_m, 0_m); - - SECTION("cut on particle type: inv") { - - ParticleCut cut(20_GeV, false, true); - CHECK(cut.GetECut() == 20_GeV); - - // add primary particle to stack - auto particle = stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - particles::Code::Proton, Eabove, - corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns}); - // view on secondary particles - corsika::SecondaryView view(particle); - // ref. to primary particle through the secondary view. - // only this way the secondary view is populated - auto projectile = view.GetProjectile(); - // add secondaries, all with energies above the threshold - // only cut is by species - for (auto proType : particleList) - projectile.AddSecondary(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, - units::si::TimeType>{ - proType, Eabove, corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns}); - - CHECK(view.getEntries() == 9); - CHECK(cut.GetNumberInvParticles() == 2); - CHECK(cut.GetInvEnergy() / 1_GeV == 2000); - } - - SECTION("cut on particle type: em") { - - ParticleCut cut(20_GeV, true, false); - - // add primary particle to stack - auto particle = stack.AddParticle(std::make_tuple( - particles::Code::Proton, Eabove, - corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), point0, 0_ns)); - // view on secondary particles - corsika::setup::StackView view(particle); - // ref. to primary particle through the secondary view. - // only this way the secondary view is populated - auto projectile = view.GetProjectile(); - // add secondaries, all with energies above the threshold - // only cut is by species - for (auto proType : particleList) { - projectile.AddSecondary(std::make_tuple( - proType, Eabove, corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - point0, 0_ns)); - } - cut.DoSecondaries(view); - - CHECK(view.getEntries() == 10); - CHECK(cut.GetNumberEmParticles() == 1); - CHECK(cut.GetEmEnergy() / 1_GeV == 1000); - } - - SECTION("cut low energy") { - ParticleCut cut(20_GeV, true, true); - - // add primary particle to stack - auto particle = stack.AddParticle( - std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - particles::Code::Proton, Eabove, - corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns}); - // view on secondary particles - corsika::SecondaryView view(particle); - // ref. to primary particle through the secondary view. - // only this way the secondary view is populated - auto projectile = view.GetProjectile(); - // add secondaries, all with energies below the threshold - // only cut is by species - for (auto proType : particleList) - projectile.AddSecondary(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, - units::si::TimeType>{ - proType, Ebelow, corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns}); - - cut.DoSecondaries(view); - - CHECK(view.getEntries() == 1); - CHECK(view.getSize() == 13); - } - - SECTION("cut on time") { - ParticleCut cut(20_GeV, false, false); - const TimeType too_late = 1_s; - - // add primary particle to stack - auto particle = stack.AddParticle(std::make_tuple( - particles::Code::Proton, Eabove, - corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), point0, 1_ns)); - // view on secondary particles - corsika::setup::StackView view(particle); - // ref. to primary particle through the secondary view. - // only this way the secondary view is populated - auto projectile = view.GetProjectile(); - // add secondaries, all with energies above the threshold - // only cut is by species - for (auto proType : particleList) { - projectile.AddSecondary(std::make_tuple( - proType, Eabove, corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - point0, too_late)); - } - cut.DoSecondaries(view); - - CHECK(view.getEntries() == 0); - CHECK(cut.GetCutEnergy() / 1_GeV == 11000); - cut.Reset(); - CHECK(cut.GetCutEnergy() == 0_GeV); - } - - corsika::setup::Trajectory const track = setup::testing::make_track<setup::Trajectory>( - geometry::Line{point0, - geometry::Vector<units::si::SpeedType::dimension_type>{ - rootCS, {0_m / second, 0_m / second, -units::constants::c}}}, - 12_m / units::constants::c); - - SECTION("cut on DoContinous, just invisibles") { - - ParticleCut cut(20_GeV, false, true); - CHECK(cut.GetECut() == 20_GeV); - - // add particles, all with energies above the threshold - // only cut is by species - for (auto proType : particleList) { - auto particle = stack.AddParticle(std::make_tuple( - proType, Eabove, corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), - point0, 0_ns)); - cut.DoContinuous(particle, track); - } - - CHECK(stack.getEntries() == 9); - CHECK(cut.GetNumberInvParticles() == 2); - CHECK(cut.GetInvEnergy() / 1_GeV == 2000); - } -} diff --git a/tests/processes/testQGSJetII.cc b/tests/processes/testQGSJetII.cc deleted file mode 100644 index ca203d3f9c555591d7846e0378b7c8a4b67a71a3..0000000000000000000000000000000000000000 --- a/tests/processes/testQGSJetII.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* - * (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu - * - * This software is distributed under the terms of the GNU General Public - * Licence version 3 (GPL Version 3). See file LICENSE for a full version of - * the license. - */ - -#include <corsika/process/QGSJetII.hpp> - -#include <corsika/framework/random/RNGManager.hpp> - -#include <corsika/framework/core/ParticleProperties.hpp> - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <catch2/catch.hpp> - -#include <cstdlib> -#include <experimental/filesystem> -#include <iostream> - -using namespace corsika; -using namespace corsika::qgsjetII; - -TEST_CASE("QgsjetII", "[processes]") { - - SECTION("Corsika -> QgsjetII") { - CHECK(process::qgsjetII::ConvertToQgsjetII(particles::PiMinus::GetCode()) == - process::qgsjetII::QgsjetIICode::PiMinus); - CHECK(process::qgsjetII::ConvertToQgsjetIIRaw(particles::Proton::GetCode()) == 2); - } - - SECTION("QgsjetII -> Corsika") { - CHECK(particles::PiPlus::GetCode() == process::qgsjetII::ConvertFromQgsjetII( - process::qgsjetII::QgsjetIICode::PiPlus)); - } - - SECTION("Corsika -> QgsjetII") { - CHECK(process::qgsjetII::ConvertToQgsjetII(particles::PiMinus::GetCode()) == - process::qgsjetII::QgsjetIICode::PiMinus); - CHECK(process::qgsjetII::ConvertToQgsjetIIRaw(particles::Proton::GetCode()) == 2); - } - - SECTION("canInteractInQgsjetII") { - - CHECK(process::qgsjetII::CanInteract(particles::Proton::GetCode())); - CHECK(process::qgsjetII::CanInteract(particles::Code::KPlus)); - CHECK(process::qgsjetII::CanInteract(particles::Nucleus::GetCode())); - // CHECK(process::qgsjetII::CanInteract(particles::Helium::GetCode())); - - CHECK_FALSE(process::qgsjetII::CanInteract(particles::EtaC::GetCode())); - CHECK_FALSE(process::qgsjetII::CanInteract(particles::SigmaC0::GetCode())); - } - - SECTION("cross-section type") { - - CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::Neutron) == - process::qgsjetII::QgsjetIIXSClass::Baryons); - CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::K0Long) == - process::qgsjetII::QgsjetIIXSClass::Kaons); - CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::Proton) == - process::qgsjetII::QgsjetIIXSClass::Baryons); - CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::PiMinus) == - process::qgsjetII::QgsjetIIXSClass::LightMesons); - } -} - -#include <corsika/framework/geometry/Point.hpp> -#include <corsika/framework/geometry/RootCoordinateSystem.hpp> -#include <corsika/framework/geometry/Vector.hpp> - -#include <corsika/framework/core/PhysicalUnits.hpp> - -#include <corsika/framework/core/ParticleProperties.hpp> -#include <corsika/setup/SetupStack.hpp> -#include <corsika/setup/SetupTrajectory.hpp> - -#include <corsika/media/Environment.hpp> -#include <corsika/media/HomogeneousMedium.hpp> -#include <corsika/media/NuclearComposition.hpp> - -using namespace corsika::units::si; -using namespace corsika::units; -using namespace corsika; - -TEST_CASE("QgsjetIIInterface", "[processes]") { - - auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen); - [[maybe_unused]] auto const& env_dummy = env; - [[maybe_unused]] auto const& node_dummy = nodePtr; - - corsika::random::RNGManager::GetInstance().RegisterRandomStream("qgsjet"); - - SECTION("InteractionInterface") { - - setup::Stack stack; - const HEPEnergyType E0 = 100_GeV; - HEPMomentumType P0 = - sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass()); - auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0}); - geometry::Point pos(cs, 0_m, 0_m, 0_m); - auto particle = - stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType, - corsika::MomentumVector, geometry::Point, - units::si::TimeType, unsigned int, unsigned int>{ - particles::Code::Nucleus, E0, plab, pos, 0_ns, 16, 8}); - // corsika::MomentumVector, geometry::Point, units::si::TimeType>{ - // particles::Code::PiPlus, E0, plab, pos, 0_ns}); - - particle.SetNode(nodePtr); - corsika::SecondaryView view(particle); - auto projectile = view.GetProjectile(); - - Interaction model; - - [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(view); - [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle); - - CHECK(length / (1_g / square(1_cm)) == Approx(93.04).margin(0.1)); - - /*********************************** - It as turned out already two times (#291 and #307) that the detailed output of - QGSJetII event generation depends on the gfortran version used. This is not reliable - and cannot be tested in a unit test here. One related problem was already found (#291) - and is realted to undefined behaviour in the evaluation of functions in logical - expressions. It is not clear if #307 is the same issue. - - CHECK(view.GetSize() == 14); - CHECK(sumCharge(view) == 2); - ************************************/ - auto const secMomSum = sumMomentum(view, projectileMomentum.GetCoordinateSystem()); - CHECK((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() == - Approx(0).margin(1e-2)); - } -}