diff --git a/applications/CMakeLists.txt b/applications/CMakeLists.txt index b9d47c0c96c056daf3199388d16d91c8fd7e1600..a7231f257d98c911ff6094b9d26755258ff75d0e 100644 --- a/applications/CMakeLists.txt +++ b/applications/CMakeLists.txt @@ -13,3 +13,10 @@ endif() install ( TARGETS c8_air_shower DESTINATION bin ) + +add_executable (cross_section cross_section.cpp) +target_link_libraries (cross_section CORSIKA8) + +install ( + TARGETS cross_section DESTINATION bin +) diff --git a/applications/cross_section.cpp b/applications/cross_section.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1eb34c0388b45752c75e6d55d30a22fc5dc90b2f --- /dev/null +++ b/applications/cross_section.cpp @@ -0,0 +1,153 @@ +/* + * (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/modules/Epos.hpp> +#include <corsika/modules/Sibyll.hpp> +#include <corsika/modules/QGSJetII.hpp> +#include <corsika/modules/Pythia8.hpp> + +#include <corsika/framework/core/ParticleProperties.hpp> +#include <corsika/framework/core/PhysicalUnits.hpp> + +//#include <corsika/framework/geometry/Point.hpp> +#include <corsika/framework/geometry/RootCoordinateSystem.hpp> +#include <corsika/framework/geometry/Vector.hpp> + +#include <corsika/framework/random/RNGManager.hpp> + +// #include <corsika/media/Environment.hpp> +// #include <corsika/media/HomogeneousMedium.hpp> +// #include <corsika/media/MediumPropertyModel.hpp> +// #include <corsika/media/NuclearComposition.hpp> +// #include <corsika/media/ShowerAxis.hpp> +// #include <corsika/media/UniformMagneticField.hpp> + +// #include <corsika/setup/SetupStack.hpp> + +#include <fstream> +#include <string> +#include <tuple> + +/* + NOTE, WARNING, ATTENTION + + The Random.hpp implements the hook of epos to the C8 random + number generator. It has to occur excatly ONCE per linked + executable. If you include the header below in multiple "tests" and + link them togehter, it will fail. + */ +#include <corsika/modules/Random.hpp> + +using namespace corsika; +// using namespace corsika::epos; + +template <typename TModel> +void calculate_cross_sections(TModel & model, std::string const &model_name, + bool lab_frame = true) { + + std::stringstream fname; + fname << "cross-sections-" << model_name << ".txt"; + std::ofstream out(fname.str()); + out << "# cross section table for " << model_name << "\n"; + out << "# i, elab, sqsnn, sig_pp, sig_pO \n"; + + CoordinateSystemPtr const &cs = get_root_CoordinateSystem(); + + float const amin = 2; + float const amax = 12; + int const nebins = 15; + float const da = (amax - amin) / (float)nebins; + + for (int i = 0; i < nebins; ++i) { + + corsika::units::si::HEPMomentumType const setP = + pow(10, da * i + amin) * 1_GeV; + + auto setE = calculate_total_energy(setP, Proton::mass); + corsika::units::si::HEPEnergyType const comEnn = + corsika::calculate_com_energy(setE, Proton::mass, + corsika::constants::nucleonMass); + + //corsika::units::si::HEPMomentumType setP = + // corsika::calculate_momentum(setE, Proton::mass); + + FourMomentum p4protonProj(0_eV, {cs, 0_GeV, 0_GeV, 0_GeV}); + FourMomentum p4protonTarg(0_eV, {cs, 0_GeV, 0_GeV, 0_GeV}); + FourMomentum p4oxygenTarg(0_eV, {cs, 0_GeV, 0_GeV, 0_GeV}); + + if (lab_frame) { + // four momenta in lab frame + p4protonProj = + corsika::FourMomentum(setE, MomentumVector(cs, {0_eV, 0_eV, setP})); + p4protonTarg = corsika::FourMomentum( + Proton::mass, MomentumVector(cs, {0_eV, 0_eV, 0_eV})); + p4oxygenTarg = corsika::FourMomentum( + Oxygen::mass, MomentumVector(cs, {0_eV, 0_eV, 0_eV})); + } else { + // four momenta in com frame + p4protonProj = corsika::FourMomentum( + corsika::calculate_total_energy(setP / 2, Proton::mass), + MomentumVector(cs, {0_eV, 0_eV, setP / 2})); + p4protonTarg = corsika::FourMomentum( + corsika::calculate_total_energy(setP / 2, Proton::mass), + MomentumVector(cs, {0_eV, 0_eV, -setP / 2})); + p4oxygenTarg = corsika::FourMomentum( + corsika::calculate_total_energy(setP / 2, Oxygen::mass), + MomentumVector(cs, {0_eV, 0_eV, -setP / 2})); + } + + // p-p + CrossSectionType const xs_prod_pp = model->getCrossSection( + Code::Proton, Code::Proton, p4protonProj, p4protonTarg); + // p-O + CrossSectionType const xs_prod_pO = model->getCrossSection( + Code::Proton, Code::Oxygen, p4protonProj, p4oxygenTarg); + + CORSIKA_LOG_INFO("Elab={:15.2f} GeV,Ecom={:15.2f} GeV, sig-p-p={:6.2f} mb, sig-p-O={:6.2f} mb", + setE / 1_GeV, comEnn / 1_GeV, xs_prod_pp / 1_mb, + xs_prod_pO / 1_mb); + + out << i << " " << setE / 1_GeV << " " << comEnn / 1_GeV << " " + << xs_prod_pp / 1_mb << " " << xs_prod_pO / 1_mb << "\n"; + } + out.close(); +} + +int main(int argc, char **argv) { + + logging::set_level(logging::level::info); + + if (argc != 2) { + std::cout + << "usage: check <interaction model> \n valid models are: sibyll, " + "epos, qgsII, pythia8" + << std::endl; + return 1; + } + std::string int_model_name = std::string(argv[1]); + + if (int_model_name == "sibyll") { + RNGManager<>::getInstance().registerRandomStream("sibyll"); + auto model = std::make_shared<corsika::sibyll::InteractionModel>(std::set<Code>{Code::Proton, Code::Oxygen}); + calculate_cross_sections(model, int_model_name); + } else if (int_model_name == "pythia8") { + RNGManager<>::getInstance().registerRandomStream("pythia"); + auto model = std::make_shared<corsika::pythia8::InteractionModel>(); + calculate_cross_sections(model, int_model_name); + + } else if (int_model_name == "epos") { + RNGManager<>::getInstance().registerRandomStream("epos"); + auto model = std::make_shared<corsika::epos::InteractionModel>(); + calculate_cross_sections(model, int_model_name); + } + else if (int_model_name == "qgsjet") { + RNGManager<>::getInstance().registerRandomStream("qgsjet"); + auto model = std::make_shared<corsika::qgsjetII::InteractionModel>(); + calculate_cross_sections(model, int_model_name); + } +}