diff --git a/corsika/detail/modules/ParticleCut.inl b/corsika/detail/modules/ParticleCut.inl
index 559102cc43278178050323eb84f3fba2eb7b7b30..4afa7b37f339b919c663754db1511a7eec69d7f0 100644
--- a/corsika/detail/modules/ParticleCut.inl
+++ b/corsika/detail/modules/ParticleCut.inl
@@ -15,44 +15,80 @@ namespace corsika {
   ParticleCut::ParticleCut(const HEPEnergyType eEleCut, const HEPEnergyType ePhoCut,
                            const HEPEnergyType eHadCut, const HEPEnergyType eMuCut,
                            bool inv)
-      : electron_energy_cut_(eEleCut)
-      , photon_energy_cut_(ePhoCut)
-      , had_energy_cut_(eHadCut)
-      , mu_energy_cut_(eMuCut)
-      , doCutEm_(false)
+      : doCutEm_(false)
       , doCutInv_(inv)
       , energy_(0_GeV)
       , em_energy_(0_GeV)
       , em_count_(0)
       , inv_energy_(0_GeV)
-      , inv_count_(0) {}
+      , inv_count_(0) {
+    for (auto p : get_all_particles())
+      if (is_hadron(p))
+        set_energy_threshold(p, eHadCut);
+      else if (is_muon(p))
+        set_energy_threshold(p, eMuCut);
+      else if (p == Code::Electron || p == Code::Positron)
+        set_energy_threshold(p, eEleCut);
+      else if (p == Code::Gamma)
+        set_energy_threshold(p, ePhoCut);
+      else if (p == Code::Nucleus)
+        // nuclei have same threshold as hadrons on the nucleon level.
+        set_energy_threshold(p, eHadCut);
+    CORSIKA_LOG_DEBUG(
+        "setting thresholds: electrons = {} GeV, photons = {} GeV, hadrons = {} GeV, "
+        "muons = {} GeV",
+        eEleCut / 1_GeV, ePhoCut / 1_GeV, eHadCut / 1_GeV, eMuCut / 1_GeV);
+    printThresholds();
+  }
 
   ParticleCut::ParticleCut(const HEPEnergyType eHadCut, const HEPEnergyType eMuCut,
                            bool inv)
-      : electron_energy_cut_(0_eV)
-      , photon_energy_cut_(0_eV)
-      , had_energy_cut_(eHadCut)
-      , mu_energy_cut_(eMuCut)
-      , doCutEm_(true)
+      : doCutEm_(true)
       , doCutInv_(inv)
       , energy_(0_GeV)
       , em_energy_(0_GeV)
       , em_count_(0)
       , inv_energy_(0_GeV)
-      , inv_count_(0) {}
+      , inv_count_(0) {
+
+    for (auto p : get_all_particles())
+      if (is_hadron(p))
+        set_energy_threshold(p, eHadCut);
+      else if (is_muon(p))
+        set_energy_threshold(p, eMuCut);
+    CORSIKA_LOG_DEBUG(
+        "setting thresholds: hadrons = {} GeV, "
+        "muons = {} GeV",
+        eHadCut / 1_GeV, eMuCut / 1_GeV);
+    printThresholds();
+  }
 
   ParticleCut::ParticleCut(const HEPEnergyType eCut, bool em, bool inv)
-      : electron_energy_cut_(eCut)
-      , photon_energy_cut_(eCut)
-      , had_energy_cut_(eCut)
-      , mu_energy_cut_(eCut)
-      , doCutEm_(em)
+      : doCutEm_(em)
+      , doCutInv_(inv)
+      , energy_(0_GeV)
+      , em_energy_(0_GeV)
+      , em_count_(0)
+      , inv_energy_(0_GeV)
+      , inv_count_(0) {
+    for (auto p : get_all_particles()) set_energy_threshold(p, eCut);
+    CORSIKA_LOG_DEBUG("setting threshold for all particles to {} GeV", eCut / 1_GeV);
+    printThresholds();
+  }
+
+  ParticleCut::ParticleCut(
+      std::unordered_map<Code const, HEPEnergyType const> const& eCuts, bool em, bool inv)
+      : doCutEm_(em)
       , doCutInv_(inv)
       , energy_(0_GeV)
       , em_energy_(0_GeV)
       , em_count_(0)
       , inv_energy_(0_GeV)
-      , inv_count_(0) {}
+      , inv_count_(0) {
+    set_energy_thresholds(eCuts);
+    CORSIKA_LOG_DEBUG("setting threshold particles individually");
+    printThresholds();
+  }
 
   template <typename TParticle>
   bool ParticleCut::isBelowEnergyCut(TParticle const& vP) const {
@@ -62,16 +98,9 @@ namespace corsika {
     if (pid == Code::Nucleus) {
       // calculate energy per nucleon
       auto const ElabNuc = energyLab / vP.getNuclearA();
-      return (ElabNuc < had_energy_cut_);
-    } else if (pid == Code::Gamma) {
-      return (energyLab < photon_energy_cut_);
-    } else if (pid == Code::Electron || pid == Code::Positron) {
-      return (energyLab < electron_energy_cut_);
-    } else if (is_muon(pid)) {
-      return (energyLab < mu_energy_cut_);
+      return (ElabNuc < get_energy_threshold(pid));
     } else {
-      // assuming the rest are hadrons
-      return (energyLab < had_energy_cut_);
+      return (energyLab < get_energy_threshold(pid));
     }
   }
 
@@ -125,6 +154,11 @@ namespace corsika {
     return ProcessReturn::Ok;
   }
 
+  void ParticleCut::printThresholds() {
+    for(auto p : get_all_particles())
+      CORSIKA_LOG_DEBUG("energy threshold for particle {} is {} GeV", p, get_energy_threshold(p) / 1_GeV);
+  }
+  
   void ParticleCut::showResults() {
     CORSIKA_LOG_INFO(
         " ******************************\n"
diff --git a/corsika/modules/ParticleCut.hpp b/corsika/modules/ParticleCut.hpp
index 11d8508adca3637e4b3d77b061e50acb44181ef1..fe709ee27d470ad385919856c102c09ff6c9e00c 100644
--- a/corsika/modules/ParticleCut.hpp
+++ b/corsika/modules/ParticleCut.hpp
@@ -42,6 +42,10 @@ namespace corsika {
     //! discarded altogether.
     ParticleCut(const HEPEnergyType eCut, bool em, bool inv);
 
+    //! threshold for specific particles redefined. EM and invisible particles can be set
+    //! to be discarded altogether.
+    ParticleCut(std::unordered_map<Code const, HEPEnergyType const> const&eCuts, bool em, bool inv);
+    
     void doSecondaries(corsika::setup::StackView&);
     ProcessReturn doContinuous(corsika::setup::Stack::particle_type& vParticle,
                                corsika::setup::Trajectory const& vTrajectory);
@@ -50,13 +54,14 @@ namespace corsika {
       return meter * std::numeric_limits<double>::infinity();
     }
 
+    void printThresholds();
     void showResults();
     void reset();
 
-    HEPEnergyType getElectronECut() const { return electron_energy_cut_; }
-    HEPEnergyType getPhotonECut() const { return photon_energy_cut_; }
-    HEPEnergyType getMuonECut() const { return mu_energy_cut_; }
-    HEPEnergyType getHadronECut() const { return had_energy_cut_; }
+    HEPEnergyType getElectronECut() const { return get_energy_threshold(Code::Electron); }
+    HEPEnergyType getPhotonECut() const { return get_energy_threshold(Code::Gamma); }
+    HEPEnergyType getMuonECut() const { return get_energy_threshold(Code::MuPlus); }
+    HEPEnergyType getHadronECut() const { return get_energy_threshold(Code::Proton); }
     HEPEnergyType getInvEnergy() const { return inv_energy_; }
     HEPEnergyType getCutEnergy() const { return energy_; }
     HEPEnergyType getEmEnergy() const { return em_energy_; }
@@ -71,10 +76,6 @@ namespace corsika {
     bool isBelowEnergyCut(TParticle const&) const;
 
   private:
-    HEPEnergyType electron_energy_cut_;
-    HEPEnergyType photon_energy_cut_;
-    HEPEnergyType had_energy_cut_;
-    HEPEnergyType mu_energy_cut_;
     bool doCutEm_;
     bool doCutInv_;
     HEPEnergyType energy_ = 0 * electronvolt;
diff --git a/tests/modules/testParticleCut.cpp b/tests/modules/testParticleCut.cpp
index 97eebdc8e8177577d2f4ab5814a0205de0ee627d..5d05f04aff38cd17922e9caca0854d57c704a714 100644
--- a/tests/modules/testParticleCut.cpp
+++ b/tests/modules/testParticleCut.cpp
@@ -25,7 +25,7 @@ using namespace corsika;
 TEST_CASE("ParticleCut", "[processes]") {
 
   logging::set_level(logging::level::info);
-  corsika_logger->set_pattern("[%n:%^%-8l%$] custom pattern: %v");
+  corsika_logger->set_pattern("[%n:%^%-8l%$] %v");
 
   feenableexcept(FE_INVALID);
   using EnvType = setup::Environment;
@@ -171,6 +171,14 @@ TEST_CASE("ParticleCut", "[processes]") {
     CHECK(view.getSize() == 5);
   }
 
+  SECTION("cut low energy:  reset thresholds of arbitrary set of particles") {
+    ParticleCut cut({{Code::Electron, 5_MeV}, {Code::Positron, 50_MeV}}, false, true);
+    CHECK(get_energy_threshold(Code::Electron)!=get_energy_threshold(Code::Positron));
+    CHECK_FALSE(get_energy_threshold(Code::Electron)==Electron::mass);
+    // test default values still correct
+    CHECK(get_energy_threshold(Code::Proton)==5_GeV);
+  }
+
   SECTION("cut on time") {
     ParticleCut cut(20_GeV, false, false);
     const TimeType too_late = 1_s;