From ef43a074c179cb6cd389b7092c5ef54f80468d18 Mon Sep 17 00:00:00 2001 From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu> Date: Tue, 15 Mar 2022 18:27:41 +0100 Subject: [PATCH] first steps --- .../detail/modules/pythia8/Interaction.inl | 119 ++++++++---------- corsika/modules/pythia8/Interaction.hpp | 6 +- 2 files changed, 50 insertions(+), 75 deletions(-) diff --git a/corsika/detail/modules/pythia8/Interaction.inl b/corsika/detail/modules/pythia8/Interaction.inl index 374088d04..38ca6094d 100644 --- a/corsika/detail/modules/pythia8/Interaction.inl +++ b/corsika/detail/modules/pythia8/Interaction.inl @@ -8,6 +8,10 @@ #pragma once +#include <tuple> + +#include <fmt/core.h> + #include <corsika/modules/pythia8/Interaction.hpp> #include <corsika/framework/geometry/FourVector.hpp> @@ -15,8 +19,6 @@ #include <corsika/media/Environment.hpp> #include <corsika/media/NuclearComposition.hpp> -#include <tuple> - namespace corsika::pythia8 { inline Interaction::~Interaction() { @@ -38,14 +40,19 @@ namespace corsika::pythia8 { Pythia8::Pythia::readString("Check:particleData = off"); Pythia8::Pythia::readString("Check:event = on"); // default: on Pythia8::Pythia::readString("Check:levelParticleData = 12"); // 1 is default - /** \TODO: proper process initialization for MinBias needed, see - also Issue https://gitlab.iap.kit.edu/AirShowerPhysics/corsika/-/issues/369 **/ - Pythia8::Pythia::readString("HardQCD:all = on"); - Pythia8::Pythia::readString("ProcessLevel:resonanceDecays = off"); + readString("SoftQCD:all = on"); + readString("LowEnergyQCD:all = on"); + readString("MultipartonInteraction:reuseInit = 3"); + readString(fmt::format("MultipartonInteraction:initFile = {}", corsika_data("pythia8/MPI_init_file"))); + readString("Beam:allowVariableEnergy = on"); + readString("Beam:allowIDASwitch = on"); + readString("Beam:frameType = 3"); // no special frame, need to specify full 3-mom + readString("Check:epTolErr = 0.1"); // relax energy-monetum conservation, copied from Pythia 8 main183.cc // we can't test this block, LCOV_EXCL_START - if (!Pythia8::Pythia::init()) + if (!Pythia8::Pythia::init()) { throw std::runtime_error("Pythia::Interaction: Initialization failed!"); + } // LCOV_EXCL_STOP // any decays in pythia? if yes need to define which particles @@ -60,10 +67,6 @@ namespace corsika::pythia8 { Interaction::setStable(HadronsWeWantTrackedByCorsika); } - - // basic initialization of cross section routines - sigma_.init(&(Pythia8::Pythia::info), Pythia8::Pythia::settings, - &(Pythia8::Pythia::particleData), &(Pythia8::Pythia::rndm)); } inline void Interaction::setStable(std::vector<Code> const& particleList) { @@ -82,50 +85,36 @@ namespace corsika::pythia8 { inline bool Interaction::isValid(Code const projectileId, Code const targetId, HEPEnergyType const sqrtS) const { - - if ((10_GeV > sqrtS) || (sqrtS > 1_PeV)) { return false; } - - if (targetId != Code::Hydrogen && targetId != Code::Neutron && - targetId != Code::Proton) { - return false; - } - - if (is_nucleus(projectileId)) { return false; } - - if (!canInteract(projectileId)) { return false; } + // TODO: rethink this function. Pythia can do much more now. return true; } inline void Interaction::configureLabFrameCollision(Code const projectileId, Code const targetId, - HEPEnergyType const BeamEnergy) { + MomentumVector const& projectileMom, + MomentumVector const& targetMom) { // 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>(get_PDG(projectileId)); - std::stringstream stBeam; - stBeam << "Beams:idA = " << pdgBeam; - Pythia8::Pythia::readString(stBeam.str()); + // set target auto pdgTarget = static_cast<int>(get_PDG(targetId)); // replace hydrogen with proton, otherwise pythia goes into heavy ion mode! - if (targetId == Code::Hydrogen) pdgTarget = static_cast<int>(get_PDG(Code::Proton)); - std::stringstream stTarget; - stTarget << "Beams:idB = " << pdgTarget; - Pythia8::Pythia::readString(stTarget.str()); - // set frame to lab. frame - Pythia8::Pythia::readString("Beams:frameType = 2"); - // set beam energy - double const Elab = BeamEnergy / 1_GeV; - std::stringstream stEnergy; - stEnergy << "Beams:eA = " << Elab; - Pythia8::Pythia::readString(stEnergy.str()); - // target at rest - Pythia8::Pythia::readString("Beams:eB = 0."); + if (targetId == Code::Hydrogen) + pdgTarget = static_cast<int>(get_PDG(Code::Proton)); + + setBeamIDs(pdgBeam, pdgTarget); + + auto const projMomGeV = projectileMom.getComponents() * (1/1_GeV); + auto const tarMomGeV = targetMom.getComponents() * (1/1_GeV); + + setKinematics(projMomGeV[0], projMomGeV[1], projMomGeV[2], + tarMomGeV[0], tarMomGeV[1], tarMomGeV[2]); + // initialize this config - // we can't test this block, LCOV_EXCL_START if (!Pythia8::Pythia::init()) throw std::runtime_error("Pythia::Interaction: Initialization failed!"); @@ -133,12 +122,11 @@ namespace corsika::pythia8 { } inline bool Interaction::canInteract(Code const pCode) const { - return pCode == Code::Proton || pCode == Code::Neutron || pCode == Code::AntiProton || - pCode == Code::AntiNeutron || pCode == Code::PiMinus || pCode == Code::PiPlus; + return true; // TODO: implement this } - inline std::tuple<CrossSectionType, CrossSectionType> - Interaction::getCrossSectionInelEla(Code const projectileId, Code const targetId, + CrossSectionType + Interaction::getCrossSection(Code const projectileId, Code const targetId, FourMomentum const& projectileP4, FourMomentum const& targetP4) const { @@ -151,23 +139,22 @@ namespace corsika::pythia8 { // input particle PDG auto const pdgCodeBeam = static_cast<int>(get_PDG(projectileId)); auto const pdgCodeTarget = static_cast<int>(get_PDG(targetId)); - double const ecm = CoMenergy / 1_GeV; - - //! @todo: remove this const_cast, when Pythia8 becomes const-correct! CHECK! - Pythia8::SigmaTotal& sigma = *const_cast<Pythia8::SigmaTotal*>(&sigma_); - - // calculate cross section - sigma.calc(pdgCodeBeam, pdgCodeTarget, ecm); - if (sigma.hasSigmaTot()) { - double const sigEla = sigma.sigmaEl(); - double const sigProd = sigma.sigmaTot() - sigEla; - - return std::make_tuple(sigProd * (1_fm * 1_fm), sigEla * (1_fm * 1_fm)); - + double const ecm_GeV = CoMenergy * (1 / 1_GeV); + + auto const sigTot = pythia.getSigmaTotal(pdgCodeBeam, 2212, ecm_GeV) * 1_mb; + auto const sigEla = pythia.getSigmaPartial(pdgCodeBeam, 2212, evm_GeV, 2) * 1_mb; + auto const sigProd = sigTot - sigEla; + + if (is_nucleus(targetId)) { + // avg. no. of sub-collisions, from 2108.03481, for Nitrogen target... + // TODO: generalize + double const nCollAvg = (sigTot < 31._mb) ? 1. + (0.017 / 1_mb) * sigTot + : 1.2 + (0.0105 / 1_mb) * sigTot; + + // TODO: is this valid also for production XS? Paper says total XS... + return get_nucleus_A(targetId) * sigProd / nCollAvg; } else { - // we can't test pythia8 internals, LCOV_EXCL_START - throw std::runtime_error("pythia cross section init failed"); - // we can't test pythia8 internals, LCOV_EXCL_STOP + return sigProd; } } @@ -201,12 +188,6 @@ namespace corsika::pythia8 { CORSIKA_LOG_DEBUG("Interaction: ebeam lab: {} GeV", eProjectileLab / 1_GeV); - // define target kinematics in lab frame - // define boost to and from CoM frame - // CoM frame definition in Pythia projectile: +z - COMBoost const boost(projectileP4, constants::nucleonMass); - auto const& labCS = boost.getOriginalCS(); - CORSIKA_LOG_DEBUG("Interaction: position of interaction: ", pOrig.getCoordinates()); CORSIKA_LOG_DEBUG("Interaction: time: {}", tOrig); @@ -217,17 +198,15 @@ namespace corsika::pythia8 { eProjectileLab / 1_GeV, sqrtS / 1_GeV); count_++; + configureLabFrameCollision(projectileId, targetId, projectileP4.getSpacelikeComponents(), targetP4.getSpacelikeComponents()); - configureLabFrameCollision(projectileId, targetId, eProjectileLab); + CrossSectionType const sigmaHp = pythiaColl.getSigmaTotal(idNow, 2212, eCMNow); // create event in pytia. LCOV_EXCL_START: we don't validate pythia8 internals if (!Pythia8::Pythia::next()) throw std::runtime_error("Pythia::DoInteraction: failed!"); // LCOV_EXCL_STOP - // link to pythia stack - Pythia8::Event& event = Pythia8::Pythia::event; - // LCOV_EXCL_START, we don't validate pythia8 internals if (print_listing_) { // print final state diff --git a/corsika/modules/pythia8/Interaction.hpp b/corsika/modules/pythia8/Interaction.hpp index 25ebf826b..6385430f9 100644 --- a/corsika/modules/pythia8/Interaction.hpp +++ b/corsika/modules/pythia8/Interaction.hpp @@ -74,10 +74,7 @@ namespace corsika::pythia8 { */ CrossSectionType getCrossSection(Code const projectile, Code const target, FourMomentum const& projectileP4, - FourMomentum const& targetP4) const { - return std::get<0>( - getCrossSectionInelEla(projectile, target, projectileP4, targetP4)); - } + FourMomentum const& targetP4) const; /** * In this function PYTHIA is called to produce one event. The @@ -89,7 +86,6 @@ namespace corsika::pythia8 { private: default_prng_type& RNG_ = RNGManager<>::getInstance().getRandomStream("pythia"); - Pythia8::SigmaTotal sigma_; bool const internalDecays_ = true; int count_ = 0; bool print_listing_ = false; -- GitLab