diff --git a/applications/c8_air_shower.cpp b/applications/c8_air_shower.cpp index e215f60228c9ce30b60ef0b9097deb3b37681101..998a5bd0a8e8229a5f104c152a86823074c7672e 100644 --- a/applications/c8_air_shower.cpp +++ b/applications/c8_air_shower.cpp @@ -195,6 +195,10 @@ int main(int argc, char** argv) { ->default_val(0.3) ->check(CLI::Range(0.000001, 1.e13)) ->group("Config"); + app.add_option("--taucut", "Min. kin. energy of tau leptons in tracking (GeV)") + ->default_val(0.3) + ->check(CLI::Range(0.000001, 1.e13)) + ->group("Config"); bool track_neutrinos = false; app.add_flag("--track-neutrinos", track_neutrinos, "switch on tracking of neutrinos") ->group("Config"); @@ -459,17 +463,19 @@ int main(int argc, char** argv) { HEPEnergyType const emcut = 1_GeV * app["--emcut"]->as<double>(); HEPEnergyType const hadcut = 1_GeV * app["--hadcut"]->as<double>(); HEPEnergyType const mucut = 1_GeV * app["--mucut"]->as<double>(); - ParticleCut<SubWriter<decltype(dEdX)>> cut(emcut, emcut, hadcut, mucut, + HEPEnergyType const taucut = 1_GeV * app["--taucut"]->as<double>(); + ParticleCut<SubWriter<decltype(dEdX)>> cut(emcut, emcut, hadcut, mucut, taucut, !track_neutrinos, dEdX); // tell proposal that we are interested in all energy losses above the particle cut - set_energy_production_threshold(Code::Electron, std::min({emcut, hadcut, mucut})); - set_energy_production_threshold(Code::Positron, std::min({emcut, hadcut, mucut})); - set_energy_production_threshold(Code::Photon, std::min({emcut, hadcut, mucut})); - set_energy_production_threshold(Code::MuMinus, std::min({emcut, hadcut, mucut})); - set_energy_production_threshold(Code::MuPlus, std::min({emcut, hadcut, mucut})); - set_energy_production_threshold(Code::TauMinus, std::min({emcut, hadcut, mucut})); - set_energy_production_threshold(Code::TauPlus, std::min({emcut, hadcut, mucut})); + auto const prod_threshold = std::min({emcut, hadcut, mucut, taucut}); + set_energy_production_threshold(Code::Electron, prod_threshold); + set_energy_production_threshold(Code::Positron, prod_threshold); + set_energy_production_threshold(Code::Photon, prod_threshold); + set_energy_production_threshold(Code::MuMinus, prod_threshold); + set_energy_production_threshold(Code::MuPlus, prod_threshold); + set_energy_production_threshold(Code::TauMinus, prod_threshold); + set_energy_production_threshold(Code::TauPlus, prod_threshold); // energy threshold for high energy hadronic model. Affects LE/HE switch for // hadron interactions and the hadronic photon model in proposal diff --git a/corsika/detail/modules/ParticleCut.inl b/corsika/detail/modules/ParticleCut.inl index 514a936500dd80763e88ed40421ad452a0d991fd..a5d6a03f210ff3fae7b7c42b24c3fb89ec2f3dc9 100644 --- a/corsika/detail/modules/ParticleCut.inl +++ b/corsika/detail/modules/ParticleCut.inl @@ -17,19 +17,23 @@ namespace corsika { inline ParticleCut<TOutput>::ParticleCut(HEPEnergyType const eEleCut, HEPEnergyType const ePhoCut, HEPEnergyType const eHadCut, - HEPEnergyType const eMuCut, bool const inv, + HEPEnergyType const eMuCut, + HEPEnergyType const eTauCut, bool const inv, TArgs&&... outputArgs) : TOutput(std::forward<TArgs>(outputArgs)...) , cut_electrons_(eEleCut) , cut_photons_(ePhoCut) - , cut_muons_(eMuCut) , cut_hadrons_(eHadCut) + , cut_muons_(eMuCut) + , cut_tau_(eTauCut) , doCutInv_(inv) { for (auto p : get_all_particles()) { if (is_hadron(p)) // nuclei are also hadrons set_kinetic_energy_propagation_threshold(p, eHadCut); else if (is_muon(p)) set_kinetic_energy_propagation_threshold(p, eMuCut); + else if (p == Code::TauMinus || p == Code::TauPlus) + set_kinetic_energy_propagation_threshold(p, eTauCut); else if (p == Code::Electron || p == Code::Positron) set_kinetic_energy_propagation_threshold(p, eEleCut); else if (p == Code::Photon) @@ -40,7 +44,8 @@ namespace corsika { "setting kinetic energy thresholds: electrons = {} GeV, photons = {} GeV, " "hadrons = {} GeV, " "muons = {} GeV", - eEleCut / 1_GeV, ePhoCut / 1_GeV, eHadCut / 1_GeV, eMuCut / 1_GeV); + "tau = {} GeV", eEleCut / 1_GeV, ePhoCut / 1_GeV, eHadCut / 1_GeV, eMuCut / 1_GeV, + eTauCut / 1_GeV); } template <typename TOutput> @@ -152,6 +157,7 @@ namespace corsika { CORSIKA_LOG_DEBUG("kinetic energy threshold for photons is {} GeV", cut_photons_ / 1_GeV); CORSIKA_LOG_DEBUG("kinetic energy threshold for muons is {} GeV", cut_muons_ / 1_GeV); + CORSIKA_LOG_DEBUG("kinetic energy threshold for tau is {} GeV", cut_tau_ / 1_GeV); CORSIKA_LOG_DEBUG("kinetic energy threshold for hadrons is {} GeV", cut_hadrons_ / 1_GeV); @@ -171,6 +177,7 @@ namespace corsika { node["cut_photons"] = cut_photons_ / 1_GeV; node["cut_muons"] = cut_muons_ / 1_GeV; node["cut_hadrons"] = cut_hadrons_ / 1_GeV; + node["cut_tau"] = cut_tau_ / 1_GeV; node["cut_invisibles"] = doCutInv_; for (auto const& cut : cuts_) { node[fmt::format("cut_{}", cut.first)] = cut.second / 1_GeV; diff --git a/corsika/modules/ParticleCut.hpp b/corsika/modules/ParticleCut.hpp index 431f1bc049630af65b66e14bfc608e83afd51865..04fdfb231efcf4d24d7b767aa6cfa342079cf828 100644 --- a/corsika/modules/ParticleCut.hpp +++ b/corsika/modules/ParticleCut.hpp @@ -44,8 +44,8 @@ namespace corsika { */ template <typename... TArgs> ParticleCut(HEPEnergyType const eEleCut, HEPEnergyType const ePhoCut, - HEPEnergyType const eHadCut, HEPEnergyType const eMuCut, bool const inv, - TArgs&&... args); + HEPEnergyType const eHadCut, HEPEnergyType const eMuCut, + HEPEnergyType const eTauCut, bool const inv, TArgs&&... args); /** * particle cut with kinetic energy thresholds for all particles. @@ -103,6 +103,7 @@ namespace corsika { HEPEnergyType getElectronKineticECut() const { return cut_electrons_; } HEPEnergyType getPhotonKineticECut() const { return cut_photons_; } HEPEnergyType getMuonKineticECut() const { return cut_muons_; } + HEPEnergyType getTauKineticECut() const { return cut_tau_; } HEPEnergyType getHadronKineticECut() const { return cut_hadrons_; } //! get configuration of this node, for output @@ -116,8 +117,9 @@ namespace corsika { private: HEPEnergyType cut_electrons_; HEPEnergyType cut_photons_; - HEPEnergyType cut_muons_; HEPEnergyType cut_hadrons_; + HEPEnergyType cut_muons_; + HEPEnergyType cut_tau_; bool doCutInv_; std::unordered_map<Code const, HEPEnergyType const> cuts_; }; // namespace corsika diff --git a/examples/cascade_examples/em_shower.cpp b/examples/cascade_examples/em_shower.cpp index c3083ec139af35150dff14e1f4943e13cbc64326..c982bcf46bfbee0148e7ff3766d60d83da48e62e 100644 --- a/examples/cascade_examples/em_shower.cpp +++ b/examples/cascade_examples/em_shower.cpp @@ -146,8 +146,8 @@ int main(int argc, char** argv) { // setup processes, decays and interactions EnergyLossWriter energyloss{showerAxis, dX}; - ParticleCut<SubWriter<decltype(energyloss)>> cut(5_MeV, 5_MeV, 100_GeV, 100_GeV, true, - energyloss); + ParticleCut<SubWriter<decltype(energyloss)>> cut(5_MeV, 5_MeV, 100_GeV, 100_GeV, + 100_GeV, true, energyloss); corsika::sibyll::Interaction sibyll(corsika::get_all_elements_in_universe(env), corsika::setup::C7trackedParticles); diff --git a/examples/cascade_examples/mars.cpp b/examples/cascade_examples/mars.cpp index b19d1de9e1d36e3caf23d62835139b5384e70ce7..5842028570cca0602f7b36c150e11a12f87e9857 100644 --- a/examples/cascade_examples/mars.cpp +++ b/examples/cascade_examples/mars.cpp @@ -313,7 +313,8 @@ int main(int argc, char** argv) { HEPEnergyType const emcut = 1_GeV; HEPEnergyType const hadcut = 1_GeV; - ParticleCut<SubWriter<decltype(dEdX)>> cut(emcut, emcut, hadcut, hadcut, true, dEdX); + ParticleCut<SubWriter<decltype(dEdX)>> cut(emcut, emcut, hadcut, hadcut, hadcut, true, + dEdX); // tell proposal that we are interested in all energy losses above the particle cut set_energy_production_threshold(Code::Electron, std::min({emcut, hadcut})); diff --git a/examples/cascade_examples/radio_em_shower.cpp b/examples/cascade_examples/radio_em_shower.cpp index 0b89a1f8adc5b19520ddab62f2c00367b237e7d1..205a25599bf1b92e6abc0237baeb2119d77771ee 100644 --- a/examples/cascade_examples/radio_em_shower.cpp +++ b/examples/cascade_examples/radio_em_shower.cpp @@ -231,8 +231,8 @@ int main(int argc, char** argv) { // setup processes, decays and interactions EnergyLossWriter energyloss{showerAxis, dX}; - ParticleCut<SubWriter<decltype(energyloss)>> cut(5_MeV, 5_MeV, 100_GeV, 100_GeV, true, - energyloss); + ParticleCut<SubWriter<decltype(energyloss)>> cut(5_MeV, 5_MeV, 100_GeV, 100_GeV, + 100_GeV, true, energyloss); corsika::sibyll::Interaction sibyll(corsika::get_all_elements_in_universe(env), corsika::setup::C7trackedParticles); diff --git a/examples/cascade_examples/water.cpp b/examples/cascade_examples/water.cpp index 26380f0e72a4b318513a7b6add58226b9c088e97..c9f48c6185fb634276a07363d0f5a26f38eecb03 100644 --- a/examples/cascade_examples/water.cpp +++ b/examples/cascade_examples/water.cpp @@ -211,7 +211,8 @@ int main(int argc, char** argv) { // particle production threshold HEPEnergyType const emCut = eCut; HEPEnergyType const hadCut = eCut; - ParticleCut<SubWriter<decltype(dEdX)>> cut(emCut, emCut, hadCut, hadCut, true, dEdX); + ParticleCut<SubWriter<decltype(dEdX)>> cut(emCut, emCut, hadCut, hadCut, hadCut, true, + dEdX); // tell proposal that we are interested in all energy losses above the particle cut set_energy_production_threshold(Code::Electron, std::min({emCut, hadCut})); diff --git a/tests/modules/testParticleCut.cpp b/tests/modules/testParticleCut.cpp index cf61644fdfeac29431cce81cb848d45f397c542a..f305bf28d2304012db160eaa9431e4e148510b81 100644 --- a/tests/modules/testParticleCut.cpp +++ b/tests/modules/testParticleCut.cpp @@ -56,7 +56,7 @@ TEST_CASE("ParticleCut", "process,continuous,secondary") { SECTION("cut on particle type: inv") { // particle cut with 20GeV threshold for all, also cut invisible - ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, true); + ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, 20_GeV, true); CHECK(cut.getHadronKineticECut() == 20_GeV); // add primary particle to stack @@ -83,7 +83,7 @@ TEST_CASE("ParticleCut", "process,continuous,secondary") { SECTION("cut on particle type: em") { - ParticleCut cut(1_EeV, 1_EeV, 1_GeV, 1_GeV, false); + ParticleCut cut(1_EeV, 1_EeV, 1_GeV, 1_GeV, 1_GeV, false); // add primary particle to stack auto particle = stack.addParticle(std::make_tuple( @@ -105,7 +105,7 @@ TEST_CASE("ParticleCut", "process,continuous,secondary") { } SECTION("cut low energy") { - ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, true); + ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, 20_GeV, true); // add primary particle to stack auto particle = stack.addParticle(std::make_tuple( @@ -133,8 +133,8 @@ TEST_CASE("ParticleCut", "process,continuous,secondary") { CHECK(view.getSize() == 13); } - SECTION("cut low energy: electrons, photons, hadrons and muons") { - ParticleCut cut(5_MeV, 5_MeV, 5_GeV, 5_GeV, true); + SECTION("cut low energy: electrons, photons, hadrons, muons and tau") { + ParticleCut cut(5_MeV, 5_MeV, 5_GeV, 5_GeV, 5_MeV, true); // add primary particle to stack auto particle = stack.addParticle(std::make_tuple(Code::Proton, Eabove - Proton::mass, @@ -177,7 +177,7 @@ TEST_CASE("ParticleCut", "process,continuous,secondary") { } SECTION("cut on time") { - ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, false); + ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, 20_GeV, false); const TimeType too_late = 1_s; // add primary particle to stack @@ -205,7 +205,7 @@ TEST_CASE("ParticleCut", "process,continuous,secondary") { SECTION("cut on doContinous, just invisibles") { - ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, true); + ParticleCut cut(20_GeV, 20_GeV, 20_GeV, 20_GeV, 20_GeV, true); // add particles, all with energies above the threshold // only cut is by species