diff --git a/examples/corsika.cpp b/examples/corsika.cpp
index 663b7c5621f3be6935798e8d62a57be902ab4e3f..76f8a194b8278c34f78c744ce145c2881fd98bbf 100644
--- a/examples/corsika.cpp
+++ b/examples/corsika.cpp
@@ -58,6 +58,7 @@
 #include <corsika/modules/StackInspector.hpp>
 #include <corsika/modules/TrackWriter.hpp>
 #include <corsika/modules/UrQMD.hpp>
+#include <corsika/modules/thinning/EMThinning.hpp>
 
 #include <corsika/setup/SetupStack.hpp>
 #include <corsika/setup/SetupTrajectory.hpp>
@@ -89,7 +90,7 @@ using EnvType = Environment<EnvironmentInterface>;
 
 using Particle = setup::Stack<EnvType>::particle_type;
 
-void registerRandomStreams(int seed) {
+void registerRandomStreams(long seed) {
   RNGManager<>::getInstance().registerRandomStream("cascade");
   RNGManager<>::getInstance().registerRandomStream("qgsjet");
   RNGManager<>::getInstance().registerRandomStream("sibyll");
@@ -98,6 +99,7 @@ void registerRandomStreams(int seed) {
   RNGManager<>::getInstance().registerRandomStream("pythia");
   RNGManager<>::getInstance().registerRandomStream("urqmd");
   RNGManager<>::getInstance().registerRandomStream("proposal");
+  RNGManager<>::getInstance().registerRandomStream("thinning");
   if (seed == 0) {
     std::random_device rd;
     seed = rd();
@@ -146,6 +148,29 @@ int main(int argc, char** argv) {
       ->default_val(0.)
       ->check(CLI::Range(0., 360.))
       ->group("Primary");
+  app.add_option("--emcut",
+                 "Min. kin. energy of photons, electrons and positrons in tracking (GeV)")
+      ->default_val(50.)
+      ->check(CLI::Range(0.000001, 1.e13))
+      ->group("Config");
+  app.add_option("--hadcut", "Min. kin. energy of hadrons in tracking (GeV)")
+      ->default_val(50.)
+      ->check(CLI::Range(0.000001, 1.e13))
+      ->group("Config");
+  app.add_option("--mucut", "Min. kin. energy of muons in tracking (GeV)")
+      ->default_val(50.)
+      ->check(CLI::Range(0.000001, 1.e13))
+      ->group("Config");
+  app.add_option("--observation-level",
+                 "Height above earth radius of the observation level (in m)")
+      ->default_val(0.)
+      ->check(CLI::Range(-1.e3, 1.e5))
+      ->group("Config");
+  app.add_option("--injection-height",
+                 "Height above earth radius of the injection point (in m)")
+      ->default_val(111.75e3)
+      ->check(CLI::Range(-1.e3, 1.e6))
+      ->group("Config");
   app.add_option("-N,--nevent", nevent, "The number of events/showers to run.")
       ->default_val(1)
       ->check(CLI::PositiveNumber)
@@ -171,6 +196,20 @@ int main(int argc, char** argv) {
       ->default_val("SIBYLL-2.3d")
       ->check(CLI::IsMember({"SIBYLL-2.3d", "QGSJet-II.04", "EPOS-LHC"}))
       ->group("Misc.");
+  app.add_option("--emthin",
+                 "fraction of primary energy at which thinning of EM particles starts")
+      ->default_val(1.e-6)
+      ->check(CLI::Range(0., 1.))
+      ->group("Thinning");
+  app.add_option(
+         "--max-weight",
+         "maximum weight for thinning of EM particles (0 to select Kobal's optimum)")
+      ->default_val(0)
+      ->check(CLI::NonNegativeNumber)
+      ->group("Thinning");
+  bool multithin = false;
+  app.add_flag("--multithin", multithin, "keep thinned particles (with weight=0)")
+      ->group("Thinning");
 
   // parse the command line options into the variables
   CLI11_PARSE(app, argc, argv);
@@ -203,7 +242,7 @@ int main(int argc, char** argv) {
   }
 
   // initialize random number sequence(s)
-  registerRandomStreams(app["--seed"]->as<int>());
+  registerRandomStreams(app["--seed"]->as<long>());
 
   /* === START: SETUP ENVIRONMENT AND ROOT COORDINATE SYSTEM === */
   EnvType env;
@@ -265,8 +304,10 @@ int main(int argc, char** argv) {
   /* === END: CONSTRUCT PRIMARY PARTICLE === */
 
   /* === START: CONSTRUCT GEOMETRY === */
-  auto const observationHeight = 0_km + constants::EarthRadius::Mean;
-  auto const injectionHeight = 111.75_km + constants::EarthRadius::Mean;
+  auto const observationHeight =
+      app["--observation-level"]->as<double>() * 1_m + constants::EarthRadius::Mean;
+  auto const injectionHeight =
+      app["--injection-height"]->as<double>() * 1_m + constants::EarthRadius::Mean;
   auto const t = -observationHeight * cos(thetaRad) +
                  sqrt(-static_pow<2>(sin(thetaRad) * observationHeight) +
                       static_pow<2>(injectionHeight));
@@ -282,6 +323,15 @@ int main(int argc, char** argv) {
   ShowerAxis const showerAxis{injectionPos, (showerCore - injectionPos) * 1.2, env};
   /* === END: CONSTRUCT GEOMETRY === */
 
+  double const emthinfrac = app["--emthin"]->as<double>();
+  double const maxWeight = std::invoke([&]() {
+    if (auto const wm = app["--max-weight"]->as<double>(); wm > 0)
+      return wm;
+    else
+      return emthinfrac * E0 / 1_GeV;
+  });
+  EMThinning thinning{emthinfrac * E0, maxWeight, !multithin};
+
   // create the output manager that we then register outputs with
   OutputManager output(app["--filename"]->as<std::string>());
 
@@ -342,9 +392,17 @@ int main(int argc, char** argv) {
   // hadronic photon interactions in resonance region
   corsika::sophia::InteractionModel sophia;
 
-  HEPEnergyType const emcut = 50_GeV;
-  HEPEnergyType const hadcut = 50_GeV;
-  ParticleCut<SubWriter<decltype(dEdX)>> cut(emcut, emcut, hadcut, hadcut, true, dEdX);
+  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, true, dEdX);
+
+  // tell proposal that we are interested in all energy losses above the emcut
+  set_energy_production_threshold(Code::Electron, emcut);
+  set_energy_production_threshold(Code::Positron, emcut);
+  set_energy_production_threshold(Code::Photon, emcut);
+  set_energy_production_threshold(Code::MuMinus, mucut);
+  set_energy_production_threshold(Code::MuPlus, mucut);
 
   // energy threshold for high energy hadronic model. Affects LE/HE switch for
   // hadron interactions and the hadronic photon model in proposal
@@ -393,7 +451,7 @@ int main(int argc, char** argv) {
   // assemble the final process sequence
   auto sequence = make_sequence(stackInspect, hadronSequence, decaySequence, emCascade,
                                 emContinuous, // trackWriter,
-                                longprof, observationLevel, cut);
+                                longprof, observationLevel, thinning, cut);
   /* === END: SETUP PROCESS LIST === */
 
   // create the cascade object using the default stack and tracking