IAP GITLAB

Commit 5556d5e0 authored by Ralf Ulrich's avatar Ralf Ulrich

Merge branch 'epos_rndm' into 'master'

Epos RNDM

See merge request !381
parents 137a1f0b 1e5e5780
Pipeline #5260 passed with stages
in 19 minutes and 51 seconds
......@@ -33,7 +33,7 @@ namespace corsika {
}
inline PDGCode constexpr get_PDG(unsigned int A, unsigned int Z) {
return static_cast<PDGCode>(1000000000 + Z * 10000 + A + 10); // 10LZZZAAAI
return static_cast<PDGCode>(1000000000 + Z * 10000 + A * 10); // 10LZZZAAAI
}
inline int16_t constexpr get_charge_number(Code const code) {
......
......@@ -55,6 +55,8 @@ namespace corsika {
profiles_.at(b)[ProfileIndex::MuMinus]++;
} else if (is_hadron(pid)) {
profiles_.at(b)[ProfileIndex::Hadron]++;
} else if (is_neutrino(pid)) {
profiles_.at(b)[ProfileIndex::Invisible]++;
}
}
......@@ -65,7 +67,7 @@ namespace corsika {
const int precision) {
CORSIKA_LOG_DEBUG("Write longprof to {}", filename);
std::ofstream f{filename};
f << "# X / g·cm¯², photon, e+, e-, mu+, mu-, all hadrons" << std::endl;
f << "# X / g·cm¯², photon, e+, e-, mu+, mu-, all hadrons, neutrinos" << std::endl;
for (size_t b = 0; b < profiles_.size(); ++b) {
f << std::setprecision(5) << std::setw(11) << b * (dX_ / (1_g / 1_cm / 1_cm));
for (auto const& N : profiles_.at(b)) {
......
......@@ -23,7 +23,8 @@ namespace corsika {
, energy_emcut_(0_GeV)
, energy_invcut_(0_GeV)
, em_count_(0)
, inv_count_(0) {
, inv_count_(0)
, energy_count_() {
for (auto p : get_all_particles())
if (is_hadron(p)) // nuclei are also hadrons
set_kinetic_energy_threshold(p, eHadCut);
......@@ -49,7 +50,8 @@ namespace corsika {
, energy_emcut_(0_GeV)
, energy_invcut_(0_GeV)
, em_count_(0)
, inv_count_(0) {
, inv_count_(0)
, energy_count_(0) {
for (auto p : get_all_particles())
if (is_hadron(p))
......@@ -70,7 +72,8 @@ namespace corsika {
, energy_emcut_(0_GeV)
, energy_invcut_(0_GeV)
, em_count_(0)
, inv_count_(0) {
, inv_count_(0)
, energy_count_(0) {
for (auto p : get_all_particles()) set_kinetic_energy_threshold(p, eCut);
CORSIKA_LOG_DEBUG("setting kinetic energy threshold for all particles to {} GeV",
eCut / 1_GeV);
......@@ -86,7 +89,8 @@ namespace corsika {
, energy_emcut_(0_GeV)
, energy_invcut_(0_GeV)
, em_count_(0)
, inv_count_(0) {
, inv_count_(0)
, energy_count_(0) {
set_kinetic_energy_thresholds(eCuts);
CORSIKA_LOG_DEBUG("setting threshold particles individually");
}
......@@ -116,26 +120,34 @@ namespace corsika {
HEPEnergyType const kine_energy = particle.getKineticEnergy();
HEPEnergyType const energy = particle.getEnergy();
CORSIKA_LOG_DEBUG(
"ParticleCut: checking {}, E_kin= {} GeV, EcutTot={} GeV", pid,
kine_energy / 1_GeV,
(energy_emcut_ + energy_invcut_ + energy_cut_ + energy_timecut_) / 1_GeV);
"ParticleCut: checking {} ({}), E_kin= {} GeV, EcutTot={} GeV, E={} GeV, m={} "
"GeV",
pid, particle.getPDG(), kine_energy / 1_GeV,
(energy_emcut_ + energy_invcut_ + energy_cut_ + energy_timecut_) / 1_GeV,
energy / 1_GeV, particle.getMass() / 1_GeV);
CORSIKA_LOG_DEBUG("p={}", particle.asString());
if (doCutEm_ && is_em(pid)) {
CORSIKA_LOG_DEBUG("removing em. particle...");
energy_emcut_ += energy;
em_count_ += 1;
energy_event_ += energy;
return true;
} else if (doCutInv_ && is_neutrino(pid)) {
CORSIKA_LOG_DEBUG("removing inv. particle...");
energy_invcut_ += energy;
inv_count_ += 1;
energy_event_ += energy;
return true;
} else if (isBelowEnergyCut(particle)) {
CORSIKA_LOG_DEBUG("removing low en. particle...");
energy_cut_ += energy;
energy_count_ += 1;
energy_event_ += energy;
return true;
} else if (particle.getTime() > 10_ms) {
CORSIKA_LOG_DEBUG("removing OLD particle...");
energy_timecut_ += energy;
energy_event_ += energy;
return true;
}
return false; // this particle will not be removed/cut
......@@ -143,11 +155,13 @@ namespace corsika {
template <typename TStackView>
inline void ParticleCut::doSecondaries(TStackView& vS) {
energy_event_ = 0_GeV; // per event counting for printout
auto particle = vS.begin();
while (particle != vS.end()) {
if (checkCutParticle(particle)) { particle.erase(); }
++particle; // next entry in SecondaryView
}
CORSIKA_LOG_DEBUG("Event cut: {} GeV", energy_event_ / 1_GeV);
}
template <typename TParticle, typename TTrajectory>
......@@ -172,16 +186,14 @@ namespace corsika {
inline void ParticleCut::showResults() {
CORSIKA_LOG_INFO(
" ******************************\n"
" energy removed by cut of electromagnetic (GeV): {} \n "
" no. of em. particles removed : {} \n "
" energy removed by cut of invisible (GeV): {} \n "
" no. of invisible particles removed : {} \n "
" energy removed by kinetic energy cut (GeV): {} \n"
"\n ******************************\n "
" energy removed by cut of electromagnetic (GeV): {} (number: {})\n "
" energy removed by cut of invisible (GeV): {} (number: {})\n "
" energy removed by kinetic energy cut (GeV): {} (number: {}) \n "
" energy removed by time cut (GeV): {} \n"
" ******************************",
energy_emcut_ / 1_GeV, em_count_, energy_invcut_ / 1_GeV, inv_count_,
energy_cut_ / 1_GeV, energy_timecut_ / 1_GeV);
energy_cut_ / 1_GeV, energy_count_, energy_timecut_ / 1_GeV);
}
inline void ParticleCut::reset() {
......@@ -190,6 +202,7 @@ namespace corsika {
energy_invcut_ = 0_GeV;
inv_count_ = 0;
energy_cut_ = 0_GeV;
energy_count_ = 0;
energy_timecut_ = 0_GeV;
}
......
......@@ -65,20 +65,26 @@ namespace corsika {
double const progress = dE / E0_;
double const eta_seconds = elapsed_seconds.count() / progress;
std::time_t const start_time = std::chrono::system_clock::to_time_t(StartTime_);
std::time_t const eta_time = std::chrono::system_clock::to_time_t(
StartTime_ + std::chrono::seconds((int)eta_seconds));
int const yday0 = std::localtime(&start_time)->tm_yday;
int const yday1 = std::localtime(&eta_time)->tm_yday;
int const dyday = yday1 - yday0;
CORSIKA_LOG_INFO(
"StackInspector: "
" time={}"
", running={} seconds"
" ( {}%)"
" ( {:.1f}%)"
", nStep={}"
", stackSize={}"
", Estack={} GeV"
", ETA={}",
", ETA={}{}",
std::put_time(std::localtime(&now_time), "%T"), elapsed_seconds.count(),
int(progress * 100), getStep(), vS.getSize(), Etot / 1_GeV,
(progress * 100), getStep(), vS.getSize(), Etot / 1_GeV,
(dyday == 0 ? "" : fmt::format("+{}d ", dyday)),
std::put_time(std::localtime(&eta_time), "%T"));
}
......
......@@ -112,7 +112,7 @@ namespace corsika {
theta, phi);
int ipart = static_cast<int>(primaryPDG);
auto rng = RNGManager<>::getInstance().getRandomStream("cascade");
auto rng = RNGManager<>::getInstance().getRandomStream("conex");
double dimpact = 0.; // valid only if shower core is fixed on the observation plane;
// for skimming showers an offset is needed like in CONEX
......
......@@ -28,8 +28,8 @@ using SetupParticle = setup::Stack::stack_iterator_type;
namespace corsika::epos {
inline Interaction::Interaction(const std::string& dataPath,
const bool epos_printout_on)
inline Interaction::Interaction(std::string const& dataPath,
bool const epos_printout_on)
: data_path_(dataPath)
, epos_listing_(epos_printout_on) {
if (dataPath == "") {
......@@ -89,8 +89,9 @@ namespace corsika::epos {
::epos::aaset_(iarg);
// debug output settings
::epos::prnt1_.ish = 0; // debug level in epos, 0: off, 6: medium output
::epos::files_.ifch = 6; // output unit, 6: screen
::epos::prnt1_.ish = 0; // debug level in epos, 0: off, 6: medium output
::epos::prnt3_.iwseed = 0; // 1: printout seeds, 0: off
::epos::files_.ifch = 6; // output unit, 6: screen
// dummy set seeds for random number generator in epos. need to fool epos checks...
// we will use external generator
......@@ -336,7 +337,7 @@ namespace corsika::epos {
BeamId, BeamA, BeamZ, TargetId, EnergyLab / 1_GeV);
// read cross section from epos internal tables
int Abeam;
int Abeam = 0;
float Ekin = -1;
if (is_nucleus(BeamId)) {
......@@ -364,11 +365,8 @@ namespace corsika::epos {
throw std::runtime_error("Epos cross section failed! Negative kinetic energy!");
}
int Atarget;
if (is_nucleus(TargetId))
Atarget = get_nucleus_A(TargetId);
else
Atarget = 1;
int Atarget = 1;
if (is_nucleus(TargetId)) { Atarget = get_nucleus_A(TargetId); }
int iMode = 3; // 0: air, >0 not air
......@@ -466,7 +464,8 @@ namespace corsika::epos {
auto const projectile = view.getProjectile();
auto const corsikaBeamId = projectile.getPID();
CORSIKA_LOGGER_DEBUG(logger_, "DoInteraction: {} interaction ", corsikaBeamId);
CORSIKA_LOGGER_DEBUG(logger_, "doInteraction: {} interaction, Elab={} ",
corsikaBeamId, projectile.getEnergy());
if (corsika::epos::canInteract(corsikaBeamId)) {
count_ = count_ + 1;
......@@ -539,7 +538,7 @@ namespace corsika::epos {
if (epos_listing_) {
char nam[9] = "EPOSLHC&";
::epos::alistf_(nam);
::epos::alistf_(nam, 9);
}
// NSTORE-part
......@@ -580,10 +579,10 @@ namespace corsika::epos {
A = 4;
Z = 2;
} else {
// 10AAAZZZ0
// 100ZZZAAA0 -> std. pdg code
EposCodeIntType const eposPdg = static_cast<EposCodeIntType>(eposId);
Z = int(eposPdg / 10) % 1000;
A = int(eposPdg / 10000) % 1000;
Z = int(abs(eposPdg) / 10000) % 1000;
A = int(abs(eposPdg) / 10) % 1000;
}
auto pnew = view.addSecondary(
std::make_tuple(Code::Nucleus, momentum, pOrig, tOrig, A, Z));
......
......@@ -29,7 +29,8 @@
namespace corsika::urqmd {
inline UrQMD::UrQMD(boost::filesystem::path xs_file) {
inline UrQMD::UrQMD(boost::filesystem::path xs_file, int const retryFlag)
: iflb_(retryFlag) {
readXSFile(xs_file);
::urqmd::iniurqmdc8_();
}
......@@ -292,7 +293,8 @@ namespace corsika::urqmd {
::urqmd::inputs_.spiso3[1] = iso3;
}
int iflb = 0; // flag for retrying interaction in case of empty event, 0 means retry
int iflb =
iflb_; // flag for retrying interaction in case of empty event, 0 means retry
::urqmd::urqmd_(iflb);
// now retrieve secondaries from UrQMD
......@@ -406,7 +408,7 @@ namespace corsika::urqmd {
std::getline(file, line);
std::stringstream ss(line);
char dummy;
char dummy; // this is '#'
int nTargets, nProjectiles, nSupports;
ss >> dummy >> nTargets >> nProjectiles >> nSupports;
......
......@@ -55,14 +55,15 @@ namespace corsika {
private:
GrammageType const dX_;
ShowerAxis const& shower_axis_;
using ProfileEntry = std::array<uint32_t, 6>;
using ProfileEntry = std::array<uint32_t, 7>;
enum ProfileIndex {
Photon = 0,
Positron = 1,
Electron = 2,
MuPlus = 3,
MuMinus = 4,
Hadron = 5
Hadron = 5,
Invisible = 6,
};
std::vector<ProfileEntry> profiles_; // longitudinal profile
};
......
......@@ -111,6 +111,9 @@ namespace corsika {
HEPEnergyType energy_invcut_ = 0 * electronvolt;
unsigned int em_count_ = 0;
unsigned int inv_count_ = 0;
unsigned int energy_count_ = 0;
HEPEnergyType energy_event_; // per event sum
};
} // namespace corsika
......
......@@ -20,3 +20,4 @@
#include <corsika/modules/epos/Random.hpp>
#include <corsika/modules/urqmd/Random.hpp>
#include <corsika/modules/qgsjetII/Random.hpp>
#include <corsika/modules/conex/Random.hpp>
......@@ -18,6 +18,32 @@
#include <array>
namespace conex {
// the CORSIKA 8 random number interface
/**
* \function epos::rndm_interface
*
* this is the random number hook to external packages.
*
* CORSIKA8, for example, has to provide an implementation of this.
**/
extern float rndm_interface();
/**
* \function epos::double_rndm_interface
*
* this is the random number hook to external packages.
*
* CORSIKA8, for example, has to provide an implementation of this.
**/
extern double double_rndm_interface();
extern "C" {}
// the CONEX fortran interface
extern "C" {
extern struct { std::array<double, 16> dptl; } cxoptl_;
......
/*
* (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/random/RNGManager.hpp>
#include <random>
/**
* \file conex/Random.hpp
*
* This file is an integral part of the epos interface. It must be
* linked to the executable linked to epos exactly once
*
*/
namespace conex {
float rndm_interface() {
static corsika::default_prng_type& rng =
corsika::RNGManager<>::getInstance().getRandomStream("conex");
std::uniform_real_distribution<float> dist;
return dist(rng);
}
double double_rndm_interface() {
static corsika::default_prng_type& rng =
corsika::RNGManager<>::getInstance().getRandomStream("conex");
std::uniform_real_distribution<double> dist;
return dist(rng);
}
} // namespace conex
......@@ -22,7 +22,7 @@ namespace corsika::epos {
bool epos_listing_;
public:
Interaction(const std::string& dataPath = "", const bool epos_printout_on = false);
Interaction(std::string const& dataPath = "", bool const epos_printout_on = false);
~Interaction();
//! returns production and elastic cross section for hadrons in epos. Inputs are:
......
......@@ -25,7 +25,13 @@ namespace corsika::urqmd {
class UrQMD : public InteractionProcess<UrQMD> {
public:
UrQMD(boost::filesystem::path const path = corsika_data("UrQMD/UrQMD-1.3.1-xs.dat"));
/**
* @param path Location of UrQMD XS data file
* @param retryFlag Internal UrQMD flag for retrying interaction in case of empty
* event, 0 means retry
*/
UrQMD(boost::filesystem::path const path = corsika_data("UrQMD/UrQMD-1.3.1-xs.dat"),
int const retryFlag = 0);
template <typename TParticle>
GrammageType getInteractionLength(TParticle const&) const;
......@@ -42,13 +48,15 @@ namespace corsika::urqmd {
void blob(int) {}
private:
static CrossSectionType getCrossSection(Code, Code, HEPEnergyType, int);
private:
void readXSFile(boost::filesystem::path);
// data members
default_prng_type& RNG_ = RNGManager<>::getInstance().getRandomStream("urqmd");
std::uniform_int_distribution<int> booleanDist_{0, 1};
int iflb_; //! // flag for retrying interaction in case of empty event, 0 means retry
boost::multi_array<CrossSectionType, 3> xs_interp_support_table_;
};
......
......@@ -48,6 +48,7 @@
#include <corsika/modules/ParticleCut.hpp>
#include <corsika/modules/Pythia8.hpp>
#include <corsika/modules/Sibyll.hpp>
#include <corsika/modules/Epos.hpp>
#include <corsika/modules/UrQMD.hpp>
#include <corsika/modules/PROPOSAL.hpp>
#include <corsika/modules/QGSJetII.hpp>
......@@ -83,13 +84,16 @@ void registerRandomStreams(int seed) {
RNGManager<>::getInstance().registerRandomStream("cascade");
RNGManager<>::getInstance().registerRandomStream("qgsjet");
RNGManager<>::getInstance().registerRandomStream("sibyll");
RNGManager<>::getInstance().registerRandomStream("epos");
RNGManager<>::getInstance().registerRandomStream("pythia");
RNGManager<>::getInstance().registerRandomStream("urqmd");
RNGManager<>::getInstance().registerRandomStream("proposal");
if (seed == 0) {
std::random_device rd;
seed = rd();
cout << "new random seed (auto) " << seed << endl;
CORSIKA_LOG_INFO("random seed (auto) {} ", seed);
} else {
CORSIKA_LOG_INFO("random seed {} ", seed);
}
RNGManager<>::getInstance().setSeed(seed);
}
......@@ -143,10 +147,12 @@ int main(int argc, char** argv) {
->check(CLI::NonexistentPath)
->group("Library/Output");
app.add_option("-s,--seed", "The random number seed.")
->default_val(12351739)
->default_val(0)
->check(CLI::NonNegativeNumber)
->group("Misc.");
app.add_flag("--force-interaction", "Force the location of the first interaction.")
bool force_interaction = false;
app.add_flag("--force-interaction", force_interaction,
"Force the location of the first interaction.")
->group("Misc.");
app.add_option("-v,--verbosity", "Verbosity level")
->default_str("info")
......@@ -222,8 +228,6 @@ int main(int argc, char** argv) {
/* === START: CONSTRUCT PRIMARY PARTICLE === */
/* === START: CONSTRUCT PRIMARY PARTICLE === */
// parse the primary ID as a PDG or A/Z code
Code beamCode;
HEPEnergyType mass;
......@@ -278,11 +282,15 @@ int main(int argc, char** argv) {
OutputManager output(app["--filename"]->as<std::string>());
/* === START: SETUP PROCESS LIST === */
// corsika::epos::Interaction heModel;
// corsika::qgsjetII::Interaction heModel;
// InteractionCounter heModelCounted(heModel);
corsika::sibyll::Interaction sibyll;
InteractionCounter sibyllCounted(sibyll);
corsika::sibyll::NuclearInteraction sibyllNuc(sibyll, env);
InteractionCounter sibyllNucCounted(sibyllNuc);
auto heModelCounted = make_sequence(sibyllNucCounted, sibyllCounted);
corsika::pythia8::Decay decayPythia;
......@@ -309,16 +317,21 @@ int main(int argc, char** argv) {
// decaySibyll.printDecayConfig();
ParticleCut cut{1_GeV, 1_GeV, 1_GeV, 1_GeV, false};
HEPEnergyType const emcut = 1_GeV;
HEPEnergyType const hadcut = 1_GeV;
ParticleCut cut(emcut, emcut, hadcut, hadcut, true);
corsika::proposal::Interaction emCascade(env);
corsika::proposal::ContinuousProcess emContinuous(env);
InteractionCounter emCascadeCounted(emCascade);
// corsika::proposal::ContinuousProcess emContinuous(env);
BetheBlochPDG emContinuous(showerAxis);
// cut.printThresholds();
LongitudinalProfile longprof{showerAxis};
LongitudinalProfile longprof(showerAxis);
corsika::urqmd::UrQMD urqmd;
InteractionCounter urqmdCounted{urqmd};
StackInspector<setup::Stack> stackInspect(5000, false, E0);
InteractionCounter urqmdCounted(urqmd);
StackInspector<setup::Stack> stackInspect(50000, false, E0);
// assemble all processes into an ordered process list
struct EnergySwitch {
......@@ -327,8 +340,7 @@ int main(int argc, char** argv) {
: cutE_(cutE) {}
bool operator()(const Particle& p) { return (p.getKineticEnergy() < cutE_); }
};
auto hadronSequence = make_select(EnergySwitch(80_GeV), urqmdCounted,
make_sequence(sibyllNucCounted, sibyllCounted));
auto hadronSequence = make_select(EnergySwitch(63.1_GeV), urqmdCounted, heModelCounted);
auto decaySequence = make_sequence(decayPythia, decaySibyll);
// track writer
......@@ -343,9 +355,9 @@ int main(int argc, char** argv) {
output.add("particles", observationLevel);
// assemble the final process sequence
auto sequence =
make_sequence(stackInspect, hadronSequence, decaySequence, emCascadeCounted,
emContinuous, cut, trackWriter, observationLevel, longprof);
auto sequence = make_sequence(stackInspect, hadronSequence, decaySequence,
emCascadeCounted, cut, emContinuous, // trackWriter,
observationLevel, longprof);
/* === END: SETUP PROCESS LIST === */
// create the cascade object using the default stack and tracking implementation
......@@ -392,7 +404,10 @@ int main(int argc, char** argv) {
}
// if we want to fix the first location of the shower
if (app["--force-interaction"]) EAS.forceInteraction();
if (force_interaction) {
CORSIKA_LOG_INFO("Fixing first interaction at injection point.");
EAS.forceInteraction();
}
// run the shower
EAS.run();
......@@ -409,6 +424,7 @@ int main(int argc, char** argv) {
cut.reset();
// emContinuous.reset();
// auto const hists = heModelCounted.getHistogram() + urqmdCounted.getHistogram();
auto const hists = sibyllCounted.getHistogram() + sibyllNucCounted.getHistogram() +
urqmdCounted.getHistogram();
......
......@@ -159,7 +159,7 @@ int main(int argc, char** argv) {
output.add("tracks", trackWriter); // register TrackWriter
// long. profile; columns for photon, e+, e- still need to be added
LongitudinalProfile longprof{showerAxis};
LongitudinalProfile longprof(showerAxis);
Plane const obsPlane(showerCore, DirectionVector(rootCS, {0., 0., 1.}));
ObservationPlane<setup::Tracking> observationLevel(
......
......@@ -71,9 +71,11 @@ void registerRandomStreams(uint64_t seed) {
RNGManager<>::getInstance().registerRandomStream("cascade");
RNGManager<>::getInstance().registerRandomStream("qgsjet");
RNGManager<>::getInstance().registerRandomStream("sibyll");
RNGManager<>::getInstance().registerRandomStream("epos");
RNGManager<>::getInstance().registerRandomStream("pythia");
RNGManager<>::getInstance().registerRandomStream("urqmd");
RNGManager<>::getInstance().registerRandomStream("proposal");
RNGManager<>::getInstance().registerRandomStream("conex");
if (seed == 0) {
std::random_device rd;
seed = rd();
......@@ -237,15 +239,15 @@ int main(int argc, char** argv) {
decaySibyll.printDecayConfig();
ParticleCut cut{3_GeV, false, true};
BetheBlochPDG eLoss{showerAxis};
ParticleCut cut(3_GeV, false, true);
BetheBlochPDG eLoss(showerAxis);
CONEXhybrid conex_model(center, showerAxis, t, injectionHeight, E0,
get_PDG(Code::Proton));
OnShellCheck reset_particle_mass(1.e-3, 1.e-1, false);
LongitudinalProfile longprof{showerAxis};
LongitudinalProfile longprof(showerAxis);
Plane const obsPlane(showerCore, DirectionVector(rootCS, {0., 0., 1.}));
ObservationPlane<setup::Tracking> observationLevel(
......
......@@ -117,7 +117,9 @@ void registerRandomStreams(int seed) {
if (seed == 0) {
std::random_device rd;
seed = rd();
cout << "new random seed (auto) " << seed << endl;
CORSIKA_LOG_INFO("random seed (auto) {} ", seed);
} else {
CORSIKA_LOG_INFO("random seed {} ", seed);
}
RNGManager<>::getInstance().setSeed(seed);
}
......@@ -171,11 +173,9 @@ int main(int argc, char** argv) {
->check(CLI::NonexistentPath)
->group("Library/Output");
app.add_option("-s,--seed", "The random number seed.")
->default_val(12351739)
->default_val(0)
->check(CLI::NonNegativeNumber)
->group("Misc.");
app.add_flag("--force-interaction", "Force the location of the first interaction.")
->group("Misc.");
app.add_option("-v,--verbosity", "Verbosity level: warn, info, debug, trace.")
->default_val("info")
->check(CLI::IsMember({"warn", "info", "debug", "trace"}))
......@@ -313,9 +313,9 @@ int main(int argc, char** argv) {
/* === START: SETUP PROCESS LIST === */
corsika::sibyll::Interaction sibyll;
InteractionCounter sibyllCounted(sibyll);
corsika::sibyll::NuclearInteraction sibyllNuc(sibyll, env);
InteractionCounter sibyllNucCounted(sibyllNuc);
auto heModelCounted = make_sequence(sibyllNucCounted, sibyllCounted);
corsika::pythia8::Decay decayPythia;
......@@ -342,10 +342,13 @@ int main(int argc, char** argv) {