diff --git a/corsika/framework/core/detail/ParticleProperties.cc b/corsika/framework/core/detail/ParticleProperties.cc
deleted file mode 100644
index a52883bf83b14a97a7a732a700db59eaf502cd8b..0000000000000000000000000000000000000000
--- a/corsika/framework/core/detail/ParticleProperties.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/particles/ParticleProperties.h>
-#include <iostream>
-
-namespace corsika::particles {
-
-  std::ostream& operator<<(std::ostream& stream, corsika::particles::Code const p) {
-    return stream << corsika::particles::GetName(p);
-  }
-
-  Code ConvertFromPDG(PDGCode p) {
-    static_assert(detail::conversionArray.size() % 2 == 1);
-    // this will fail, for the strange case where the maxPDG is negative...
-    unsigned int constexpr maxPDG{(detail::conversionArray.size() - 1) >> 1};
-    auto k = static_cast<PDGCodeType>(p);
-    if ((unsigned int)abs(k) <= maxPDG) {
-      return detail::conversionArray[k + maxPDG];
-    } else {
-      return detail::conversionMap.at(p);
-    }
-  }
-
-} // namespace corsika::particles
diff --git a/corsika/framework/geometry/detail/CoordinateSystem.cc b/corsika/framework/geometry/detail/CoordinateSystem.cc
deleted file mode 100644
index e822267277f9542ba64d7e745691aee986eac62d..0000000000000000000000000000000000000000
--- a/corsika/framework/geometry/detail/CoordinateSystem.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/geometry/CoordinateSystem.h>
-#include <stdexcept>
-
-using namespace corsika::geometry;
-
-/**
- * returns the transformation matrix necessary to transform primitives with coordinates
- * in \a pFrom to \a pTo, e.g.
- * \f$ \vec{v}^{\text{(to)}} = \mathcal{M} \vec{v}^{\text{(from)}} \f$
- * (\f$ \vec{v}^{(.)} \f$ denotes the coordinates/components of the component in
- * the indicated CoordinateSystem).
- */
-EigenTransform CoordinateSystem::GetTransformation(CoordinateSystem const& pFrom,
-                                                   CoordinateSystem const& pTo) {
-  CoordinateSystem const* a{&pFrom};
-  CoordinateSystem const* b{&pTo};
-  CoordinateSystem const* commonBase{nullptr};
-
-  while (a != b && b != nullptr) {
-    a = &pFrom;
-
-    while (a != b && a != nullptr) { a = a->GetReference(); }
-
-    if (a == b) break;
-
-    b = b->GetReference();
-  }
-
-  if (a == b && a != nullptr) {
-    commonBase = a;
-
-  } else {
-    throw std::runtime_error("no connection between coordinate systems found!");
-  }
-
-  EigenTransform t = EigenTransform::Identity();
-  auto* p = &pFrom;
-
-  while (p != commonBase) {
-    t = p->GetTransform() * t;
-    p = p->GetReference();
-  }
-
-  p = &pTo;
-
-  while (p != commonBase) {
-    t = t * p->GetTransform().inverse(Eigen::TransformTraits::Isometry);
-    p = p->GetReference();
-  }
-
-  return t;
-}
diff --git a/corsika/framework/utility/detail/COMBoost.cc b/corsika/framework/utility/detail/COMBoost.cc
deleted file mode 100644
index 5bb4be9da2a2784dc70efa0a7b6b5b1233d3b3f4..0000000000000000000000000000000000000000
--- a/corsika/framework/utility/detail/COMBoost.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/geometry/CoordinateSystem.h>
-#include <corsika/geometry/FourVector.h>
-#include <corsika/geometry/Vector.h>
-#include <corsika/units/PhysicalUnits.h>
-#include <corsika/utl/COMBoost.h>
-#include <corsika/utl/sgn.h>
-#include <corsika/logging/Logging.h>
-
-#include <cmath>
-
-using namespace corsika::utl;
-using namespace corsika::units::si;
-using namespace corsika::geometry;
-
-COMBoost::COMBoost(FourVector<HEPEnergyType, Vector<hepmomentum_d>> const& Pprojectile,
-                   const HEPMassType massTarget)
-    : originalCS_{Pprojectile.GetSpaceLikeComponents().GetCoordinateSystem()}
-    , rotatedCS_{originalCS_.RotateToZ(Pprojectile.GetSpaceLikeComponents())} {
-  auto const pProjectile = Pprojectile.GetSpaceLikeComponents();
-  auto const pProjNormSquared = pProjectile.squaredNorm();
-  auto const pProjNorm = sqrt(pProjNormSquared);
-
-  auto const eProjectile = Pprojectile.GetTimeLikeComponent();
-  auto const massProjectileSquared = eProjectile * eProjectile - pProjNormSquared;
-  auto const s =
-      massTarget * massTarget + massProjectileSquared + 2 * eProjectile * massTarget;
-
-  auto const sqrtS = sqrt(s);
-  auto const sinhEta = -pProjNorm / sqrtS;
-  auto const coshEta = sqrt(1 + pProjNormSquared / s);
-
-  setBoost(coshEta, sinhEta);
-
-  C8LOG_TRACE("COMBoost (1-beta)={}, gamma={}, det={}", 1 - sinhEta / coshEta, coshEta,
-              boost_.determinant() - 1);
-}
-
-COMBoost::COMBoost(geometry::Vector<units::si::hepmomentum_d> const& momentum,
-                   units::si::HEPEnergyType mass)
-    : originalCS_{momentum.GetCoordinateSystem()}
-    , rotatedCS_{originalCS_.RotateToZ(momentum)} {
-  auto const squaredNorm = momentum.squaredNorm();
-  auto const norm = sqrt(squaredNorm);
-  auto const sinhEta = -norm / mass;
-  auto const coshEta = sqrt(1 + squaredNorm / (mass * mass));
-  setBoost(coshEta, sinhEta);
-}
-
-void COMBoost::setBoost(double coshEta, double sinhEta) {
-  boost_ << coshEta, sinhEta, sinhEta, coshEta;
-  inverseBoost_ << coshEta, -sinhEta, -sinhEta, coshEta;
-}
-
-CoordinateSystem const& COMBoost::GetRotatedCS() const { return rotatedCS_; }
diff --git a/corsika/framework/utility/detail/CorsikaFenvDefault.cc b/corsika/framework/utility/detail/CorsikaFenvDefault.cc
deleted file mode 100644
index 4d3426ad6b6c2b3c40e51d7103cec38b5ec12b87..0000000000000000000000000000000000000000
--- a/corsika/framework/utility/detail/CorsikaFenvDefault.cc
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * (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.
- */
-
-// do nothing, functions exist in system libraries
diff --git a/corsika/modules/Sibyll/Decay.cc b/corsika/modules/Sibyll/Decay.cc
deleted file mode 100644
index 844f3fdab9c1f497b87ef0e874ac6c56866f741a..0000000000000000000000000000000000000000
--- a/corsika/modules/Sibyll/Decay.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/sibyll/Decay.h>
-
-#include <corsika/process/sibyll/ParticleConversion.h>
-#include <corsika/process/sibyll/SibStack.h>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using std::make_tuple;
-using std::tuple;
-using std::vector;
-
-using namespace corsika;
-using namespace corsika;
-
-using SetupView = corsika::StackView;
-using SetupProjectile = corsika::StackView::ParticleType;
-using SetupParticle = corsika::Stack::ParticleType;
-
-namespace corsika::sibyll {
-
-  Decay::Decay(const bool sibyll_printout_on)
-      : sibyll_listing_(sibyll_printout_on) {
-    // switch off decays to avoid internal decay chains
-    SetAllStable();
-    // handle all decays by default
-    handleAllDecays_ = true;
-  }
-
-  Decay::Decay(std::set<particles::Code> vHandled)
-      : handleAllDecays_(false)
-      , handledDecays_(vHandled) {
-    SetAllStable();
-  }
-
-  Decay::~Decay() { C8LOG_DEBUG("Sibyll::Decay n={}", count_); }
-
-  bool Decay::CanHandleDecay(const particles::Code vParticleCode) {
-    using namespace corsika::particles;
-    // if known to sibyll and not proton or neutrino it can decay
-    if (vParticleCode == Code::Proton || vParticleCode == Code::AntiProton ||
-        vParticleCode == Code::NuE || vParticleCode == Code::NuMu ||
-        vParticleCode == Code::NuTau || vParticleCode == Code::NuEBar ||
-        vParticleCode == Code::NuMuBar || vParticleCode == Code::NuTauBar ||
-        vParticleCode == Code::Electron || vParticleCode == Code::Positron)
-      return false;
-    else if (process::sibyll::ConvertToSibyllRaw(
-                 vParticleCode)) // non-zero for particles known to sibyll
-      return true;
-    else
-      return false;
-  }
-
-  void Decay::SetHandleDecay(const particles::Code vParticleCode) {
-    handleAllDecays_ = false;
-    C8LOG_DEBUG("Sibyll::Decay: set to handle decay of {}", vParticleCode);
-    if (Decay::CanHandleDecay(vParticleCode))
-      handledDecays_.insert(vParticleCode);
-    else
-      throw std::runtime_error("this decay can not be handled by sibyll!");
-  }
-
-  void Decay::SetHandleDecay(const vector<particles::Code> vParticleList) {
-    handleAllDecays_ = false;
-    for (auto p : vParticleList) Decay::SetHandleDecay(p);
-  }
-
-  bool Decay::IsDecayHandled(const corsika::particles::Code vParticleCode) {
-    if (handleAllDecays_ && Decay::CanHandleDecay(vParticleCode))
-      return true;
-    else
-      return Decay::handledDecays_.find(vParticleCode) != Decay::handledDecays_.end()
-                 ? true
-                 : false;
-  }
-
-  void Decay::SetStable(const vector<particles::Code> vParticleList) {
-    for (auto p : vParticleList) Decay::SetStable(p);
-  }
-
-  void Decay::SetUnstable(const vector<particles::Code> vParticleList) {
-    for (auto p : vParticleList) Decay::SetUnstable(p);
-  }
-
-  bool Decay::IsStable(const particles::Code vCode) {
-    return abs(process::sibyll::ConvertToSibyllRaw(vCode)) <= 0 ? true : false;
-  }
-
-  bool Decay::IsUnstable(const particles::Code vCode) {
-    return abs(process::sibyll::ConvertToSibyllRaw(vCode)) > 0 ? true : false;
-  }
-
-  void Decay::SetDecay(const particles::Code vCode, const bool vMakeUnstable) {
-    vMakeUnstable ? SetUnstable(vCode) : SetStable(vCode);
-  }
-
-  void Decay::SetUnstable(const particles::Code vCode) {
-    C8LOG_DEBUG("Sibyll::Decay: setting {} unstable. ", vCode);
-    const int s_id = abs(process::sibyll::ConvertToSibyllRaw(vCode));
-    s_csydec_.idb[s_id - 1] = abs(s_csydec_.idb[s_id - 1]);
-  }
-
-  void Decay::SetStable(const particles::Code vCode) {
-    C8LOG_DEBUG("Sibyll::Decay: setting {} stable. ", vCode);
-    const int s_id = abs(process::sibyll::ConvertToSibyllRaw(vCode));
-    s_csydec_.idb[s_id - 1] = (-1) * abs(s_csydec_.idb[s_id - 1]);
-  }
-
-  void Decay::SetAllStable() {
-    for (int i = 0; i < 99; ++i) s_csydec_.idb[i] = -1 * abs(s_csydec_.idb[i]);
-  }
-
-  void Decay::SetAllUnstable() {
-    for (int i = 0; i < 99; ++i) s_csydec_.idb[i] = abs(s_csydec_.idb[i]);
-  }
-
-  void Decay::PrintDecayConfig([[maybe_unused]] const particles::Code vCode) {
-    [[maybe_unused]] const int sibCode = process::sibyll::ConvertToSibyllRaw(vCode);
-    [[maybe_unused]] const int absSibCode = abs(sibCode);
-    C8LOG_DEBUG("Decay: Sibyll decay configuration: {} is {}", vCode,
-                (s_csydec_.idb[absSibCode - 1] <= 0) ? "stable" : "unstable");
-  }
-
-  void Decay::PrintDecayConfig() {
-    C8LOG_DEBUG("Sibyll::Decay: decay configuration:");
-    if (handleAllDecays_) {
-      C8LOG_DEBUG("     all particles known to Sibyll are handled by Sibyll::Decay!");
-    } else {
-      for ([[maybe_unused]] auto& pCode : handledDecays_) {
-        C8LOG_DEBUG("      Decay of {}  is handled by Sibyll!", pCode);
-      }
-    }
-  }
-
-  template <>
-  units::si::TimeType Decay::GetLifetime(Particle const& vP) {
-    using namespace units::si;
-
-    const particles::Code pid = vP.GetPID();
-    if (Decay::IsDecayHandled(pid)) {
-      HEPEnergyType E = vP.GetEnergy();
-      HEPMassType m = vP.GetMass();
-
-      const double gamma = E / m;
-
-      const TimeType t0 = particles::GetLifetime(vP.GetPID());
-      auto const lifetime = gamma * t0;
-
-      [[maybe_unused]] const auto mkin =
-          (E * E - vP.GetMomentum().squaredNorm()); // delta_mass(vP.GetMomentum(), E, m);
-      C8LOG_DEBUG("Sibyll::Decay: code: {} ", vP.GetPID());
-      C8LOG_DEBUG("Sibyll::Decay: MinStep: t0: {} ", t0);
-      C8LOG_DEBUG("Sibyll::Decay: MinStep: energy: {} GeV ", E / 1_GeV);
-      C8LOG_DEBUG("Sibyll::Decay: momentum: {} GeV ",
-                  vP.GetMomentum().GetComponents() / 1_GeV);
-      C8LOG_DEBUG("Sibyll::Decay: momentum: shell mass-kin. inv. mass {} {}",
-                  mkin / 1_GeV / 1_GeV, m / 1_GeV * m / 1_GeV);
-      [[maybe_unused]] auto sib_id = process::sibyll::ConvertToSibyllRaw(vP.GetPID());
-      C8LOG_DEBUG("Sibyll::Decay: sib mass: {}", get_sibyll_mass2(sib_id));
-      C8LOG_DEBUG("Sibyll::Decay: MinStep: gamma:  {}", gamma);
-      C8LOG_DEBUG("Sibyll::Decay: MinStep: tau {} s: ", lifetime / 1_s);
-
-      return lifetime;
-    } else
-      return std::numeric_limits<double>::infinity() * 1_s;
-  }
-
-  template <>
-  void Decay::DoDecay(SetupView& view) {
-    using geometry::Point;
-    using namespace units::si;
-
-    auto const projectile = view.GetProjectile();
-
-    const particles::Code pCode = projectile.GetPID();
-    // check if sibyll is configured to handle this decay!
-    if (!IsDecayHandled(pCode))
-      throw std::runtime_error("STOP! Sibyll not configured to execute this decay!");
-
-    count_++;
-    SibStack ss;
-    ss.Clear();
-
-    // copy particle to sibyll stack
-    ss.AddParticle(process::sibyll::ConvertToSibyllRaw(pCode), projectile.GetEnergy(),
-                   projectile.GetMomentum(),
-                   // setting particle mass with Corsika values, may be inconsistent
-                   // with sibyll internal values
-                   particles::GetMass(pCode));
-    // remember position
-    Point const decayPoint = projectile.GetPosition();
-    TimeType const t0 = projectile.GetTime();
-    // remember if particles is unstable
-    // auto const priorIsUnstable = IsUnstable(pCode);
-    // switch on decay for this particle
-    SetUnstable(pCode);
-    PrintDecayConfig(pCode);
-
-    // call sibyll decay
-    C8LOG_DEBUG("Decay: calling Sibyll decay routine..");
-    decsib_();
-
-    if (sibyll_listing_) {
-      // print output
-      int print_unit = 6;
-      sib_list_(print_unit);
-    }
-
-    // reset to stable
-    SetStable(pCode);
-
-    // copy particles from sibyll stack to corsika
-    for (auto& psib : ss) {
-      // FOR NOW: skip particles that have decayed in Sibyll, move to iterator?
-      if (psib.HasDecayed()) continue;
-      // add to corsika stack
-      vP.AddSecondary(
-          tuple<particles::Code, units::si::HEPEnergyType, corsika::MomentumVector,
-                geometry::Point, units::si::TimeType>{
-              process::sibyll::ConvertFromSibyll(psib.GetPID()), psib.GetEnergy(),
-              psib.GetMomentum(), decayPoint, t0});
-    }
-    // empty sibyll stack
-    ss.Clear();
-  }
-
-} // namespace corsika::sibyll
diff --git a/corsika/modules/Sibyll/Interaction.cc b/corsika/modules/Sibyll/Interaction.cc
deleted file mode 100644
index 219494e057c4e1a1eb9fba63131ee529905383da..0000000000000000000000000000000000000000
--- a/corsika/modules/Sibyll/Interaction.cc
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/sibyll/Interaction.h>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-#include <corsika/framework/geometry/FourVector.hpp>
-#include <corsika/process/sibyll/ParticleConversion.h>
-#include <corsika/process/sibyll/SibStack.h>
-#include <corsika/process/sibyll/sibyll2.3c.h>
-#include <corsika/framework/utility/COMBoost.hpp>
-
-#include <tuple>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using std::cout;
-using std::endl;
-using std::tuple;
-
-using namespace corsika;
-using namespace corsika;
-using SetupParticle = setup::Stack::StackIterator;
-using SetupProjectile = setup::StackView::StackIterator;
-using Track = Trajectory;
-
-namespace corsika::sibyll {
-
-  bool Interaction::initialized_ = false;
-
-  Interaction::Interaction(const bool sibyll_printout_on)
-      : sibyll_listing_(sibyll_printout_on) {
-    using random::RNGManager;
-
-    // initialize Sibyll
-    if (!initialized_) {
-      sibyll_ini_();
-      initialized_ = true;
-    }
-  }
-
-  Interaction::~Interaction() {
-    C8LOG_DEBUG(fmt::format("Sibyll::Interaction n={}, Nnuc={}", count_, nucCount_));
-  }
-
-  void Interaction::SetAllStable() {
-    for (int i = 0; i < 99; ++i) s_csydec_.idb[i] = -1 * abs(s_csydec_.idb[i]);
-  }
-
-  tuple<units::si::CrossSectionType, units::si::CrossSectionType>
-  Interaction::GetCrossSection(const particles::Code BeamId,
-                               const particles::Code TargetId,
-                               const units::si::HEPEnergyType CoMenergy) const {
-    using namespace units::si;
-    double sigProd, sigEla, dummy, dum1, dum3, dum4;
-    double dumdif[3];
-    const int iBeam = process::sibyll::GetSibyllXSCode(BeamId);
-    if (!IsValidCoMEnergy(CoMenergy)) {
-      throw std::runtime_error(
-          "Interaction: GetCrossSection: CoM energy outside range for Sibyll!");
-    }
-    const double dEcm = CoMenergy / 1_GeV;
-    if (particles::IsNucleus(TargetId)) {
-      const int iTarget = particles::GetNucleusA(TargetId);
-      if (iTarget > maxTargetMassNumber_ || iTarget == 0)
-        throw std::runtime_error(
-            "Sibyll target outside range. Only nuclei with A<18 are allowed.");
-      sib_sigma_hnuc_(iBeam, iTarget, dEcm, sigProd, dummy, sigEla);
-    } else if (TargetId == particles::Proton::GetCode()) {
-      sib_sigma_hp_(iBeam, dEcm, dum1, sigEla, sigProd, dumdif, dum3, dum4);
-    } else {
-      // no interaction in sibyll possible, return infinite cross section? or throw?
-      sigProd = std::numeric_limits<double>::infinity();
-      sigEla = std::numeric_limits<double>::infinity();
-    }
-    return std::make_tuple(sigProd * 1_mb, sigEla * 1_mb);
-  }
-
-  template <>
-  units::si::GrammageType Interaction::GetInteractionLength(Particle const& vP) const {
-
-    using namespace units;
-    using namespace units::si;
-    using namespace geometry;
-
-    // coordinate system, get global frame of reference
-    CoordinateSystem& rootCS =
-        RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-
-    const particles::Code corsikaBeamId = vP.GetPID();
-
-    // beam particles for sibyll : 1, 2, 3 for p, pi, k
-    // read from cross section code table
-    const bool kInteraction = process::sibyll::CanInteract(corsikaBeamId);
-
-    // FOR NOW: assume target is at rest
-    MomentumVector pTarget(rootCS, {0_GeV, 0_GeV, 0_GeV});
-
-    // total momentum and energy
-    HEPEnergyType Elab = vP.GetEnergy() + constants::nucleonMass;
-    MomentumVector pTotLab(rootCS, {0_GeV, 0_GeV, 0_GeV});
-    pTotLab += vP.GetMomentum();
-    pTotLab += pTarget;
-    auto const pTotLabNorm = pTotLab.norm();
-    // calculate cm. energy
-    const HEPEnergyType ECoM = sqrt(
-        (Elab + pTotLabNorm) * (Elab - pTotLabNorm)); // binomial for numerical accuracy
-
-    C8LOG_DEBUG(
-        fmt::format("Interaction: LambdaInt: \n"
-                    " input energy: {} GeV "
-                    " beam can interact: {} "
-                    " beam pid: {}",
-                    vP.GetEnergy() / 1_GeV, kInteraction, vP.GetPID()));
-
-    // TODO: move limits into variables
-    // FR: removed && Elab >= 8.5_GeV
-    if (kInteraction && IsValidCoMEnergy(ECoM)) {
-
-      // get target from environment
-      /*
-        the target should be defined by the Environment,
-        ideally as full particle object so that the four momenta
-        and the boosts can be defined..
-      */
-
-      auto const* currentNode = vP.GetNode();
-      const auto& mediumComposition =
-          currentNode->GetModelProperties().GetNuclearComposition();
-
-      si::CrossSectionType weightedProdCrossSection = mediumComposition.WeightedSum(
-          [=](particles::Code targetID) -> si::CrossSectionType {
-            return std::get<0>(this->GetCrossSection(corsikaBeamId, targetID, ECoM));
-          });
-
-      C8LOG_DEBUG(
-          fmt::format("Interaction: "
-                      "IntLength: weighted CrossSection (mb): {} ",
-                      weightedProdCrossSection / 1_mb));
-
-      // calculate interaction length in medium
-      GrammageType const int_length = mediumComposition.GetAverageMassNumber() *
-                                      units::constants::u / weightedProdCrossSection;
-      C8LOG_DEBUG(
-          fmt::format("Interaction: "
-                      "interaction length (g/cm2): {} ",
-                      int_length / (0.001_kg) * 1_cm * 1_cm));
-
-      return int_length;
-    }
-
-    return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
-  }
-
-  /**
-     In this function SIBYLL is called to produce one event. The
-     event is copied (and boosted) into the shower lab frame.
-   */
-
-  template <>
-  process::EProcessReturn Interaction::DoInteraction(SetupView& view) {
-    using namespace utl;
-    using namespace units;
-    using namespace units::si;
-    using namespace geometry;
-
-    auto const projectile = view.GetProjectile();
-
-    const auto corsikaBeamId = projectile.GetPID();
-
-    if (particles::IsNucleus(corsikaBeamId)) {
-      // nuclei handled by different process, this should not happen
-      throw std::runtime_error("Nuclear projectile are not handled by SIBYLL!");
-    }
-
-    // position and time of interaction, not used in Sibyll
-    Point const pOrig = projectile.GetPosition();
-    TimeType const tOrig = projectile.GetTime();
-
-    // define projectile
-    HEPEnergyType const eProjectileLab = projectile.GetEnergy();
-    auto const pProjectileLab = projectile.GetMomentum();
-    const CoordinateSystem& originalCS = pProjectileLab.GetCoordinateSystem();
-
-    C8LOG_DEBUG(
-        "ProcessSibyll: "
-        "DoInteraction: pid {} interaction ",
-        corsikaBeamId);
-
-    // define target
-    // for Sibyll is always a single nucleon
-    // FOR NOW: target is always at rest
-    const auto eTargetLab = 0_GeV + constants::nucleonMass;
-    const auto pTargetLab = MomentumVector(originalCS, 0_GeV, 0_GeV, 0_GeV);
-    const FourVector PtargLab(eTargetLab, pTargetLab);
-
-    C8LOG_DEBUG(
-        "Interaction: ebeam lab: {} GeV"
-        "Interaction: pbeam lab: {} GeV",
-        eProjectileLab / 1_GeV, pProjectileLab.GetComponents());
-    C8LOG_DEBUG(
-        "Interaction: etarget lab: {} GeV "
-        "Interaction: ptarget lab: {} GeV",
-        eTargetLab / 1_GeV, pTargetLab.GetComponents() / 1_GeV);
-
-    const FourVector PprojLab(eProjectileLab, pProjectileLab);
-
-    // define target kinematics in lab frame
-    // define boost to and from CoM frame
-    // CoM frame definition in Sibyll projectile: +z
-    COMBoost const boost(PprojLab, constants::nucleonMass);
-    auto const& csPrime = boost.GetRotatedCS();
-
-    // just for show:
-    // boost projecticle
-    [[maybe_unused]] auto const PprojCoM = boost.toCoM(PprojLab);
-
-    // boost target
-    [[maybe_unused]] auto const PtargCoM = boost.toCoM(PtargLab);
-
-    C8LOG_DEBUG(
-        "Interaction: ebeam CoM: {} GeV "
-        "Interaction: pbeam CoM: {} GeV ",
-        PprojCoM.GetTimeLikeComponent() / 1_GeV,
-        PprojCoM.GetSpaceLikeComponents().GetComponents(csPrime) / 1_GeV);
-    C8LOG_DEBUG(
-        "Interaction: etarget CoM: {} GeV "
-        "Interaction: ptarget CoM: {} GeV ",
-        PtargCoM.GetTimeLikeComponent() / 1_GeV,
-        PtargCoM.GetSpaceLikeComponents().GetComponents(csPrime) / 1_GeV);
-
-    C8LOG_DEBUG("Interaction: position of interaction: {} ", pOrig.GetCoordinates());
-    C8LOG_DEBUG("Interaction: time: {} ", tOrig);
-
-    HEPEnergyType Etot = eProjectileLab + eTargetLab;
-    MomentumVector Ptot = projectile.GetMomentum();
-    // invariant mass, i.e. cm. energy
-    HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.squaredNorm());
-
-    // sample target mass number
-    auto const* currentNode = projectile.GetNode();
-    auto const& mediumComposition =
-        currentNode->GetModelProperties().GetNuclearComposition();
-    // get cross sections for target materials
-    /*
-      Here we read the cross section from the interaction model again,
-      should be passed from GetInteractionLength if possible
-     */
-    //#warning reading interaction cross section again, should not be necessary
-    auto const& compVec = mediumComposition.GetComponents();
-    std::vector<CrossSectionType> cross_section_of_components(compVec.size());
-
-    for (size_t i = 0; i < compVec.size(); ++i) {
-      auto const targetId = compVec[i];
-      const auto [sigProd, sigEla] = GetCrossSection(corsikaBeamId, targetId, Ecm);
-      [[maybe_unused]] const auto& dummy_sigEla = sigEla;
-      cross_section_of_components[i] = sigProd;
-    }
-
-    const auto targetCode =
-        mediumComposition.SampleTarget(cross_section_of_components, RNG_);
-    C8LOG_DEBUG("Interaction: target selected: {} ", targetCode);
-    /*
-      FOR NOW: allow nuclei with A<18 or protons only.
-      when medium composition becomes more complex, approximations will have to be
-      allowed air in atmosphere also contains some Argon.
-    */
-    int targetSibCode = -1;
-    if (IsNucleus(targetCode)) targetSibCode = GetNucleusA(targetCode);
-    if (targetCode == particles::Proton::GetCode()) targetSibCode = 1;
-    C8LOG_DEBUG("Interaction: sibyll code: {}", targetSibCode);
-    if (targetSibCode > maxTargetMassNumber_ || targetSibCode < 1)
-      throw std::runtime_error(
-          "Sibyll target outside range. Only nuclei with A<18 or protons are "
-          "allowed.");
-
-    // beam id for sibyll
-    const int kBeam = process::sibyll::ConvertToSibyllRaw(corsikaBeamId);
-
-    C8LOG_DEBUG(
-        "Interaction: "
-        " DoInteraction: E(GeV): {} "
-        " Ecm(GeV): {} ",
-        eProjectileLab / 1_GeV, Ecm / 1_GeV);
-    if (Ecm > GetMaxEnergyCoM())
-      throw std::runtime_error("Interaction::DoInteraction: CoM energy too high!");
-    // FR: removed eProjectileLab < 8.5_GeV ||
-    if (Ecm < GetMinEnergyCoM()) {
-      C8LOG_DEBUG(
-          "Interaction: "
-          " DoInteraction: should have dropped particle.. "
-          "THIS IS AN ERROR");
-      throw std::runtime_error("energy too low for SIBYLL");
-    } else {
-      count_++;
-      // Sibyll does not know about units..
-      const double sqs = Ecm / 1_GeV;
-      // running sibyll, filling stack
-      sibyll_(kBeam, targetSibCode, sqs);
-
-      if (sibyll_listing_) {
-        // print final state
-        int print_unit = 6;
-        sib_list_(print_unit);
-        nucCount_ += get_nwounded() - 1;
-      }
-
-      // add particles from sibyll to stack
-      // link to sibyll stack
-      SibStack ss;
-
-      MomentumVector Plab_final(originalCS, {0.0_GeV, 0.0_GeV, 0.0_GeV});
-      HEPEnergyType Elab_final = 0_GeV, Ecm_final = 0_GeV;
-      for (auto& psib : ss) {
-
-        // abort on particles that have decayed in Sibyll. Should not happen!
-        if (psib.HasDecayed())
-          throw std::runtime_error("found particle that decayed in SIBYLL!");
-
-        // transform 4-momentum to lab. frame
-        // note that the momentum needs to be rotated back
-        auto const tmp = psib.GetMomentum().GetComponents();
-        auto const pCoM = Vector<hepmomentum_d>(csPrime, tmp);
-        HEPEnergyType const eCoM = psib.GetEnergy();
-        auto const Plab = boost.fromCoM(FourVector(eCoM, pCoM));
-        auto const p3lab = Plab.GetSpaceLikeComponents();
-        assert(p3lab.GetCoordinateSystem() == originalCS); // just to be sure!
-
-        // add to corsika stack
-        auto pnew = view.AddSecondary(
-            make_tuple(process::sibyll::ConvertFromSibyll(psib.GetPID()),
-                       Plab.GetTimeLikeComponent(), p3lab, pOrig, tOrig));
-
-        Plab_final += pnew.GetMomentum();
-        Elab_final += pnew.GetEnergy();
-        Ecm_final += psib.GetEnergy();
-      }
-      C8LOG_DEBUG(
-          "conservation (all GeV):"
-          "Ecm_initial(per nucleon)={}, Ecm_final(per nucleon)={}, "
-          "Elab_initial={}, Elab_final={}, "
-          "diff (%)={}, "
-          "E in nucleons={}, "
-          "Plab_initial={}, "
-          "Plab_final={} ",
-          Ecm / 1_GeV, Ecm_final * 2. / (get_nwounded() + 1) / 1_GeV, Etot / 1_GeV,
-          Elab_final / 1_GeV, (Elab_final / Etot / get_nwounded() - 1) * 100,
-          constants::nucleonMass * get_nwounded() / 1_GeV,
-          (pProjectileLab / 1_GeV).GetComponents(), (Plab_final / 1_GeV).GetComponents());
-    }
-    return process::EProcessReturn::eOk;
-  }
-
-} // namespace corsika::sibyll
diff --git a/corsika/modules/Sibyll/NuclearInteraction.cc b/corsika/modules/Sibyll/NuclearInteraction.cc
deleted file mode 100644
index 2ec18ed40d8f7b8a915978e6be0a6e39ab9d3162..0000000000000000000000000000000000000000
--- a/corsika/modules/Sibyll/NuclearInteraction.cc
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/sibyll/Interaction.h>
-#include <corsika/process/sibyll/NuclearInteraction.h>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-#include <corsika/framework/geometry/FourVector.hpp>
-#include <corsika/process/sibyll/nuclib.h>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include <corsika/framework/utility/COMBoost.hpp>
-
-#include <set>
-#include <sstream>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using std::cout;
-using std::endl;
-using std::tuple;
-using std::vector;
-
-using namespace corsika;
-using namespace corsika;
-using Particle = Stack::ParticleType;        // StackIterator; // ParticleType;
-using Projectile = StackView::StackIterator; // StackView::ParticleType;
-using Track = Trajectory;
-
-namespace corsika::sibyll {
-
-  template <>
-  NuclearInteraction<setup::Environment>::~NuclearInteraction() {
-    C8LOG_DEBUG(
-        fmt::format("Nuclib::NuclearInteraction n={} Nnuc={}", count_, nucCount_));
-  }
-
-  template <>
-  void NuclearInteraction<SetupEnvironment>::PrintCrossSectionTable(
-      corsika::Code pCode) {
-    using namespace corsika;
-    const int k = targetComponentsIndex_.at(pCode);
-    Code pNuclei[] = {Code::Helium, Code::Lithium7, Code::Oxygen,
-                      Code::Neon,   Code::Argon,    Code::Iron};
-    std::ostringstream table;
-    table << "Nuclear CrossSectionTable pCode=" << pCode << " :\n en/A ";
-    for (auto& j : pNuclei) table << std::setw(9) << j;
-    table << "\n";
-
-    // loop over energy bins
-    for (unsigned int i = 0; i < GetNEnergyBins(); ++i) {
-      table << " " << i << "  ";
-      for (auto& n : pNuclei) {
-        auto const j = GetNucleusA(n);
-        table << " " << std::setprecision(5) << std::setw(8)
-              << cnucsignuc_.sigma[j - 1][k][i];
-      }
-      table << "\n";
-    }
-    C8LOG_DEBUG(table.str());
-  }
-
-  template <>
-  void NuclearInteraction<SetupEnvironment>::InitializeNuclearCrossSections() {
-    using namespace corsika;
-    using namespace units::si;
-
-    auto& universe = *(environment_.GetUniverse());
-
-    auto const allElementsInUniverse = std::invoke([&]() {
-      std::set<particles::Code> allElementsInUniverse;
-      auto collectElements = [&](auto& vtn) {
-        if (vtn.HasModelProperties()) {
-          auto const& comp =
-              vtn.GetModelProperties().GetNuclearComposition().GetComponents();
-          for (auto const c : comp) allElementsInUniverse.insert(c);
-        }
-      };
-      universe.walk(collectElements);
-      return allElementsInUniverse;
-    });
-
-    C8LOG_DEBUG("NuclearInteraction: initializing nuclear cross sections...");
-
-    // loop over target components, at most 4!!
-    int k = -1;
-    for (auto& ptarg : allElementsInUniverse) {
-      ++k;
-      C8LOG_DEBUG(fmt::format("NuclearInteraction: init target component: {}", ptarg));
-      const int ib = GetNucleusA(ptarg);
-      if (!hadronicInteraction_.IsValidTarget(ptarg)) {
-        C8LOG_DEBUG(fmt::format(
-            "NuclearInteraction::InitializeNuclearCrossSections: target nucleus? id={}",
-            ptarg));
-        throw std::runtime_error(
-            " target can not be handled by hadronic interaction model! ");
-      }
-      targetComponentsIndex_.insert(std::pair<Code, int>(ptarg, k));
-      // loop over energies, fNEnBins log. energy bins
-      for (unsigned int i = 0; i < GetNEnergyBins(); ++i) {
-        // hard coded energy grid, has to be aligned to definition in signuc2!!, no
-        // comment..
-        const units::si::HEPEnergyType Ecm = pow(10., 1. + 1. * i) * 1_GeV;
-        // get p-p cross sections
-        auto const protonId = Code::Proton;
-        auto const [siginel, sigela] =
-            hadronicInteraction_.GetCrossSection(protonId, protonId, Ecm);
-        const double dsig = siginel / 1_mb;
-        const double dsigela = sigela / 1_mb;
-        // loop over projectiles, mass numbers from 2 to fMaxNucleusAProjectile
-        for (unsigned int j = 1; j < gMaxNucleusAProjectile_; ++j) {
-          const int jj = j + 1;
-          double sig_out, dsig_out, sigqe_out, dsigqe_out;
-          sigma_mc_(jj, ib, dsig, dsigela, gNSample_, sig_out, dsig_out, sigqe_out,
-                    dsigqe_out);
-          // write to table
-          cnucsignuc_.sigma[j][k][i] = sig_out;
-          cnucsignuc_.sigqe[j][k][i] = sigqe_out;
-        }
-      }
-    }
-    C8LOG_DEBUG(
-        fmt::format("NuclearInteraction: cross sections for {} "
-                    " components initialized!",
-                    targetComponentsIndex_.size()));
-    for (auto& ptarg : allElementsInUniverse) { PrintCrossSectionTable(ptarg); }
-  }
-
-  template <>
-  units::si::CrossSectionType
-  NuclearInteraction<setup::Environment>::ReadCrossSectionTable(
-      const int ia, particles::Code pTarget, units::si::HEPEnergyType elabnuc) {
-    using namespace corsika;
-    using namespace units::si;
-    const int ib = targetComponentsIndex_.at(pTarget) + 1; // table index in fortran
-    auto const ECoMNuc = sqrt(2. * corsika::units::constants::nucleonMass * elabnuc);
-    if (ECoMNuc < GetMinEnergyPerNucleonCoM() || ECoMNuc > GetMaxEnergyPerNucleonCoM())
-      throw std::runtime_error("NuclearInteraction: energy outside tabulated range!");
-    const double e0 = elabnuc / 1_GeV;
-    double sig;
-    C8LOG_DEBUG(fmt::format("ReadCrossSectionTable: {} {} {}", ia, ib, e0));
-    signuc2_(ia, ib, e0, sig);
-    C8LOG_DEBUG(fmt::format("ReadCrossSectionTable: sig={}", sig));
-    return sig * 1_mb;
-  }
-
-  // TODO: remove elastic cross section?
-  template <>
-  template <>
-  tuple<units::si::CrossSectionType, units::si::CrossSectionType>
-  NuclearInteraction<setup::Environment>::GetCrossSection(
-      Particle const& vP, const particles::Code TargetId) {
-    using namespace units::si;
-    if (vP.GetPID() != particles::Code::Nucleus)
-      throw std::runtime_error(
-          "NuclearInteraction: GetCrossSection: particle not a nucleus!");
-
-    const unsigned int iBeamA = vP.GetNuclearA();
-    HEPEnergyType LabEnergyPerNuc = vP.GetEnergy() / iBeamA;
-    C8LOG_DEBUG(
-        fmt::format("NuclearInteraction: GetCrossSection: called with: beamNuclA={} "
-                    " TargetId={} LabEnergyPerNuc={}GeV ",
-                    iBeamA, TargetId, LabEnergyPerNuc / 1_GeV));
-
-    // use nuclib to calc. nuclear cross sections
-    // TODO: for now assumes air with hard coded composition
-    // extend to arbitrary mixtures, requires smarter initialization
-    // get nuclib projectile code: nucleon number
-    if (iBeamA > GetMaxNucleusAProjectile() || iBeamA < 2) {
-      C8LOG_DEBUG(
-          "NuclearInteraction: beam nucleus outside allowed range for NUCLIB!"
-          "A=" +
-          std::to_string(iBeamA));
-      throw std::runtime_error(
-          "NuclearInteraction: GetCrossSection: beam nucleus outside allowed range for "
-          "NUCLIB!");
-    }
-
-    if (hadronicInteraction_.IsValidTarget(TargetId)) {
-      auto const sigProd = ReadCrossSectionTable(iBeamA, TargetId, LabEnergyPerNuc);
-      C8LOG_DEBUG("cross section (mb): " + std::to_string(sigProd / 1_mb));
-      return std::make_tuple(sigProd, 0_mb);
-    } else {
-      throw std::runtime_error("target outside range.");
-    }
-    return std::make_tuple(std::numeric_limits<double>::infinity() * 1_mb,
-                           std::numeric_limits<double>::infinity() * 1_mb);
-  }
-
-  template <>
-  template <>
-  units::si::GrammageType NuclearInteraction<setup::Environment>::GetInteractionLength(
-      Particle const& vP) {
-
-    using namespace units;
-    using namespace units::si;
-    using namespace geometry;
-
-    // coordinate system, get global frame of reference
-    CoordinateSystem& rootCS =
-        RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-
-    const particles::Code corsikaBeamId = vP.GetPID();
-
-    if (corsikaBeamId != particles::Code::Nucleus) {
-      // check if target-style nucleus (enum), these are not allowed as projectile
-      if (particles::IsNucleus(corsikaBeamId))
-        throw std::runtime_error(
-            "NuclearInteraction: GetInteractionLength: Wrong nucleus type. Nuclear "
-            "projectiles should use NuclearStackExtension!");
-      else {
-        // no nuclear interaction
-        return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
-      }
-    }
-
-    // read from cross section code table
-
-    // FOR NOW: assume target is at rest
-    corsika::MomentumVector pTarget(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV});
-
-    // total momentum and energy
-    HEPEnergyType Elab = vP.GetEnergy() + constants::nucleonMass;
-    unsigned int const nuclA = vP.GetNuclearA();
-    auto const ElabNuc = vP.GetEnergy() / nuclA;
-
-    corsika::MomentumVector pTotLab(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV});
-    pTotLab += vP.GetMomentum();
-    pTotLab += pTarget;
-    auto const pTotLabNorm = pTotLab.norm();
-    // calculate cm. energy
-    [[maybe_unused]] const HEPEnergyType ECoM = sqrt(
-        (Elab + pTotLabNorm) * (Elab - pTotLabNorm)); // binomial for numerical accuracy
-    auto const ECoMNN = sqrt(2. * ElabNuc * constants::nucleonMass);
-    C8LOG_DEBUG(
-        fmt::format("NuclearInteraction: LambdaInt: \n"
-                    " input energy: {}GeV\n"
-                    " input energy CoM: {}GeV\n"
-                    " beam pid: {}\n"
-                    " beam A: {}\n"
-                    " input energy per nucleon: {}GeV\n"
-                    " input energy CoM per nucleon: {}GeV ",
-                    Elab / 1_GeV, ECoM / 1_GeV, particles::GetName(corsikaBeamId), nuclA,
-                    ElabNuc / 1_GeV, ECoMNN / 1_GeV));
-    //      throw std::runtime_error("stop here");
-
-    // energy limits
-    // TODO: values depend on hadronic interaction model !! this is sibyll specific
-    if (ElabNuc >= 8.5_GeV && ECoMNN >= gMinEnergyPerNucleonCoM_ &&
-        ECoMNN < gMaxEnergyPerNucleonCoM_) {
-
-      // get target from environment
-      /*
-        the target should be defined by the Environment,
-        ideally as full particle object so that the four momenta
-        and the boosts can be defined..
-      */
-      auto const* const currentNode = vP.GetNode();
-      auto const& mediumComposition =
-          currentNode->GetModelProperties().GetNuclearComposition();
-      // determine average interaction length
-      // weighted sum
-      int i = -1;
-      si::CrossSectionType weightedProdCrossSection = 0_mb;
-      // get weights of components from environment/medium
-      const auto& w = mediumComposition.GetFractions();
-      // loop over components in medium
-      for (auto const targetId : mediumComposition.GetComponents()) {
-        i++;
-        C8LOG_DEBUG("NuclearInteraction: get interaction length for target: " +
-                    particles::GetName(targetId));
-        auto const [productionCrossSection, elaCrossSection] =
-            GetCrossSection(vP, targetId);
-        [[maybe_unused]] auto& dummy_elaCrossSection = elaCrossSection;
-
-        C8LOG_DEBUG(
-            "NuclearInteraction: "
-            "IntLength: nuclib return (mb): " +
-            std::to_string(productionCrossSection / 1_mb));
-        weightedProdCrossSection += w[i] * productionCrossSection;
-      }
-      C8LOG_DEBUG(
-          "NuclearInteraction: "
-          "IntLength: weighted CrossSection (mb): " +
-          std::to_string(weightedProdCrossSection / 1_mb));
-
-      // calculate interaction length in medium
-      GrammageType const int_length = mediumComposition.GetAverageMassNumber() *
-                                      units::constants::u / weightedProdCrossSection;
-      C8LOG_DEBUG(
-          "NuclearInteraction: "
-          "interaction length (g/cm2): " +
-          std::to_string(int_length * (1_cm * 1_cm / (0.001_kg))));
-
-      return int_length;
-    } else {
-      return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
-    }
-  }
-
-  template <>
-  template <>
-  process::EProcessReturn NuclearInteraction<setup::Environment>::DoInteraction(
-      View& view) {
-
-    // this routine superimposes different nucleon-nucleon interactions
-    // in a nucleus-nucleus interaction, based the SIBYLL routine SIBNUC
-
-    using namespace units;
-    using namespace utl;
-    using namespace units::si;
-    using namespace geometry;
-
-    auto projectile = view.GetProjectile();
-
-    const auto ProjId = projectile.GetPID();
-    // TODO: calculate projectile mass in nuclearStackExtension
-    //      const auto ProjMass = projectile.GetMass();
-    C8LOG_DEBUG("NuclearInteraction: DoInteraction: called with:" +
-                particles::GetName(ProjId));
-
-    // check if target-style nucleus (enum)
-    if (ProjId != particles::Code::Nucleus)
-      throw std::runtime_error(
-          "NuclearInteraction: DoInteraction: Wrong nucleus type. Nuclear projectiles "
-          "should use NuclearStackExtension!");
-
-    auto const ProjMass = projectile.GetNuclearZ() * particles::Proton::GetMass() +
-                          (projectile.GetNuclearA() - projectile.GetNuclearZ()) *
-                              particles::Neutron::GetMass();
-    C8LOG_DEBUG("NuclearInteraction: projectile mass: " +
-                std::to_string(ProjMass / 1_GeV));
-
-    count_++;
-
-    const CoordinateSystem& rootCS =
-        RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-
-    // position and time of interaction, not used in NUCLIB
-    Point pOrig = projectile.GetPosition();
-    TimeType tOrig = projectile.GetTime();
-
-    C8LOG_DEBUG(
-        fmt::format("Interaction: position of interaction: {}", pOrig.GetCoordinates()));
-    C8LOG_DEBUG("Interaction: time: " + std::to_string(tOrig / 1_s));
-
-    // projectile nucleon number
-    const unsigned int kAProj = projectile.GetNuclearA();
-    if (kAProj > GetMaxNucleusAProjectile())
-      throw std::runtime_error("Projectile nucleus too large for NUCLIB!");
-
-    // kinematics
-    // define projectile nucleus
-    HEPEnergyType const eProjectileLab = projectile.GetEnergy();
-    auto const pProjectileLab = projectile.GetMomentum();
-    const FourVector PprojLab(eProjectileLab, pProjectileLab);
-
-    C8LOG_DEBUG(
-        fmt::format("NuclearInteraction: eProj lab: {} "
-                    "pProj lab: {} ",
-                    eProjectileLab / 1_GeV, pProjectileLab.GetComponents() / 1_GeV));
-    ;
-
-    // define projectile nucleon
-    HEPEnergyType const eProjectileNucLab = projectile.GetEnergy() / kAProj;
-    auto const pProjectileNucLab = projectile.GetMomentum() / kAProj;
-    const FourVector PprojNucLab(eProjectileNucLab, pProjectileNucLab);
-
-    C8LOG_DEBUG(fmt::format(
-        "NuclearInteraction: eProjNucleon lab (GeV): {} "
-        "pProjNucleon lab (GeV): {}",
-        eProjectileNucLab / 1_GeV, pProjectileNucLab.GetComponents() / 1_GeV));
-
-    // define target
-    // always a nucleon
-    // target is always at rest
-    const auto eTargetNucLab = 0_GeV + constants::nucleonMass;
-    const auto pTargetNucLab =
-        corsika::MomentumVector(rootCS, 0_GeV, 0_GeV, 0_GeV);
-    const FourVector PtargNucLab(eTargetNucLab, pTargetNucLab);
-
-    C8LOG_DEBUG(
-        fmt::format("NuclearInteraction: etarget lab(GeV): {}"
-                    "NuclearInteraction: ptarget lab(GeV): {} ",
-                    eTargetNucLab / 1_GeV, pTargetNucLab.GetComponents() / 1_GeV));
-
-    // center-of-mass energy in nucleon-nucleon frame
-    auto const PtotNN4 = PtargNucLab + PprojNucLab;
-    HEPEnergyType EcmNN = PtotNN4.GetNorm();
-    C8LOG_DEBUG("NuclearInteraction: nuc-nuc cm energy: " +
-                std::to_string(EcmNN / 1_GeV));
-
-    if (!hadronicInteraction_.IsValidCoMEnergy(EcmNN)) {
-      C8LOG_DEBUG(
-          "NuclearInteraction: nuc-nuc. CoM energy too low for hadronic "
-          "interaction model!");
-      throw std::runtime_error("NuclearInteraction: DoInteraction: energy too low!");
-    }
-
-    // define boost to NUCLEON-NUCLEON frame
-    COMBoost const boost(PprojNucLab, constants::nucleonMass);
-    // boost projecticle
-    [[maybe_unused]] auto const PprojNucCoM = boost.toCoM(PprojNucLab);
-
-    // boost target
-    [[maybe_unused]] auto const PtargNucCoM = boost.toCoM(PtargNucLab);
-
-    C8LOG_DEBUG(
-        fmt::format("Interaction: ebeam CoM: {} "
-                    ", pbeam CoM: {}",
-                    PprojNucCoM.GetTimeLikeComponent() / 1_GeV,
-                    PprojNucCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV));
-    C8LOG_DEBUG(
-        fmt::format("Interaction: etarget CoM: {}"
-                    ", ptarget CoM: {}",
-                    PtargNucCoM.GetTimeLikeComponent() / 1_GeV,
-                    PtargNucCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV));
-
-    // sample target nucleon number
-    //
-    // proton stand-in for nucleon
-    const auto beamId = particles::Proton::GetCode();
-    auto const* const currentNode = projectile.GetNode();
-    const auto& mediumComposition =
-        currentNode->GetModelProperties().GetNuclearComposition();
-    C8LOG_DEBUG("get nucleon-nucleus cross sections for target materials..");
-    // get cross sections for target materials
-    // using nucleon-target-nucleus cross section!!!
-    /*
-      Here we read the cross section from the interaction model again,
-      should be passed from GetInteractionLength if possible
-    */
-    auto const& compVec = mediumComposition.GetComponents();
-    vector<si::CrossSectionType> cross_section_of_components(compVec.size());
-
-    for (size_t i = 0; i < compVec.size(); ++i) {
-      auto const targetId = compVec[i];
-      C8LOG_DEBUG("target component: " + particles::GetName(targetId));
-      C8LOG_DEBUG("beam id: " + particles::GetName(beamId));
-      const auto [sigProd, sigEla] =
-          hadronicInteraction_.GetCrossSection(beamId, targetId, EcmNN);
-      cross_section_of_components[i] = sigProd;
-      [[maybe_unused]] auto sigElaCopy = sigEla; // ONLY TO AVOID COMPILER WARNINGS
-    }
-
-    const auto targetCode =
-        mediumComposition.SampleTarget(cross_section_of_components, RNG_);
-    C8LOG_DEBUG("Interaction: target selected: " + particles::GetName(targetCode));
-    /*
-      FOR NOW: allow nuclei with A<18 or protons only.
-      when medium composition becomes more complex, approximations will have to be
-      allowed air in atmosphere also contains some Argon.
-    */
-    int kATarget = -1;
-    if (IsNucleus(targetCode)) kATarget = GetNucleusA(targetCode);
-    if (targetCode == particles::Proton::GetCode()) kATarget = 1;
-    C8LOG_DEBUG("NuclearInteraction: nuclib target code: " + std::to_string(kATarget));
-    if (!hadronicInteraction_.IsValidTarget(targetCode))
-      throw std::runtime_error("target outside range. ");
-    // end of target sampling
-
-    // superposition
-    C8LOG_DEBUG("NuclearInteraction: sampling nuc. multiple interaction structure.. ");
-    // get nucleon-nucleon cross section
-    // (needed to determine number of nucleon-nucleon scatterings)
-    const auto protonId = particles::Proton::GetCode();
-    const auto [prodCrossSection, elaCrossSection] =
-        hadronicInteraction_.GetCrossSection(protonId, protonId, EcmNN);
-    const double sigProd = prodCrossSection / 1_mb;
-    const double sigEla = elaCrossSection / 1_mb;
-    // sample number of interactions (only input variables, output in common cnucms)
-    // nuclear multiple scattering according to glauber (r.i.p.)
-    int_nuc_(kATarget, kAProj, sigProd, sigEla);
-
-    C8LOG_DEBUG(
-        fmt::format("number of nucleons in target           : {}\n"
-                    "number of wounded nucleons in target   : {}\n"
-                    "number of nucleons in projectile       : {}\n"
-                    "number of wounded nucleons in project. : {}\n"
-                    "number of inel. nuc.-nuc. interactions : {}\n"
-                    "number of elastic nucleons in target   : {}\n"
-                    "number of elastic nucleons in project. : {}\n"
-                    "impact parameter: {}",
-                    kATarget, cnucms_.na, kAProj, cnucms_.nb, cnucms_.ni, cnucms_.nael,
-                    cnucms_.nbel, cnucms_.b));
-
-    // calculate fragmentation
-    C8LOG_DEBUG("calculating nuclear fragments..");
-    // number of interactions
-    // include elastic
-    const int nElasticNucleons = cnucms_.nbel;
-    const int nInelNucleons = cnucms_.nb;
-    const int nIntProj = nInelNucleons + nElasticNucleons;
-    const double impactPar = cnucms_.b; // only needed to avoid passing common var.
-    int nFragments = 0;
-    // number of fragments is limited to 60
-    int AFragments[60];
-    // call fragmentation routine
-    // input: target A, projectile A, number of int. nucleons in projectile, impact
-    // parameter (fm) output: nFragments, AFragments in addition the momenta ar stored
-    // in pf in common fragments, neglected
-    fragm_(kATarget, kAProj, nIntProj, impactPar, nFragments, AFragments);
-
-    // this should not occur but well :)
-    if (nFragments > (int)GetMaxNFragments())
-      throw std::runtime_error("Number of nuclear fragments in NUCLIB exceeded!");
-
-    C8LOG_DEBUG("number of fragments: " + std::to_string(nFragments));
-    for (int j = 0; j < nFragments; ++j)
-      C8LOG_DEBUG(fmt::format("fragment {}: A={} px={} py={} pz={}", j, AFragments[j],
-                              fragments_.ppp[j][0], fragments_.ppp[j][1],
-                              fragments_.ppp[j][2]));
-
-    C8LOG_DEBUG("adding nuclear fragments to particle stack..");
-    // put nuclear fragments on corsika stack
-    for (int j = 0; j < nFragments; ++j) {
-      particles::Code specCode;
-      const int nuclA = AFragments[j];
-      // get Z from stability line
-      const int nuclZ = int(nuclA / 2.15 + 0.7);
-
-      // TODO: do we need to catch single nucleons??
-      if (nuclA == 1)
-        // TODO: sample neutron or proton
-        specCode = particles::Code::Proton;
-      else
-        specCode = particles::Code::Nucleus;
-
-      // TODO: mass of nuclei?
-      const HEPMassType mass =
-          particles::Proton::GetMass() * nuclZ +
-          (nuclA - nuclZ) * particles::Neutron::GetMass(); // this neglects binding energy
-
-      C8LOG_DEBUG("NuclearInteraction: adding fragment: " + particles::GetName(specCode));
-      C8LOG_DEBUG("NuclearInteraction: A,Z: " + std::to_string(nuclA) + ", " +
-                  std::to_string(nuclZ));
-      C8LOG_DEBUG("NuclearInteraction: mass: " + std::to_string(mass / 1_GeV));
-
-      // CORSIKA 7 way
-      // spectators inherit momentum from original projectile
-      const double mass_ratio = mass / ProjMass;
-
-      C8LOG_DEBUG("NuclearInteraction: mass ratio " + std::to_string(mass_ratio));
-
-      auto const Plab = PprojLab * mass_ratio;
-
-      C8LOG_DEBUG(fmt::format("NuclearInteraction: fragment momentum: {}",
-                              Plab.GetSpaceLikeComponents().GetComponents() / 1_GeV));
-
-      if (nuclA == 1)
-        // add nucleon
-        projectile.AddSecondary(make_tuple(specCode, Plab.GetTimeLikeComponent(),
-                                           Plab.GetSpaceLikeComponents(), pOrig, tOrig));
-      else
-        // add nucleus
-        vP.AddSecondary(tuple<particles::Code, units::si::HEPEnergyType,
-                              corsika::MomentumVector, geometry::Point,
-                              units::si::TimeType, unsigned short, unsigned short>{
-            specCode, Plab.GetTimeLikeComponent(), Plab.GetSpaceLikeComponents(), pOrig,
-            tOrig, nuclA, nuclZ});
-    }
-
-    // add elastic nucleons to corsika stack
-    // TODO: the elastic interaction could be external like the inelastic interaction,
-    // e.g. use existing ElasticModel
-    C8LOG_DEBUG("adding elastically scattered nucleons to particle stack..");
-    for (int j = 0; j < nElasticNucleons; ++j) {
-      // TODO: sample proton or neutron
-      auto const elaNucCode = particles::Code::Proton;
-
-      // CORSIKA 7 way
-      // elastic nucleons inherit momentum from original projectile
-      // neglecting momentum transfer in interaction
-      const double mass_ratio = particles::GetMass(elaNucCode) / ProjMass;
-      auto const Plab = PprojLab * mass_ratio;
-
-      vP.AddSecondary(
-          tuple<particles::Code, units::si::HEPEnergyType, corsika::MomentumVector,
-                geometry::Point, units::si::TimeType>{
-              elaNucCode, Plab.GetTimeLikeComponent(), Plab.GetSpaceLikeComponents(),
-              pOrig, tOrig});
-    }
-
-    // add inelastic interactions
-    C8LOG_DEBUG("calculate inelastic nucleon-nucleon interactions..");
-    for (int j = 0; j < nInelNucleons; ++j) {
-      // TODO: sample neutron or proton
-      auto pCode = particles::Proton::GetCode();
-      // temporarily add to stack, will be removed after interaction in DoInteraction
-      cout << "inelastic interaction no. " << j << endl;
-      auto inelasticNucleon = vP.AddSecondary(
-          tuple<particles::Code, units::si::HEPEnergyType, corsika::MomentumVector,
-                geometry::Point, units::si::TimeType>{
-              pCode, PprojNucLab.GetTimeLikeComponent(),
-              PprojNucLab.GetSpaceLikeComponents(), pOrig, tOrig});
-      // create inelastic interaction
-      cout << "calling HadronicInteraction..." << endl;
-      hadronicInteraction_.DoInteraction(inelasticNucleon);
-    }
-
-    C8LOG_DEBUG("NuclearInteraction: DoInteraction: done");
-
-    return process::EProcessReturn::eOk;
-  }
-
-} // namespace corsika::sibyll
diff --git a/corsika/modules/Sibyll/ParticleConversion.cc b/corsika/modules/Sibyll/ParticleConversion.cc
deleted file mode 100644
index 2e73f3a66373bb16d8dfe3b2cf330c2f52d6d1ad..0000000000000000000000000000000000000000
--- a/corsika/modules/Sibyll/ParticleConversion.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/process/sibyll/ParticleConversion.h>
-
-using namespace corsika::sibyll;
-
-corsika::units::si::HEPMassType corsika::process::sibyll::GetSibyllMass(
-    corsika::particles::Code const pCode) {
-  using namespace corsika::units;
-  using namespace corsika::units::si;
-  if (pCode == corsika::particles::Code::Nucleus)
-    throw std::runtime_error("Cannot GetMass() of particle::Nucleus -> unspecified");
-  auto sCode = ConvertToSibyllRaw(pCode);
-  if (sCode == 0)
-    throw std::runtime_error("GetSibyllMass: unknown particle!");
-  else
-    return sqrt(get_sibyll_mass2(sCode)) * 1_GeV;
-}
diff --git a/corsika/modules/Sibyll/code_generator.py b/corsika/modules/Sibyll/code_generator.py
deleted file mode 100755
index 22cb11022741597b6807c844766dcf0158f24365..0000000000000000000000000000000000000000
--- a/corsika/modules/Sibyll/code_generator.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python3
-
-# (c) Copyright 2018-2019 CORSIKA Project, corsika-project@lists.kit.edu
-#
-# See file AUTHORS for a list of contributors.
-#
-# 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.
-
-
-import pickle, sys, itertools
-
-
-
-def load_particledb(filename):
-    '''
-    loads the pickled particle_db (which is an OrderedDict)
-    '''
-    with open(filename, "rb") as f:
-        particle_db = pickle.load(f)
-    return particle_db
-
-
-
-def read_sibyll_codes(filename, particle_db):
-    '''
-    reads to sibyll codes data file
-
-    For particls known to sibyll, add 'sibyll_code' and 'sibyll_xsType' to particle_db
-    '''
-    with open(filename) as f:
-        for line in f:
-            line = line.strip()
-            if len(line)==0 or line[0] == '#':
-                continue            
-            identifier, sib_code, canInteractFlag, xsType = line.split()
-            try:
-                particle_db[identifier]["sibyll_code"] = int(sib_code)
-                particle_db[identifier]["sibyll_xsType"] = xsType
-            except KeyError as e:
-                raise Exception("Identifier '{:s}' not found in particle_db".format(identifier))
-
-
-            
-
-def generate_sibyll_enum(particle_db):
-    '''
-     generates the enum to access sibyll particles by readable names
-    '''
-    output = "enum class SibyllCode : int8_t {\n"
-    for identifier, pData in particle_db.items():
-        if 'sibyll_code' in pData:
-            output += "  {:s} = {:d},\n".format(identifier, pData['sibyll_code'])
-    output += "};\n"
-    return output
-
-
-
-def generate_corsika2sibyll(particle_db):    
-    '''
-    generates the look-up table to convert corsika codes to sibyll codes
-    '''
-    string = "std::array<SibyllCode, {:d}> constexpr corsika2sibyll = {{\n".format(len(particle_db))
-    for identifier, pData in particle_db.items():
-        if 'sibyll_code' in pData:
-            string += "  SibyllCode::{:s}, \n".format(identifier)
-        else:
-            string += "  SibyllCode::Unknown, // {:s}\n".format(identifier + ' not implemented in SIBYLL')
-    string += "};\n"
-    return string
-    
-
-
-def generate_corsika2sibyll_xsType(particle_db):    
-    '''
-    generates the look-up table to convert corsika codes to sibyll codes
-    '''
-    string = "std::array<SibyllXSClass, {:d}> constexpr corsika2sibyllXStype = {{\n".format(len(particle_db))
-    for identifier, pData in particle_db.items():
-        if 'sibyll_xsType' in pData:
-            string += "  SibyllXSClass::{:s}, // {:s}\n".format(pData['sibyll_xsType'], identifier)
-        else:
-            string += "  SibyllXSClass::CannotInteract, // {:s}\n".format(identifier + ' not implemented in SIBYLL')
-    string += "};\n"
-    return string
-
-
-def generate_sibyll2corsika(particle_db) :
-    '''
-    generates the look-up table to convert sibyll codes to corsika codes    
-    '''
-    string = ""
-    
-    minID = 0
-    for identifier, pData in particle_db.items() :
-        if 'sibyll_code' in pData:
-            minID = min(minID, pData['sibyll_code'])
-
-    string += "SibyllCodeIntType constexpr minSibyll = {:d};\n\n".format(minID)
-
-    pDict = {}
-    for identifier, pData in particle_db.items() :
-        if 'sibyll_code' in pData:
-            sib_code = pData['sibyll_code'] - minID
-            pDict[sib_code] = identifier
-    
-    nPart = max(pDict.keys()) - min(pDict.keys()) + 1
-    string += "std::array<corsika::Code, {:d}> constexpr sibyll2corsika = {{\n".format(nPart)
-    
-    for iPart in range(nPart) :
-        if iPart in pDict:
-            identifier = pDict[iPart]
-        else:
-            identifier = "Unknown"
-        string += "  corsika::Code::{:s}, \n".format(identifier)
-    
-    string += "};\n"
-    return string
-
-if __name__ == "__main__":
-    if len(sys.argv) != 3:
-        print("usage: {:s} <particle_db.pkl> <sibyll_codes.dat>".format(sys.argv[0]), file=sys.stderr)
-        sys.exit(1)
-        
-    print("code_generator.py for SIBYLL")
-    
-    particle_db = load_particledb(sys.argv[1])
-    read_sibyll_codes(sys.argv[2], particle_db)
-    
-    with open("Generated.inc", "w") as f:
-        print("// this file is automatically generated\n// edit at your own risk!\n", file=f)
-        print(generate_sibyll_enum(particle_db), file=f)
-        print(generate_corsika2sibyll(particle_db), file=f)
-        print(generate_sibyll2corsika(particle_db), file=f)
-        print(generate_corsika2sibyll_xsType(particle_db), file=f)
diff --git a/corsika/modules/Sibyll/sibyll_codes.dat b/corsika/modules/Sibyll/sibyll_codes.dat
deleted file mode 100644
index d8cce42e494585023d460a0a50635a12d44139fd..0000000000000000000000000000000000000000
--- a/corsika/modules/Sibyll/sibyll_codes.dat
+++ /dev/null
@@ -1,132 +0,0 @@
-# input file for particle conversion to/from SIBYLL
-# the format of this file is: "corsika-identifier" "sibyll-id" "can-interact-in-sibyll" "cross-section-type"
-
-# The unknown particle is to handle all particles that are not known to SIBYLL.
-# It is important that sibyll-id does not overlap with any existing sibyll particle!
-# Be careful
-Unknown                  0       0       CannotInteract
-
-# Here is the list of particles known to sibyll 
-Electron                 3       0       CannotInteract
-Positron                 2       0       CannotInteract
-NuE                      15      0       CannotInteract
-NuEBar                   16      0       CannotInteract
-MuMinus                  5       0       CannotInteract
-MuPlus                   4       0       CannotInteract
-NuMu                     17      0       CannotInteract
-NuMuBar                  18      0       CannotInteract
-TauMinus                 91      0       CannotInteract
-TauPlus                  90      0       CannotInteract
-NuTau                    92      0       CannotInteract
-NuTauBar                 93      0       CannotInteract
-Gamma                    1       0       CannotInteract
-Pi0                      6       1       Pion
-#                        rho0    could interact but sibyll has no cross section/interaction length. was used for gamma had int
-Rho0                     27      0       CannotInteract
-K0Long                   11      1       Kaon
-K0                       21      0       Kaon
-K0Bar                    22      0       Kaon
-PiPlus                   7       1       Pion
-PiMinus                  8       1       Pion
-RhoPlus                  25      0       CannotInteract
-RhoMinus                 26      0       CannotInteract
-Eta                      23      0       CannotInteract
-EtaPrime                 24      0       CannotInteract
-Pi1300Plus               62      0       CannotInteract
-Pi1300Minus              63      0       CannotInteract
-Pi1300_0                 61      0       CannotInteract
-Omega                    32      0       CannotInteract
-K0Short                  12      1       Kaon
-KStar0                   30      0       CannotInteract
-KStar0Bar                31      0       CannotInteract
-KPlus                    9       1       Kaon
-KMinus                   10      1       Kaon
-KStarPlus                28      0       CannotInteract
-KStarMinus               29      0       CannotInteract
-KStar0_1430_0            66      0       CannotInteract
-KStar0_1430_0Bar         67      0       CannotInteract
-KStar0_1430_Plus         64      0       CannotInteract
-KStar0_1430_MinusBar     65      0       CannotInteract
-DPlus                    59      1       Kaon
-DMinus                   60      1       Kaon
-DStarPlus                78      0       CannotInteract
-DStarMinus               79      0       CannotInteract
-D0                       71      1       Kaon
-D0Bar                    72      1       Kaon
-DStar0                   80      0       CannotInteract
-DStar0Bar                81      0       CannotInteract
-DsPlus                   74      1       Kaon
-DsMinus                  75      1       Kaon
-DStarSPlus               76      0       CannotInteract
-DStarSMinus              77      0       CannotInteract
-EtaC                     73      0       CannotInteract
-Neutron                  14      1       Baryon
-AntiNeutron              -14     1       Baryon
-Delta0                   42      0       CannotInteract
-Delta0Bar                -42     0       CannotInteract
-DeltaMinus               43      0       CannotInteract
-DeltaPlusBar             -43     0       CannotInteract
-Proton                   13      1       Baryon
-AntiProton               -13     1       Baryon
-N1440Plus                51      0       CannotInteract
-N1440MinusBar            -51     0       CannotInteract
-N1440_0                  52      0       CannotInteract
-N1440_0Bar               -52     0       CannotInteract
-N1710Plus                53      0       CannotInteract
-N1710MinusBar            -53     0       CannotInteract
-N1710_0                  54      0       CannotInteract
-N1710_0Bar               -54     0       CannotInteract
-DeltaPlus                41      0       CannotInteract
-DeltaMinusBar            -41     0       CannotInteract
-DeltaPlusPlus            40      0       CannotInteract
-DeltaMinusMinusBar       -40     0       CannotInteract
-SigmaMinus               36      1       Baryon
-SigmaPlusBar             -36     1       Baryon
-SigmaStarMinus           46      0       CannotInteract
-SigmaStarPlusBar         -46     0       CannotInteract
-SigmaStarPlus            44      0       CannotInteract
-SigmaStarMinusBar        -44     0       CannotInteract
-SigmaStar0               45      0       CannotInteract
-SigmaStar0Bar            -45     0       CannotInteract
-Lambda0                  39      1       Baryon
-Lambda0Bar               -39     1       Baryon
-Sigma0                   35      1       Baryon
-Sigma0Bar                -35     1       Baryon
-SigmaPlus                34      1       Baryon
-SigmaMinusBar            -34     1       Baryon
-XiMinus                  38      1       Baryon
-XiPlusBar                -38     1       Baryon
-Xi0                      37      1       Baryon
-Xi0Bar                   -37     1       Baryon
-XiStarMinus              48      0       CannotInteract
-XiStarPlusBar            -48     0       CannotInteract  
-XiStar0                  47      0       CannotInteract
-XiStar0Bar               -47     0       CannotInteract
-OmegaMinus               49      0       CannotInteract
-OmegaPlusBar             -49     0       CannotInteract
-SigmaC0                  86      0       CannotInteract
-SigmaC0Bar               -86     0       CannotInteract
-SigmaStarC0              96      0       CannotInteract
-SigmaStarC0Bar           -96     0       CannotInteract
-LambdaCPlus              89      1       Baryon
-LambdaCMinusBar          -89     1       Baryon
-XiC0                     88      1       Baryon
-XiC0Bar                  -88     1       Baryon
-SigmaCPlus               85      0       CannotInteract
-SigmaCMinusBar           -85     0       CannotInteract
-SigmaStarCPlus           95      0       CannotInteract
-SigmaStarCMinusBar       -95     0       CannotInteract
-SigmaCPlusPlus           84      0       CannotInteract
-SigmaCMinusMinusBar      -84     0       CannotInteract
-SigmaStarCPlusPlus       94      0       CannotInteract
-SigmaStarCMinusMinusBar  -94     0       CannotInteract
-XiCPlus                  87      1       Baryon
-XiCMinusBar              -87     1       Baryon
-XiStarCPlus              97      0       CannotInteract
-XiStarCMinusBar          -97     0       CannotInteract
-XiStarC0                 98      0       CannotInteract
-XiStarC0Bar              -98     0       CannotInteract
-OmegaC0                  99      0       CannotInteract
-OmegaC0Bar               -99     0       CannotInteract
-Jpsi                     83      0       CannotInteract
-Phi                      33      0       CannotInteract
diff --git a/corsika/modules/Sibyll/testSibyll.cc b/corsika/modules/Sibyll/testSibyll.cc
deleted file mode 100644
index cc9245629639004dd9bec1551faeec4eb0c9127e..0000000000000000000000000000000000000000
--- a/corsika/modules/Sibyll/testSibyll.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * (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/process/sibyll/Decay.h>
-#include <corsika/process/sibyll/Interaction.h>
-#include <corsika/process/sibyll/NuclearInteraction.h>
-#include <corsika/process/sibyll/ParticleConversion.h>
-
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <catch2/catch.hpp>
-#include <tuple>
-
-using namespace corsika;
-using namespace corsika::sibyll;
-
-TEST_CASE("Sibyll", "[processes]") {
-
-  SECTION("Sibyll -> Corsika") {
-    CHECK(particles::Electron::GetCode() ==
-          process::sibyll::ConvertFromSibyll(process::sibyll::SibyllCode::Electron));
-  }
-
-  SECTION("Corsika -> Sibyll") {
-    CHECK(process::sibyll::ConvertToSibyll(particles::Electron::GetCode()) ==
-          process::sibyll::SibyllCode::Electron);
-    CHECK(process::sibyll::ConvertToSibyllRaw(particles::Proton::GetCode()) == 13);
-    CHECK(process::sibyll::ConvertToSibyll(particles::XiStarC0::GetCode()) ==
-          process::sibyll::SibyllCode::XiStarC0);
-  }
-
-  SECTION("canInteractInSibyll") {
-
-    CHECK(process::sibyll::CanInteract(particles::Proton::GetCode()));
-    CHECK(process::sibyll::CanInteract(particles::Code::XiCPlus));
-
-    CHECK_FALSE(process::sibyll::CanInteract(particles::Electron::GetCode()));
-    CHECK_FALSE(process::sibyll::CanInteract(particles::SigmaC0::GetCode()));
-
-    CHECK_FALSE(process::sibyll::CanInteract(particles::Nucleus::GetCode()));
-    CHECK_FALSE(process::sibyll::CanInteract(particles::Helium::GetCode()));
-  }
-
-  SECTION("cross-section type") {
-
-    CHECK(process::sibyll::GetSibyllXSCode(particles::Code::Electron) == 0);
-    CHECK(process::sibyll::GetSibyllXSCode(particles::Code::K0Long) == 3);
-    CHECK(process::sibyll::GetSibyllXSCode(particles::Code::SigmaPlus) == 1);
-    CHECK(process::sibyll::GetSibyllXSCode(particles::Code::PiMinus) == 2);
-  }
-
-  SECTION("sibyll mass") {
-
-    CHECK_FALSE(process::sibyll::GetSibyllMass(particles::Code::Electron) == 0_GeV);
-  }
-}
-
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/HomogeneousMedium.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-#include <corsika/process/sibyll/sibyll2.3c.h>
-
-using namespace corsika::units::si;
-using namespace corsika::units;
-
-template <typename TStackView>
-auto sumMomentum(TStackView const& view, geometry::CoordinateSystem const& vCS) {
-  geometry::Vector<hepenergy_d> sum{vCS, 0_eV, 0_eV, 0_eV};
-  for (auto const& p : view) { sum += p.GetMomentum(); }
-  return sum;
-}
-
-TEST_CASE("SibyllInterface", "[processes]") {
-
-  auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen);
-  auto const& cs = *csPtr;
-  [[maybe_unused]] auto const& env_dummy = env;
-  [[maybe_unused]] auto const& node_dummy = nodePtr;
-
-  random::RNGManager::GetInstance().RegisterRandomStream("sibyll");
-
-  SECTION("InteractionInterface - low energy") {
-
-    const HEPEnergyType P0 = 60_GeV;
-    auto [stack, viewPtr] =
-        setup::testing::setupStack(particles::Code::Proton, 0, 0, P0, nodePtr, cs);
-    const auto plab = corsika::stack::MomentumVector(
-        cs, {P0, 0_eV, 0_eV}); // this is secret knowledge about setupStack
-    setup::StackView& view = *viewPtr;
-
-    setup::Stack stack;
-    const HEPEnergyType E0 = 100_GeV;
-    HEPMomentumType P0 =
-        sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass());
-    auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0});
-    geometry::Point pos(cs, 0_m, 0_m, 0_m);
-    auto particle = stack.AddParticle(
-        std::tuple<particles::Code, units::si::HEPEnergyType,
-                   corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-            particles::Code::Proton, E0, plab, pos, 0_ns});
-    particle.SetNode(nodePtr);
-    corsika::SecondaryView view(particle);
-    auto projectile = view.GetProjectile();
-
-    Interaction model;
-
-    [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(view);
-    auto const pSum = sumMomentum(view, cs);
-
-    /*
-      Interactions between hadrons (h) and nuclei (A) in Sibyll are treated in the
-      hadron-nucleon center-of-mass frame (hnCoM). The incoming hadron (h) and
-      nucleon (N) are assumed massless, such that the energy and momentum in the hnCoM are
-      : E_i_cm = 0.5 * SQS and P_i_cm = +- 0.5 * SQS  where i is either the projectile
-      hadron or the target nucleon and SQS is the hadron-nucleon center-of-mass energy.
-
-      The true energies and momenta, accounting for the hadron masses, are: E_i = ( S +
-      m_i**2 - m_j**2 ) / (2 * SQS) and Pcm = +-
-      sqrt( (S-(m_j+m_i)**2) * (s-(m_j-m_i)**2) ) / (2*SQS) where m_i is the projectiles
-      mass and m_j is the target particles mass. In terms of lab. frame variables Pcm =
-      m_j * Plab_i / SQS, where Plab_i is the momentum of the projectile (i) in the lab.
-      and m_j is the mass of the target, i.e. the particle at rest (usually a nucleon).
-
-      Any hadron-nucleus event can contain several nucleon interactions. In case of Nw
-      (number of wounded nucleons) nucleons interacting in the hadron-nucleus interaction,
-      the total energy and momentum in the hadron(i)-nucleon(N) center-of-mass frame are:
-      momentum: p_projectile + p_nucleon_1 + p_nucleon_2 + .... p_nucleon_Nw = -(Nw-1) *
-      Pcm with center-of-mass momentum Pcm = p_projectile = - p_nucleon_i. For the energy:
-      E_projectile + E_nucleon_1 + ... E_nucleon_Nw = E_projectile + Nw * E_nucleon.
-
-      Using the above definitions of center-of-mass energies and momenta this leads to the
-      total energy: E_tot = SQS/2 * (1+Nw) + (m_N**2-m_i**2)/(2*SQS) * (Nw-1) and P_tot
-      = -m_N * Plab_i / SQS * (Nw-1).
-
-      A Lorentztransformation of these quantities to the lab. frame recovers Plab_i for
-      the total momentum, so momentum is exactly conserved, and Elab_i + Nw * m_N for the
-      total energy. Not surprisingly the total energy differs from the total energy before
-      the collision by the mass of the additional nucleons (Nw-1)*m_N. In relative terms
-      the additional energy is entirely negligible and as it is not kinetic energy there
-      is zero influence on the shower development.
-
-      Due to the ommission of the hadron masses in Sibyll, the total energy and momentum
-      in the center-of-mass system after the collision are just: E_tot = SQS/2 * (1+Nw)
-      and P_tot = SQS/2 * (1-Nw). After the Lorentztransformation the total momentum in
-      the lab. thus differs from the initial value by (1-Nw)/2 * ( m_N + m_i**2 / (2 *
-      Plab_i) ) and momentum is NOT conserved. Note however that the second term quickly
-      vanishes as the lab. momentum of the projectile increases. The first term is fixed
-      as it depends only on the number of additional nucleons, in relative terms it is
-      always small at high energies.
-
-      For this reason the numerical precision in these tests is limited to 5% to still
-      pass at low energies and no absolute check is implemented, e.g.
-
-          CHECK(pSum.GetComponents(cs).GetX() / P0 == Approx(1).margin(0.05));
-          CHECK((pSum - plab).norm()/1_GeV == Approx(0).margin(plab.norm() * 0.05/1_GeV));
-
-      /FR'2020
-
-      See also:
-
-      Issue 272 / MR 204
-      https://gitlab.ikp.kit.edu/AirShowerPhysics/corsika/-/merge_requests/204
-
-    */
-
-    CHECK(pSum.GetComponents(cs).GetX() / P0 == Approx(1).margin(0.05));
-    CHECK(pSum.GetComponents(cs).GetY() / 1_GeV == Approx(0).margin(1e-4));
-    CHECK(pSum.GetComponents(cs).GetZ() / 1_GeV == Approx(0).margin(1e-4));
-
-    CHECK((pSum - plab).norm() / 1_GeV == Approx(0).margin(plab.norm() * 0.05 / 1_GeV));
-    CHECK(pSum.norm() / P0 == Approx(1).margin(0.05));
-    [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle);
-    CHECK(length / 1_g * 1_cm * 1_cm == Approx(88.7).margin(0.1));
-    // CHECK(view.getSize() == 20); // also sibyll not stable wrt. to compiler changes
-  }
-
-  SECTION("NuclearInteractionInterface") {
-
-    setup::Stack stack;
-    const HEPEnergyType E0 = 400_GeV;
-    HEPMomentumType P0 =
-        sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass());
-    auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0});
-    geometry::Point pos(cs, 0_m, 0_m, 0_m);
-
-    auto particle =
-        stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                     corsika::MomentumVector, geometry::Point,
-                                     units::si::TimeType, unsigned short, unsigned short>{
-            particles::Code::Nucleus, E0, plab, pos, 0_ns, 4, 2});
-    particle.SetNode(nodePtr);
-    corsika::SecondaryView view(particle);
-    auto projectile = view.GetProjectile();
-
-    Interaction hmodel;
-    NuclearInteraction model(hmodel, *env);
-
-    [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(view);
-    [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle);
-    CHECK(length / 1_g * 1_cm * 1_cm == Approx(44.2).margin(.1));
-    // CHECK(view.getSize() == 11); // also sibyll not stable wrt. to compiler changes
-  }
-
-  SECTION("DecayInterface") {
-
-    setup::Stack stack;
-    const HEPEnergyType E0 = 10_GeV;
-    HEPMomentumType P0 =
-        sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass());
-    auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0});
-    geometry::Point pos(cs, 0_m, 0_m, 0_m);
-    auto particle = stack.AddParticle(
-        std::tuple<particles::Code, units::si::HEPEnergyType,
-                   corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-            particles::Code::Lambda0, E0, plab, pos, 0_ns});
-    corsika::SecondaryView view(particle);
-    auto projectile = view.GetProjectile();
-
-    Decay model;
-    model.PrintDecayConfig();
-    [[maybe_unused]] const TimeType time = model.GetLifetime(particle);
-
-    /*[[maybe_unused]] const process::EProcessReturn ret =*/model.DoDecay(view);
-    // run checks
-    // lambda decays into proton and pi- or neutron and pi+
-    CHECK(stack.getEntries() == 3);
-  }
-
-  SECTION("DecayConfiguration") {
-
-    Decay model({particles::Code::PiPlus, particles::Code::PiMinus});
-    CHECK(model.IsDecayHandled(particles::Code::PiPlus));
-    CHECK(model.IsDecayHandled(particles::Code::PiMinus));
-    CHECK_FALSE(model.IsDecayHandled(particles::Code::KPlus));
-
-    const std::vector<particles::Code> particleTestList = {
-        particles::Code::PiPlus, particles::Code::PiMinus, particles::Code::KPlus,
-        particles::Code::Lambda0Bar, particles::Code::D0Bar};
-
-    // setup decays
-    model.SetHandleDecay(particleTestList);
-    for (auto& pCode : particleTestList) CHECK(model.IsDecayHandled(pCode));
-
-    // individually
-    model.SetHandleDecay(particles::Code::KMinus);
-
-    // possible decays
-    CHECK_FALSE(model.CanHandleDecay(particles::Code::Proton));
-    CHECK_FALSE(model.CanHandleDecay(particles::Code::Electron));
-    CHECK(model.CanHandleDecay(particles::Code::PiPlus));
-    CHECK(model.CanHandleDecay(particles::Code::MuPlus));
-  }
-}
diff --git a/corsika/modules/UrQMD/UrQMD.cc b/corsika/modules/UrQMD/UrQMD.cc
deleted file mode 100644
index a433088454a218c29075975f7bbe673fb35bc9da..0000000000000000000000000000000000000000
--- a/corsika/modules/UrQMD/UrQMD.cc
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/framework/geometry/QuantityVector.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/process/urqmd/UrQMD.h>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <algorithm>
-#include <array>
-#include <cassert>
-#include <cmath>
-#include <fstream>
-#include <functional>
-#include <random>
-#include <sstream>
-
-using namespace corsika::UrQMD;
-using namespace corsika::units::si;
-
-UrQMD::UrQMD() { iniurqmd_(); }
-
-using SetupStack = corsika::Stack;
-using SetupParticle = corsika::Stack::StackIterator;
-using SetupProjectile = corsika::StackView::StackIterator;
-
-CrossSectionType UrQMD::GetCrossSection(particles::Code vProjectileCode,
-                                        corsika::Code vTargetCode,
-                                        HEPEnergyType vLabEnergy, int vAProjectile = 1) {
-  // the following is a translation of ptsigtot() into C++
-  if (vProjectileCode != particles::Code::Nucleus &&
-      !IsNucleus(vTargetCode)) { // both particles are "special"
-    auto const mProj = particles::GetMass(vProjectileCode);
-    auto const mTar = particles::GetMass(vTargetCode);
-    double sqrtS = sqrt(units::si::detail::static_pow<2>(mProj) +
-                        units::si::detail::static_pow<2>(mTar) + 2 * vLabEnergy * mTar) *
-                   (1 / 1_GeV);
-
-    // we must set some UrQMD globals first...
-    auto const [ityp, iso3] = ConvertToUrQMD(projectileCode);
-    inputs_.spityp[0] = ityp;
-    inputs_.spiso3[0] = iso3;
-
-    auto const [itypTar, iso3Tar] = ConvertToUrQMD(targetCode);
-    inputs_.spityp[1] = itypTar;
-    inputs_.spiso3[1] = iso3Tar;
-
-    int one = 1;
-    int two = 2;
-    int three = 3;
-
-    double const totalXS = sigtot_(one, two, sqrtS);
-
-    // subtract elastic cross-section as in ptsigtot()
-    int itypmn, itypmx, iso3mn, iso3mx;
-    if (ityp < itypTar) {
-      itypmn = ityp;
-      itypmx = itypTar;
-
-      iso3mn = iso3;
-      iso3mx = iso3Tar;
-    } else {
-      itypmx = ityp;
-      itypmn = itypTar;
-
-      iso3mx = iso3;
-      iso3mn = iso3Tar;
-    }
-
-    int isigline = collclass_(itypmx, iso3mx, itypmn, iso3mn);
-    int iline = readsigmaln_(three, one, isigline);
-    double sigEl;
-    double massProj = mProj / 1_GeV;
-    double massTar = mTar / 1_GeV;
-
-    crossx_(iline, sqrtS, ityp, iso3, massProj, itypTar, iso3Tar, massTar, sigEl);
-
-    if (totalXS > sigEl) {
-      return (totalXS - sigEl) * 1_mb;
-    } else {
-      return sigEl * 0_mb;
-    }
-  } else {
-    int const Ap = projectileA;
-    int const At = IsNucleus(targetCode) ? particles::GetNucleusA(targetCode) : 1;
-
-    double const maxImpact = nucrad_(Ap) + nucrad_(At) + 2 * options_.CTParam[30 - 1];
-    return 10_mb * M_PI * units::static_pow<2>(maxImpact);
-    // is a constant cross-section really reasonable?
-  }
-}
-
-template <typename TParticle> // need template here, as this is called both with
-                              // SetupParticle as well as SetupProjectile
-CrossSectionType UrQMD::GetCrossSection(TParticle const& vProjectile,
-                                        corsika::Code vTargetCode) const {
-  // TODO: return 0 for non-hadrons?
-
-  auto const projectileCode = vProjectile.GetPID();
-  auto const projectileEnergyLab = vProjectile.GetEnergy();
-
-  if (projectileCode == particles::Code::K0Long) {
-    return 0.5 *
-           (GetCrossSection(particles::Code::K0, vTargetCode, projectileEnergyLab) +
-            GetCrossSection(particles::Code::K0Bar, vTargetCode, projectileEnergyLab));
-  }
-
-  return GetTabulatedCrossSection(projectileCode, targetCode, projectileEnergyLab);
-}
-
-bool UrQMD::CanInteract(particles::Code code) const {
-  // According to the manual, UrQMD can use all mesons, baryons and nucleons
-  // which are modeled also as input particles. I think it is safer to accept
-  // only the usual long-lived species as input.
-
-  // Interactions with nucleus projectiles are possible in principle with UrQMD
-  // but right now we don't have access to the inelastic (production) cross-section,
-  // so we unfortunately have to forbid these interactions for the time being.
-
-  static particles::Code const validProjectileCodes[] = {
-      particles::Code::Proton,      particles::Code::AntiProton, particles::Code::Neutron,
-      particles::Code::AntiNeutron, particles::Code::PiPlus,     particles::Code::PiMinus,
-      particles::Code::KPlus,       particles::Code::KMinus,     particles::Code::K0Short,
-      particles::Code::K0Long};
-
-  return std::find(std::cbegin(validProjectileCodes), std::cend(validProjectileCodes),
-                   code) != std::cend(validProjectileCodes);
-}
-
-GrammageType UrQMD::GetInteractionLength(SetupParticle const& particle) const {
-  if (!CanInteract(particle.GetPID())) {
-    // we could do the canInteract check in GetCrossSection, too but if
-    // we do it here we have the advantage of avoiding the loop
-    return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
-  }
-
-  auto const& mediumComposition =
-      particle.GetNode()->GetModelProperties().GetNuclearComposition();
-  using namespace std::placeholders;
-
-  CrossSectionType const weightedProdCrossSection = mediumComposition.WeightedSum(
-      std::bind(&UrQMD::GetCrossSection<decltype(particle)>, this, particle, _1));
-
-  return mediumComposition.GetAverageMassNumber() * units::constants::u /
-         weightedProdCrossSection;
-}
-
-corsika::EProcessReturn UrQMD::DoInteraction(SetupProjectile& vProjectile) {
-  using namespace units::si;
-
-  auto const projectile = view.GetProjectile();
-
-  auto projectileCode = projectile.GetPID();
-  auto const projectileEnergyLab = projectile.GetEnergy();
-  auto const& projectileMomentumLab = projectile.GetMomentum();
-  auto const& projectilePosition = projectile.GetPosition();
-  auto const projectileTime = projectile.GetTime();
-
-  C8LOG_DEBUG("UrQMD::DoInteraction pid={} E={} GeV", projectileCode,
-              projectileEnergyLab / 1_GeV);
-
-  // sample target particle
-  auto const& mediumComposition =
-      projectile.GetNode()->GetModelProperties().GetNuclearComposition();
-  auto const componentCrossSections = std::invoke([&]() {
-    auto const& components = mediumComposition.GetComponents();
-    std::vector<CrossSectionType> crossSections;
-    crossSections.reserve(components.size());
-
-    for (auto const c : components) {
-      crossSections.push_back(GetCrossSection(projectile, c));
-    }
-
-    return crossSections;
-  });
-
-  auto const targetCode = mediumComposition.SampleTarget(componentCrossSections, rng_);
-  auto const targetA = particles::GetNucleusA(targetCode);
-  auto const targetZ = particles::GetNucleusZ(targetCode);
-
-  inputs_.nevents = 1;
-  sys_.eos = 0; // could be configurable in principle
-  inputs_.outsteps = 1;
-  sys_.nsteps = 1;
-
-  // initialization regarding projectile
-  if (particles::Code::Nucleus == projectileCode) {
-    // is this everything?
-    inputs_.prspflg = 0;
-
-    sys_.Ap = projectile.GetNuclearA();
-    sys_.Zp = projectile.GetNuclearZ();
-    rsys_.ebeam = (projectileEnergyLab - projectile.GetMass()) * (1 / 1_GeV) /
-                  projectile.GetNuclearA();
-
-    rsys_.bdist = nucrad_(targetA) + nucrad_(sys_.Ap) + 2 * options_.CTParam[30 - 1];
-
-    int const id = 1;
-    cascinit_(sys_.Zp, sys_.Ap, id);
-  } else {
-    inputs_.prspflg = 1;
-    sys_.Ap = 1; // even for non-baryons this has to be set, see vanilla UrQMD.f
-    rsys_.bdist = nucrad_(targetA) + nucrad_(1) + 2 * options_.CTParam[30 - 1];
-    rsys_.ebeam = (projectileEnergyLab - projectile.GetMass()) * (1 / 1_GeV);
-
-    if (projectileCode == particles::Code::K0Long ||
-        projectileCode == particles::Code::K0Short) {
-      projectileCode = booleanDist_(rng_) ? particles::Code::K0 : particles::Code::K0Bar;
-    }
-
-    auto const [ityp, iso3] = ConvertToUrQMD(projectileCode);
-    // todo: conversion of K_long/short into strong eigenstates;
-    inputs_.spityp[0] = ityp;
-    inputs_.spiso3[0] = iso3;
-  }
-
-  // initilazation regarding target
-  if (particles::IsNucleus(targetCode)) {
-    sys_.Zt = targetZ;
-    sys_.At = targetA;
-    inputs_.trspflg = 0; // nucleus as target
-    int const id = 2;
-    cascinit_(sys_.Zt, sys_.At, id);
-  } else {
-    inputs_.trspflg = 1; // special particle as target
-    auto const [ityp, iso3] = ConvertToUrQMD(targetCode);
-    inputs_.spityp[1] = ityp;
-    inputs_.spiso3[1] = iso3;
-  }
-
-  int iflb = 0; // flag for retrying interaction in case of empty event, 0 means retry
-  urqmd_(iflb);
-
-  // now retrieve secondaries from UrQMD
-  auto const& originalCS = projectileMomentumLab.GetCoordinateSystem();
-  geometry::CoordinateSystem const zAxisFrame =
-      originalCS.RotateToZ(projectileMomentumLab);
-
-  for (int i = 0; i < sys_.npart; ++i) {
-    auto code = ConvertFromUrQMD(isys_.ityp[i], isys_.iso3[i]);
-    if (code == particles::Code::K0 || code == particles::Code::K0Bar) {
-      code = booleanDist_(rng_) ? particles::Code::K0Short : particles::Code::K0Long;
-    }
-
-    // "coor_.p0[i] * 1_GeV" is likely off-shell as UrQMD doesn't preserve masses well
-    auto momentum = geometry::Vector(
-        zAxisFrame,
-        geometry::QuantityVector<dimensionless_d>{coor_.px[i], coor_.py[i], coor_.pz[i]} *
-            1_GeV);
-
-    auto const energy = sqrt(momentum.squaredNorm() + square(particles::GetMass(code)));
-
-    momentum.rebase(originalCS); // transform back into standard lab frame
-    C8LOG_DEBUG(" Secondary {} code {} p={} GeV", i, code,
-                momentum.GetComponents() / 1_GeV);
-
-    view.AddSecondary(
-        std::make_tuple(code, energy, momentum, projectilePosition, projectileTime));
-  }
-
-  C8LOG_DEBUG("UrQMD generated {} secondaries!", sys_.npart);
-
-  return process::EProcessReturn::eOk;
-}
-
-/**
- * the random number generator function of UrQMD
- */
-double corsika::UrQMD::ranf_(int&) {
-  static corsika::RNG& rng =
-      corsika::RNGManager::GetInstance().GetRandomStream("UrQMD");
-  static std::uniform_real_distribution<double> dist;
-
-  return dist(rng);
-}
-
-corsika::Code corsika::UrQMD::ConvertFromUrQMD(int vItyp, int vIso3) {
-  int const pdgInt =
-      pdgid_(vItyp, vIso3); // use the conversion function provided by UrQMD
-  if (pdgInt == 0) {        // pdgid_ returns 0 on error
-    throw std::runtime_error("UrQMD pdgid() returned 0");
-  }
-  auto const pdg = static_cast<particles::PDGCode>(pdgInt);
-  return particles::ConvertFromPDG(pdg);
-}
-
-std::pair<int, int> corsika::UrQMD::ConvertToUrQMD(
-    corsika::Code code) {
-  static const std::map<int, std::pair<int, int>> mapPDGToUrQMD{
-      // data mostly from github.com/afedynitch/ParticleDataTool
-      {22, {100, 0}},      // gamma
-      {111, {101, 0}},     // pi0
-      {211, {101, 2}},     // pi+
-      {-211, {101, -2}},   // pi-
-      {321, {106, 1}},     // K+
-      {-321, {-106, -1}},  // K-
-      {311, {106, -1}},    // K0
-      {-311, {-106, 1}},   // K0bar
-      {2212, {1, 1}},      // p
-      {2112, {1, -1}},     // n
-      {-2212, {-1, -1}},   // pbar
-      {-2112, {-1, 1}},    // nbar
-      {221, {102, 0}},     // eta
-      {213, {104, 2}},     // rho+
-      {-213, {104, -2}},   // rho-
-      {113, {104, 0}},     // rho0
-      {323, {108, 2}},     // K*+
-      {-323, {108, -2}},   // K*-
-      {313, {108, 0}},     // K*0
-      {-313, {-108, 0}},   // K*0-bar
-      {223, {103, 0}},     // omega
-      {333, {109, 0}},     // phi
-      {3222, {40, 2}},     // Sigma+
-      {3212, {40, 0}},     // Sigma0
-      {3112, {40, -2}},    // Sigma-
-      {3322, {49, 0}},     // Xi0
-      {3312, {49, -1}},    // Xi-
-      {3122, {27, 0}},     // Lambda0
-      {2224, {17, 4}},     // Delta++
-      {2214, {17, 2}},     // Delta+
-      {2114, {17, 0}},     // Delta0
-      {1114, {17, -2}},    // Delta-
-      {3224, {41, 2}},     // Sigma*+
-      {3214, {41, 0}},     // Sigma*0
-      {3114, {41, -2}},    // Sigma*-
-      {3324, {50, 0}},     // Xi*0
-      {3314, {50, -1}},    // Xi*-
-      {3334, {55, 0}},     // Omega-
-      {411, {133, 2}},     // D+
-      {-411, {133, -2}},   // D-
-      {421, {133, 0}},     // D0
-      {-421, {-133, 0}},   // D0-bar
-      {441, {107, 0}},     // etaC
-      {431, {138, 1}},     // Ds+
-      {-431, {138, -1}},   // Ds-
-      {433, {139, 1}},     // Ds*+
-      {-433, {139, -1}},   // Ds*-
-      {413, {134, 1}},     // D*+
-      {-413, {134, -1}},   // D*-
-      {10421, {134, 0}},   // D*0
-      {-10421, {-134, 0}}, // D*0-bar
-      {443, {135, 0}},     // jpsi
-  };
-
-  return mapPDGToUrQMD.at(static_cast<int>(GetPDG(code)));
-}
-
-void UrQMD::readXSFile(std::string const& filename) {
-  std::ifstream file(filename, std::ios::in);
-
-  if (!file.is_open()) { throw std::runtime_error(filename + " could not be opened."); }
-
-  std::string line;
-
-  std::getline(file, line);
-  std::stringstream ss(line);
-
-  char dummy;
-  int nTargets, nProjectiles, nSupports;
-  ss >> dummy >> nTargets >> nProjectiles >> nSupports;
-
-  decltype(xs_interp_support_table_)::extent_gen extents;
-  xs_interp_support_table_.resize(extents[nProjectiles][nTargets][nSupports]);
-
-  for (int i = 0; i < nTargets; ++i) {
-    for (int j = 0; j < nProjectiles; ++j) {
-      for (int k = 0; k < nSupports; ++k) {
-        std::getline(file, line);
-        std::stringstream s(line);
-        double energy, sigma;
-        s >> energy >> sigma;
-        xs_interp_support_table_[j][i][k] = sigma * 1_mb;
-      }
-
-      std::getline(file, line);
-      std::getline(file, line);
-    }
-  }
-}
diff --git a/corsika/modules/UrQMD/UrQMD.h b/corsika/modules/UrQMD/UrQMD.h
deleted file mode 100644
index 61a23b0ef876be1fd48d746a8f1cd3c451eec6d4..0000000000000000000000000000000000000000
--- a/corsika/modules/UrQMD/UrQMD.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * (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/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/InteractionProcess.hpp>
-#include <corsika/framework/random/RNGManager.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <array>
-#include <random>
-#include <string>
-#include <utility>
-#include "../../corsika/setup/SetupStack.hpp"
-
-namespace corsika::UrQMD {
-  class UrQMD : public corsika::InteractionProcess<UrQMD> {
-  public:
-    UrQMD(std::string const& path = utl::CorsikaData("UrQMD/UrQMD-1.3.1-xs.dat"));
-    corsika::units::si::GrammageType GetInteractionLength(
-        corsika::Stack::StackIterator&) const;
-
-    template <typename TParticle>
-    corsika::units::si::CrossSectionType GetCrossSection(TParticle const&,
-                                                         corsika::Code) const;
-
-    corsika::EProcessReturn DoInteraction(
-        corsika::StackView::StackIterator&);
-
-    bool CanInteract(particles::Code) const;
-
-  private:
-    static corsika::units::si::CrossSectionType GetCrossSection(
-        particles::Code, particles::Code, corsika::units::si::HEPEnergyType, int);
-    corsika::RNG& fRNG =
-        corsika::RNGManager::GetInstance().GetRandomStream("UrQMD");
-
-    corsika::random::RNG& rng_ =
-        corsika::random::RNGManager::GetInstance().GetRandomStream("urqmd");
-
-    std::uniform_int_distribution<int> booleanDist_{0, 1};
-    boost::multi_array<corsika::units::si::CrossSectionType, 3> xs_interp_support_table_;
-  };
-
-  namespace details::constants {
-    // from coms.f
-    int constexpr nmax = 500;
-
-    // from options.f
-    int constexpr numcto = 400;
-    int constexpr numctp = 400;
-
-    // from inputs.f
-    int constexpr aamax = 300;
-
-  } // namespace details::constants
-
-  template <typename T>
-  using nmaxArray = std::array<T, details::constants::nmax>;
-  using nmaxIntArray = nmaxArray<int>;
-  using nmaxDoubleArray = nmaxArray<double>;
-
-  extern "C" {
-  // FORTRAN functions defined in UrQMD
-  void iniurqmdc8_();
-  double ranf_(int&);
-  void cascinit_(int const&, int const&, int const&);
-  double nucrad_(int const&);
-  void urqmd_(int&);
-  int pdgid_(int const&, int const&);
-  double sigtot_(int&, int&, double&);
-  int collclass_(int&, int&, int&, int&);
-  double crossx_(int const&, double const&, int const&, int const&, double const&,
-                 int const&, int const&, double const&, double&);
-  int readsigmaln_(int const&, int const&, int const&);
-
-  // defined in coms.f
-  extern struct {
-    int npart, nbar, nmes, ctag, nsteps, uid_cnt, ranseed, event;
-    int Ap; // projectile mass number (in case of nucleus)
-    int At; // target mass number (in case of nucleus)
-    int Zp; // projectile charge number (in case of nucleus)
-    int Zt; // target charge number (in case of nucleus)
-    int eos, dectag, NHardRes, NSoftRes, NDecRes, NElColl, NBlColl;
-  } sys_;
-
-  extern struct {
-    double time, acttime, bdist, bimp, bmin;
-    double ebeam; // lab-frame energy of projectile
-    double ecm;
-  } rsys_;
-
-  // defined in coms.f
-  extern struct {
-    nmaxIntArray spin, ncoll, charge, ityp, lstcoll, iso3, origin, strid, uid;
-  } isys_;
-
-  // defined in coor.f
-  extern struct {
-    nmaxDoubleArray r0, rx, ry, rz, p0, px, py, pz, fmass, rww, dectime;
-  } coor_;
-
-  // defined in inputs.f
-  extern struct {
-    int nevents;
-    std::array<int, 2> spityp; // particle codes of: [0]: projectile, [1]: target
-    int prspflg;               // projectile special flag
-    int trspflg; // target special flag, set to 1 unless target is nucleus > H
-    std::array<int, 2> spiso3; // particle codes of: [0]: projectile, [1]: target
-    int outsteps, bflag, srtflag, efuncflag, nsrt, npb, firstev;
-  } inputs_;
-
-  // defined in inputs.f
-  extern struct {
-    double srtmin, srtmax, pbeam, betann, betatar, betapro, pbmin, pbmax;
-  } input2_;
-
-  // defined in options.f
-  extern struct {
-    std::array<double, details::constants::numcto> CTOption;
-    std::array<double, details::constants::numctp> CTParam;
-  } options_;
-
-  extern struct {
-    int fixedseed, bf13, bf14, bf15, bf16, bf17, bf18, bf19, bf20;
-  } loptions_;
-
-  // defined in urqmdInterface.F
-  extern struct { std::array<double, 3> xs, bim; } cxs_u2_;
-  }
-
-  /**
-   * convert CORSIKA code to UrQMD code tuple
-   *
-   * In the current implementation a detour via the PDG code is made.
-   */
-  std::pair<int, int> ConvertToUrQMD(particles::Code);
-  particles::Code ConvertFromUrQMD(int vItyp, int vIso3);
-
-} // namespace corsika::UrQMD
-
-#endif
diff --git a/corsika/modules/UrQMD/testUrQMD.cc b/corsika/modules/UrQMD/testUrQMD.cc
deleted file mode 100644
index 8bcfd651c5b386be18c119d94fe09455229a8c66..0000000000000000000000000000000000000000
--- a/corsika/modules/UrQMD/testUrQMD.cc
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/urqmd/UrQMD.h>
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-
-#include <corsika/framework/core/PhysicalConstants.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/framework/utility/CorsikaFenv.hpp>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/HomogeneousMedium.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-
-#include <tuple>
-#include <utility>
-
-#include <catch2/catch.hpp>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using namespace corsika;
-using namespace corsika::UrQMD;
-using namespace corsika::units::si;
-
-template <typename TStackView>
-auto sumCharge(TStackView const& view) {
-  int totalCharge = 0;
-
-  for (auto const& p : view) { totalCharge += particles::GetChargeNumber(p.GetPID()); }
-
-  return totalCharge;
-}
-
-template <typename TStackView>
-auto sumMomentum(TStackView const& view, geometry::CoordinateSystem const& vCS) {
-  geometry::Vector<hepenergy_d> sum{vCS, 0_eV, 0_eV, 0_eV};
-
-  for (auto const& p : view) { sum += p.GetMomentum(); }
-
-  return sum;
-}
-
-auto setupEnvironment(particles::Code vTargetCode) {
-  // setup environment, geometry
-  auto env = std::make_unique<environment::Environment<environment::IMediumModel>>();
-  auto& universe = *(env->GetUniverse());
-  const geometry::CoordinateSystem& cs = env->GetCoordinateSystem();
-
-  auto theMedium =
-      environment::Environment<environment::IMediumModel>::CreateNode<geometry::Sphere>(
-          geometry::Point{cs, 0_m, 0_m, 0_m},
-          1_km * std::numeric_limits<double>::infinity());
-
-  using MyHomogeneousModel = environment::HomogeneousMedium<environment::IMediumModel>;
-  theMedium->SetModelProperties<MyHomogeneousModel>(
-      1_kg / (1_m * 1_m * 1_m),
-      environment::NuclearComposition(std::vector<particles::Code>{vTargetCode},
-                                      std::vector<float>{1.}));
-
-  auto const* nodePtr = theMedium.get();
-  universe.AddChild(std::move(theMedium));
-
-  return std::make_tuple(std::move(env), &cs, nodePtr);
-}
-
-template <typename TNodeType>
-auto setupStack(int vA, int vZ, HEPEnergyType vMomentum, TNodeType* vNodePtr,
-                geometry::CoordinateSystem const& cs) {
-  auto stack = std::make_unique<setup::Stack>();
-  auto constexpr mN = corsika::units::constants::nucleonMass;
-
-  geometry::Point const origin(cs, {0_m, 0_m, 0_m});
-  corsika::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV});
-
-  HEPEnergyType const E0 =
-      sqrt(units::si::detail::static_pow<2>(mN * vA) + pLab.squaredNorm());
-  auto particle =
-      stack->AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                    corsika::MomentumVector, geometry::Point,
-                                    units::si::TimeType, unsigned short, unsigned short>{
-          particles::Code::Nucleus, E0, pLab, origin, 0_ns, vA, vZ});
-
-  particle.SetNode(vNodePtr);
-  return std::make_tuple(
-      std::move(stack),
-      std::make_unique<decltype(corsika::SecondaryView(particle))>(particle));
-}
-
-template <typename TNodeType>
-auto setupStack(particles::Code vProjectileType, HEPEnergyType vMomentum,
-                TNodeType* vNodePtr, geometry::CoordinateSystem const& cs) {
-  auto stack = std::make_unique<setup::Stack>();
-
-  geometry::Point const origin(cs, {0_m, 0_m, 0_m});
-  corsika::MomentumVector const pLab(cs, {vMomentum, 0_GeV, 0_GeV});
-
-  HEPEnergyType const E0 =
-      sqrt(units::si::detail::static_pow<2>(particles::GetMass(vProjectileType)) +
-           pLab.squaredNorm());
-  auto particle = stack->AddParticle(
-      std::tuple<particles::Code, units::si::HEPEnergyType,
-                 corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-          vProjectileType, E0, pLab, origin, 0_ns});
-
-  particle.SetNode(vNodePtr);
-  return std::make_tuple(
-      std::move(stack),
-      std::make_unique<decltype(corsika::SecondaryView(particle))>(particle));
-}
-
-TEST_CASE("UrQMD") {
-  SECTION("conversion") {
-    REQUIRE_THROWS(process::UrQMD::ConvertFromUrQMD(106, 0));
-    REQUIRE(process::UrQMD::ConvertFromUrQMD(101, 0) == particles::Code::Pi0);
-    REQUIRE(process::UrQMD::ConvertToUrQMD(particles::Code::PiPlus) ==
-            std::make_pair<int, int>(101, 2));
-  }
-
-  feenableexcept(FE_INVALID);
-  corsika::RNGManager::GetInstance().RegisterRandomStream("UrQMD");
-  UrQMD urqmd;
-
-  SECTION("interaction length") {
-    auto [env, csPtr, nodePtr] =
-        setup::testing::setupEnvironment(particles::Code::Nitrogen);
-    auto const& cs = *csPtr;
-    [[maybe_unused]] auto const& env_dummy = env;
-    [[maybe_unused]] auto const& node_dummy = nodePtr;
-
-    particles::Code validProjectileCodes[] = {
-        particles::Code::PiPlus,  particles::Code::PiMinus, particles::Code::Proton,
-        particles::Code::Neutron, particles::Code::KPlus,   particles::Code::KMinus,
-        particles::Code::K0,      particles::Code::K0Bar,   particles::Code::K0Long};
-
-    for (auto code : validProjectileCodes) {
-      auto [stack, view] = setup::testing::setupStack(code, 0, 0, 100_GeV, nodePtr, cs);
-      REQUIRE(stack->getEntries() == 1);
-      REQUIRE(view->getEntries() == 0);
-
-      // simple check whether the cross-section is non-vanishing
-      // only nuclei with available tabluated data so far
-      REQUIRE(urqmd.GetInteractionLength(stack->GetNextParticle()) > 1_g / square(1_cm));
-    }
-  }
-
-  SECTION("nucleus projectile") {
-    auto [env, csPtr, nodePtr] =
-        setup::testing::setupEnvironment(particles::Code::Oxygen);
-    [[maybe_unused]] auto const& env_dummy = env;      // against warnings
-    [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings
-
-    unsigned short constexpr A = 14, Z = 7;
-    auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::Nucleus, A,
-                                                             Z, 400_GeV, nodePtr, *csPtr);
-    REQUIRE(stackPtr->getEntries() == 1);
-    REQUIRE(secViewPtr->getEntries() == 0);
-
-    // must be assigned to variable, cannot be used as rvalue?!
-    auto projectile = secViewPtr->GetProjectile();
-    auto const projectileMomentum = projectile.GetMomentum();
-    [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr);
-
-    REQUIRE(sumCharge(*secViewPtr) ==
-            Z + particles::GetChargeNumber(particles::Code::Oxygen));
-
-    auto const secMomSum =
-        sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem());
-    REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() ==
-            Approx(0).margin(1e-2));
-  }
-
-  SECTION("\"special\" projectile") {
-    auto [env, csPtr, nodePtr] =
-        setup::testing::setupEnvironment(particles::Code::Oxygen);
-    [[maybe_unused]] auto const& env_dummy = env;      // against warnings
-    [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings
-
-    auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::PiPlus, 0,
-                                                             0, 400_GeV, nodePtr, *csPtr);
-    REQUIRE(stackPtr->getEntries() == 1);
-    REQUIRE(secViewPtr->getEntries() == 0);
-
-    // must be assigned to variable, cannot be used as rvalue?!
-    auto projectile = secViewPtr->GetProjectile();
-    auto const projectileMomentum = projectile.GetMomentum();
-
-    [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr);
-
-    REQUIRE(sumCharge(*secViewPtr) ==
-            particles::GetChargeNumber(particles::Code::PiPlus) +
-                particles::GetChargeNumber(particles::Code::Oxygen));
-
-    auto const secMomSum =
-        sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem());
-    REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() ==
-            Approx(0).margin(1e-2));
-  }
-
-  SECTION("K0Long projectile") {
-    auto [env, csPtr, nodePtr] =
-        setup::testing::setupEnvironment(particles::Code::Oxygen);
-    [[maybe_unused]] auto const& env_dummy = env;      // against warnings
-    [[maybe_unused]] auto const& node_dummy = nodePtr; // against warnings
-
-    auto [stackPtr, secViewPtr] = setup::testing::setupStack(particles::Code::K0Long, 0,
-                                                             0, 400_GeV, nodePtr, *csPtr);
-    REQUIRE(stackPtr->getEntries() == 1);
-    REQUIRE(secViewPtr->getEntries() == 0);
-
-    // must be assigned to variable, cannot be used as rvalue?!
-    auto projectile = secViewPtr->GetProjectile();
-    auto const projectileMomentum = projectile.GetMomentum();
-
-    [[maybe_unused]] process::EProcessReturn const ret = urqmd.DoInteraction(*secViewPtr);
-
-    REQUIRE(sumCharge(*secViewPtr) ==
-            particles::GetChargeNumber(particles::Code::K0Long) +
-                particles::GetChargeNumber(particles::Code::Oxygen));
-
-    auto const secMomSum =
-        sumMomentum(*secViewPtr, projectileMomentum.GetCoordinateSystem());
-    REQUIRE((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() ==
-            Approx(0).margin(1e-2));
-  }
-}
diff --git a/corsika/modules/UrQMD/urqmdInterface.F b/corsika/modules/UrQMD/urqmdInterface.F
deleted file mode 100644
index ec2bd092a8386393368a6789df73b3efa3253160..0000000000000000000000000000000000000000
--- a/corsika/modules/UrQMD/urqmdInterface.F
+++ /dev/null
@@ -1,447 +0,0 @@
-c 18.11.2011 Link routines between UrQMD 1.3 and CONEX.
-c author T. Pierog based on CORSIKA and EPOS link to UrQMD
-
-c adapted by M. Reininghaus for linking UrQMD to CORSIKA 8 (Apr 2019)
-
-#ifdef __STD__
-#define __GHEISHA__
-#define __QGSJET__
-#define __ANALYSIS__
-#endif
-
-
-c-----------------------------------------------------------------------
-      subroutine IniUrQMDC8
-c-----------------------------------------------------------------------
-c Primary initialization for UrQMD 1.31
-c-----------------------------------------------------------------------
-      implicit none
-c CONEX includes
-c~ #include "conex.h"
-c~ #include "conex.incnex"
-#ifndef __CXCORSIKA__
-c~       character*500 furqdat
-c~       integer ifurqdat, nfurqdat
-c~       common/urqfname/  furqdat, ifurqdat, nfurqdat
-
-      include 'boxinc.f'
-      include 'inputs.f'
-      include 'options.f'
-      
-c commons from coms.f
-      integer Ap, At, Zp, Zt, npart, nbar, nmes, ctag
-      integer nsteps,ranseed,event,eos,dectag,uid_cnt
-      integer NHardRes,NSoftRes,NDecRes,NElColl,NBlColl
-      common /sys/ npart, nbar, nmes, ctag,nsteps,uid_cnt,
-     +             ranseed,event,Ap,At,Zp,Zt,eos,dectag,
-     +             NHardRes,NSoftRes,NDecRes,NElColl,NBlColl
-
-c local
-      INTEGER          i,io,ia,ie,id
-      CHARACTER        CTPStrg(numctp)*60, CTOStrng(numcto)*60
-      integer mxie,mxid,mxia
-      parameter (mxie=41,mxid=10,mxia=3)
-      character adum
-      double precision sig_u1,ekdummy
-      integer iamaxu,idmaxu,iemaxu
-c~       common /cxs_u1/ sig_u1(mxie,mxid,mxia),iamaxu,idmaxu,iemaxu
-c~       double precision xs(3),bim(3)
-c~ c M.R.: bim added to cxs_u2
-c~       common /cxs_u2/ xs,bim
-      integer iudebug
-c~       data bim/6.d0,6.d0,7.d0/
-      integer init
-      data init/0/
-      SAVE
-
-      if(init.ge.1)return
-      init=init+1
-#ifdef __CXDEBUG__
-      call utisx1('iniurqmd  ',4)
-      write(*,'(a)')'initialize URQMD ...'
-#endif
-
-C-----------------------------------------------------------------------
-
-c~       IF ( isx.ge.2 ) THEN
-c~         IUDEBUG = isx-1
-c~       ELSE
-c~         IUDEBUG = 0
-c~       ENDIF
-
-      WRITE (*,*)
-     $   '############################################################'
-      WRITE (*,*)
-     $   '##                                                        ##'
-      WRITE (*,*)
-     $   '##     UrQMD 1.3.1  University of Frankfurt               ##'
-      WRITE (*,*)
-     $   '##                  urqmd@th.physik.uni-frankfurt.de      ##'
-      WRITE (*,*)
-     $   '##                                                        ##'
-      WRITE (*,*)
-     $   '############################################################'
-      WRITE (*,*)
-     $   '##                                                        ##'
-      WRITE (*,*)
-     $   '##     please cite when using this model:                 ##'
-      WRITE (*,*)
-     $   '##     S.A.Bass et al. Prog.Part.Nucl.Phys. 41 (1998) 225 ##'
-      WRITE (*,*)
-     $   '##     M.Bleicher et al. J.Phys. G25  (1999) 1859         ##'
-      WRITE (*,*)
-     $   '##                                                        ##'
-      WRITE (*,*)
-     $   '############################################################'
-
-C  SET THE 'LARGE' CROSS-SECTIONS FOR ALL 3 TARGET ELEMENTS
-c~       DO  I = 1, 3
-c~         XS(I) = 10.D0 * PI * BIM(I)**2
-c~       ENDDO
-
-C  SET NMAX TO DEFAULT VALUE
-      call set0
-      call params
-
-C  THIS IS THE SUBSTITUE FOR THE URQMD INPUT ROUTINE
-C  INITIALIZE COUNTERS
-      boxflag = 0
-      mbflag  = 0
-      edens   = 0.d0
-      para    = 0
-      solid   = 0
-      mbox    = 0
-      io      = 0
-
-C  THE FOLLOWING FLAGS CHECK, WHETHER ALL NECESSARY INPUT IS GIVEN
-C  PROJECTILE
-      prspflg = 0
-C  TARGET
-      trspflg = 0
-C
-      srtflag = 0
-      firstev = 0
-C  EXCITATION FUNCTION
-      nsrt    = 1
-      npb     = 1
-      efuncflag = 0
-C  DEFAULT NUMBER OF EVENTS
-      nevents = 1
-C  DEFAULT NUMBER OF TIMESTEPS
-      nsteps  = 1000
-
-C  SKIP CONDITIONS ON UNIT 13, 14, 15, 16 & 18
-C  SUPPRESS ALL OUTPUT
-      bf13 = .true.
-      bf14 = .true.
-      bf15 = .true.
-      bf16 = .true.
-      bf18 = .true.
-      bf19 = .true.
-      bf20 = .true.
-C  SET DEBUG OUTPUT DEPENDING ON CHOSEN DEBUG LEVEL
-C  SET THE OUTPUT OF UNITS 13, 14, 15 TO THE DEBUG OUTPUT UNIT
-c~       IF     ( IUDEBUG .EQ. 1 ) THEN
-c~         bf13 = .true.
-c~         bf14 = .false.
-c~         call uounit(14,IFCK)
-c~         bf15 = .true.
-c~       ELSEIF ( IUDEBUG .EQ. 2 ) THEN
-c~         bf13 = .false.
-c~         call uounit(13,IFCK)
-c~         bf14 = .true.
-c~         bf15 = .true.
-c~       ELSEIF ( IUDEBUG .GT. 2 ) THEN
-c~         bf13 = .true.
-c~         bf14 = .true.
-c~         bf15 = .false.
-c~         call uounit(15,IFCK)
-c~       ENDIF
-      do  i = 1, numcto
-         CTOdc(i) = '  '
-      enddo
-      do  i = 1, numctp
-         CTPdc(i) = '  '
-      enddo
-      do  i = 1, maxstables
-         stabvec(i) = 0
-      enddo
-      nstable = 0
-
-C  DEFAULT SETTINGS FOR CTParam AND CTOption
-C  DEFAULT SETTINGS FOR CTParam
-      CTParam(1)=1.d0
-      CTPStrg(1)='scaling factor for decay-width'
-      CTParam(2)=0.52d0
-      CTPStrg(2)='used for minimal stringmass & el/inel cut in makestr'
-      CTParam(3)=2.d0
-      CTPStrg(3)='velocity exponent for modified AQM'
-      CTParam(4)=0.3d0
-      CTPStrg(4)='transverse pion mass, used in make22 & strexct'
-      CTParam(5)=0.d0
-      CTPStrg(5)='probabil. for quark rearrangement in cluster'
-      CTParam(6)=0.37d0
-      CTPstrg(6)='strangeness probability'
-      CTParam(7)=0.d0
-      CTPStrg(7)='charm probability (not yet implemented in UQMD)'
-      CTParam(8)=0.093d0
-      CTPStrg(8)='probability to create a diquark'
-      CTParam(9)=0.35d0
-      CTPStrg(9)='kinetic energy cut off for last string break'
-      CTParam(10)=0.25d0
-      CTPStrg(10)='min. kinetic energy for hadron in string'
-      CTParam(11)=0.d0
-      CTPStrg(11)='fraction of non groundstate resonances'
-      CTParam(12)=.5d0
-      CTPStrg(12)='probability for rho 770 in String'
-      CTParam(13)=.27d0
-      CTPStrg(13)='probability for rho 1450 (rest->rho1700)'
-      CTParam(14)=.49d0
-      CTPStrg(14)='probability for omega 782'
-      CTParam(15)=.27d0
-      CTPStrg(15)='probability for omega 1420(rest->om1600)'
-      CTParam(16)=1.0d0
-      CTPStrg(16)='mass cut betw. rho770 and rho 1450'
-      CTParam(17)=1.6d0
-      CTPSTRG(17)='mass cut betw. rho1450 and rho1700'
-      CTParam(18)=.85d0
-      CTPStrg(18)='mass cut betw. om 782 and om1420'
-      CTParam(19)=1.55d0
-      CTPStrg(19)='mass cut betw. om1420 and om1600'
-      CTParam(20)=0.0d0
-      CTPStrg(20)=' distance for second projectile'
-      CTParam(21)=0.0d0
-      CTPStrg(21)=' deformation parameter'
-
-      CTParam(25)=.9d0
-      CTPStrg(25)=' probability for diquark not to break'
-      CTParam(26)=50.d0
-      CTPStrg(26)=' maximum trials to get string masses'
-      CTParam(27)=1.d0
-      CTPStrg(27)=' scaling factor for xmin in string excitation'
-      CTParam(28)=1.d0
-      CTPStrg(28)=' scaling factor for transverse fermi motion'
-      CTParam(29)=0.4d0
-      CTPStrg(29)=' single strange di-quark suppression factor '
-      CTParam(30)=1.5d0
-      CTPStrg(30)=' radius offset for initialization  '
-      CTParam(31)=1.6d0
-      CTPStrg(31)=' sigma of gaussian for tranverse momentum tranfer '
-      CTParam(32)=0.d0
-      CTPStrg(32)=' alpha-1 for valence quark distribution  '
-      CTParam(33)=2.5d0
-      CTPStrg(33)=' betav for valence quark distribution  (DPM)'
-      CTParam(34)=0.1d0
-      CTPStrg(34)=' minimal x multiplied with ecm  '
-      CTParam(35)=3.0d0
-      CTPStrg(35)=' offset for cut for the FSM '
-      CTParam(36)=0.275d0
-      CTPStrg(36)=' fragmentation function parameter a  '
-      CTParam(37)=0.42d0
-      CTPStrg(37)=' fragmentation function parameter b  '
-      CTParam(38)=1.08d0
-      CTPStrg(38)=' diquark pt scaling factor '
-      CTParam(39)=0.8d0
-      CTPStrg(39)=' strange quark pt scaling factor '
-      CTParam(40)=0.5d0
-      CTPStrg(40)=' betas-1 for valence quark distribution (LEM)'
-      CTParam(41)=0.d0
-      CTPStrg(41)=' distance of initialization'
-      CTParam(42)=0.55d0
-      CTPStrg(42)=' width of gaussian -> pt in string-fragmentation '
-      CTParam(43)=5.d0
-      CTPStrg(43)=' maximum kinetic energy in mesonic clustr '
-      CTParam(44)=0.8d0
-      CTPStrg(44)=' prob. of double vs. single excitation for AQM inel.'
-      CTParam(45)=0.5d0
-      CTPStrg(45)=' offset for minimal mass generation of strings'
-      CTParam(46)=800000.d0
-      CTPStrg(46)=' maximal number of rejections for initialization'
-      CTParam(47)=1.0d0
-      CTPStrg(47)=' field feynman fragmentation funct. param. a'
-      CTParam(48)=2.0d0
-      CTPStrg(48)=' field feynman fragmentation funct. param. b'
-
-      CTParam(50)=1.d0
-      CTPStrg(50)=' enhancement factor for 0- mesons'
-      CTParam(51)=1.d0
-      CTPStrg(51)=' enhancement factor for 1- mesons'
-      CTParam(52)=1.d0
-      CTPStrg(52)=' enhancement factor for 0+ mesons'
-      CTParam(53)=1.d0
-      CTPStrg(53)=' enhancement factor for 1+ mesons'
-      CTParam(54)=1.d0
-      CTPStrg(54)=' enhancement factor for 2+ mesons'
-      CTParam(55)=1.d0
-      CTPStrg(55)=' enhancement factor for 1+-mesons'
-      CTParam(56)=1.d0
-      CTPStrg(56)=' enhancement factor for 1-*mesons'
-      CTParam(57)=1.d0
-      CTPStrg(57)=' enhancement factor for 1-*mesons'
-      CTParam(58)=1.d0
-      CTPStrg(58)=' scaling factor for DP time-delay'
-
-C  DEFAULT SETTINGS FOR CTOption
-      CTOption(1)=1                  ! hjd1
-      CTOStrng(1)=' resonance widths are mass dependent '
-      CTOption(2)=0
-      CTOStrng(2)=' conservation of scattering plane'
-      CTOption(3)=0
-      CTOStrng(3)=' use modified detailed balance'
-      CTOption(4)=0
-      CTOStrng(4)=' no initial conf. output '
-      CTOption(5)=0
-      CTOStrng(5)=' fixed random impact parameter'
-      CTOption(6)=0
-      CTOStrng(6)=' no first collisions inside proj/target'
-      CTOption(7)=0
-      CTOStrng(7)=' elastic cross-section enabled (<>0:total=inelast)'
-      CTOption(8)=0
-      CTOStrng(8)=' extrapolate branching ratios '
-      CTOption(9)=0
-      CTOStrng(9)=' use tabulated pp cross-sections '
-      CTOption(10)=0
-      CTOStrng(10)=' enable Pauli Blocker'
-      CTOption(11)=0
-      CTOStrng(11)=' mass reduction for cascade initialization'
-      CTOption(12)=0
-      CTOStrng(12)=' string condition =0 (.ne.0 no strings)'
-      CTOption(13)=0
-      CTOStrng(13)=' enhanced file16 output '
-      CTOption(14)=0
-      CTOStrng(14)=' cos(the) is distributet between -1..1 '
-      CTOption(15)=0
-      CTOStrng(15)=' allow mm&mb-scattering'
-      CTOption(16)=0
-      CTOStrng(16)=' propagate without collisions'
-      CTOption(17)=0
-      CTOStrng(17)=' colload after every timestep '
-      CTOption(18)=0
-      CTOStrng(18)=' final decay of unstable particles'
-      CTOption(19)=0
-      CTOStrng(19)=' allow bbar annihilaion'
-      CTOption(20)=0
-      CTOStrng(20)=' dont generate e+e- instead of bbar'
-      CTOption(21)=0
-      CTOStrng(21)=' use field feynman frgm. function'
-      CTOption(22)=1
-      CTOStrng(22)=' use lund excitation function'
-      CTOption(23)=0
-      CTOStrng(23)=' lorentz contraction of projectile & targed'
-      CTOption(24)=2      ! 1 is default    2 means fast method
-      CTOStrng(24)=' Wood-Saxon initialization'
-      CTOption(25)=0
-      CTOStrng(25)=' phase space corrections for resonance mass'
-      CTOption(26)=0
-      CTOStrng(26)=' use z -> 1-z for diquark-pairs'
-      CTOption(27)=1             ! hjd1
-      CTOStrng(27)=' reference frame (1=target, 2=projectile, else=cms)'
-      CTOption(28)=1             ! M.R. 2019-04-15
-      CTOStrng(28)=' propagate spectators also '
-      CTOption(29)=2
-      CTOStrng(29)=' no transverse momentum in clustr '
-      CTOption(30)=1
-      CTOStrng(30)=' frozen fermi motion '
-      CTOption(31)=0
-      CTOStrng(31)='  reduced mass spectrum in string'
-      CTOption(32)=0
-      CTOStrng(32)=' masses are distributed acc. to m-dep. widths'
-      CTOption(33)=0
-      CTOStrng(33)=' use tables & m-dep. for pmean in fprwdt & fwidth'
-      CTOption(34)=1
-      CTOStrng(34)=' lifetme according to m-dep. width'
-      CTOption(35)=1
-      CTOStrng(35)=' generate high precision tables'
-      CTOption(36)=0
-      CTOStrng(36)=' normalize Breit-Wigners with m.dep. widths '
-      CTOption(37)=0
-      CTOStrng(37)=' heavy quarks form di-quark clusters'
-      CTOption(38)=0
-      CTOStrng(38)=' scale p-pbar to b-bbar with equal p_lab '
-      CTOption(39)=0
-      CTOStrng(39)=' dont call pauliblocker'
-      CTOption(40)=0
-      CTOStrng(40)=' read old fort.14 file '
-      CTOption(41)=0
-      CTOStrng(41)=' generate extended output for cto40'
-      CTOption(42)=0
-      CTOStrng(42)=' hadrons now have color fluctuations'
-      CTOption(43)=0
-      CTOStrng(43)=' dont generate dimuon intead of dielectron output'
-      CTOption(44)=0
-      CTOStrng(44)=' not used at the moment'
-      CTOption(45)=0
-      CTOStrng(45)=' not used at the moment'
-
-C  INITIALIZE ARRAYS FOR SPECIAL PRO/TAR COMBINATIONS
-      do  i = 1, 2
-         spityp(i) = 0
-         spiso3(i) = 0
-      enddo
-
-C  INITIALIZE ARRAYS FOR SPECIAL PARTICLES
-      EoS = 0
-
-C  READ CROSS-SECTION FILES
-Cdh   CALL URQREC()
-
-C  INITIALIZES SOME ARRAYS
-      call strini      ! initialize mixing angles for meson-multipletts
-      call loginit
-
-      IF ( CTOption(33) .EQ. 0  .OR.  CTOption(9) .EQ. 0 ) THEN
-        call loadwtab(io)
-c~         IF ( IUDEBUG .GT. 0 ) WRITE(IFCK,*) 'URQINI: AFTER LOADWTAB'
-      ENDIF
-
-C READ URQMD TOTAL CROSS SECTION TABLE
-c
-c   ie=1..41   E=10.0**(float(ie)/10-1.0-0.05)  (bin-middle)
-c   id=1..9    p,ap,n,an,pi+,pi-,K+,K-,KS
-c   ia=1..3    N,O,Ar
-c
-c~       if(ifurqdat.eq.1)then
-c~         OPEN(UNIT=76,FILE=furqdat(1:nfurqdat),STATUS='OLD')
-c~       else
-c~         OPEN(UNIT=76,FILE='UrQMD-1.3.1-xs.dat',STATUS='OLD')
-c~       endif
-c~       read(76,*) adum,iamaxu,idmaxu,iemaxu
-c~       do ia=1,iamaxu
-c~         do id=1,idmaxu
-c~           do ie=1,iemaxu
-c~             read(76,*) ekdummy,sig_u1(ie,id,ia)
-c~           enddo
-c~           read(76,*)
-c~           read(76,*)
-c~         enddo
-c~       enddo
-c~       close(76)
-
-C  IN CASE OF CASCADE MODE, THE POTENTIALS NEED NOT BE CALCULATED
-
-C  CALCULATE NORMALIZATION OF RESONANCES DISTRIBUTION...
-      call norm_init
-#endif
-
-
-c~       xsegymin=0.25d0
-
-#ifdef __CXDEBUG__
-      call utisx2
-#endif
-
-      end
-
-c
-c M. Reininghaus, 2020-04-08
-c
-      integer function ReadSigmaLn(ia, ib, ic)
-      implicit none
-
-      include 'comres.f'
-
-      integer :: ia, ib, ic
-
-      ReadSigmaLn = SigmaLn(ia, ib, ic)
-
-      end function ReadSigmaLn
diff --git a/corsika/process/EnergyLoss.hpp b/corsika/process/EnergyLoss.hpp
deleted file mode 100644
index 656f644c0c93ff98ac2d322de7a7ce6f678d45af..0000000000000000000000000000000000000000
--- a/corsika/process/EnergyLoss.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * (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/geometry/Point.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-#include <corsika/framework/sequence/ContinuousProcess.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <map>
-
-#include <corsika/setup/SetupStack.hpp>
-#include <corsika/setup/SetupTrajectory.hpp>
-
-namespace corsika {
-
-  class EnergyLoss : public corsika::ContinuousProcess<EnergyLoss> {
-
-    using MeVgcm2 = decltype(1e6 * units::si::electronvolt / units::si::gram *
-                             units::si::square(1e-2 * units::si::meter));
-
-    void MomentumUpdate(setup::Stack::ParticleType&, units::si::HEPEnergyType Enew);
-
-  public:
-    template <typename TDim>
-    EnergyLoss(geometry::Point const& injectionPoint,
-               geometry::Vector<TDim> const& direction)
-        : InjectionPoint_(injectionPoint)
-        , ShowerAxisDirection_(direction.normalized()) {}
-
-    EnergyLoss(setup::Trajectory const& trajectory)
-        : EnergyLoss(trajectory.GetPosition(0), trajectory.GetV0()){};
-
-    process::EProcessReturn DoContinuous(setup::Stack::ParticleType&,
-                                         setup::Trajectory const&);
-    units::si::LengthType MaxStepLength(setup::Stack::ParticleType const&,
-                                        setup::Trajectory const&) const;
-    units::si::HEPEnergyType GetTotal() const;
-    void PrintProfile() const;
-    static units::si::HEPEnergyType BetheBloch(setup::Stack::ParticleType const&,
-                                               const units::si::GrammageType);
-    static units::si::HEPEnergyType RadiationLosses(setup::Stack::ParticleType const&,
-                                                    const units::si::GrammageType);
-    static units::si::HEPEnergyType TotalEnergyLoss(setup::Stack::ParticleType const&,
-                                                    const units::si::GrammageType);
-
-    void showResults() const;
-    void reset();
-    corsika::units::si::HEPEnergyType energyLost() const { return energy_lost_; }
-
-  private:
-    void FillProfile(setup::Trajectory const&, units::si::HEPEnergyType);
-
-    units::si::GrammageType const dX_ = std::invoke([]() {
-      using namespace units::si;
-      return 10_g / square(1_cm);
-    }); // profile binning
-
-  private:
-    environment::ShowerAxis const& shower_axis_;
-    corsika::units::si::HEPEnergyType emCut_;
-    std::vector<units::si::HEPEnergyType> profile_; // longitudinal profile
-    units::si::HEPEnergyType energy_lost_ = 0 * units::si::electronvolt;
-  };
-
-  units::si::GrammageType const dX_threshold_ = std::invoke([]() {
-    using namespace units::si;
-    return 0.0001_g / square(1_cm);
-  });
-} // namespace corsika
diff --git a/corsika/process/HadronicElasticModel.hpp b/corsika/process/HadronicElasticModel.hpp
deleted file mode 100644
index 0466a037ec5fed6339ebd43f8b339746e65bdd2a..0000000000000000000000000000000000000000
--- a/corsika/process/HadronicElasticModel.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * (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/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/InteractionProcess.hpp>
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/core/PhysicalConstants.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-namespace corsika::HadronicElasticModel {
-  /**
-   * A simple model for elastic hadronic interactions based on the formulas
-   * in Gaisser, Engel, Resconi, Cosmic Rays and Particle Physics (Cambridge Univ. Press,
-   * 2016), section 4.2 and Donnachie, Landshoff, Phys. Lett. B 296, 227 (1992)
-   *
-   * Currently only \f$p\f$ projectiles are supported and cross-sections are assumed to be
-   * \f$pp\f$-like even for nuclei.
-   */
-  class HadronicElasticInteraction
-      : public corsika::InteractionProcess<HadronicElasticInteraction> {
-  private:
-    corsika::units::si::CrossSectionType const fX, fY;
-
-    static double constexpr gfEpsilon = 0.0808;
-    static double constexpr gfEta = 0.4525;
-    // Froissart-Martin is not violated up for sqrt s < 10^32 eV with these values [DL].
-
-    using SquaredHEPEnergyType = decltype(corsika::units::si::HEPEnergyType() *
-                                          corsika::units::si::HEPEnergyType());
-
-    using eV2 = decltype(units::si::square(units::si::electronvolt));
-    using inveV2 = decltype(1 / units::si::square(units::si::electronvolt));
-
-    corsika::RNG& fRNG =
-        corsika::RNGManager::GetInstance().GetRandomStream("HadronicElasticModel");
-
-    inveV2 B(eV2 s) const;
-    corsika::units::si::CrossSectionType CrossSection(SquaredHEPEnergyType s) const;
-
-  public:
-    HadronicElasticInteraction( // x & y values taken from DL for pp collisions
-        units::si::CrossSectionType x = 0.0217 * units::si::barn,
-        units::si::CrossSectionType y = 0.05608 * units::si::barn);
-
-    template <typename Particle>
-    corsika::units::si::GrammageType GetInteractionLength(Particle const& p);
-
-    template <typename Particle>
-    corsika::EProcessReturn DoInteraction(Particle&);
-  };
-
-} // namespace corsika::HadronicElasticModel
diff --git a/corsika/process/ObservationPlane.hpp b/corsika/process/ObservationPlane.hpp
deleted file mode 100644
index 3ac64e263539824e439544409d28aeb94cccafa7..0000000000000000000000000000000000000000
--- a/corsika/process/ObservationPlane.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * (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.
- */
-
-#pragma once
-
-#include <corsika/framework/geometry/Plane.hpp>
-#include <corsika/framework/sequence/ContinuousProcess.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <fstream>
-
-#include "corsika/setup/SetupStack.hpp"
-#include "corsika/setup/SetupTrajectory.hpp"
-
-namespace corsika::observation_plane {
-
-  /**
-   * The ObservationPlane writes PDG codes, energies, and distances of particles to the
-   * central point of the plane into its output file. The particles are considered
-   * "absorbed" afterwards.
-   */
-  class ObservationPlane : public corsika::ContinuousProcess<ObservationPlane> {
-
-  public:
-    ObservationPlane(geometry::Plane const&,
-                     geometry::Vector<units::si::dimensionless_d> const&,
-                     std::string const&, bool = true);
-
-    corsika::EProcessReturn DoContinuous(corsika::Stack::ParticleType const& vParticle,
-                                         corsika::Trajectory const& vTrajectory);
-
-    corsika::units::si::LengthType MaxStepLength(corsika::Stack::ParticleType const&,
-                                                 corsika::Trajectory const& vTrajectory);
-
-    void ShowResults() const;
-    void Reset();
-    corsika::units::si::HEPEnergyType GetEnergyGround() const { return energy_ground_; }
-
-  private:
-    geometry::Plane const plane_;
-    std::ofstream outputStream_;
-    bool const deleteOnHit_;
-
-    units::si::HEPEnergyType energy_ground_ = 0 * units::si::electronvolt;
-    unsigned int count_ground_ = 0;
-    geometry::Vector<units::si::dimensionless_d> const xAxis_, yAxis_;
-  };
-} // namespace corsika::observation_plane
diff --git a/corsika/process/ParticleCut.hpp b/corsika/process/ParticleCut.hpp
deleted file mode 100644
index 435eb09f3eca7bc731ae7f3916e61c263beb78f4..0000000000000000000000000000000000000000
--- a/corsika/process/ParticleCut.hpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * (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/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/SecondariesProcess.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include "corsika/setup/SetupStack.hpp"
-
-namespace corsika {
-  namespace particle_cut {
-    class ParticleCut : public process::SecondariesProcess<ParticleCut>,
-                        public corsika::process::ContinuousProcess<ParticleCut> {
-
-      units::si::HEPEnergyType const energy_cut_;
-      bool bCutEm;
-      bool bCutInv;
-
-      units::si::HEPEnergyType fEnergy = 0 * units::si::electronvolt;
-      units::si::HEPEnergyType fEmEnergy = 0 * units::si::electronvolt;
-      unsigned int uiEmCount = 0;
-      units::si::HEPEnergyType fInvEnergy = 0 * units::si::electronvolt;
-      unsigned int uiInvCount = 0;
-
-    public:
-      ParticleCut(const units::si::HEPEnergyType vCut)
-          : fECut(vCut) {}
-
-      bool ParticleIsInvisible(particles::Code) const;
-      EProcessReturn DoSecondaries(corsika::StackView&);
-
-      void DoSecondaries(corsika::setup::StackView&);
-
-      EProcessReturn DoContinuous(corsika::setup::Stack::ParticleType& vParticle,
-                                  corsika::setup::Trajectory const& vTrajectory);
-
-      corsika::units::si::LengthType MaxStepLength(
-          corsika::setup::Stack::ParticleType const&, corsika::setup::Trajectory const&) {
-        return units::si::meter * std::numeric_limits<double>::infinity();
-      }
-
-      units::si::HEPEnergyType GetECut() const { return energy_cut_; }
-      units::si::HEPEnergyType GetInvEnergy() const { return fInvEnergy; }
-      units::si::HEPEnergyType GetCutEnergy() const { return fEnergy; }
-      units::si::HEPEnergyType GetEmEnergy() const { return fEmEnergy; }
-      unsigned int GetNumberEmParticles() const { return uiEmCount; }
-      unsigned int GetNumberInvParticles() const { return uiInvCount; }
-
-      void ShowResults() const;
-      void Reset();
-
-    protected:
-      template <typename TParticle>
-      bool checkCutParticle(const TParticle& p);
-
-      template <typename TParticle>
-      bool ParticleIsBelowEnergyCut(TParticle const&) const;
-
-      bool ParticleIsEmParticle(particles::Code) const;
-      bool ParticleIsInvisible(particles::Code) const;
-    };
-  } // namespace particle_cut
-} // namespace corsika
diff --git a/corsika/process/Pythia/Decay.hpp b/corsika/process/Pythia/Decay.hpp
deleted file mode 100644
index 20bbf96943e9d48aee30e876c676e3dc2ae25bd6..0000000000000000000000000000000000000000
--- a/corsika/process/Pythia/Decay.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * (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 <Pythia8/Pythia.h>
-
-#include <iostream>
-#include <vector>
-#include <tuple>
-#include <corsika/setup/SetupStack.hpp>
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/DecayProcess.hpp>
-
-namespace corsika {
-
-  namespace pythia {
-
-    typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector;
-
-    class Decay : public corsika::DecayProcess<Decay> {
-
-      const std::vector<particles::Code> fTrackedParticles;
-      int fCount = 0;
-
-    public:
-      Decay(std::vector<corsika::Code>);
-      ~Decay();
-
-      void SetParticleListStable(std::vector<particles::Code> const&);
-      void SetUnstable(const corsika::Code);
-      void SetStable(const corsika::Code);
-
-      corsika::units::si::TimeType GetLifetime(corsika::Stack::ParticleType const&);
-
-      void DoDecay(corsika::StackView::ParticleType&);
-
-    private:
-      void SetUnstable(const corsika::particles::Code);
-      void SetStable(const corsika::particles::Code);
-      void SetStable(const std::vector<particles::Code>);
-      bool IsStable(const corsika::particles::Code);
-
-      Pythia8::Pythia fPythia;
-      std::set<particles::Code> handledDecays_;
-    };
-
-  } // namespace pythia
-} // namespace corsika
-
-#include <corsika/detail/process/Pythia/Decay.inl>
diff --git a/corsika/process/Pythia/Interaction.hpp b/corsika/process/Pythia/Interaction.hpp
deleted file mode 100644
index e5d473f98904c64362eeaea7f3812981a686c978..0000000000000000000000000000000000000000
--- a/corsika/process/Pythia/Interaction.hpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * (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 <Pythia8/Pythia.h>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/InteractionProcess.hpp>
-#include <corsika/framework/random/RNGManager.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include <tuple>
-
-namespace corsika::pythia {
-
-  class Interaction : public corsika::InteractionProcess<Interaction> {
-
-    int fCount = 0;
-    bool fInitialized = false;
-    bool print_listing_ = false;
-
-  public:
-    Interaction(const bool print_listing = false);
-    ~Interaction() = default;
-
-    void SetParticleListStable(std::vector<particles::Code> const&);
-    void SetUnstable(const corsika::Code);
-    void SetStable(const corsika::Code);
-
-    bool WasInitialized() { return fInitialized; }
-    bool ValidCoMEnergy(corsika::units::si::HEPEnergyType ecm) {
-      using namespace corsika::units::si;
-      return (10_GeV < ecm) && (ecm < 1_PeV);
-    }
-
-    bool CanInteract(const corsika::Code);
-    void ConfigureLabFrameCollision(const corsika::Code, const corsika::Code,
-                                    const corsika::units::si::HEPEnergyType);
-    std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType>
-    GetCrossSection(const corsika::Code BeamId, const corsika::Code TargetId,
-                    const corsika::units::si::HEPEnergyType CoMenergy);
-
-    template <typename TParticle>
-    corsika::units::si::GrammageType GetInteractionLength(const TParticle&);
-
-    /**
-       In this function PYTHIA is called to produce one event. The
-       event is copied (and boosted) into the shower lab frame.
-     */
-
-    template <typename TProjectile>
-    corsika::EProcessReturn DoInteraction(TProjectile&);
-
-  private:
-    corsika::RNG& fRNG = corsika::RNGManager::GetInstance().GetRandomStream("pythia");
-    Pythia8::Pythia fPythia;
-    Pythia8::SigmaTotal fSigma;
-    const bool fInternalDecays = true;
-  };
-
-} // namespace corsika::pythia
-
-#endif
diff --git a/corsika/process/Pythia/Random.hpp b/corsika/process/Pythia/Random.hpp
deleted file mode 100644
index 3858be7933eafae27d2c8f5cfe8d9527478da65b..0000000000000000000000000000000000000000
--- a/corsika/process/Pythia/Random.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * (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 <Pythia8/Pythia.h>
-#include <corsika/framework/random/RNGManager.hpp>
-
-namespace corsika {
-
-  namespace pythia {
-
-    class Random : public Pythia8::RndmEngine {
-      double flat();
-
-    private:
-      std::uniform_real_distribution<double> fDist;
-      corsika::RNG& fRNG = corsika::RNGManager::GetInstance().GetRandomStream("pythia");
-    };
-
-  } // namespace pythia
-} // namespace corsika
-
-#endif
diff --git a/corsika/process/QGSJetII/Interaction.hpp b/corsika/process/QGSJetII/Interaction.hpp
deleted file mode 100644
index fd331d75aac0bb42dca79c03dc520258317a3ba0..0000000000000000000000000000000000000000
--- a/corsika/process/QGSJetII/Interaction.hpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * (c) Copyright 2020 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/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/InteractionProcess.hpp>
-#include <corsika/framework/random/RNGManager.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <string>
-
-namespace corsika::qgsjetII {
-
-  class Interaction : public corsika::InteractionProcess<Interaction> {
-
-    std::string data_path_;
-    int count_ = 0;
-    bool initialized_ = false;
-    QgsjetIIHadronType alternate_ =
-        QgsjetIIHadronType::PiPlusType; // for pi0, rho0 projectiles
-
-  public:
-    Interaction(const std::string& dataPath = "");
-    ~Interaction();
-
-    bool WasInitialized() { return initialized_; }
-    int GetMaxTargetMassNumber() const { return maxMassNumber_; }
-    bool IsValidTarget(corsika::Code TargetId) const {
-      return (corsika::GetNucleusA(TargetId) < maxMassNumber_) &&
-             corsika::IsNucleus(TargetId);
-    }
-
-    corsika::units::si::CrossSectionType GetCrossSection(
-        const corsika::Code, const corsika::Code, const corsika::units::si::HEPEnergyType,
-        const unsigned int Abeam = 0, const unsigned int Atarget = 0) const;
-
-    template <typename TParticle>
-    corsika::units::si::GrammageType GetInteractionLength(TParticle const&) const;
-
-    /**
-       In this function QGSJETII is called to produce one event. The
-       event is copied (and boosted) into the shower lab frame.
-     */
-
-    template <typename TProjectile>
-    corsika::EProcessReturn DoInteraction(TProjectile&);
-
-  private:
-    corsika::RNG& fRNG = corsika::RNGManager::GetInstance().GetRandomStream("qgran");
-    const int maxMassNumber_ = 208;
-  };
-
-} // namespace corsika::qgsjetII
-
-#endif
diff --git a/corsika/process/QGSJetII/ParticleConversion.hpp b/corsika/process/QGSJetII/ParticleConversion.hpp
deleted file mode 100644
index aef660ee28ab3261320d44d386d9bb835100e29b..0000000000000000000000000000000000000000
--- a/corsika/process/QGSJetII/ParticleConversion.hpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * (c) Copyright 2020 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/core/ParticleProperties.hpp>
-
-#include <string>
-
-namespace corsika::qgsjetII {
-
-  /**
-     These are the possible secondaries produced by QGSJetII
-   */
-  enum class QgsjetIICode : int8_t;
-  using QgsjetIICodeIntType = std::underlying_type<QgsjetIICode>::type;
-
-  /**
-     These are the possible projectile for which QGSJetII knwos cross section
-   */
-  enum class QgsjetIIXSClass : int8_t {
-    CannotInteract = 0,
-    LightMesons = 1,
-    Baryons = 2,
-    Kaons = 3,
-  };
-  using QgsjetIIXSClassIntType = std::underlying_type<QgsjetIIXSClass>::type;
-
-  /**
-     These are the only possible projectile types in QGSJetII
-   */
-  enum class QgsjetIIHadronType : int8_t {
-    UndefinedType = 0,
-    PiPlusType = +1,
-    PiMinusType = -1,
-    ProtonType = +2,
-    AntiProtonType = -2,
-    NeutronType = +3,
-    AntiNeutronType = -3,
-    KaonPlusType = +4,
-    KaonMinusType = -4,
-    Kaon0LType = +5,
-    Kaon0SType = -5,
-    // special codes, not in QGSJetII
-    NucleusType = 100,
-    NeutralLightMesonType = 101,
-  };
-  using QgsjetIIHadronTypeIntType = std::underlying_type<QgsjetIIHadronType>::type;
-
-#include <corsika/process/qgsjetII/Generated.inc>
-
-  QgsjetIICode constexpr ConvertToQgsjetII(corsika::Code pCode) {
-    return static_cast<QgsjetIICode>(
-        corsika2qgsjetII[static_cast<corsika::CodeIntType>(pCode)]);
-  }
-
-  corsika::Code constexpr ConvertFromQgsjetII(QgsjetIICode pCode) {
-    auto const pCodeInt = static_cast<QgsjetIICodeIntType>(pCode);
-    auto const corsikaCode = qgsjetII2corsika[pCodeInt - minQgsjetII];
-    if (corsikaCode == corsika::Code::Unknown) {
-      throw std::runtime_error(std::string("QGSJETII/CORSIKA conversion of pCodeInt=")
-                                   .append(std::to_string(pCodeInt))
-                                   .append(" impossible"));
-    }
-    return corsikaCode;
-  }
-
-  int constexpr ConvertToQgsjetIIRaw(corsika::Code pCode) {
-    return static_cast<int>(ConvertToQgsjetII(pCode));
-  }
-
-  int constexpr GetQgsjetIIXSCode(corsika::Code pCode) {
-    if (pCode == corsika::Code::Nucleus) return 2;
-    return corsika2qgsjetIIXStype[static_cast<corsika::CodeIntType>(pCode)];
-  }
-
-  bool constexpr CanInteract(corsika::Code pCode) {
-    return (GetQgsjetIIXSCode(pCode) > 0) && (ConvertToQgsjetIIRaw(pCode) <= 5);
-  }
-
-} // namespace corsika::qgsjetII
-
-} // namespace corsika::process::qgsjetII
diff --git a/corsika/process/QGSJetII/QGSJetIIFragmentsStack.hpp b/corsika/process/QGSJetII/QGSJetIIFragmentsStack.hpp
deleted file mode 100644
index bbb852f245cbeec06a8c8043de741e6232aa4a6e..0000000000000000000000000000000000000000
--- a/corsika/process/QGSJetII/QGSJetIIFragmentsStack.hpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * (c) Copyright 2020 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/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-#include <corsika/process/QGSJetII/ParticleConversion.hpp>
-#include <corsika/process/QGSJetII/qgsjet-II-04.h>
-#include <corsika/framework/stack/Stack.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-namespace corsika::qgsjetII {
-
-  class QGSJetIIFragmentsStackData {
-
-  public:
-    void Dump() const {}
-
-    void Clear() {
-      qgarr13_.nsf = 0;
-      qgarr55_.nwt = 0;
-    }
-    unsigned int GetSize() const { return qgarr13_.nsf; }
-    unsigned int GetCapacity() const { return iapmax; }
-
-    static unsigned int GetWoundedNucleonsTarget() { return qgarr55_.nwt; }
-    static unsigned int GetWoundedNucleonsProjectile() { return qgarr55_.nwp; }
-
-    int GetFragmentSize(const unsigned int i) const { return qgarr13_.iaf[i]; }
-    void SetFragmentSize(const unsigned int i, const int v) { qgarr13_.iaf[i] = v; }
-
-    void Copy(const unsigned int i1, const unsigned int i2) {
-      qgarr13_.iaf[i2] = qgarr13_.iaf[i1];
-    }
-
-    void Swap(const unsigned int i1, const unsigned int i2) {
-      std::swap(qgarr13_.iaf[i1], qgarr13_.iaf[i2]);
-    }
-
-    void IncrementSize() { qgarr13_.nsf++; }
-    void DecrementSize() {
-      if (qgarr13_.nsf > 0) { qgarr13_.nsf--; }
-    }
-  };
-
-  template <typename StackIteratorInterface>
-  class FragmentsInterface : public corsika::ParticleBase<StackIteratorInterface> {
-
-    using corsika::ParticleBase<StackIteratorInterface>::GetStackData;
-    using corsika::ParticleBase<StackIteratorInterface>::GetIndex;
-
-  public:
-    void SetParticleData(const int vSize) { SetFragmentSize(vSize); }
-
-    void SetParticleData(FragmentsInterface<StackIteratorInterface>& /*parent*/,
-                         const int vSize) {
-      SetFragmentSize(vSize);
-    }
-
-    void SetFragmentSize(const int v) { GetStackData().SetFragmentSize(GetIndex(), v); }
-
-    double GetFragmentSize() const { return GetStackData().GetFragmentSize(GetIndex()); }
-  };
-
-  typedef corsika::Stack<QGSJetIIFragmentsStackData, FragmentsInterface>
-      QGSJetIIFragmentsStack;
-
-} // end namespace corsika::qgsjetII
-
-#endif
diff --git a/corsika/process/QGSJetII/QGSJetIIStack.hpp b/corsika/process/QGSJetII/QGSJetIIStack.hpp
deleted file mode 100644
index 403fa90322c13f3e8bd2da2a3abfd3d5a035456f..0000000000000000000000000000000000000000
--- a/corsika/process/QGSJetII/QGSJetIIStack.hpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * (c) Copyright 2020 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/geometry/CoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-#include <corsika/process/QGSJetII/ParticleConversion.hpp>
-#include <corsika/process/QGSJetII/qgsjet-II-04.h>
-#include <corsika/framework/stack/Stack.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-namespace corsika::qgsjetII {
-
-  typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector;
-
-  class QGSJetIIStackData {
-
-  public:
-    void Dump() const {}
-
-    void Clear() {
-      qgarr12_.nsp = 0;
-      qgarr13_.nsf = 0;
-      qgarr55_.nwt = 0;
-    }
-    unsigned int GetSize() const { return qgarr12_.nsp; }
-    unsigned int GetCapacity() const { return nptmax; }
-
-    void SetId(const unsigned int i, const int v) { qgarr14_.ich[i] = v; }
-    void SetEnergy(const unsigned int i, const corsika::units::si::HEPEnergyType v) {
-      using namespace corsika::units::si;
-      qgarr14_.esp[i][0] = v / 1_GeV;
-    }
-
-    void SetMomentum(const unsigned int i, const MomentumVector& v) {
-      using namespace corsika::units::si;
-      auto tmp = v.GetComponents();
-      qgarr14_.esp[i][2] = tmp[0] / 1_GeV;
-      qgarr14_.esp[i][3] = tmp[1] / 1_GeV;
-      qgarr14_.esp[i][1] = tmp[2] / 1_GeV;
-    }
-
-    int GetId(const unsigned int i) const { return qgarr14_.ich[i]; }
-    corsika::units::si::HEPEnergyType GetEnergy(const int i) const {
-      using namespace corsika::units::si;
-      return qgarr14_.esp[i][0] * 1_GeV;
-    }
-    MomentumVector GetMomentum(const unsigned int i,
-                               const corsika::CoordinateSystem& CS) const {
-      using namespace corsika::units::si;
-      geometry::QuantityVector<hepmomentum_d> components = {qgarr14_.esp[i][2] * 1_GeV,
-                                                            qgarr14_.esp[i][3] * 1_GeV,
-                                                            qgarr14_.esp[i][1] * 1_GeV};
-      return MomentumVector(CS, components);
-    }
-
-    void Copy(const unsigned int i1, const unsigned int i2) {
-      qgarr14_.ich[i2] = qgarr14_.ich[i1];
-      for (unsigned int i = 0; i < 4; ++i) qgarr14_.esp[i2][i] = qgarr14_.esp[i1][i];
-    }
-
-    void Swap(const unsigned int i1, const unsigned int i2) {
-      std::swap(qgarr14_.ich[i1], qgarr14_.ich[i2]);
-      for (unsigned int i = 0; i < 4; ++i)
-        std::swap(qgarr14_.esp[i1][i], qgarr14_.esp[i2][i]);
-    }
-
-    void IncrementSize() { qgarr12_.nsp++; }
-    void DecrementSize() {
-      if (qgarr12_.nsp > 0) { qgarr12_.nsp--; }
-    }
-  };
-
-  template <typename StackIteratorInterface>
-  class ParticleInterface : public corsika::ParticleBase<StackIteratorInterface> {
-
-    using corsika::ParticleBase<StackIteratorInterface>::GetStackData;
-    using corsika::ParticleBase<StackIteratorInterface>::GetIndex;
-
-  public:
-    void SetParticleData(const int vID, const corsika::units::si::HEPEnergyType vE,
-                         const MomentumVector& vP,
-                         const corsika::units::si::HEPMassType) {
-      SetPID(vID);
-      SetEnergy(vE);
-      SetMomentum(vP);
-    }
-
-    void SetParticleData(ParticleInterface<StackIteratorInterface>& /*parent*/,
-                         const int vID, const corsika::units::si::HEPEnergyType vE,
-                         const MomentumVector& vP,
-                         const corsika::units::si::HEPMassType) {
-      SetPID(vID);
-      SetEnergy(vE);
-      SetMomentum(vP);
-    }
-
-    void SetEnergy(const corsika::units::si::HEPEnergyType v) {
-      GetStackData().SetEnergy(GetIndex(), v);
-    }
-
-    corsika::units::si::HEPEnergyType GetEnergy() const {
-      return GetStackData().GetEnergy(GetIndex());
-    }
-
-    void SetPID(const int v) { GetStackData().SetId(GetIndex(), v); }
-
-    corsika::qgsjetII::QgsjetIICode GetPID() const {
-      return static_cast<corsika::qgsjetII::QgsjetIICode>(
-          GetStackData().GetId(GetIndex()));
-    }
-
-    MomentumVector GetMomentum(const corsika::CoordinateSystem& CS) const {
-      return GetStackData().GetMomentum(GetIndex(), CS);
-    }
-
-    void SetMomentum(const MomentumVector& v) {
-      GetStackData().SetMomentum(GetIndex(), v);
-    }
-  };
-
-  typedef corsika::Stack<QGSJetIIStackData, ParticleInterface> QGSJetIIStack;
-
-} // end namespace corsika::qgsjetII
-
-#endif
diff --git a/corsika/process/QGSJetII/qgsjet-II-04.h b/corsika/process/QGSJetII/qgsjet-II-04.h
deleted file mode 100644
index f9f75d826371873fc9985fb05478c48c81ab17dc..0000000000000000000000000000000000000000
--- a/corsika/process/QGSJetII/qgsjet-II-04.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * (c) Copyright 2020 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 <string>
-
-//----------------------------------------------
-//  C++ interface for the QGSJetII event generator
-//----------------------------------------------
-// wrapper
-
-extern "C" {
-
-// data memory layout
-
-extern struct { int nsp; } qgarr12_;
-
-const int nptmax = 95000;
-const int iapmax = 208;
-
-extern struct {
-  double esp[nptmax][4];
-  int ich[nptmax];
-} qgarr14_;
-
-extern struct {
-  // c nsf - number of secondary fragments;
-  // c iaf(i) - mass of the i-th fragment
-  int nsf;
-  int iaf[iapmax];
-} qgarr13_;
-
-extern struct {
-  int nwt;
-  int nwp;
-} qgarr55_;
-
-/**
-   Small helper class to provide a data-directory name in the format qgsjetII expects
- */
-class datadir {
-private:
-  datadir operator=(const std::string& dir);
-  datadir operator=(const datadir&);
-
-public:
-  datadir(const std::string& dir);
-  char data[132];
-};
-
-// functions
-void qgset_();
-void qgaini_(
-    const char* datdir); // Note: there is a length limiation 132 from fortran-qgsjet here
-
-/**
-   @function qgini_
-
-   additional initialization procedure per event
-
-   @parameter e0n  - interaction energy (per hadron/nucleon),
-   @parameter icp0 - hadron type (+-1 - pi+-, +-2 - p(p~), +-3 - n(n~), +-4 - K+-, +-5 -
-   K_l/s),
-   @parameter iap  - projectile mass number (1 - for a hadron),
-   @parameter iat  - target mass number
-*/
-void qgini_(const double& e0n, const int& icp0, const int& iap, const int& iat);
-
-/**
-   @function qgconf_
-
-   generate one event configuration
-*/
-void qgconf_();
-
-/**
-   @function qgsect_
-
-   hadron-nucleus (hadron-nucleus) particle production cross section
-
-   @parameter e0n lab. energy per projectile nucleon (hadron)
-   @parameter icz hadron class (1 - pion, 2 - nucleon, 3 - kaon)
-   @parameter iap projectile mass number (1=<iap<=iapmax),
-   @parameter iat target mass number     (1=<iat<=iapmax)
- */
-double qgsect_(const double& e0n, const int& icz, const int& iap0, const int& iat0);
-
-/**
-   @function qgran
-
-   link to random number generation
- */
-double qgran_(int&);
-}
diff --git a/corsika/process/Sibyll/Decay.hpp b/corsika/process/Sibyll/Decay.hpp
deleted file mode 100644
index dbd009dcfe0a7f0d33c7c0467034e92f4dd38839..0000000000000000000000000000000000000000
--- a/corsika/process/Sibyll/Decay.hpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * (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/core/ParticleProperties.hpp>
-#include <corsika/process/DecayProcess.h>
-#include <corsika/framework/sequence/SecondariesProcess.hpp>
-
-#include <set>
-#include <vector>
-
-namespace corsika {
-
-  namespace sibyll {
-
-    class Decay : public corsika::DecayProcess<Decay> {
-      int fCount = 0;
-
-    public:
-      Decay(const bool sibyll_listing = false);
-      Decay(std::set<particles::Code>);
-      ~Decay();
-      void Init();
-
-      void SetStable(const std::vector<particles::Code>);
-      void SetUnstable(const std::vector<particles::Code>);
-      void SetUnstable(const corsika::Code);
-      void SetStable(const corsika::Code);
-      void SetAllUnstable();
-      void SetAllStable();
-      bool IsStable(const corsika::Code);
-      bool IsUnstable(const corsika::Code);
-      void SetDecay(const particles::Code, const bool);
-
-      void PrintDecayConfig(const corsika::Code);
-      void SetHadronsUnstable();
-
-      // is Sibyll::Decay set to handle the decay of this particle?
-      bool IsDecayHandled(const corsika::particles::Code);
-
-      // is decay possible in principle?
-      bool CanHandleDecay(const corsika::particles::Code);
-
-      // set Sibyll::Decay to handle the decay of this particle!
-      void SetHandleDecay(const corsika::particles::Code);
-      // set Sibyll::Decay to handle the decay of this list of particles!
-      void SetHandleDecay(const std::vector<particles::Code>);
-      // set Sibyll::Decay to handle all particle decays
-      void SetHandleAllDecay();
-
-      template <typename TParticle>
-      corsika::units::si::TimeType GetLifetime(TParticle const&);
-
-      /**
-       In this function SIBYLL is called to produce to decay the input particle.
-     */
-
-      template <typename TSecondaryView>
-      void DoDecay(TSecondaryView&);
-
-      template <typename TParticleView>
-      EProcessReturn DoSecondaries(TParticleView&);
-
-    private:
-      // internal routines to set particles stable and unstable in the COMMON blocks in
-      // sibyll
-      void SetStable(const std::vector<particles::Code>);
-      void SetUnstable(const std::vector<particles::Code>);
-
-      void SetStable(const corsika::particles::Code);
-      void SetUnstable(const corsika::particles::Code);
-
-      // internally set all particles to decay/not to decay
-      void SetAllUnstable();
-      void SetAllStable();
-
-      // will this particle be stable in sibyll ?
-      bool IsStable(const corsika::particles::Code);
-      // will this particle decay in sibyll ?
-      bool IsUnstable(const corsika::particles::Code);
-      // set particle with input code to decay or not
-      void SetDecay(const particles::Code, const bool);
-
-      std::set<particles::Code> handledDecays_;
-    };
-
-  } // namespace sibyll
-
-} // namespace corsika
-
-#endif
diff --git a/corsika/process/Sibyll/Interaction.hpp b/corsika/process/Sibyll/Interaction.hpp
deleted file mode 100644
index 9c263aaa59b6dc1f1d617ce6ef9fc70fb21a934c..0000000000000000000000000000000000000000
--- a/corsika/process/Sibyll/Interaction.hpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * (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/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/InteractionProcess.hpp>
-#include <corsika/framework/random/RNGManager.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include <tuple>
-
-namespace corsika::sibyll {
-
-  class Interaction : public corsika::InteractionProcess<Interaction> {
-
-    int count_ = 0;
-    int nucCount_ = 0;
-    static bool initialized_; ///! flag to assure init is done only once
-    bool sibyll_listing_;
-
-  public:
-    Interaction(const bool sibyll_printout_on = false);
-    ~Interaction();
-
-    void Init();
-
-    void SetStable(std::vector<particles::Code> const&);
-    void SetUnstable(std::vector<particles::Code> const&);
-
-    void SetUnstable(const corsika::Code);
-    void SetStable(const corsika::Code);
-    void SetAllUnstable();
-    void SetAllStable();
-
-    static bool WasInitialized() { return initialized_; }
-    bool IsValidCoMEnergy(corsika::units::si::HEPEnergyType ecm) const {
-      return (minEnergyCoM_ <= ecm) && (ecm <= maxEnergyCoM_);
-    }
-    int GetMaxTargetMassNumber() const { return maxTargetMassNumber_; }
-    corsika::units::si::HEPEnergyType GetMinEnergyCoM() const { return minEnergyCoM_; }
-    corsika::units::si::HEPEnergyType GetMaxEnergyCoM() const { return maxEnergyCoM_; }
-    bool IsValidTarget(corsika::Code TargetId) const {
-      return (corsika::GetNucleusA(TargetId) < maxTargetMassNumber_) &&
-             corsika::IsNucleus(TargetId);
-    }
-
-    std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType>
-    GetCrossSection(const corsika::Code, const corsika::Code,
-                    const corsika::units::si::HEPEnergyType) const;
-
-    template <typename TParticle>
-    corsika::units::si::GrammageType GetInteractionLength(const TParticle&) const;
-
-    /**
-       In this function SIBYLL is called to produce one event. The
-       event is copied (and boosted) into the shower lab frame.
-     */
-
-    template <typename TProjectile>
-    corsika::EProcessReturn DoInteraction(TProjectile&);
-
-  private:
-    corsika::RNG& RNG_ = corsika::RNGManager::GetInstance().GetRandomStream("s_rndm");
-    // FOR NOW keep trackedParticles private, could be configurable
-    std::vector<particles::Code> const trackedParticles_ = {
-        particles::Code::PiPlus,     particles::Code::PiMinus,
-        particles::Code::Pi0,        particles::Code::KMinus,
-        particles::Code::KPlus,      particles::Code::K0Long,
-        particles::Code::K0Short,    particles::Code::SigmaPlus,
-        particles::Code::Sigma0,     particles::Code::Sigma0Bar,
-        particles::Code::SigmaMinus, particles::Code::Lambda0,
-        particles::Code::Xi0,        particles::Code::XiMinus,
-        particles::Code::OmegaMinus, particles::Code::DPlus,
-        particles::Code::DMinus,     particles::Code::D0,
-        particles::Code::MuMinus,    particles::Code::MuPlus,
-        particles::Code::D0Bar};
-    const bool internalDecays_ = true;
-    const corsika::units::si::HEPEnergyType minEnergyCoM_ =
-        10. * 1e9 * corsika::units::si::electronvolt;
-    const corsika::units::si::HEPEnergyType maxEnergyCoM_ =
-        1.e6 * 1e9 * corsika::units::si::electronvolt;
-    const int maxTargetMassNumber_ = 18;
-  };
-
-} // namespace corsika::sibyll
-
-#endif
diff --git a/corsika/process/Sibyll/NuclearInteraction.hpp b/corsika/process/Sibyll/NuclearInteraction.hpp
deleted file mode 100644
index a587bf0f82fa002c089ac4cca36848d669c4ac07..0000000000000000000000000000000000000000
--- a/corsika/process/Sibyll/NuclearInteraction.hpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * (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/core/ParticleProperties.hpp>
-#include <corsika/framework/sequence/InteractionProcess.hpp>
-#include <corsika/framework/random/RNGManager.hpp>
-
-namespace corsika::sibyll {
-
-  class Interaction; // fwd-decl
-
-  /**
-   *
-   *
-   **/
-  template <class TEnvironment>
-  class NuclearInteraction
-      : public corsika::InteractionProcess<NuclearInteraction<TEnvironment>> {
-
-    int count_ = 0;
-    int nucCount_ = 0;
-
-  public:
-    NuclearInteraction(corsika::sibyll::Interaction&, TEnvironment const&);
-    ~NuclearInteraction();
-
-    void InitializeNuclearCrossSections();
-    void PrintCrossSectionTable(corsika::Code);
-    corsika::units::si::CrossSectionType ReadCrossSectionTable(
-        const int, corsika::Code, corsika::units::si::HEPEnergyType);
-    corsika::units::si::HEPEnergyType GetMinEnergyPerNucleonCoM() {
-      return gMinEnergyPerNucleonCoM_;
-    }
-    corsika::units::si::HEPEnergyType GetMaxEnergyPerNucleonCoM() {
-      return gMaxEnergyPerNucleonCoM_;
-    }
-    unsigned int constexpr GetMaxNucleusAProjectile() { return gMaxNucleusAProjectile_; }
-    unsigned int constexpr GetMaxNFragments() { return gMaxNFragments_; }
-    unsigned int constexpr GetNEnergyBins() { return gNEnBins_; }
-
-    template <typename Particle>
-    std::tuple<corsika::units::si::CrossSectionType, corsika::units::si::CrossSectionType>
-    GetCrossSection(Particle& p, const corsika::Code TargetId);
-
-    template <typename Particle>
-    corsika::units::si::GrammageType GetInteractionLength(Particle const&);
-
-    template <typename Projectile>
-    corsika::EProcessReturn DoInteraction(Projectile&);
-
-  private:
-    TEnvironment const& environment_;
-    corsika::sibyll::Interaction& hadronicInteraction_;
-    std::map<corsika::Code, int> targetComponentsIndex_;
-    corsika::RNG& RNG_ = corsika::RNGManager::GetInstance().GetRandomStream("s_rndm");
-    static constexpr int gNSample_ =
-        500; // number of samples in MC estimation of cross section
-    static constexpr unsigned int gMaxNucleusAProjectile_ = 56;
-    static constexpr unsigned int gNEnBins_ = 6;
-    static constexpr unsigned int gMaxNFragments_ = 60;
-    // energy limits defined by table used for cross section in signuc.f
-    // 10**1 GeV to 10**6 GeV
-    static constexpr corsika::units::si::HEPEnergyType gMinEnergyPerNucleonCoM_ =
-        10. * 1e9 * corsika::units::si::electronvolt;
-    static constexpr corsika::units::si::HEPEnergyType gMaxEnergyPerNucleonCoM_ =
-        1.e6 * 1e9 * corsika::units::si::electronvolt;
-  };
-
-} // namespace corsika::sibyll
-
-#endif
diff --git a/corsika/process/Sibyll/ParticleConversion.h b/corsika/process/Sibyll/ParticleConversion.h
deleted file mode 100644
index a2bc716cafd56e9a1aa8a52c4448f4466510a79b..0000000000000000000000000000000000000000
--- a/corsika/process/Sibyll/ParticleConversion.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * (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/core/ParticleProperties.hpp>
-
-#include <string>
-
-namespace corsika::sibyll {
-
-  enum class SibyllCode : int8_t;
-  using SibyllCodeIntType = std::underlying_type<SibyllCode>::type;
-
-  /**
-     These are the possible projectile for which Sibyll knows the cross section
-   */
-  enum class SibyllXSClass : int8_t {
-    CannotInteract = 0,
-    Baryon = 1,
-    Pion = 2,
-    Kaon = 3,
-  };
-  using SibyllXSClassIntType = std::underlying_type<SibyllXSClass>::type;
-
-#include <corsika/process/sibyll/Generated.inc>
-
-  SibyllCode constexpr ConvertToSibyll(corsika::Code pCode) {
-    return static_cast<SibyllCode>(
-        corsika2sibyll[static_cast<corsika::CodeIntType>(pCode)]);
-  }
-
-  corsika::Code constexpr ConvertFromSibyll(SibyllCode pCode) {
-    auto const s = static_cast<SibyllCodeIntType>(pCode);
-    auto const corsikaCode = sibyll2corsika[s - minSibyll];
-    if (corsikaCode == corsika::Code::Unknown) {
-      throw std::runtime_error(std::string("SIBYLL/CORSIKA conversion of ")
-                                   .append(std::to_string(s))
-                                   .append(" impossible"));
-    }
-    return corsikaCode;
-  }
-
-  int constexpr ConvertToSibyllRaw(corsika::Code pCode) {
-    return static_cast<int>(ConvertToSibyll(pCode));
-  }
-
-  int constexpr GetSibyllXSCode(corsika::Code pCode) {
-    return corsika2sibyllXStype[static_cast<corsika::CodeIntType>(pCode)];
-  }
-
-  bool constexpr CanInteract(corsika::Code pCode) {
-    return GetSibyllXSCode(pCode) > 0;
-  }
-
-} // namespace corsika::sibyll
-
-} // namespace corsika::process::sibyll
diff --git a/corsika/process/Sibyll/SibStack.hpp b/corsika/process/Sibyll/SibStack.hpp
deleted file mode 100644
index 1217468313febf5f11782e01ed67c0980f6179b4..0000000000000000000000000000000000000000
--- a/corsika/process/Sibyll/SibStack.hpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * (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/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-#include <corsika/process/sibyll/ParticleConversion.h>
-#include <corsika/process/sibyll/sibyll2.3c.h>
-#include <corsika/framework/stack/Stack.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-namespace corsika::sibyll {
-
-  typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector;
-
-  class SibStackData {
-
-  public:
-    void Dump() const {}
-
-    void Clear() { s_plist_.np = 0; }
-    unsigned int GetSize() const { return s_plist_.np; }
-    unsigned int GetCapacity() const { return 8000; }
-
-    void SetId(const unsigned int i, const int v) { s_plist_.llist[i] = v; }
-    void SetEnergy(const unsigned int i, const corsika::units::si::HEPEnergyType v) {
-      using namespace corsika::units::si;
-      s_plist_.p[3][i] = v / 1_GeV;
-    }
-    void SetMass(const unsigned int i, const corsika::units::si::HEPMassType v) {
-      using namespace corsika::units::si;
-      s_plist_.p[4][i] = v / 1_GeV;
-    }
-    void SetMomentum(const unsigned int i, const MomentumVector& v) {
-      using namespace corsika::units::si;
-      auto tmp = v.GetComponents();
-      for (int idx = 0; idx < 3; ++idx) s_plist_.p[idx][i] = tmp[idx] / 1_GeV;
-    }
-
-    int GetId(const unsigned int i) const { return s_plist_.llist[i]; }
-    corsika::units::si::HEPEnergyType GetEnergy(const int i) const {
-      using namespace corsika::units::si;
-      return s_plist_.p[3][i] * 1_GeV;
-    }
-    corsika::units::si::HEPEnergyType GetMass(const unsigned int i) const {
-      using namespace corsika::units::si;
-      return s_plist_.p[4][i] * 1_GeV;
-    }
-    MomentumVector GetMomentum(const unsigned int i) const {
-      using corsika::CoordinateSystem;
-      using corsika::QuantityVector;
-      using corsika::RootCoordinateSystem;
-      using namespace corsika::units::si;
-      CoordinateSystem& rootCS =
-          RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-      QuantityVector<hepmomentum_d> components = {
-          s_plist_.p[0][i] * 1_GeV, s_plist_.p[1][i] * 1_GeV, s_plist_.p[2][i] * 1_GeV};
-      return MomentumVector(rootCS, components);
-    }
-
-    void Copy(const unsigned int i1, const unsigned int i2) {
-      s_plist_.llist[i2] = s_plist_.llist[i1];
-      for (unsigned int i = 0; i < 5; ++i) s_plist_.p[i][i2] = s_plist_.p[i][i1];
-    }
-
-    void Swap(const unsigned int i1, const unsigned int i2) {
-      std::swap(s_plist_.llist[i1], s_plist_.llist[i2]);
-      for (unsigned int i = 0; i < 5; ++i)
-        std::swap(s_plist_.p[i][i1], s_plist_.p[i][i2]);
-    }
-
-    void IncrementSize() { s_plist_.np++; }
-    void DecrementSize() {
-      if (s_plist_.np > 0) { s_plist_.np--; }
-    }
-  };
-
-  template <typename StackIteratorInterface>
-  class ParticleInterface : public corsika::ParticleBase<StackIteratorInterface> {
-
-    using corsika::ParticleBase<StackIteratorInterface>::GetStackData;
-    using corsika::ParticleBase<StackIteratorInterface>::GetIndex;
-
-  public:
-    void SetParticleData(const int vID, // corsika::sibyll::SibyllCode vID,
-                         const corsika::units::si::HEPEnergyType vE,
-                         const MomentumVector& vP,
-                         const corsika::units::si::HEPMassType vM) {
-      SetPID(vID);
-      SetEnergy(vE);
-      SetMomentum(vP);
-      SetMass(vM);
-    }
-
-    void SetParticleData(ParticleInterface<StackIteratorInterface>& /*parent*/,
-                         const int vID, //  corsika::sibyll::SibyllCode vID,
-                         const corsika::units::si::HEPEnergyType vE,
-                         const MomentumVector& vP,
-                         const corsika::units::si::HEPMassType vM) {
-      SetPID(vID);
-      SetEnergy(vE);
-      SetMomentum(vP);
-      SetMass(vM);
-    }
-
-    void SetEnergy(const corsika::units::si::HEPEnergyType v) {
-      GetStackData().SetEnergy(GetIndex(), v);
-    }
-
-    corsika::units::si::HEPEnergyType GetEnergy() const {
-      return GetStackData().GetEnergy(GetIndex());
-    }
-
-    bool HasDecayed() const { return abs(GetStackData().GetId(GetIndex())) > 100; }
-
-    void SetMass(const corsika::units::si::HEPMassType v) {
-      GetStackData().SetMass(GetIndex(), v);
-    }
-
-    corsika::units::si::HEPEnergyType GetMass() const {
-      return GetStackData().GetMass(GetIndex());
-    }
-
-    void SetPID(const int v) { GetStackData().SetId(GetIndex(), v); }
-
-    corsika::sibyll::SibyllCode GetPID() const {
-      return static_cast<corsika::sibyll::SibyllCode>(GetStackData().GetId(GetIndex()));
-    }
-
-    MomentumVector GetMomentum() const { return GetStackData().GetMomentum(GetIndex()); }
-
-    void SetMomentum(const MomentumVector& v) {
-      GetStackData().SetMomentum(GetIndex(), v);
-    }
-  };
-
-  typedef corsika::Stack<SibStackData, ParticleInterface> SibStack;
-
-} // end namespace corsika::sibyll
-
-#endif
diff --git a/corsika/process/StackInspector.hpp b/corsika/process/StackInspector.hpp
deleted file mode 100644
index ff9169d4d5ddd00efe9929d882b646cf4e214dfd..0000000000000000000000000000000000000000
--- a/corsika/process/StackInspector.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * (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/sequence/StackProcess.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <chrono>
-#include "corsika/setup/SetupTrajectory.hpp"
-
-namespace corsika {
-
-  namespace stack_inspector {
-
-    template <typename TStack>
-    class StackInspector : public corsika::StackProcess<StackInspector<TStack>> {
-
-      typedef typename TStack::ParticleType Particle;
-
-      using corsika::StackProcess<StackInspector<TStack>>::GetStep;
-
-    public:
-      StackInspector(const int vNStep, const bool vReportStack,
-                     const corsika::units::si::HEPEnergyType vE0);
-      ~StackInspector();
-
-      void DoStack(const TStack&);
-
-      /**
-       * To set a new E0, for example when a new shower event is started
-       */
-      void SetE0(const corsika::units::si::HEPEnergyType vE0) { E0_ = vE0; }
-
-    private:
-      bool ReportStack_;
-      corsika::units::si::HEPEnergyType E0_;
-      const corsika::units::si::HEPEnergyType dE_threshold_ = std::invoke([]() {
-        using namespace units::si;
-        return 1_eV;
-      });
-      decltype(std::chrono::system_clock::now()) StartTime_;
-    };
-
-  } // namespace stack_inspector
-
-} // namespace corsika
diff --git a/corsika/process/SwitchProcess.hpp b/corsika/process/SwitchProcess.hpp
deleted file mode 100644
index 2c08016fd5c89c83ca1ed9d3dad89a2e0b9033b5..0000000000000000000000000000000000000000
--- a/corsika/process/SwitchProcess.hpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * (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/sequence/InteractionProcess.hpp>
-#include <corsika/framework/sequence/ProcessSequence.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include "corsika/setup/SetupStack.hpp"
-
-namespace corsika::switch_process {
-
-  /**
-   * This process provides an energy-based switch between two interaction processes P1 and
-   * P2. For energies below the threshold, P1 is invoked, otherwise P2. Both can be either
-   * single interaction processes or multiple ones combined in a ProcessSequence. A
-   * SwitchProcess itself will always be regarded as a distinct case when assembled into a
-   * (greater) ProcessSequence.
-   */
-
-  template <class TLowEProcess, class THighEProcess>
-  class SwitchProcess : public BaseProcess<SwitchProcess<TLowEProcess, THighEProcess>> {
-    TLowEProcess& fLowEProcess;
-    THighEProcess& fHighEProcess;
-    units::si::HEPEnergyType const fThresholdEnergy;
-
-  public:
-    SwitchProcess(TLowEProcess& vLowEProcess, THighEProcess& vHighEProcess,
-                  units::si::HEPEnergyType vThresholdEnergy)
-        : fLowEProcess(vLowEProcess)
-        , fHighEProcess(vHighEProcess)
-        , fThresholdEnergy(vThresholdEnergy) {}
-
-    template <typename TParticle>
-    corsika::units::si::InverseGrammageType GetInverseInteractionLength(TParticle& p) {
-      return 1 / GetInteractionLength(p);
-    }
-
-    template <typename TParticle>
-    units::si::GrammageType GetInteractionLength(TParticle& vParticle) {
-      if (vParticle.GetEnergy() < fThresholdEnergy) {
-        if constexpr (is_process_sequence_v<TLowEProcess>) {
-          return fLowEProcess.GetTotalInteractionLength(vParticle);
-        } else {
-          return fLowEProcess.GetInteractionLength(vParticle);
-        }
-      } else {
-        if constexpr (is_process_sequence_v<THighEProcess>) {
-          return fHighEProcess.GetTotalInteractionLength(vParticle);
-        } else {
-          return fHighEProcess.GetInteractionLength(vParticle);
-        }
-      }
-    }
-
-    // required to conform to ProcessSequence interface. We cannot just
-    // implement DoInteraction() because we want to call SelectInteraction
-    // in case a member process is a ProcessSequence.
-    template <typename TParticle, typename TSecondaries>
-    EProcessReturn SelectInteraction(
-        TParticle& vP, TSecondaries& vS,
-        [[maybe_unused]] corsika::units::si::InverseGrammageType lambda_select,
-        corsika::units::si::InverseGrammageType& lambda_inv_count) {
-      if (vP.GetEnergy() < fThresholdEnergy) {
-        if constexpr (is_process_sequence_v<TLowEProcess> ||
-                      is_switch_process_v<TLowEProcess>) {
-          return fLowEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count);
-        } else {
-          lambda_inv_count += fLowEProcess.GetInverseInteractionLength(vP);
-          // check if we should execute THIS process and then EXIT
-          if (lambda_select < lambda_inv_count) {
-            fLowEProcess.DoInteraction(vS);
-            return EProcessReturn::eInteracted;
-          } else {
-            return EProcessReturn::eOk;
-          }
-        }
-      } else {
-        if constexpr (is_process_sequence_v<THighEProcess> ||
-                      is_switch_process_v<THighEProcess>) {
-          return fHighEProcess.SelectInteraction(vP, vS, lambda_select, lambda_inv_count);
-        } else {
-          lambda_inv_count += fHighEProcess.GetInverseInteractionLength(vP);
-          // check if we should execute THIS process and then EXIT
-          if (lambda_select < lambda_inv_count) {
-            fHighEProcess.DoInteraction(vS);
-            return EProcessReturn::eInteracted;
-          } else {
-            return EProcessReturn::eOk;
-          }
-        }
-      }
-    }
-  };
-} // namespace corsika::switch_process
diff --git a/corsika/process/TrackWriter.hpp b/corsika/process/TrackWriter.hpp
deleted file mode 100644
index d0f9d84622b2c6726daae7f43ae3522806e46a9f..0000000000000000000000000000000000000000
--- a/corsika/process/TrackWriter.hpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * (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/sequence/ContinuousProcess.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <fstream>
-#include <string>
-
-namespace corsika::track_writer {
-
-  class TrackWriter : public corsika::ContinuousProcess<TrackWriter> {
-
-  public:
-    TrackWriter(std::string const& filename);
-
-    template <typename Particle, typename Track>
-    corsika::EProcessReturn DoContinuous(Particle&, Track&);
-
-    template <typename Particle, typename Track>
-    corsika::units::si::LengthType MaxStepLength(Particle&, Track&) {
-      return units::si::meter * std::numeric_limits<double>::infinity();
-    }
-
-  private:
-    std::string const fFilename;
-    std::ofstream fFile;
-
-    int width = 14;
-    int precision = 6;
-  };
-
-} // namespace corsika::track_writer
diff --git a/corsika/process/detail/EnergyLoss.cc b/corsika/process/detail/EnergyLoss.cc
deleted file mode 100644
index 6e6d44ac7305f3cb58ad95b301355c8b0fabf8b0..0000000000000000000000000000000000000000
--- a/corsika/process/detail/EnergyLoss.cc
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/energy_loss/EnergyLoss.h>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-
-#include <corsika/framework/geometry/Line.hpp>
-
-#include <cmath>
-#include <fstream>
-#include <iostream>
-#include <limits>
-#include <numeric>
-
-#include "../corsika/setup/SetupStack.hpp"
-#include "../corsika/setup/SetupTrajectory.hpp"
-
-using namespace std;
-
-using namespace corsika;
-using namespace corsika::units::si;
-using SetupParticle = corsika::Stack::ParticleType;
-using SetupTrack = corsika::Trajectory;
-
-namespace corsika {
-
-  auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-    return sqrt((Elab - m) * (Elab + m));
-  };
-
-  /**
-   *   PDG2018, passage of particles through matter
-   *
-   * Note, that \f$I_{\mathrm{eff}}\f$ of composite media a determined from \f$ \ln I =
-   * \sum_i a_i \ln(I_i) \f$ where \f$ a_i \f$ is the fraction of the electron population
-   * (\f$\sim Z_i\f$) of the \f$i\f$-th element. This can also be used for shell
-   * corrections or density effects.
-   *
-   * The \f$I_{\mathrm{eff}}\f$ of compounds is not better than a few percent, if not
-   * measured explicitly.
-   *
-   * For shell correction, see Sec 6 of https://www.nap.edu/read/20066/chapter/8#115
-   *
-   */
-  HEPEnergyType EnergyLoss::BetheBloch(SetupParticle const& p, GrammageType const dX) {
-
-    // all these are material constants and have to come through Environment
-    // right now: values for nitrogen_D
-    // 7 nitrogen_gas 82.0 0.49976 D E 0.0011653 0.0 1.7378 4.1323 0.15349 3.2125 10.54
-    auto Ieff = 82.0_eV;
-    [[maybe_unused]] auto Zmat = 7;
-    auto ZoverA = 0.49976_mol / 1_g;
-    const double x0 = 1.7378;
-    const double x1 = 4.1323;
-    const double Cbar = 10.54;
-    const double delta0 = 0.0;
-    const double aa = 0.15349;
-    const double sk = 3.2125;
-    // end of material constants
-
-    // this is the Bethe-Bloch coefficiet 4pi N_A r_e^2 m_e c^2
-    auto constexpr K = 0.307075_MeV / 1_mol * square(1_cm);
-    HEPEnergyType const E = p.GetEnergy();
-    HEPMassType const m = p.GetMass();
-    double const gamma = E / m;
-    int const Z = p.GetChargeNumber();
-    int const Z2 = Z * Z;
-    HEPMassType constexpr me = particles::Electron::GetMass();
-    auto const m2 = m * m;
-    auto constexpr me2 = me * me;
-    double const gamma2 = gamma * gamma;
-
-    double const beta2 = (gamma2 - 1) / gamma2; // 1-1/gamma2    (1-1/gamma)*(1+1/gamma);
-                                                // (gamma_2-1)/gamma_2 = (1-1/gamma2);
-    double constexpr c2 = 1;                    // HEP convention here c=c2=1
-    cout << "BetheBloch beta2=" << beta2 << " gamma2=" << gamma2 << endl;
-    [[maybe_unused]] double const eta2 = beta2 / (1 - beta2);
-    HEPMassType const Wmax =
-        2 * me * c2 * beta2 * gamma2 / (1 + 2 * gamma * me / m + me2 / m2);
-    // approx, but <<1%    HEPMassType const Wmax = 2*me*c2*beta2*gamma2;      for HEAVY
-    // PARTICLES Wmax ~ 2me v2 for non-relativistic particles
-    cout << "BetheBloch Wmax=" << Wmax << endl;
-
-    // Sternheimer parameterization, density corrections towards high energies
-    // NOTE/TODO: when Cbar is 0 it needs to be approximated from parameterization ->
-    // MISSING
-    cout << "BetheBloch p.GetMomentum().GetNorm()/m=" << p.GetMomentum().GetNorm() / m
-         << endl;
-    double const x = log10(p.GetMomentum().GetNorm() / m);
-    double delta = 0;
-    if (x >= x1) {
-      delta = 2 * (log(10)) * x - Cbar;
-    } else if (x < x1 && x >= x0) {
-      delta = 2 * (log(10)) * x - Cbar + aa * pow((x1 - x), sk);
-    } else if (x < x0) { // and IF conductor (otherwise, this is 0)
-      delta = delta0 * pow(100, 2 * (x - x0));
-    }
-    cout << "BetheBloch delta=" << delta << endl;
-
-    // with further low energies correction, accurary ~1% down to beta~0.05 (1MeV for p)
-
-    // shell correction, <~100MeV
-    // need more clarity about formulas and units
-    const double Cadj = 0;
-    /*
-    // https://www.nap.edu/read/20066/chapter/8#104
-    HEPEnergyType Iadj = 12_eV * Z + 7_eV;  // Iadj<163eV
-    if (Iadj>=163_eV)
-      Iadj = 9.76_eV * Z + 58.8_eV * pow(Z, -0.19);  // Iadj>=163eV
-    double const Cadj = (0.422377/eta2 + 0.0304043/(eta2*eta2) -
-    0.00038106/(eta2*eta2*eta2)) * 1e-6 * Iadj*Iadj + (3.858019/eta2 -
-    0.1667989/(eta2*eta2) + 0.00157955/(eta2*eta2*eta2)) * 1e-9 * Iadj*Iadj*Iadj;
-    */
-
-    // Barkas correction O(Z3) higher-order Born approximation
-    // see Appl. Phys. 85 (1999) 1249
-    // double A = 1;
-    // if (p.GetPID() == particles::Code::Nucleus) A = p.GetNuclearA();
-    // double const Erel = (p.GetEnergy()-p.GetMass()) / A / 1_keV;
-    // double const Llow = 0.01 * Erel;
-    // double const Lhigh = 1.5/pow(Erel, 0.4) + 45000./Zmat * pow(Erel, 1.6);
-    // double const barkas = Z * Llow*Lhigh/(Llow+Lhigh); // RU, I think the Z was
-    // missing...
-    double const barkas = 1; // does not work yet
-
-    // Bloch correction for O(Z4) higher-order Born approximation
-    // see Appl. Phys. 85 (1999) 1249
-    const double alpha = 1. / 137.035999173;
-    double const y2 = Z * Z * alpha * alpha / beta2;
-    double const bloch = -y2 * (1.202 - y2 * (1.042 - 0.855 * y2 + 0.343 * y2 * y2));
-
-    // cout << "BetheBloch Erel=" << Erel << " barkas=" << barkas << " bloch=" << bloch <<
-    // endl;
-
-    double const aux = 2 * me * c2 * beta2 * gamma2 * Wmax / (Ieff * Ieff);
-    return -K * Z2 * ZoverA / beta2 *
-           (0.5 * log(aux) - beta2 - Cadj / Z - delta / 2 + barkas + bloch) * dX;
-  }
-
-EnergyLoss::EnergyLoss(environment::ShowerAxis const& shower_axis,
-                       corsika::units::si::HEPEnergyType emCut)
-    : shower_axis_(shower_axis)
-    , emCut_(emCut)
-    , profile_(int(shower_axis.maximumX() / dX_) + 1) {}
-
-auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-  return sqrt((Elab - m) * (Elab + m));
-};
-
-/**
- *   PDG2018, passage of particles through matter
- *
- * Note, that \f$I_{\mathrm{eff}}\f$ of composite media a determined from \f$ \ln I =
- * \sum_i a_i \ln(I_i) \f$ where \f$ a_i \f$ is the fraction of the electron population
- * (\f$\sim Z_i\f$) of the \f$i\f$-th element. This can also be used for shell
- * corrections or density effects.
- *
- * The \f$I_{\mathrm{eff}}\f$ of compounds is not better than a few percent, if not
- * measured explicitly.
- *
- * For shell correction, see Sec 6 of https://www.nap.edu/read/20066/chapter/8#115
- *
- */
-HEPEnergyType EnergyLoss::BetheBloch(SetupParticle const& p, GrammageType const dX) {
-
-  // all these are material constants and have to come through Environment
-  // right now: values for nitrogen_D
-  // 7 nitrogen_gas 82.0 0.49976 D E 0.0011653 0.0 1.7378 4.1323 0.15349 3.2125 10.54
-  auto Ieff = 82.0_eV;
-  [[maybe_unused]] auto Zmat = 7;
-  auto ZoverA = 0.49976_mol / 1_g;
-  const double x0 = 1.7378;
-  const double x1 = 4.1323;
-  const double Cbar = 10.54;
-  const double delta0 = 0.0;
-  const double aa = 0.15349;
-  const double sk = 3.2125;
-  // end of material constants
-
-  // this is the Bethe-Bloch coefficiet 4pi N_A r_e^2 m_e c^2
-  auto constexpr K = 0.307075_MeV / 1_mol * square(1_cm);
-  HEPEnergyType const E = p.GetEnergy();
-  HEPMassType const m = p.GetMass();
-  double const gamma = E / m;
-  int const Z = p.GetChargeNumber();
-  int const Z2 = Z * Z;
-  HEPMassType constexpr me = particles::Electron::GetMass();
-  auto const m2 = m * m;
-  auto constexpr me2 = me * me;
-  double const gamma2 = gamma * gamma;
-
-  double const beta2 = (gamma2 - 1) / gamma2; // 1-1/gamma2    (1-1/gamma)*(1+1/gamma);
-                                              // (gamma_2-1)/gamma_2 = (1-1/gamma2);
-  double constexpr c2 = 1;                    // HEP convention here c=c2=1
-  C8LOG_DEBUG("BetheBloch beta2={}, gamma2={}", beta2, gamma2);
-  [[maybe_unused]] double const eta2 = beta2 / (1 - beta2);
-  HEPMassType const Wmax =
-      2 * me * c2 * beta2 * gamma2 / (1 + 2 * gamma * me / m + me2 / m2);
-  // approx, but <<1%    HEPMassType const Wmax = 2*me*c2*beta2*gamma2;      for HEAVY
-  // PARTICLES Wmax ~ 2me v2 for non-relativistic particles
-  C8LOG_DEBUG("BetheBloch Wmax={}", Wmax);
-
-  // Sternheimer parameterization, density corrections towards high energies
-  // NOTE/TODO: when Cbar is 0 it needs to be approximated from parameterization ->
-  // MISSING
-  C8LOG_DEBUG("BetheBloch p.GetMomentum().GetNorm()/m{}=", p.GetMomentum().GetNorm() / m);
-  double const x = log10(p.GetMomentum().GetNorm() / m);
-  double delta = 0;
-  if (x >= x1) {
-    delta = 2 * (log(10)) * x - Cbar;
-  } else if (x < x1 && x >= x0) {
-    delta = 2 * (log(10)) * x - Cbar + aa * pow((x1 - x), sk);
-  } else if (x < x0) { // and IF conductor (otherwise, this is 0)
-    delta = delta0 * pow(100, 2 * (x - x0));
-  }
-
-  void EnergyLoss::MomentumUpdate(corsika::Stack::ParticleType& vP,
-                                  corsika::units::si::HEPEnergyType Enew) {
-    HEPMomentumType Pnew = elab2plab(Enew, vP.GetMass());
-    auto pnew = vP.GetMomentum();
-    vP.SetMomentum(pnew * Pnew / pnew.GetNorm());
-  }
-
-  void EnergyLoss::FillProfile(SetupParticle const& vP, SetupTrack const& vTrack,
-                               const HEPEnergyType dE) {
-
-    using namespace corsika;
-
-    auto const toStart = vTrack.GetPosition(0) - InjectionPoint_;
-    auto const toEnd = vTrack.GetPosition(1) - InjectionPoint_;
-
-    auto const v1 = (toStart * 1_Hz).dot(ShowerAxisDirection_);
-    auto const v2 = (toEnd * 1_Hz).dot(ShowerAxisDirection_);
-    geometry::Line const lineToStartBin(InjectionPoint_, ShowerAxisDirection_ * v1);
-    geometry::Line const lineToEndBin(InjectionPoint_, ShowerAxisDirection_ * v2);
-
-    SetupTrack const trajToStartBin(lineToStartBin, 1_s);
-    SetupTrack const trajToEndBin(lineToEndBin, 1_s);
-
-    GrammageType const grammageStart =
-        vP.GetNode()->GetModelProperties().IntegratedGrammage(trajToStartBin,
-                                                              trajToStartBin.GetLength());
-    GrammageType const grammageEnd =
-        vP.GetNode()->GetModelProperties().IntegratedGrammage(trajToEndBin,
-                                                              trajToEndBin.GetLength());
-
-    const int binStart = grammageStart / dX_;
-    const int binEnd = grammageEnd / dX_;
-
-    std::cout << "energy deposit of " << -dE << " between " << grammageStart << " and "
-              << grammageEnd << std::endl;
-
-    auto energyCount = HEPEnergyType::zero();
-
-    auto fill = [&](int bin, GrammageType weight) {
-      const auto dX = grammageEnd - grammageStart;
-      if (dX > dX_threshold_) {
-        auto const increment = -dE * weight / (grammageEnd - grammageStart);
-        Profile_[bin] += increment;
-        energyCount += increment;
-
-        std::cout << "filling bin " << bin << " with weight " << weight << ": "
-                  << increment << std::endl;
-      }
-    };
-
-    // fill longitudinal profile
-    fill(binStart, (1 + binStart) * dX_ - grammageStart);
-    fill(binEnd, grammageEnd - binEnd * dX_);
-
-    if (binStart == binEnd) { fill(binStart, -dX_); }
-
-    for (int bin = binStart + 1; bin < binEnd; ++bin) { fill(bin, dX_); }
-
-  // fill longitudinal profile
-  if (binStart == binEnd) {
-    fill(binStart, 1);
-  } else {
-    fill(binStart, ((1 + binStart) * dX_ - grammageStart) / deltaX);
-    fill(binEnd, (grammageEnd - binEnd * dX_) / deltaX);
-    for (int bin = binStart + 1; bin < binEnd; ++bin) { fill(bin, 1); }
-  }
-
-  C8LOG_DEBUG("total energy added to histogram: {} ", energyCount);
-}
-
-void EnergyLoss::PrintProfile() const {
-  std::ofstream file("EnergyLossProfile.dat");
-  file << "# EnergyLoss profile" << std::endl
-       << "# lower X bin edge [g/cm2]  dE/dX [GeV/g/cm2]" << endl;
-  double const deltaX = dX_ / 1_g * square(1_cm);
-  for (size_t i = 0; i < profile_.size(); ++i) {
-    file << std::scientific << std::setw(15) << i * deltaX << std::setw(15)
-         << profile_.at(i) / (deltaX * 1_GeV) << endl;
-  }
-
-} // namespace corsika
diff --git a/corsika/process/detail/HadronicElasticModel.cc b/corsika/process/detail/HadronicElasticModel.cc
deleted file mode 100644
index a7fad5814c73ce63029c04575beb48e9c4d14ed5..0000000000000000000000000000000000000000
--- a/corsika/process/detail/HadronicElasticModel.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/hadronic_elastic_model/HadronicElasticModel.h>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-#include <corsika/framework/geometry/FourVector.hpp>
-#include <corsika/framework/random/ExponentialDistribution.hpp>
-#include <corsika/framework/utility/COMBoost.hpp>
-
-#include <iomanip>
-#include <iostream>
-#include "../corsika/setup/SetupStack.hpp"
-
-using namespace corsika;
-using SetupParticle = corsika::Stack::ParticleType;
-
-namespace corsika::HadronicElasticModel {
-
-  void HadronicElasticInteraction::Init() {}
-
-  HadronicElasticInteraction::HadronicElasticInteraction(units::si::CrossSectionType x,
-                                                         units::si::CrossSectionType y)
-      : fX(x)
-      , fY(y) {}
-
-  template <>
-  units::si::GrammageType HadronicElasticInteraction::GetInteractionLength(
-      SetupParticle const& p) {
-    using namespace units::si;
-    if (p.GetPID() == particles::Code::Proton) {
-      auto const* currentNode = p.GetNode();
-      auto const& mediumComposition =
-          currentNode->GetModelProperties().GetNuclearComposition();
-
-      auto const& components = mediumComposition.GetComponents();
-      auto const& fractions = mediumComposition.GetFractions();
-
-      auto const projectileMomentum = p.GetMomentum();
-      auto const projectileMomentumSquaredNorm = projectileMomentum.squaredNorm();
-      auto const projectileEnergy = p.GetEnergy();
-
-HadronicElasticInteraction::HadronicElasticInteraction(units::si::CrossSectionType x,
-                                                       units::si::CrossSectionType y)
-    : fX(x)
-    , fY(y) {}
-
-template <>
-units::si::GrammageType HadronicElasticInteraction::GetInteractionLength(
-    SetupParticle const& p) {
-  using namespace units::si;
-  if (p.GetPID() == particles::Code::Proton) {
-    auto const* currentNode = p.GetNode();
-    auto const& mediumComposition =
-        currentNode->GetModelProperties().GetNuclearComposition();
-
-    auto const& components = mediumComposition.GetComponents();
-    auto const& fractions = mediumComposition.GetFractions();
-
-    auto const projectileMomentum = p.GetMomentum();
-    auto const projectileMomentumSquaredNorm = projectileMomentum.squaredNorm();
-    auto const projectileEnergy = p.GetEnergy();
-
-    auto const avgCrossSection = [&]() {
-      CrossSectionType avgCrossSection = 0_b;
-
-      for (size_t i = 0; i < fractions.size(); ++i) {
-        auto const targetMass = particles::GetMass(components[i]);
-        auto const s = units::static_pow<2>(projectileEnergy + targetMass) -
-                       projectileMomentumSquaredNorm;
-        avgCrossSection += CrossSection(s) * fractions[i];
-      }
-
-      std::cout << "avgCrossSection: " << avgCrossSection / 1_mb << " mb" << std::endl;
-
-      return avgCrossSection;
-    }();
-
-    auto const avgTargetMassNumber = mediumComposition.GetAverageMassNumber();
-
-    GrammageType const interactionLength =
-        avgTargetMassNumber * units::constants::u / avgCrossSection;
-
-    return interactionLength;
-  } else {
-    return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
-  }
-}
-
-template <>
-process::EProcessReturn HadronicElasticInteraction::DoInteraction(SetupView& view) {
-  using namespace units::si;
-  using namespace units::constants;
-
-  auto p = view.GetProjectile();
-  if (p.GetPID() != particles::Code::Proton) { return process::EProcessReturn::eOk; }
-
-  const auto* currentNode = p.GetNode();
-  const auto& composition = currentNode->GetModelProperties().GetNuclearComposition();
-  const auto& components = composition.GetComponents();
-
-  std::vector<units::si::CrossSectionType> cross_section_of_components(
-      composition.GetComponents().size());
-
-  auto const projectileMomentum = p.GetMomentum();
-  auto const projectileMomentumSquaredNorm = projectileMomentum.squaredNorm();
-  auto const projectileEnergy = p.GetEnergy();
-
-  for (size_t i = 0; i < components.size(); ++i) {
-    auto const targetMass = particles::GetMass(components[i]);
-    auto const s = units::static_pow<2>(projectileEnergy + targetMass) -
-                   projectileMomentumSquaredNorm;
-    cross_section_of_components[i] = CrossSection(s);
-  }
-
-} // namespace corsika::HadronicElasticModel
diff --git a/corsika/process/detail/ObservationPlane.cc b/corsika/process/detail/ObservationPlane.cc
deleted file mode 100644
index 402d9c0f303ce3f21155c9f57a93926c14a22a67..0000000000000000000000000000000000000000
--- a/corsika/process/detail/ObservationPlane.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * (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/process/observation_plane/ObservationPlane.hpp>
-
-#include <fstream>
-
-using namespace corsika::observation_plane;
-using namespace corsika::units::si;
-
-ObservationPlane::ObservationPlane(
-    geometry::Plane const& obsPlane,
-    geometry::Vector<units::si::dimensionless_d> const& x_axis,
-    std::string const& filename, bool deleteOnHit)
-    : plane_(obsPlane)
-    , outputStream_(filename)
-    , deleteOnHit_(deleteOnHit)
-    , energy_ground_(0_GeV)
-    , count_ground_(0)
-    , xAxis_(x_axis.normalized())
-    , yAxis_(obsPlane.GetNormal().cross(xAxis_)) {
-  outputStream_ << "#PDG code, energy / eV, x distance / m, y distance / m" << std::endl;
-}
-
-corsika::EProcessReturn ObservationPlane::DoContinuous(
-    setup::Stack::ParticleType const& particle, setup::Trajectory const& trajectory) {
-  TimeType const timeOfIntersection =
-      (plane_.GetCenter() - trajectory.GetLine().GetR0()).dot(plane_.GetNormal()) /
-      trajectory.GetLine().GetV0().dot(plane_.GetNormal());
-
-  if (timeOfIntersection < TimeType::zero()) { return process::EProcessReturn::eOk; }
-
-  if (plane_.IsAbove(trajectory.GetLine().GetR0()) ==
-      plane_.IsAbove(trajectory.GetPosition(1))) {
-    return process::EProcessReturn::eOk;
-  }
-
-  const auto energy = particle.GetEnergy();
-  auto const displacement = trajectory.GetPosition(1) - plane_.GetCenter();
-
-  outputStream_ << static_cast<int>(particles::GetPDG(particle.GetPID())) << ' '
-                << energy / 1_eV << ' ' << displacement.dot(xAxis_) / 1_m << ' '
-                << displacement.dot(yAxis_) / 1_m
-                << (trajectory.GetPosition(1) - plane_.GetCenter()).norm() / 1_m
-                << std::endl;
-
-  if (deleteOnHit_) {
-    count_ground_++;
-    energy_ground_ += energy;
-    particle.Delete();
-    return process::EProcessReturn::eParticleAbsorbed;
-  } else {
-    return process::EProcessReturn::eOk;
-  }
-}
-
-LengthType ObservationPlane::MaxStepLength(setup::Stack::ParticleType const& vParticle,
-                                           setup::Trajectory const& trajectory) {
-  int chargeNumber;
-  if (corsika::particles::IsNucleus(vParticle.GetPID())) {
-    chargeNumber = vParticle.GetNuclearZ();
-  } else {
-    chargeNumber = corsika::particles::GetChargeNumber(vParticle.GetPID());
-  }
-  auto const* currentLogicalVolumeNode = vParticle.GetNode();
-  auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField(
-      vParticle.GetPosition());
-  auto direction = trajectory.GetLine().GetV0().normalized();
-
-  if (chargeNumber != 0 &&
-      abs(plane_.GetNormal().dot(trajectory.GetLine().GetV0().cross(magneticfield))) *
-              1_s / 1_m / 1_T >
-          1e-6) {
-    auto const* currentLogicalVolumeNode = vParticle.GetNode();
-    auto magneticfield = currentLogicalVolumeNode->GetModelProperties().GetMagneticField(
-        vParticle.GetPosition());
-    auto k = chargeNumber * corsika::units::constants::c * 1_eV /
-             (vParticle.GetMomentum().norm() * 1_V);
-
-    if (direction.dot(plane_.GetNormal()) * direction.dot(plane_.GetNormal()) -
-            (plane_.GetNormal().dot(trajectory.GetLine().GetR0() - plane_.GetCenter()) *
-             plane_.GetNormal().dot(direction.cross(magneticfield)) * 2 * k) <
-        0) {
-      return std::numeric_limits<double>::infinity() * 1_m;
-    }
-
-    LengthType MaxStepLength1 =
-        (sqrt(direction.dot(plane_.GetNormal()) * direction.dot(plane_.GetNormal()) -
-              (plane_.GetNormal().dot(trajectory.GetLine().GetR0() - plane_.GetCenter()) *
-               plane_.GetNormal().dot(direction.cross(magneticfield)) * 2 * k)) -
-         direction.dot(plane_.GetNormal()) / direction.GetNorm()) /
-        (plane_.GetNormal().dot(direction.cross(magneticfield)) * k);
-
-    LengthType MaxStepLength2 =
-        (-sqrt(
-             direction.dot(plane_.GetNormal()) * direction.dot(plane_.GetNormal()) -
-             (plane_.GetNormal().dot(trajectory.GetLine().GetR0() - plane_.GetCenter()) *
-              plane_.GetNormal().dot(direction.cross(magneticfield)) * 2 * k)) -
-         direction.dot(plane_.GetNormal()) / direction.GetNorm()) /
-        (plane_.GetNormal().dot(direction.cross(magneticfield)) * k);
-
-    if (MaxStepLength1 <= 0_m && MaxStepLength2 <= 0_m) {
-      return std::numeric_limits<double>::infinity() * 1_m;
-    } else if (MaxStepLength1 <= 0_m || MaxStepLength2 < MaxStepLength1) {
-      std::cout << " steplength to obs plane 2: " << MaxStepLength2 << std::endl;
-      return MaxStepLength2 *
-             (direction + direction.cross(magneticfield) * MaxStepLength2 * k / 2)
-                 .norm() *
-             1.001;
-    } else if (MaxStepLength2 <= 0_m || MaxStepLength1 < MaxStepLength2) {
-      std::cout << " steplength to obs plane 1: " << MaxStepLength1 << std::endl;
-      return MaxStepLength1 *
-             (direction + direction.cross(magneticfield) * MaxStepLength2 * k / 2)
-                 .norm() *
-             1.001;
-    }
-  }
-  TimeType const timeOfIntersection =
-      (plane_.GetCenter() - trajectory.GetLine().GetR0()).dot(plane_.GetNormal()) /
-      trajectory.GetLine().GetV0().dot(plane_.GetNormal());
-
-  if (timeOfIntersection < TimeType::zero()) {
-    return std::numeric_limits<double>::infinity() * 1_m;
-  }
-
-  auto const pointOfIntersection = trajectory.GetLine().GetPosition(timeOfIntersection);
-  std::cout << " obs plane non b-field " << std::endl;
-  return (trajectory.GetLine().GetR0() - pointOfIntersection).norm() * 1.0001;
-}
-
-void ObservationPlane::ShowResults() const {
-  C8LOG_INFO(
-      " ******************************\n"
-      " ObservationPlane: \n"
-      " energy in ground (GeV)     :  {}\n"
-      " no. of particles in ground :  {}\n"
-      " ******************************",
-      energy_ground_ / 1_GeV, count_ground_);
-}
-
-void ObservationPlane::Reset() {
-  energy_ground_ = 0_GeV;
-  count_ground_ = 0;
-}
diff --git a/corsika/process/detail/ParticleCut.cc b/corsika/process/detail/ParticleCut.cc
deleted file mode 100644
index 5cd87dad75a07b89679bee90efc33e05997620dd..0000000000000000000000000000000000000000
--- a/corsika/process/detail/ParticleCut.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/particle_cut/ParticleCut.hpp>
-
-using namespace std;
-
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::units::si;
-using namespace corsika;
-using namespace corsika;
-
-namespace corsika {
-  namespace particle_cut {
-
-    template <typename TParticle>
-    bool ParticleCut::ParticleIsBelowEnergyCut(TParticle const& vP) const {
-      auto const energyLab = vP.GetEnergy();
-      // nuclei
-      if (vP.GetPID() == particles::Code::Nucleus) {
-        // calculate energy per nucleon
-        auto const ElabNuc = energyLab / vP.GetNuclearA();
-        return (ElabNuc <= energy_cut_);
-      } else {
-        return (energyLab <= energy_cut_);
-      }
-    }
-
-    bool ParticleCut::ParticleIsEmParticle(Code vCode) const {
-      switch (vCode) {
-        case Code::Gamma:
-        case Code::Electron:
-        case Code::Positron:
-          return true;
-        default:
-          return false;
-      }
-    }
-
-    bool ParticleCut::ParticleIsInvisible(Code vCode) const {
-      switch (vCode) {
-        case Code::NuE:
-        case Code::NuEBar:
-        case Code::NuMu:
-        case Code::NuMuBar:
-          return true;
-
-        default:
-          return false;
-      }
-    }
-
-    EProcessReturn ParticleCut::DoSecondaries(corsika::StackView& vS) {
-      auto p = vS.begin();
-      while (p != vS.end()) {
-        const Code pid = p.GetPID();
-        HEPEnergyType energy = p.GetEnergy();
-        cout << "ProcessCut: DoSecondaries: " << pid << " E= " << energy
-             << ", EcutTot=" << (fEmEnergy + fInvEnergy + fEnergy) / 1_GeV << " GeV"
-             << endl;
-        if (ParticleIsEmParticle(pid)) {
-          cout << "removing em. particle..." << endl;
-          fEmEnergy += energy;
-          fEmCount += 1;
-          p.Delete();
-        } else if (ParticleIsInvisible(pid)) {
-          cout << "removing inv. particle..." << endl;
-          fInvEnergy += energy;
-          fInvCount += 1;
-          p.Delete();
-        } else if (ParticleIsBelowEnergyCut(p)) {
-          cout << "removing low en. particle..." << endl;
-          fEnergy += energy;
-          p.Delete();
-        } else if (p.GetTime() > 10_ms) {
-          cout << "removing OLD particle..." << endl;
-          fEnergy += energy;
-          p.Delete();
-        } else {
-          ++p; // next entry in SecondaryView
-        }
-      }
-      return false; // this particle will not be removed/cut
-    }
-
-    void ParticleCut::DoSecondaries(corsika::setup::StackView& vS) {
-      auto particle = vS.begin();
-      while (particle != vS.end()) {
-        if (checkCutParticle(particle)) { particle.Delete(); }
-        ++particle; // next entry in SecondaryView
-      }
-    }
-
-    process::EProcessReturn ParticleCut::DoContinuous(
-        corsika::setup::Stack::ParticleType& particle,
-        corsika::setup::Trajectory const&) {
-      C8LOG_TRACE("ParticleCut::DoContinuous");
-      if (checkCutParticle(particle)) {
-        C8LOG_TRACE("removing during continuous");
-        particle.Delete();
-        // signal to upstream code that this particle was deleted
-        return process::EProcessReturn::eParticleAbsorbed;
-      }
-      return process::EProcessReturn::eOk;
-    }
-
-    ParticleCut::ParticleCut(const units::si::HEPEnergyType eCut, bool em, bool inv)
-        : energy_cut_(eCut)
-        , bCutEm(em)
-        , bCutInv(inv) {
-      fEmEnergy = 0_GeV;
-      uiEmCount = 0;
-      fInvEnergy = 0_GeV;
-      uiInvCount = 0;
-      fEnergy = 0_GeV;
-    }
-
-    // LCOV_EXCL_START
-    void ParticleCut::ShowResults() const {
-      C8LOG_INFO(fmt::format(
-          " ******************************\n"
-          " ParticleCut: \n"
-          " energy in em.  component (GeV):  {}\n"
-          " no. of em.  particles injected:  {}\n"
-          " energy in inv. component (GeV):  {}\n"
-          " no. of inv. particles injected:  {}\n"
-          " energy below particle cut (GeV): {}\n"
-          " ******************************",
-          fEmEnergy / 1_GeV, uiEmCount, fInvEnergy / 1_GeV, uiInvCount, fEnergy / 1_GeV));
-    }
-    // LCOV_EXCL_STOP
-
-    void ParticleCut::Reset() {
-      fEmEnergy = 0_GeV;
-      uiEmCount = 0;
-      fInvEnergy = 0_GeV;
-      uiInvCount = 0;
-      fEnergy = 0_GeV;
-    }
-
-  } // namespace particle_cut
-} // namespace corsika
diff --git a/corsika/process/detail/Pythia/Decay.cc b/corsika/process/detail/Pythia/Decay.cc
deleted file mode 100644
index e79d534bd7245c2ad81ab8459f658d4ade4edde3..0000000000000000000000000000000000000000
--- a/corsika/process/detail/Pythia/Decay.cc
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * (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.
- */
-
-#include <Pythia8/Pythia.h>
-#include <corsika/process/pythia/Decay.h>
-#include <corsika/process/pythia/Random.h>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using std::cout;
-using std::endl;
-using std::tuple;
-using std::vector;
-
-using namespace corsika;
-using namespace corsika;
-using Projectile = corsika::StackView::ParticleType;
-using Particle = corsika::Stack::ParticleType;
-using Track = Trajectory;
-
-namespace corsika::pythia {
-
-  Decay::Decay(const bool print_listing)
-      : print_listing_(print_listing) {
-
-    // set random number generator in pythia
-    Pythia8::RndmEngine* rndm = new corsika::pythia::Random();
-    fPythia.setRndmEnginePtr(rndm);
-
-    /*
-       issue xyz: definition of particles and decay channels use the same mechanism in
-       corsika and pythia we should force pythia to use the file in corsika.
-     */
-    // bool ParticleData::reInit(string startFile, bool xmlFormat = true)
-    // read in particle data from Corsika 8
-    // fPythia.particleData.reInit("/home/felix/ngcorsika/corsika-build/include/corsika/particles/ParticleData.xml");
-    // fPythia.particleData.checkTable();
-
-    fPythia.readString("Next:numberShowInfo = 0");
-    fPythia.readString("Next:numberShowProcess = 0");
-    fPythia.readString("Next:numberShowEvent = 0");
-
-    fPythia.readString("Print:quiet = on");
-    fPythia.readString("Check:particleData = 0");
-
-    /*
-       switching off event check in pythia is needed to allow decays that are off-shell
-       according to the mass definition in pythia.
-       the consistency of particle masses between event generators is an unsolved issues
-    */
-    cout << "Pythia::Init: switching off event checking in pythia.." << endl;
-    fPythia.readString("Check:event = 1");
-
-    fPythia.readString("ProcessLevel:all = off");
-    fPythia.readString("ProcessLevel:resonanceDecays = off");
-
-    // making sure
-    SetStable(particles::Code::Pi0);
-
-    //    fPythia.particleData.readString("59:m0 = 101.00");
-
-    if (!fPythia.init())
-      throw std::runtime_error("Pythia::Decay: Initialization failed!");
-  }
-
-  Decay::Decay(std::set<particles::Code> vHandled)
-      : handleAllDecays_(false)
-      , handledDecays_(vHandled) {}
-
-  Decay::~Decay() { cout << "Pythia::Decay n=" << fCount << endl; }
-
-  bool Decay::CanHandleDecay(const particles::Code vParticleCode) {
-    using namespace corsika::particles;
-    // if known to pythia and not proton, electron or neutrino it can decay
-    if (vParticleCode == Code::Proton || vParticleCode == Code::AntiProton ||
-        vParticleCode == Code::NuE || vParticleCode == Code::NuMu ||
-        vParticleCode == Code::NuTau || vParticleCode == Code::NuEBar ||
-        vParticleCode == Code::NuMuBar || vParticleCode == Code::NuTauBar ||
-        vParticleCode == Code::Electron || vParticleCode == Code::Positron)
-      return false;
-    else if (CanDecay(vParticleCode)) // non-zero for particles known to sibyll
-      return true;
-    else
-      return false;
-  }
-
-  void Decay::SetHandleDecay(const particles::Code vParticleCode) {
-    handleAllDecays_ = false;
-    cout << "Pythia::Decay: set to handle decay of " << vParticleCode << endl;
-    if (Decay::CanHandleDecay(vParticleCode))
-      handledDecays_.insert(vParticleCode);
-    else
-      throw std::runtime_error("this decay can not be handled by pythia!");
-  }
-
-  void Decay::SetHandleDecay(const vector<particles::Code> vParticleList) {
-    handleAllDecays_ = false;
-    for (auto p : vParticleList) SetHandleDecay(p);
-  }
-
-  bool Decay::IsDecayHandled(const corsika::particles::Code vParticleCode) {
-    if (handleAllDecays_ && CanHandleDecay(vParticleCode))
-      return true;
-    else
-      return handledDecays_.find(vParticleCode) != Decay::handledDecays_.end();
-  }
-
-  bool Decay::IsStable(const particles::Code vCode) {
-    return fPythia.particleData.canDecay(static_cast<int>(particles::GetPDG(vCode)));
-  }
-
-  void Decay::PrintDecayConfig(const particles::Code vCode) {
-    cout << "Decay: Pythia decay configuration:" << endl;
-    cout << vCode << " is ";
-    if (IsStable(vCode))
-      cout << "stable" << endl;
-    else
-      cout << "unstable" << endl;
-  }
-
-  void Decay::PrintDecayConfig() {
-    cout << "Pythia::Decay: decay configuration:" << endl;
-    if (handleAllDecays_)
-      cout << " all particles known to Pythia are handled by Pythia::Decay!" << endl;
-    else
-      for (auto& pCode : handledDecays_)
-        cout << "Decay of " << pCode << " is handled by Pythia!" << endl;
-  }
-
-  void Decay::SetStable(const vector<particles::Code> particleList) {
-    for (auto p : particleList) Decay::SetStable(p);
-  }
-
-  bool Decay::CanDecay(const particles::Code pCode) {
-    std::cout << "Pythia::Decay: checking if particle: " << pCode
-              << " can decay in PYTHIA? ";
-    const bool ans =
-        fPythia.particleData.canDecay(static_cast<int>(particles::GetPDG(pCode)));
-    std::cout << ans << std::endl;
-    return ans;
-  }
-
-  void Decay::SetUnstable(const particles::Code pCode) {
-    cout << "Pythia::Decay: setting " << pCode << " unstable.." << endl;
-    fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), true);
-  }
-
-  void Decay::SetStable(const particles::Code pCode) {
-    cout << "Pythia::Decay: setting " << pCode << " stable.." << endl;
-    fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), false);
-  }
-
-  template <>
-  units::si::TimeType Decay::GetLifetime(Particle const& vP) {
-    using namespace units::si;
-
-    const auto pid = vP.GetPID();
-    if (CanDecay(pid)) {
-      HEPEnergyType E = vP.GetEnergy();
-      HEPMassType m = vP.GetMass();
-
-      const double gamma = E / m;
-
-      const TimeType t0 = particles::GetLifetime(pid);
-      auto const lifetime = gamma * t0;
-      cout << "Pythia::Decay: code: " << vP.GetPID() << endl;
-      cout << "Pythia::Decay: MinStep: t0: " << t0 << endl;
-      cout << "Pythia::Decay: MinStep: energy: " << E / 1_GeV << " GeV" << endl;
-      cout << "Pythia::Decay: momentum: " << vP.GetMomentum().GetComponents() / 1_GeV
-           << " GeV" << endl;
-      cout << "Pythia::Decay: MinStep: gamma: " << gamma << endl;
-      cout << "Pythia::Decay: MinStep: tau: " << lifetime << endl;
-
-      return lifetime;
-    } else
-      return std::numeric_limits<double>::infinity() * 1_s;
-  }
-
-  template <>
-  void Decay::DoDecay(View& view) {
-    using geometry::Point;
-    using namespace units;
-    using namespace units::si;
-
-    auto const projectile = view.GetProjectile();
-
-    auto const& decayPoint = projectile.GetPosition();
-    auto const t0 = projectile.GetTime();
-
-    auto const& labMomentum = projectile.GetMomentum();
-    geometry::CoordinateSystem const& labCS = labMomentum.GetCoordinateSystem();
-
-    // define target kinematics in lab frame
-    // define boost to and from CoM frame
-    // CoM frame definition in Pythia projectile: +z
-    utl::COMBoost const boost(labMomentum, projectile.GetMass());
-    auto const& rotatedCS = boost.GetRotatedCS();
-
-    fCount++;
-
-    // pythia stack
-    Pythia8::Event& event = fPythia.event;
-    event.reset();
-
-    auto const particleId = projectile.GetPID();
-
-    // set particle unstable
-    Decay::SetUnstable(particleId);
-
-    // input particle PDG
-    auto const pdgCode = static_cast<int>(particles::GetPDG(particleId));
-
-    double constexpr px = 0;
-    double constexpr py = 0;
-    double constexpr pz = 0;
-    double const en = projectile.GetMass() / 1_GeV;
-    double const m = en;
-
-    // add particle to pythia stack
-    event.append(pdgCode, 1, 0, 0, px, py, pz, en, m);
-
-    if (!fPythia.next())
-      throw std::runtime_error("Pythia::Decay: decay failed!");
-    else
-      cout << "Pythia::Decay: particles after decay: " << event.size() << endl;
-
-    if (print_listing_) {
-      // list final state
-      event.list();
-    }
-
-    // loop over final state
-    for (int i = 0; i < event.size(); ++i)
-      if (event[i].isFinal()) {
-        auto const pyId =
-            particles::ConvertFromPDG(static_cast<particles::PDGCode>(event[i].id()));
-        HEPEnergyType const Erest = event[i].e() * 1_GeV;
-        MomentumVector const pRest(
-            rotatedCS,
-            {event[i].px() * 1_GeV, event[i].py() * 1_GeV, event[i].pz() * 1_GeV});
-        geometry::FourVector const fourMomRest{Erest, pRest};
-        auto const fourMomLab = boost.fromCoM(fourMomRest);
-
-        cout << "particle: id=" << pyId << " momentum="
-             << fourMomLab.GetSpaceLikeComponents().GetComponents(labCS) / 1_GeV
-             << " energy=" << fourMomLab.GetTimeLikeComponent() << endl;
-
-        view.AddSecondary(
-            tuple<particles::Code, units::si::HEPEnergyType,
-                  corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-                pyId, pyEn, pyP, decayPoint, t0});
-      }
-
-    // set particle stable
-    Decay::SetStable(particleId);
-  }
-
-} // namespace corsika::pythia
diff --git a/corsika/process/detail/Pythia/Interaction.cc b/corsika/process/detail/Pythia/Interaction.cc
deleted file mode 100644
index 1b22153ef6a5f326eb30b5698a6acaef3c66fc48..0000000000000000000000000000000000000000
--- a/corsika/process/detail/Pythia/Interaction.cc
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/pythia/Interaction.h>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-#include <corsika/framework/geometry/FourVector.hpp>
-#include <corsika/framework/utility/COMBoost.hpp>
-
-#include <tuple>
-#include "../../corsika/setup/SetupStack.hpp"
-
-using std::cout;
-using std::endl;
-using std::tuple;
-
-using namespace corsika;
-using namespace corsika;
-using Projectile = corsika::StackView::ParticleType;
-using Particle = corsika::Stack::ParticleType;
-
-namespace corsika::pythia {
-
-  typedef corsika::Vector<corsika::units::si::hepmomentum_d> MomentumVector;
-
-  Interaction::Interaction(const bool print_listing)
-      : print_listing_(print_listing) {
-
-    cout << "Pythia::Interaction n=" << fCount << endl;
-
-    using random::RNGManager;
-
-    // initialize Pythia
-    if (!fInitialized) {
-
-      fPythia.readString("Print:quiet = on");
-      // TODO: proper process initialization for MinBias needed
-      fPythia.readString("HardQCD:all = on");
-      fPythia.readString("ProcessLevel:resonanceDecays = off");
-
-      fPythia.init();
-
-      // any decays in pythia? if yes need to define which particles
-      if (fInternalDecays) {
-        // define which particles are passed to corsika, i.e. which particles make it into
-        // history even very shortlived particles like charm or pi0 are of interest here
-        const std::vector<particles::Code> HadronsWeWantTrackedByCorsika = {
-            particles::Code::PiPlus,     particles::Code::PiMinus,
-            particles::Code::Pi0,        particles::Code::KMinus,
-            particles::Code::KPlus,      particles::Code::K0Long,
-            particles::Code::K0Short,    particles::Code::SigmaPlus,
-            particles::Code::SigmaMinus, particles::Code::Lambda0,
-            particles::Code::Xi0,        particles::Code::XiMinus,
-            particles::Code::OmegaMinus, particles::Code::DPlus,
-            particles::Code::DMinus,     particles::Code::D0,
-            particles::Code::D0Bar};
-
-        Interaction::SetParticleListStable(HadronsWeWantTrackedByCorsika);
-      }
-
-      // basic initialization of cross section routines
-      fSigma.init(&fPythia.info, fPythia.settings, &fPythia.particleData, &fPythia.rndm);
-
-      fInitialized = true;
-    }
-  }
-
-  void Interaction::SetParticleListStable(
-      std::vector<particles::Code> const& particleList) {
-    for (auto p : particleList) Interaction::SetStable(p);
-  }
-
-  void Interaction::SetUnstable(const particles::Code pCode) {
-    cout << "Pythia::Interaction: setting " << pCode << " unstable.." << endl;
-    fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), true);
-  }
-
-  void Interaction::SetStable(const particles::Code pCode) {
-    cout << "Pythia::Interaction: setting " << pCode << " stable.." << endl;
-    fPythia.particleData.mayDecay(static_cast<int>(particles::GetPDG(pCode)), false);
-  }
-
-  void Interaction::ConfigureLabFrameCollision(
-      const particles::Code BeamId, const particles::Code TargetId,
-      const units::si::HEPEnergyType BeamEnergy) {
-    using namespace units::si;
-    // Pythia configuration of the current event
-    // very clumsy. I am sure this can be done better..
-
-    // set beam
-    // beam id for pythia
-    auto const pdgBeam = static_cast<int>(particles::GetPDG(BeamId));
-    std::stringstream stBeam;
-    stBeam << "Beams:idA = " << pdgBeam;
-    fPythia.readString(stBeam.str());
-    // set target
-    auto pdgTarget = static_cast<int>(particles::GetPDG(TargetId));
-    // replace hydrogen with proton, otherwise pythia goes into heavy ion mode!
-    if (TargetId == particles::Code::Hydrogen)
-      pdgTarget = static_cast<int>(particles::GetPDG(particles::Code::Proton));
-    std::stringstream stTarget;
-    stTarget << "Beams:idB = " << pdgTarget;
-    fPythia.readString(stTarget.str());
-    // set frame to lab. frame
-    fPythia.readString("Beams:frameType = 2");
-    // set beam energy
-    const double Elab = BeamEnergy / 1_GeV;
-    std::stringstream stEnergy;
-    stEnergy << "Beams:eA = " << Elab;
-    fPythia.readString(stEnergy.str());
-    // target at rest
-    fPythia.readString("Beams:eB = 0.");
-    // initialize this config
-    fPythia.init();
-  }
-
-  bool Interaction::CanInteract(const corsika::Code pCode) {
-    return pCode == corsika::Code::Proton ||
-           pCode == corsika::Code::Neutron ||
-           pCode == corsika::Code::AntiProton ||
-           pCode == corsika::Code::AntiNeutron ||
-           pCode == corsika::Code::PiMinus ||
-           pCode == corsika::Code::PiPlus;
-  }
-
-  tuple<units::si::CrossSectionType, units::si::CrossSectionType>
-  Interaction::GetCrossSection(const particles::Code BeamId,
-                               const particles::Code TargetId,
-                               const units::si::HEPEnergyType CoMenergy) {
-    using namespace units::si;
-
-    // interaction possible in pythia?
-    if (TargetId == particles::Code::Proton || TargetId == particles::Code::Hydrogen) {
-      if (CanInteract(BeamId) && ValidCoMEnergy(CoMenergy)) {
-        // input particle PDG
-        auto const pdgCodeBeam = static_cast<int>(particles::GetPDG(BeamId));
-        auto const pdgCodeTarget = static_cast<int>(particles::GetPDG(TargetId));
-        const double ecm = CoMenergy / 1_GeV;
-
-        // calculate cross section
-        fSigma.calc(pdgCodeBeam, pdgCodeTarget, ecm);
-        if (fSigma.hasSigmaTot()) {
-          const double sigEla = fSigma.sigmaEl();
-          const double sigProd = fSigma.sigmaTot() - sigEla;
-
-          return std::make_tuple(sigProd * (1_fm * 1_fm), sigEla * (1_fm * 1_fm));
-
-        } else
-          throw std::runtime_error("pythia cross section init failed");
-
-      } else {
-        return std::make_tuple(std::numeric_limits<double>::infinity() * 1_mb,
-                               std::numeric_limits<double>::infinity() * 1_mb);
-      }
-    } else {
-      throw std::runtime_error("invalid target for pythia");
-    }
-  }
-
-  template <>
-  units::si::GrammageType Interaction::GetInteractionLength(const Particle& p) {
-
-    using namespace units;
-    using namespace units::si;
-    using namespace geometry;
-
-    // coordinate system, get global frame of reference
-    CoordinateSystem& rootCS =
-        RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-
-    const particles::Code corsikaBeamId = p.GetPID();
-
-    // beam particles for pythia : 1, 2, 3 for p, pi, k
-    // read from cross section code table
-    const bool kInteraction = CanInteract(corsikaBeamId);
-
-    // FOR NOW: assume target is at rest
-    process::pythia::MomentumVector pTarget(rootCS, {0_GeV, 0_GeV, 0_GeV});
-
-    // total momentum and energy
-    HEPEnergyType Elab = p.GetEnergy() + constants::nucleonMass;
-    process::pythia::MomentumVector pTotLab(rootCS, {0_GeV, 0_GeV, 0_GeV});
-    pTotLab += p.GetMomentum();
-    pTotLab += pTarget;
-    auto const pTotLabNorm = pTotLab.norm();
-    // calculate cm. energy
-    const HEPEnergyType ECoM = sqrt(
-        (Elab + pTotLabNorm) * (Elab - pTotLabNorm)); // binomial for numerical accuracy
-
-    cout << "Interaction: LambdaInt: \n"
-         << " input energy: " << p.GetEnergy() / 1_GeV << endl
-         << " beam can interact:" << kInteraction << endl
-         << " beam pid:" << p.GetPID() << endl;
-
-    // TODO: move limits into variables
-    if (kInteraction && Elab >= 8.5_GeV && ValidCoMEnergy(ECoM)) {
-
-      // get target from environment
-      /*
-        the target should be defined by the Environment,
-        ideally as full particle object so that the four momenta
-        and the boosts can be defined..
-      */
-      const auto* currentNode = p.GetNode();
-      const auto mediumComposition =
-          currentNode->GetModelProperties().GetNuclearComposition();
-      // determine average interaction length
-
-      auto const weightedProdCrossSection =
-          mediumComposition.WeightedSum([=](auto vTargetID) {
-            return std::get<0>(this->GetCrossSection(corsikaBeamId, vTargetID, ECoM));
-          });
-
-      cout << "Interaction: IntLength: weighted CrossSection (mb): "
-           << weightedProdCrossSection / 1_mb << endl
-           << "Interaction: IntLength: average mass number: "
-           << mediumComposition.GetAverageMassNumber() << endl;
-
-      // calculate interaction length in medium
-      GrammageType const int_length = mediumComposition.GetAverageMassNumber() *
-                                      units::constants::u / weightedProdCrossSection;
-      cout << "Interaction: "
-           << "interaction length (g/cm2): " << int_length / (0.001_kg) * 1_cm * 1_cm
-           << endl;
-
-      return int_length;
-    }
-
-    return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
-  }
-
-  /**
-     In this function PYTHIA is called to produce one event. The
-     event is copied (and boosted) into the shower lab frame.
-   */
-
-  template <>
-  process::EProcessReturn Interaction::DoInteraction(SecondaryView& view) {
-
-    using namespace units;
-    using namespace utl;
-    using namespace units::si;
-    using namespace geometry;
-
-    auto const projectile = view.GetProjectile();
-
-    const auto corsikaBeamId = projectile.GetPID();
-    cout << "Pythia::Interaction: "
-         << "DoInteraction: " << corsikaBeamId << " interaction? "
-         << process::pythia::Interaction::CanInteract(corsikaBeamId) << endl;
-
-    if (particles::IsNucleus(corsikaBeamId)) {
-      // nuclei handled by different process, this should not happen
-      throw std::runtime_error("Nuclear projectile are not handled by PYTHIA!");
-    }
-
-    if (process::pythia::Interaction::CanInteract(corsikaBeamId)) {
-
-      const CoordinateSystem& rootCS =
-          RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-
-      // position and time of interaction, not used in Sibyll
-      Point pOrig = projectile.GetPosition();
-      TimeType tOrig = projectile.GetTime();
-
-      // define target
-      // FOR NOW: target is always at rest
-      const auto eTargetLab = 0_GeV + constants::nucleonMass;
-      const auto pTargetLab = MomentumVector(rootCS, 0_GeV, 0_GeV, 0_GeV);
-      const FourVector PtargLab(eTargetLab, pTargetLab);
-
-      // define projectile
-      HEPEnergyType const eProjectileLab = projectile.GetEnergy();
-      auto const pProjectileLab = projectile.GetMomentum();
-
-      cout << "Interaction: ebeam lab: " << eProjectileLab / 1_GeV << endl
-           << "Interaction: pbeam lab: " << pProjectileLab.GetComponents() / 1_GeV
-           << endl;
-      cout << "Interaction: etarget lab: " << eTargetLab / 1_GeV << endl
-           << "Interaction: ptarget lab: " << pTargetLab.GetComponents() / 1_GeV << endl;
-
-      const FourVector PprojLab(eProjectileLab, pProjectileLab);
-
-      // define target kinematics in lab frame
-      // define boost to and from CoM frame
-      // CoM frame definition in Pythia projectile: +z
-      COMBoost const boost(PprojLab, constants::nucleonMass);
-
-      // just for show:
-      // boost projecticle
-      auto const PprojCoM = boost.toCoM(PprojLab);
-
-      // boost target
-      auto const PtargCoM = boost.toCoM(PtargLab);
-
-      cout << "Interaction: ebeam CoM: " << PprojCoM.GetTimeLikeComponent() / 1_GeV
-           << endl
-           << "Interaction: pbeam CoM: "
-           << PprojCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV << endl;
-      cout << "Interaction: etarget CoM: " << PtargCoM.GetTimeLikeComponent() / 1_GeV
-           << endl
-           << "Interaction: ptarget CoM: "
-           << PtargCoM.GetSpaceLikeComponents().GetComponents() / 1_GeV << endl;
-
-      cout << "Interaction: position of interaction: " << pOrig.GetCoordinates() << endl;
-      cout << "Interaction: time: " << tOrig << endl;
-
-      HEPEnergyType Etot = eProjectileLab + eTargetLab;
-      MomentumVector Ptot = projectile.GetMomentum();
-      // invariant mass, i.e. cm. energy
-      HEPEnergyType Ecm = sqrt(Etot * Etot - Ptot.squaredNorm());
-
-      // sample target mass number
-      const auto* currentNode = projectile.GetNode();
-      const auto& mediumComposition =
-          currentNode->GetModelProperties().GetNuclearComposition();
-      // get cross sections for target materials
-      /*
-        Here we read the cross section from the interaction model again,
-        should be passed from GetInteractionLength if possible
-       */
-      //#warning reading interaction cross section again, should not be necessary
-      auto const& compVec = mediumComposition.GetComponents();
-      std::vector<si::CrossSectionType> cross_section_of_components(compVec.size());
-
-      for (size_t i = 0; i < compVec.size(); ++i) {
-        auto const targetId = compVec[i];
-        const auto [sigProd, sigEla] = GetCrossSection(corsikaBeamId, targetId, Ecm);
-        [[maybe_unused]] const auto& dummy_sigEla = sigEla;
-        cross_section_of_components[i] = sigProd;
-      }
-
-      const auto corsikaTargetId =
-          mediumComposition.SampleTarget(cross_section_of_components, fRNG);
-      cout << "Interaction: target selected: " << corsikaTargetId << endl;
-
-      if (corsikaTargetId != particles::Code::Hydrogen &&
-          corsikaTargetId != particles::Code::Neutron &&
-          corsikaTargetId != particles::Code::Proton)
-        throw std::runtime_error("DoInteraction: wrong target for PYTHIA");
-
-      cout << "Interaction: "
-           << " DoInteraction: E(GeV):" << eProjectileLab / 1_GeV
-           << " Ecm(GeV): " << Ecm / 1_GeV << endl;
-
-      if (eProjectileLab < 8.5_GeV || !ValidCoMEnergy(Ecm)) {
-        cout << "Interaction: "
-             << " DoInteraction: should have dropped particle.. "
-             << "THIS IS AN ERROR" << endl;
-        throw std::runtime_error("energy too low for PYTHIA");
-
-      } else {
-        fCount++;
-
-        ConfigureLabFrameCollision(corsikaBeamId, corsikaTargetId, eProjectileLab);
-
-        // create event in pytia
-        if (!fPythia.next()) throw std::runtime_error("Pythia::DoInteraction: failed!");
-
-        // link to pythia stack
-        Pythia8::Event& event = fPythia.event;
-
-        if (print_listing_) {
-          // list final state
-          event.list();
-        }
-
-        MomentumVector Plab_final(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV});
-        HEPEnergyType Elab_final = 0_GeV;
-        for (int i = 0; i < event.size(); ++i) {
-          Pythia8::Particle& p8p = event[i];
-          // skip particles that have decayed in pythia
-          if (!p8p.isFinal()) continue;
-
-          auto const pyId =
-              particles::ConvertFromPDG(static_cast<particles::PDGCode>(p8p.id()));
-
-          const MomentumVector pyPlab(
-              rootCS, {p8p.px() * 1_GeV, p8p.py() * 1_GeV, p8p.pz() * 1_GeV});
-          HEPEnergyType const pyEn = p8p.e() * 1_GeV;
-
-          // add to corsika stack
-          auto pnew = view.AddSecondary(
-              tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector,
-                    geometry::Point, units::si::TimeType>{pyId, pyEn, pyPlab, pOrig,
-                                                          tOrig});
-
-          Plab_final += pnew.GetMomentum();
-          Elab_final += pnew.GetEnergy();
-        }
-        cout << "conservation (all GeV): "
-             << "Elab_final=" << Elab_final / 1_GeV
-             << ", Plab_final=" << (Plab_final / 1_GeV).GetComponents() << endl;
-      }
-    }
-    return process::EProcessReturn::eOk;
-  }
-
-} // namespace corsika::pythia
diff --git a/corsika/process/detail/Pythia/Random.cc b/corsika/process/detail/Pythia/Random.cc
deleted file mode 100644
index 0ebfbd85b670637d7339366f60713cf7d26b8c4d..0000000000000000000000000000000000000000
--- a/corsika/process/detail/Pythia/Random.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/pythia/Random.h>
-
-namespace corsika::pythia {
-
-  double Random::flat() { return fDist(fRNG); }
-
-} // namespace corsika::pythia
diff --git a/corsika/process/detail/QGSJetII/Interaction.cc b/corsika/process/detail/QGSJetII/Interaction.cc
deleted file mode 100644
index 086f98a9a592c42633298e9e5ce27f8368d17c2c..0000000000000000000000000000000000000000
--- a/corsika/process/detail/QGSJetII/Interaction.cc
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * (c) Copyright 2020 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/process/qgsjetII/Interaction.h>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-#include <corsika/framework/geometry/QuantityVector.hpp>
-#include <corsika/framework/geometry/FourVector.hpp>
-#include <corsika/process/qgsjetII/ParticleConversion.h>
-#include <corsika/process/qgsjetII/QGSJetIIFragmentsStack.h>
-#include <corsika/process/qgsjetII/QGSJetIIStack.h>
-#include <corsika/process/qgsjetII/qgsjet-II-04.h>
-#include <corsika/framework/utility/COMBoost.hpp>
-
-#include <random>
-#include <sstream>
-#include <string>
-#include <tuple>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using std::cout;
-using std::endl;
-using std::ostringstream;
-using std::string;
-using std::tuple;
-
-using namespace corsika;
-using namespace corsika;
-using SetupParticle = setup::Stack::StackIterator;
-using SetupView = setup::StackView;
-using Track = Trajectory;
-
-namespace corsika::qgsjetII {
-
-  Interaction::Interaction(const string& dataPath)
-      : data_path_(dataPath) {
-    if (dataPath == "") {
-      if (std::getenv("CORSIKA_DATA")) {
-        data_path_ = string(std::getenv("CORSIKA_DATA")) + "/QGSJetII/";
-        cout << "Searching for QGSJetII data tables in " << data_path_ << endl;
-      }
-    }
-
-    // initialize QgsjetII
-    if (!initialized_) {
-      qgset_();
-      datadir DIR(data_path_);
-      qgaini_(DIR.data);
-      initialized_ = true;
-    }
-  }
-
-  Interaction::~Interaction() { cout << "QgsjetII::Interaction n=" << count_ << endl; }
-
-  units::si::CrossSectionType Interaction::GetCrossSection(
-      const particles::Code beamId, const particles::Code targetId,
-      const units::si::HEPEnergyType Elab, const unsigned int Abeam,
-      const unsigned int targetA) const {
-    using namespace units::si;
-    double sigProd = std::numeric_limits<double>::infinity();
-
-    if (process::qgsjetII::CanInteract(beamId)) {
-
-      const int xsCode = process::qgsjetII::GetQgsjetIIXSCodeRaw(beamId);
-      int iTarget = 1;
-      if (particles::IsNucleus(targetId)) {
-        iTarget = targetA;
-        if (iTarget > maxMassNumber_ || iTarget <= 0) {
-          std::ostringstream txt;
-          txt << "QgsjetII target outside range. iTarget=" << iTarget;
-          throw std::runtime_error(txt.str().c_str());
-        }
-      }
-      int iProjectile = 1;
-      if (particles::IsNucleus(beamId)) {
-        iProjectile = Abeam;
-        if (iProjectile > maxMassNumber_ || iProjectile <= 0)
-          throw std::runtime_error("QgsjetII target outside range. ");
-      }
-
-      cout << "QgsjetII::GetCrossSection Elab=" << Elab << " xs-code=" << xsCode
-           << " iProjectile=" << iProjectile << " iTarget=" << iTarget << endl;
-      sigProd = qgsect_(Elab / 1_GeV, xsCode, iProjectile, iTarget);
-      cout << "QgsjetII::GetCrossSection sigProd=" << sigProd << endl;
-    }
-
-    return sigProd * 1_mb;
-  }
-
-  template <>
-  units::si::GrammageType Interaction::GetInteractionLength(
-      SetupParticle const& vP) const {
-
-    using namespace units;
-    using namespace units::si;
-    using namespace geometry;
-
-    // coordinate system, get global frame of reference
-    CoordinateSystem& rootCS =
-        RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-
-    const particles::Code corsikaBeamId = vP.GetPID();
-
-    // beam particles for qgsjetII : 1, 2, 3 for p, pi, k
-    // read from cross section code table
-    const bool kInteraction = process::qgsjetII::CanInteract(corsikaBeamId);
-
-    // FOR NOW: assume target is at rest
-    MomentumVector pTarget(rootCS, {0_GeV, 0_GeV, 0_GeV});
-
-    // total momentum and energy
-    HEPEnergyType Elab = vP.GetEnergy();
-
-    cout << "Interaction: LambdaInt: \n"
-         << " input energy: " << vP.GetEnergy() / 1_GeV << endl
-         << " beam can interact:" << kInteraction << endl
-         << " beam pid:" << vP.GetPID() << endl;
-
-    if (kInteraction) {
-
-      int Abeam = 0;
-      if (particles::IsNucleus(vP.GetPID())) Abeam = vP.GetNuclearA();
-
-      // get target from environment
-      /*
-        the target should be defined by the Environment,
-        ideally as full particle object so that the four momenta
-        and the boosts can be defined..
-      */
-
-      auto const* currentNode = vP.GetNode();
-      const auto& mediumComposition =
-          currentNode->GetModelProperties().GetNuclearComposition();
-
-      si::CrossSectionType weightedProdCrossSection = mediumComposition.WeightedSum(
-          [=](particles::Code targetID) -> si::CrossSectionType {
-            int targetA = 0;
-            if (corsika::IsNucleus(targetID))
-              targetA = particles::GetNucleusA(targetID);
-            return GetCrossSection(corsikaBeamId, targetID, Elab, Abeam, targetA);
-          });
-
-      cout << "Interaction: "
-           << "IntLength: weighted CrossSection (mb): " << weightedProdCrossSection / 1_mb
-           << endl;
-
-      // calculate interaction length in medium
-      GrammageType const int_length = mediumComposition.GetAverageMassNumber() *
-                                      units::constants::u / weightedProdCrossSection;
-      cout << "Interaction: "
-           << "interaction length (g/cm2): " << int_length / (0.001_kg) * 1_cm * 1_cm
-           << endl;
-
-      return int_length;
-    }
-
-    return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
-  }
-
-  /**
-     In this function QGSJETII is called to produce one event. The
-     event is copied (and boosted) into the shower lab frame.
-   */
-
-  template <>
-  process::EProcessReturn Interaction::DoInteraction(SetupView& view) {
-
-    using namespace units;
-    using namespace utl;
-    using namespace units::si;
-    using namespace geometry;
-
-    auto const projectile = view.GetProjectile();
-
-    const auto corsikaBeamId = projectile.GetPID();
-    cout << "ProcessQgsjetII: "
-         << "DoInteraction: " << corsikaBeamId << " interaction? "
-         << process::qgsjetII::CanInteract(corsikaBeamId) << endl;
-
-    if (process::qgsjetII::CanInteract(corsikaBeamId)) {
-
-      const CoordinateSystem& rootCS =
-          RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
-
-      // position and time of interaction, not used in QgsjetII
-      Point pOrig = projectile.GetPosition();
-      TimeType tOrig = projectile.GetTime();
-
-      // define target
-      // for QgsjetII is always a single nucleon
-      // FOR NOW: target is always at rest
-      const auto targetEnergyLab = 0_GeV + constants::nucleonMass;
-      const auto targetMomentumLab = MomentumVector(rootCS, 0_GeV, 0_GeV, 0_GeV);
-      const FourVector PtargLab(targetEnergyLab, targetMomentumLab);
-
-      // define projectile
-      HEPEnergyType const projectileEnergyLab = projectile.GetEnergy();
-      auto const projectileMomentumLab = projectile.GetMomentum();
-
-      int beamA = 1;
-      if (particles::IsNucleus(corsikaBeamId)) beamA = projectile.GetNuclearA();
-
-      const HEPEnergyType projectileEnergyLabPerNucleon = projectileEnergyLab / beamA;
-
-      cout << "Interaction: ebeam lab: " << projectileEnergyLab / 1_GeV << endl
-           << "Interaction: pbeam lab: " << projectileMomentumLab.GetComponents() / 1_GeV
-           << endl;
-      cout << "Interaction: etarget lab: " << targetEnergyLab / 1_GeV << endl
-           << "Interaction: ptarget lab: " << targetMomentumLab.GetComponents() / 1_GeV
-           << endl;
-
-      cout << "Interaction: position of interaction: " << pOrig.GetCoordinates() << endl;
-      cout << "Interaction: time: " << tOrig << endl;
-
-      // sample target mass number
-      auto const* currentNode = projectile.GetNode();
-      auto const& mediumComposition =
-          currentNode->GetModelProperties().GetNuclearComposition();
-      // get cross sections for target materials
-      /*
-        Here we read the cross section from the interaction model again,
-        should be passed from GetInteractionLength if possible
-       */
-      auto const& compVec = mediumComposition.GetComponents();
-      std::vector<si::CrossSectionType> cross_section_of_components(compVec.size());
-
-      for (size_t i = 0; i < compVec.size(); ++i) {
-        auto const targetId = compVec[i];
-        int targetA = 0;
-        if (corsika::IsNucleus(targetId))
-          targetA = particles::GetNucleusA(targetId);
-        const auto sigProd =
-            GetCrossSection(corsikaBeamId, targetId, projectileEnergyLab, beamA, targetA);
-        cross_section_of_components[i] = sigProd;
-      }
-
-      const auto targetCode =
-          mediumComposition.SampleTarget(cross_section_of_components, rng_);
-      cout << "Interaction: target selected: " << targetCode << endl;
-
-      int targetMassNumber = 1;               // proton
-      if (particles::IsNucleus(targetCode)) { // nucleus
-        targetMassNumber = particles::GetNucleusA(targetCode);
-        if (targetMassNumber > maxMassNumber_)
-          throw std::runtime_error("QgsjetII target mass outside range.");
-      } else {
-        if (targetCode != particles::Proton::GetCode())
-          throw std::runtime_error("QgsjetII Taget not possible.");
-      }
-      cout << "Interaction: target qgsjetII code/A: " << targetMassNumber << endl;
-
-      int projectileMassNumber = 1; // "1" means "hadron"
-      QgsjetIIHadronType qgsjet_hadron_type =
-          process::qgsjetII::GetQgsjetIIHadronType(corsikaBeamId);
-      if (qgsjet_hadron_type == QgsjetIIHadronType::NucleusType) {
-        projectileMassNumber = projectile.GetNuclearA();
-        if (projectileMassNumber > maxMassNumber_)
-          throw std::runtime_error("QgsjetII projectile mass outside range.");
-        std::array<QgsjetIIHadronType, 2> constexpr nucleons = {
-            QgsjetIIHadronType::ProtonType, QgsjetIIHadronType::NeutronType};
-        std::uniform_int_distribution select(0, 1);
-        qgsjet_hadron_type = nucleons[select(rng_)];
-      } else {
-        // from conex: replace pi0 or rho0 with pi+/pi- in alternating sequence
-        if (qgsjet_hadron_type == QgsjetIIHadronType::NeutralLightMesonType) {
-          qgsjet_hadron_type = alternate_;
-          alternate_ = (alternate_ == QgsjetIIHadronType::PiPlusType
-                            ? QgsjetIIHadronType::PiMinusType
-                            : QgsjetIIHadronType::PiPlusType);
-        }
-      }
-      cout << "Interaction: projectile qgsjetII code/A: " << projectileMassNumber << " "
-           << corsikaBeamId << endl;
-
-      int qgsjet_hadron_type_int = static_cast<QgsjetIICodeIntType>(qgsjet_hadron_type);
-
-      cout << "Interaction: "
-           << " DoInteraction: E(GeV):" << projectileEnergyLab / 1_GeV << endl;
-      count_++;
-      qgini_(projectileEnergyLab / 1_GeV, qgsjet_hadron_type_int, projectileMassNumber,
-             targetMassNumber);
-      qgconf_();
-
-      // bookkeeping
-      MomentumVector Plab_final(rootCS, {0.0_GeV, 0.0_GeV, 0.0_GeV});
-      HEPEnergyType Elab_final = 0_GeV;
-
-      // to read the secondaries
-      // define rotation to and from CoM frame
-      // CoM frame definition in QgsjetII projectile: +z
-      auto const& originalCS = projectileMomentumLab.GetCoordinateSystem();
-      geometry::CoordinateSystem const zAxisFrame =
-          originalCS.RotateToZ(projectileMomentumLab);
-
-      // nuclear projectile fragments
-      QGSJetIIFragmentsStack qfs;
-      for (auto& fragm : qfs) {
-        particles::Code idFragm = particles::Code::Nucleus;
-        const int A = fragm.GetFragmentSize();
-        int Z = 0;
-        switch (A) {
-          case 1: { // proton/neutron
-            idFragm = particles::Code::Proton;
-
-	    auto momentum = geometry::Vector(
-					     zAxisFrame,
-					     corsika::QuantityVector<hepmomentum_d>{0.0_GeV, 0.0_GeV,
-						 sqrt((projectileEnergyLab + particles::Proton::GetMass()) *
-						      (projectileEnergyLab - particles::Proton::GetMass()))});
-	    
-	    auto const energy = sqrt(momentum.squaredNorm() + square(particles::GetMass(idFragm)));	    
-	    momentum.rebase(originalCS); // transform back into standard lab frame
-	    std::cout << "secondary fragment> id=" << idFragm << " p=" << momentum.GetComponents() << std::endl;
-            auto pnew = vP.AddSecondary(
-                tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector,
-                      geometry::Point, units::si::TimeType>{idFragm, energy, momentum,
-                                                            pOrig, tOrig});
-            Plab_final += pnew.GetMomentum();
-            Elab_final += pnew.GetEnergy();
-          } break;
-          case 2: // deuterium
-            Z = 1;
-            break;
-          case 3: // tritium
-            Z = 1;
-            break;
-          case 4: // helium
-            Z = 2;
-            break;
-          default: // nucleus
-          {
-            Z = int(A / 2.15 + 0.7);
-          }
-        }
-
-        if (idFragm == particles::Code::Nucleus) { // thus: not p or n
-          const HEPMassType nucleusMass =
-              particles::Proton::GetMass() * Z + particles::Neutron::GetMass() * (A - Z);
-          auto momentum = geometry::Vector(
-              zAxisFrame, geometry::QuantityVector<hepmomentum_d>{
-                              0.0_GeV, 0.0_GeV,
-                              sqrt((projectileEnergyLabPerNucleon * A + nucleusMass) *
-                                   (projectileEnergyLabPerNucleon * A - nucleusMass))});
-
-          auto const energy = sqrt(momentum.squaredNorm() + square(nucleusMass));
-          momentum.rebase(originalCS); // transform back into standard lab frame
-          std::cout << "secondary fragment> id=" << idFragm
-                    << " p=" << momentum.GetComponents() << " A=" << A << " Z=" << Z
-                    << std::endl;
-          auto pnew = view.AddSecondary(
-              tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector,
-                    geometry::Point, units::si::TimeType, unsigned short, unsigned short>{
-                  idFragm, energy, momentum, pOrig, tOrig, A, Z});
-          Plab_final += pnew.GetMomentum();
-          Elab_final += pnew.GetEnergy();
-        }
-      }
-
-      // secondaries
-      QGSJetIIStack qs;
-      for (auto& psec : qs) {
-
-        auto momentum = psec.GetMomentum(zAxisFrame);
-        auto const energy = psec.GetEnergy();
-
-        momentum.rebase(originalCS); // transform back into standard lab frame
-        std::cout << "secondary fragment> id="
-                  << process::qgsjetII::ConvertFromQgsjetII(psec.GetPID())
-                  << " p=" << momentum.GetComponents() << std::endl;
-        auto pnew = view.AddSecondary(
-            tuple<particles::Code, units::si::HEPEnergyType, stack::MomentumVector,
-                  geometry::Point, units::si::TimeType>{
-                process::qgsjetII::ConvertFromQgsjetII(psec.GetPID()), energy, momentum,
-                pOrig, tOrig});
-        Plab_final += pnew.GetMomentum();
-        Elab_final += pnew.GetEnergy();
-      }
-      cout << "conservation (all GeV): Ecm_final= n/a" /* << Ecm_final / 1_GeV*/ << endl
-           << "Elab_final=" << Elab_final / 1_GeV
-           << ", Plab_final=" << (Plab_final / 1_GeV).GetComponents()
-           << ", N_wounded,targ="
-           << QGSJetIIFragmentsStackData::GetWoundedNucleonsTarget()
-           << ", N_wounded,proj="
-           << QGSJetIIFragmentsStackData::GetWoundedNucleonsProjectile()
-           << ", N_fragm,proj=" << qfs.getEntries() << endl;
-    }
-    return process::EProcessReturn::eOk;
-  }
-
-} // namespace corsika::qgsjetII
diff --git a/corsika/process/detail/QGSJetII/ParticleConversion.cc b/corsika/process/detail/QGSJetII/ParticleConversion.cc
deleted file mode 100644
index b9e40535448c230d80022c82ecfb3089218995e6..0000000000000000000000000000000000000000
--- a/corsika/process/detail/QGSJetII/ParticleConversion.cc
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * (c) Copyright 2020 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/framework/core/ParticleProperties.hpp>
-#include <corsika/process/qgsjetII/ParticleConversion.h>
-
-using namespace corsika::qgsjetII;
diff --git a/corsika/process/detail/QGSJetII/qgsjet-II-04.cc b/corsika/process/detail/QGSJetII/qgsjet-II-04.cc
deleted file mode 100644
index d668daf0b025c5361e43b863cb441fcbf2939a68..0000000000000000000000000000000000000000
--- a/corsika/process/detail/QGSJetII/qgsjet-II-04.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * (c) Copyright 2020 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/process/qgsjetII/qgsjet-II-04.h>
-
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <iostream>
-#include <random>
-
-datadir::datadir(const std::string& dir) {
-  if (dir.length() > 130) {
-    std::cerr << "QGSJetII error, will cut datadir \"" << dir
-              << "\" to 130 characters: " << std::endl;
-  }
-  int i = 0;
-  for (i = 0; i < std::min(130, int(dir.length())); ++i) data[i] = dir[i];
-  data[i + 0] = ' ';
-  data[i + 1] = '\0';
-}
-
-double qgran_(int&) {
-  static corsika::RNG& rng =
-      corsika::RNGManager::GetInstance().GetRandomStream("qgran");
-
-  std::uniform_real_distribution<double> dist;
-  return dist(rng);
-}
diff --git a/corsika/process/detail/StackInspector.cc b/corsika/process/detail/StackInspector.cc
deleted file mode 100644
index 2a5622b3e67b33c6e9cbb34899ba0d5afca7a2e6..0000000000000000000000000000000000000000
--- a/corsika/process/detail/StackInspector.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/framework/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/process/stack_inspector/StackInspector.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/logging/Logger.h>
-
-#include <chrono>
-#include <iomanip>
-#include <iostream>
-#include <limits>
-
-#include "../corsika/setup/SetupTrajectory.hpp"
-using namespace std;
-
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::units::si;
-using namespace corsika_inspector;
-
-template <typename TStack>
-StackInspector<TStack>::StackInspector(const int vNStep, const bool vReportStack,
-                                       const HEPEnergyType vE0)
-    : StackProcess<StackInspector<TStack>>(vNStep)
-    , ReportStack_(vReportStack)
-    , E0_(vE0)
-    , StartTime_(std::chrono::system_clock::now()) {
-
-  ReportStack_ = false;
-  StartTime_ = std::chrono::system_clock::now();
-}
-
-template <typename TStack>
-StackInspector<TStack>::~StackInspector() {}
-
-template <typename TStack>
-void StackInspector<TStack>::DoStack(const TStack& vS) {
-  [[maybe_unused]] int i = 0;
-  HEPEnergyType Etot = 0_GeV;
-
-  for (const auto& iterP : vS) {
-    HEPEnergyType E = iterP.GetEnergy();
-    Etot += E;
-    if (ReportStack_) {
-      geometry::CoordinateSystem& rootCS = geometry::RootCoordinateSystem::GetInstance()
-                                               .GetRootCoordinateSystem(); // for printout
-      auto pos = iterP.GetPosition().GetCoordinates(rootCS);
-      cout << "StackInspector: i=" << setw(5) << fixed << (i++) << ", id=" << setw(30)
-           << iterP.GetPID() << " E=" << setw(15) << scientific << (E / 1_GeV) << " GeV, "
-           << " pos=" << pos << " node = " << iterP.GetNode();
-      if (iterP.GetPID() == Code::Nucleus) cout << " nuc_ref=" << iterP.GetNucleusRef();
-      cout << endl;
-    }
-  }
-
-  auto const now = std::chrono::system_clock::now();
-  const std::chrono::duration<double> elapsed_seconds = now - StartTime_;
-  std::time_t const now_time = std::chrono::system_clock::to_time_t(now);
-  auto const dE = E0_ - Etot;
-  if (dE < dE_threshold_) return;
-  double const progress = dE / E0_;
-
-  double const eta_seconds = elapsed_seconds.count() / progress;
-  std::time_t const eta_time = std::chrono::system_clock::to_time_t(
-      StartTime_ + std::chrono::seconds((int)eta_seconds));
-
-  cout << "StackInspector: "
-       << " time=" << std::put_time(std::localtime(&now_time), "%T")
-       << ", running=" << elapsed_seconds.count() << " seconds"
-       << " (" << setw(3) << int(progress * 100) << "%)"
-       << ", nStep=" << GetStep() << ", stackEntries=" << vS.getEntries()
-       << ", Estack=" << Etot / 1_GeV << " GeV"
-       << ", ETA=" << std::put_time(std::localtime(&eta_time), "%T") << endl;
-  return;
-}
-
-#include <corsika/cascade/testCascade.h>
-#include "../corsika/setup/SetupStack.hpp"
-
-template class process::stack_inspector::StackInspector<setup::Stack>;
-template class process::stack_inspector::StackInspector<TestCascadeStack>;
diff --git a/corsika/process/detail/TrackWriter.cc b/corsika/process/detail/TrackWriter.cc
deleted file mode 100644
index 7ce08e49d1b8c17604850d45c96ca0d58adbb1d5..0000000000000000000000000000000000000000
--- a/corsika/process/detail/TrackWriter.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/track_writer/TrackWriter.h>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-
-#include <iomanip>
-#include <limits>
-
-#include "../corsika/setup/SetupStack.hpp"
-#include "../corsika/setup/SetupTrajectory.hpp"
-
-using namespace corsika;
-using Particle = Stack::ParticleType;
-using Track = Trajectory;
-
-namespace corsika::track_writer {
-
-  TrackWriter::TrackWriter(std::string const& filename)
-      : fFilename(filename) {
-
-    using namespace std::string_literals;
-
-    fFile.open(fFilename);
-    fFile
-        << "# PID, E / eV, start coordinates / m, displacement vector to end / m, steplength / m "s
-        << '\n';
-  }
-
-  template <>
-  process::EProcessReturn TrackWriter::DoContinuous(Particle& vP, Track& vT) {
-    using namespace units::si;
-    auto const start = vT.GetPosition(0).GetCoordinates();
-    auto const delta = vT.GetPosition(1).GetCoordinates() - start;
-    auto const pdg = static_cast<int>(particles::GetPDG(vP.GetPID()));
-
-    // clang-format off
-    fFile << std::setw(7) << pdg
-          << std::setw(width) << std::scientific << std::setprecision(precision) << vP.GetEnergy() / 1_eV
-          << std::setw(width) << std::scientific << std::setprecision(precision) << start[0] / 1_m 
-          << std::setw(width) << std::scientific << std::setprecision(precision) << start[1] / 1_m
-          << std::setw(width) << std::scientific << std::setprecision(precision) << start[2] / 1_m
-          << std::setw(width) << std::scientific << std::setprecision(precision) << delta[0] / 1_m
-          << std::setw(width) << std::scientific << std::setprecision(precision) << delta[1] / 1_m
-          << std::setw(width) << std::scientific << std::setprecision(precision) << delta[2] / 1_m 
-          << std::setw(width) << std::scientific << std::setprecision(precision) << delta.norm() / 1_m
-          << '\n';
-    // clang-format on
-
-    return process::EProcessReturn::eOk;
-  }
-
-  template <>
-  units::si::LengthType TrackWriter::MaxStepLength(Particle&, Track&) {
-    return units::si::meter * std::numeric_limits<double>::infinity();
-  }
-
-} // namespace corsika::track_writer
diff --git a/examples/boundary_example.cc b/examples/boundary_example.cc
deleted file mode 100644
index addd6f4a9f5a00b4ea3e33e22f61b6be321c7e43..0000000000000000000000000000000000000000
--- a/examples/boundary_example.cc
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/framework/core/Cascade.hpp>
-#include <corsika/framework/sequence/ProcessSequence.hpp>
-#include <corsika/process/tracking_line/TrackingLine.hpp>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/HomogeneousMedium.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-
-#include <corsika/framework/geometry/Sphere.hpp>
-
-#include <corsika/process/sibyll/Decay.h>
-#include <corsika/process/sibyll/Interaction.h>
-#include <corsika/process/sibyll/NuclearInteraction.h>
-
-#include <corsika/process/track_writer/TrackWriter.h>
-
-#include <corsika/process/particle_cut/ParticleCut.hpp>
-
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/utility/CorsikaFenv.hpp>
-
-#include <corsika/logging/Logging.h>
-
-#include <iostream>
-#include <limits>
-#include <typeinfo>
-
-#include "../../corsika/setup/SetupEnvironment.hpp"
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::units;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::environment;
-
-using namespace std;
-using namespace corsika::units::si;
-
-template <bool deleteParticle>
-struct MyBoundaryCrossingProcess
-    : public BoundaryCrossingProcess<MyBoundaryCrossingProcess<deleteParticle>> {
-
-  MyBoundaryCrossingProcess(std::string const& filename) { fFile.open(filename); }
-
-  template <typename Particle>
-  EProcessReturn DoBoundaryCrossing(Particle& p,
-                                    typename Particle::BaseNodeType const& from,
-                                    typename Particle::BaseNodeType const& to) {
-
-    C8LOG_INFO("MyBoundaryCrossingProcess: crossing! from: {} to: {} ", fmt::ptr(&from),
-               fmt::ptr(&to));
-
-    auto const& name = particles::GetName(p.GetPID());
-    auto const start = p.GetPosition().GetCoordinates();
-
-    fFile << name << "    " << start[0] / 1_m << ' ' << start[1] / 1_m << ' '
-          << start[2] / 1_m << '\n';
-
-    if constexpr (deleteParticle) { p.Delete(); }
-
-    return EProcessReturn::eOk;
-  }
-
-private:
-  std::ofstream fFile;
-};
-
-//
-// The example main program for a particle cascade
-//
-int main() {
-
-  logging::SetLevel(logging::level::trace);
-
-  C8LOG_INFO("boundary_example");
-
-  feenableexcept(FE_INVALID);
-  // initialize random number sequence(s)
-  random::RNGManager::GetInstance().RegisterRandomStream("cascade");
-
-  // setup environment, geometry
-  using EnvType = setup::Environment;
-  EnvType env;
-  auto& universe = *(env.GetUniverse());
-
-  const CoordinateSystem& rootCS = env.GetCoordinateSystem();
-
-  // create "world" as infinite sphere filled with protons
-  auto world = EnvType::CreateNode<Sphere>(
-      Point{rootCS, 0_m, 0_m, 0_m}, 100_km);
-
-  using MyHomogeneousModel =
-      environment::MediumPropertyModel<environment::UniformMagneticField<
-          environment::HomogeneousMedium<setup::EnvironmentInterface>>>;
-
-  auto const props = world->SetModelProperties<MyHomogeneousModel>(
-      environment::Medium::AirDry1Atm, Vector(rootCS, 0_T, 0_T, 0_T),
-      1_kg / (1_m * 1_m * 1_m),
-      environment::NuclearComposition(
-          std::vector<particles::Code>{particles::Code::Proton},
-          std::vector<float>{1.f}));
-
-  // add a "target" sphere with 5km readius at 0,0,0
-  auto target = EnvType::CreateNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 5_km);
-  target->SetModelProperties(props);
-
-  world->AddChild(std::move(target));
-  universe.AddChild(std::move(world));
-
-  // setup processes, decays and interactions
-  setup::Tracking tracking;
-
-  random::RNGManager::GetInstance().RegisterRandomStream("sibyll");
-  process::sibyll::Interaction sibyll;
-  process::sibyll::Decay decay;
-
-  process::particle_cut::ParticleCut cut(50_GeV, true, true);
-
-  process::track_writer::TrackWriter trackWriter("boundary_tracks.dat");
-  MyBoundaryCrossingProcess<true> boundaryCrossing("crossings.dat");
-
-  // assemble all processes into an ordered process list
-  auto sequence = process::sequence(sibyll, decay, cut, boundaryCrossing, trackWriter);
-
-  // setup particle stack, and add primary particles
-  setup::Stack stack;
-  stack.Clear();
-  const Code beamCode = Code::MuPlus;
-  const HEPMassType mass = particles::GetMass(beamCode);
-  const HEPEnergyType E0 = 100_GeV;
-
-  std::uniform_real_distribution distTheta(0., 180.);
-  std::uniform_real_distribution distPhi(0., 360.);
-  std::mt19937 rng;
-
-  for (int i = 0; i < 100; ++i) {
-    double const theta = distTheta(rng);
-    double const phi = distPhi(rng);
-
-    auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-      return sqrt((Elab - m) * (Elab + m));
-    };
-    HEPMomentumType P0 = elab2plab(E0, mass);
-    auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) {
-      return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi),
-                             -ptot * cos(theta));
-    };
-    auto const [px, py, pz] =
-        momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0);
-    auto plab = corsika::MomentumVector(rootCS, {px, py, pz});
-    cout << "input particle: " << beamCode << endl;
-    cout << "input angles: theta=" << theta << " phi=" << phi << endl;
-    cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl;
-    Point pos(rootCS, 0_m, 0_m, 0_m);
-    stack.AddParticle(
-        std::tuple<particles::Code, units::si::HEPEnergyType,
-                   corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-            beamCode, E0, plab, pos, 0_ns});
-  }
-
-  // define air shower object, run simulation
-  cascade::Cascade EAS(env, tracking, sequence, stack);
-
-  EAS.Run();
-
-  C8LOG_INFO("Result: E0={}GeV", E0 / 1_GeV);
-  cut.ShowResults();
-  [[maybe_unused]] const HEPEnergyType Efinal =
-      (cut.GetCutEnergy() + cut.GetInvEnergy() + cut.GetEmEnergy());
-  C8LOG_INFO("Total energy (GeV): {} relative difference (%): {}", Efinal / 1_GeV,
-             (Efinal / E0 - 1.) * 100);
-}
diff --git a/examples/cascade_example.cc b/examples/cascade_example.cc
deleted file mode 100644
index 1915125f1ef422f5ff13811430a7aa214d15fea7..0000000000000000000000000000000000000000
--- a/examples/cascade_example.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * (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.
- */
-
-
-#include <corsika/framework/core/Cascade.hpp>
-#include <corsika/framework/sequence/ProcessSequence.hpp>
-#include <corsika/process/energy_loss/EnergyLoss.h>
-#include <corsika/process/stack_inspector/StackInspector.hpp>
-#include <corsika/process/tracking_line/TrackingLine.hpp>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/HomogeneousMedium.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-
-#include <corsika/framework/geometry/Sphere.hpp>
-
-#include <corsika/process/sibyll/Decay.h>
-#include <corsika/process/sibyll/Interaction.h>
-#include <corsika/process/sibyll/NuclearInteraction.h>
-
-#include <corsika/process/particle_cut/ParticleCut.hpp>
-#include <corsika/process/track_writer/TrackWriter.h>
-
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/utility/CorsikaFenv.hpp>
-
-#include <iostream>
-#include <limits>
-
-#include "../../corsika/setup/SetupEnvironment.hpp"
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::units;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::environment;
-
-using namespace std;
-using namespace corsika::units::si;
-
-//
-// The example main program for a particle cascade
-//
-int main() {
-
-  logging::SetLevel(logging::level::info);
-
-  C8LOG_INFO("vertical_EAS");
-
-  std::cout << "cascade_example" << std::endl;
-
-  const LengthType height_atmosphere = 112.8_km;
-
-  feenableexcept(FE_INVALID);
-  // initialize random number sequence(s)
-  random::RNGManager::GetInstance().RegisterRandomStream("cascade");
-
-  // setup environment, geometry
-  setup::Environment env;
-  auto& universe = *(env.GetUniverse());
-
-  const CoordinateSystem& rootCS = env.GetCoordinateSystem();
-
-  auto world = setup::Environment::CreateNode<Sphere>(
-      Point{rootCS, 0_m, 0_m, 0_m}, 150_km);
-
-  using MyHomogeneousModel =
-      environment::MediumPropertyModel<environment::UniformMagneticField<
-          environment::HomogeneousMedium<setup::EnvironmentInterface>>>;
-
-  // fraction of oxygen
-  const float fox = 0.20946;
-  auto const props = world->SetModelProperties<MyHomogeneousModel>(
-      environment::Medium::AirDry1Atm, Vector(rootCS, 0_T, 0_T, 0_T),
-      1_kg / (1_m * 1_m * 1_m),
-      environment::NuclearComposition(
-          std::vector<particles::Code>{particles::Code::Nitrogen,
-                                       particles::Code::Oxygen},
-          std::vector<float>{1.f - fox, fox}));
-
-  auto innerMedium =
-      setup::Environment::CreateNode<Sphere>(Point{rootCS, 0_m, 0_m, 0_m}, 5000_m);
-
-  innerMedium->SetModelProperties(props);
-  world->AddChild(std::move(innerMedium));
-  universe.AddChild(std::move(world));
-
-  // setup particle stack, and add primary particle
-  setup::Stack stack;
-  stack.Clear();
-  const Code beamCode = Code::Nucleus;
-  const int nuclA = 4;
-  const int nuclZ = int(nuclA / 2.15 + 0.7);
-  const HEPMassType mass = GetNucleusMass(nuclA, nuclZ);
-  const HEPEnergyType E0 = nuclA * 1_TeV;
-  double theta = 0.;
-  double phi = 0.;
-
-  Point const injectionPos(
-      rootCS, 0_m, 0_m,
-      height_atmosphere); // this is the CORSIKA 7 start of atmosphere/universe
-
-  ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env};
-
-  {
-    auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-      return sqrt((Elab - m) * (Elab + m));
-    };
-    HEPMomentumType P0 = elab2plab(E0, mass);
-    auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) {
-      return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi),
-                             -ptot * cos(theta));
-    };
-    auto const [px, py, pz] =
-        momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0);
-    auto plab = corsika::MomentumVector(rootCS, {px, py, pz});
-    cout << "input particle: " << beamCode << endl;
-    cout << "input angles: theta=" << theta << " phi=" << phi << endl;
-    cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl;
-    stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                 corsika::MomentumVector, geometry::Point,
-		      units::si::TimeType, unsigned short, unsigned short>{
-        beamCode, E0, plab, injectionPos, 0_ns, nuclA, nuclZ});
-  }
-
-  // setup processes, decays and interactions
-  setup::Tracking tracking;
-  stack_inspector::StackInspector<setup::Stack> stackInspect(1, true, E0);
-
-  random::RNGManager::GetInstance().RegisterRandomStream("sibyll");
-  random::RNGManager::GetInstance().RegisterRandomStream("pythia");
-  process::sibyll::Interaction sibyll;
-  process::sibyll::NuclearInteraction sibyllNuc(sibyll, env);
-  process::sibyll::Decay decay;
-  // cascade with only HE model ==> HE cut
-  process::particle_cut::ParticleCut cut(80_GeV, true, true);
-
-  process::track_writer::TrackWriter trackWriter("tracks.dat");
-  process::energy_loss::EnergyLoss eLoss{showerAxis, cut.GetECut()};
-
-  // assemble all processes into an ordered process list
-  auto sequence =
-      process::sequence(stackInspect, sibyll, sibyllNuc, decay, eLoss, cut, trackWriter);
-
-  // define air shower object, run simulation
-  cascade::Cascade EAS(env, tracking, sequence, stack);
-
-  EAS.Run();
-
-  eLoss.PrintProfile(); // print longitudinal profile
-
-  cut.ShowResults();
-  const HEPEnergyType Efinal =
-      cut.GetCutEnergy() + cut.GetInvEnergy() + cut.GetEmEnergy();
-  cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl
-       << "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl;
-  cout << "total dEdX energy (GeV): " << eLoss.GetTotal() / 1_GeV << endl
-       << "relative difference (%): " << eLoss.GetTotal() / E0 * 100 << endl;
-  cut.Reset();
-}
diff --git a/examples/cascade_proton_example.cc b/examples/cascade_proton_example.cc
deleted file mode 100644
index 3512cac6a14256bb9d5352d16eb9f3f57ceeba52..0000000000000000000000000000000000000000
--- a/examples/cascade_proton_example.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/framework/core/Cascade.hpp>
-#include <corsika/framework/sequence/ProcessSequence.hpp>
-#include <corsika/process/hadronic_elastic_model/HadronicElasticModel.h>
-#include <corsika/process/stack_inspector/StackInspector.hpp>
-#include <corsika/process/tracking_line/TrackingLine.hpp>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/HomogeneousMedium.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-
-#include <corsika/framework/geometry/Sphere.hpp>
-
-#include <corsika/process/sibyll/Decay.h>
-#include <corsika/process/sibyll/Interaction.h>
-#include <corsika/process/sibyll/NuclearInteraction.h>
-
-#include <corsika/process/pythia/Decay.h>
-#include <corsika/process/pythia/Interaction.h>
-
-#include <corsika/process/track_writer/TrackWriter.h>
-
-#include <corsika/process/particle_cut/ParticleCut.hpp>
-
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/utility/CorsikaFenv.hpp>
-
-#include <boost/type_index.hpp>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-using boost::typeindex::type_id_with_cvr;
-
-#include <iostream>
-#include <limits>
-#include <typeinfo>
-
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::units;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::environment;
-
-using namespace std;
-using namespace corsika::units::si;
-
-//
-// The example main program for a particle cascade
-//
-int main() {
-
-  logging::SetLevel(logging::level::info);
-
-  std::cout << "cascade_proton_example" << std::endl;
-
-  feenableexcept(FE_INVALID);
-  // initialize random number sequence(s)
-  random::RNGManager::GetInstance().RegisterRandomStream("cascade");
-
-  // setup environment, geometry
-  using EnvType = setup::Environment;
-  EnvType env;
-  auto& universe = *(env.GetUniverse());
-  const CoordinateSystem& rootCS = env.GetCoordinateSystem();
-
-  auto world = EnvType::CreateNode<Sphere>(
-      Point{rootCS, 0_m, 0_m, 0_m}, 150_km);
-
-  using MyHomogeneousModel =
-      environment::MediumPropertyModel<environment::UniformMagneticField<
-          environment::HomogeneousMedium<setup::EnvironmentInterface>>>;
-
-  world->SetModelProperties<MyHomogeneousModel>(
-      environment::Medium::AirDry1Atm, geometry::Vector(rootCS, 0_T, 0_T, 1_T),
-      1_kg / (1_m * 1_m * 1_m),
-      NuclearComposition(std::vector<particles::Code>{particles::Code::Hydrogen},
-                         std::vector<float>{(float)1.}));
-
-  universe.AddChild(std::move(world));
-
-  // setup particle stack, and add primary particle
-  setup::Stack stack;
-  stack.Clear();
-  const Code beamCode = Code::Proton;
-  const HEPMassType mass = particles::Proton::GetMass();
-  const HEPEnergyType E0 = 100_GeV;
-  double theta = 0.;
-  double phi = 0.;
-
-  Point injectionPos(rootCS, 0_m, 0_m, 0_m);
-  {
-    auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-      return sqrt(Elab * Elab - m * m);
-    };
-    HEPMomentumType P0 = elab2plab(E0, mass);
-    auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) {
-      return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi),
-                             -ptot * cos(theta));
-    };
-    auto const [px, py, pz] =
-        momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0);
-    auto plab = corsika::MomentumVector(rootCS, {px, py, pz});
-    cout << "input particle: " << beamCode << endl;
-    cout << "input angles: theta=" << theta << " phi=" << phi << endl;
-    cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl;
-    stack.AddParticle(
-        std::tuple<particles::Code, units::si::HEPEnergyType,
-                   corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-            beamCode, E0, plab, pos, 0_ns});
-  }
-
-  // setup processes, decays and interactions
-  setup::Tracking tracking;
-  stack_inspector::StackInspector<setup::Stack> stackInspect(1, true, E0);
-
-  random::RNGManager::GetInstance().RegisterRandomStream("sibyll");
-  random::RNGManager::GetInstance().RegisterRandomStream("pythia");
-  //  process::sibyll::Interaction sibyll(env);
-  process::pythia::Interaction pythia;
-  //  process::sibyll::NuclearInteraction sibyllNuc(env, sibyll);
-  //  process::sibyll::Decay decay;
-  process::pythia::Decay decay;
-  process::particle_cut::ParticleCut cut(60_GeV, true, true);
-
-  // random::RNGManager::GetInstance().RegisterRandomStream("HadronicElasticModel");
-  // process::HadronicElasticModel::HadronicElasticInteraction
-  // hadronicElastic(env);
-
-  process::track_writer::TrackWriter trackWriter("tracks.dat");
-  ShowerAxis const showerAxis{injectionPos, Vector{rootCS, 0_m, 0_m, -100_km}, env};
-  process::energy_loss::EnergyLoss eLoss{showerAxis, cut.GetECut()};
-
-  // assemble all processes into an ordered process list
-  // auto sequence = sibyll << decay << hadronicElastic << cut << trackWriter;
-  auto sequence = process::sequence(pythia, decay, eLoss, cut, trackWriter, stackInspect);
-
-  // define air shower object, run simulation
-  cascade::Cascade EAS(env, tracking, sequence, stack);
-
-  EAS.Run();
-
-  cout << "Result: E0=" << E0 / 1_GeV << endl;
-  cut.ShowResults();
-  const HEPEnergyType Efinal =
-      cut.GetCutEnergy() + cut.GetInvEnergy() + cut.GetEmEnergy();
-  cout << "total energy (GeV): " << Efinal / 1_GeV << endl
-       << "relative difference (%): " << (Efinal / E0 - 1.) * 100 << endl;
-}
diff --git a/examples/stopping_power.cc b/examples/stopping_power.cc
deleted file mode 100644
index d6d5bb89ef7d8ce9a33752d3e78fb6d44bb2dc8d..0000000000000000000000000000000000000000
--- a/examples/stopping_power.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * (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/media/Environment.hpp>
-#include <corsika/framework/geometry/Sphere.hpp>
-#include <corsika/process/energy_loss/EnergyLoss.h>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include <corsika/framework/utility/CorsikaFenv.hpp>
-
-#include <fstream>
-#include <iostream>
-#include <limits>
-#include "../../corsika/setup/SetupStack.hpp"
-
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::environment;
-
-using namespace std;
-using namespace corsika::units::si;
-
-//
-// This example demonstrates the energy loss of muons as function of beta*gamma (=p/m)
-//
-int main() {
-
-  std::cout << "stopping_power" << std::endl;
-
-  feenableexcept(FE_INVALID);
-
-  // setup environment, geometry
-  using EnvType = Environment<IMediumModel>;
-  EnvType env;
-  env.GetUniverse()->SetModelProperties<HomogeneousMedium<IMediumModel>>(
-      1_g / cube(1_cm), NuclearComposition{{particles::Code::Unknown}, {1.f}});
-
-  const CoordinateSystem& rootCS = env.GetCoordinateSystem();
-
-  Point const injectionPos(
-      rootCS, 0_m, 0_m,
-      112.8_km); // this is the CORSIKA 7 start of atmosphere/universe
-
-  environment::ShowerAxis showerAxis{injectionPos,
-                                     Vector<length_d>{rootCS, 0_m, 0_m, 1_m}, env};
-  process::energy_loss::EnergyLoss eLoss{showerAxis, 300_MeV};
-
-  setup::Stack stack;
-
-  std::ofstream file("dEdX.dat");
-  file << "# beta*gamma, dE/dX / eV/(g/cm²)" << std::endl;
-
-  for (HEPEnergyType E0 = 300_MeV; E0 < 1_PeV; E0 *= 1.05) {
-    stack.Clear();
-    const Code beamCode = Code::MuPlus;
-    const HEPMassType mass = GetMass(beamCode);
-    double theta = 0.;
-    double phi = 0.;
-
-    auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-      return sqrt((Elab - m) * (Elab + m));
-    };
-    HEPMomentumType P0 = elab2plab(E0, mass);
-    auto momentumComponents = [](double theta, double phi, HEPMomentumType ptot) {
-      return std::make_tuple(ptot * sin(theta) * cos(phi), ptot * sin(theta) * sin(phi),
-                             -ptot * cos(theta));
-    };
-    auto const [px, py, pz] =
-        momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0);
-    auto plab = corsika::MomentumVector(rootCS, {px, py, pz});
-    cout << "input particle: " << beamCode << endl;
-    cout << "input angles: theta=" << theta << " phi=" << phi << endl;
-    cout << "input momentum: " << plab.GetComponents() / 1_GeV << endl;
-
-    stack.AddParticle(
-        std::tuple<particles::Code, units::si::HEPEnergyType,
-                   corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-            beamCode, E0, plab, injectionPos, 0_ns});
-
-    auto const p = stack.GetNextParticle();
-    HEPEnergyType dE = eLoss.TotalEnergyLoss(p, 1_g / square(1_cm));
-    file << P0 / mass << "\t" << -dE / 1_eV << std::endl;
-  }
-}
diff --git a/examples/vertical_EAS.cc b/examples/vertical_EAS.cc
deleted file mode 100644
index 50071a8f8729d2ec202a46f4b65524aa568747b6..0000000000000000000000000000000000000000
--- a/examples/vertical_EAS.cc
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/framework/core/Cascade.hpp>
-#include <corsika/framework/sequence/ProcessSequence.hpp>
-#include <corsika/process/StackProcess.h>
-#include <corsika/process/energy_loss/EnergyLoss.h>
-#include <corsika/process/observation_plane/ObservationPlane.hpp>
-#include <corsika/process/particle_cut/ParticleCut.hpp>
-#include <corsika/process/switch_process/SwitchProcess.hpp>
-#include <corsika/process/tracking_line/TrackingLine.hpp>
-
-#include <corsika/media/LayeredSphericalAtmosphereBuilder.hpp>
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/FlatExponential.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-
-#include <corsika/framework/geometry/Plane.hpp>
-#include <corsika/framework/geometry/Sphere.hpp>
-
-#include <corsika/process/sibyll/Decay.h>
-#include <corsika/process/stack_inspector/StackInspector.h>
-#include <corsika/process/sibyll/Interaction.h>
-#include <corsika/process/sibyll/NuclearInteraction.h>
-#include <corsika/process/urqmd/UrQMD.h>
-
-#include <corsika/process/particle_cut/ParticleCut.hpp>
-#include <corsika/process/track_writer/TrackWriter.h>
-
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/utility/CorsikaFenv.hpp>
-
-#include <iomanip>
-#include <iostream>
-#include <limits>
-#include <string>
-
-#include "../../corsika/setup/SetupStack.hpp"
-#include "../../corsika/setup/SetupTrajectory.hpp"
-
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::units;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika::environment;
-
-using namespace std;
-using namespace corsika::units::si;
-
-using Particle = setup::Stack::StackIterator;
-
-void registerRandomStreams(const int seed) {
-  random::RNGManager::GetInstance().RegisterRandomStream("cascade");
-  random::RNGManager::GetInstance().RegisterRandomStream("qgsjet");
-  random::RNGManager::GetInstance().RegisterRandomStream("sibyll");
-  random::RNGManager::GetInstance().RegisterRandomStream("pythia");
-  random::RNGManager::GetInstance().RegisterRandomStream("urqmd");
-  random::RNGManager::GetInstance().RegisterRandomStream("proposal");
-
-  if (seed == 0)
-    random::RNGManager::GetInstance().SeedAll();
-  else
-    random::RNGManager::GetInstance().SeedAll(seed);
-}
-
-template <typename T>
-using MyExtraEnv = environment::MediumPropertyModel<environment::UniformMagneticField<T>>;
-
-int main(int argc, char** argv) {
-
-  logging::SetLevel(logging::level::info);
-
-  C8LOG_INFO("vertical_EAS");
-
-  if (argc < 4) {
-    std::cerr << "usage: vertical_EAS <A> <Z> <energy/GeV> [seed]" << std::endl;
-    std::cerr << "       if no seed is given, a random seed is chosen" << std::endl;
-    return 1;
-  }
-  feenableexcept(FE_INVALID);
-
-  int seed = 0;
-  if (argc > 4) seed = std::stoi(std::string(argv[4]));
-  // initialize random number sequence(s)
-  registerRandomStreams(seed);
-
-  // setup environment, geometry
-  using EnvType = setup::Environment;
-  EnvType env;
-  const CoordinateSystem& rootCS = env.GetCoordinateSystem();
-  Point const center{rootCS, 0_m, 0_m, 0_m};
-  auto builder = environment::make_layered_spherical_atmosphere_builder<
-      setup::EnvironmentInterface,
-      MyExtraEnv>::create(center, units::constants::EarthRadius::Mean,
-                          environment::Medium::AirDry1Atm,
-                          geometry::Vector{rootCS, 0_T, 50_uT, 0_T});
-  builder.setNuclearComposition(
-      {{particles::Code::Nitrogen, particles::Code::Oxygen},
-       {0.7847f, 1.f - 0.7847f}}); // values taken from AIRES manual, Ar removed for now
-
-  builder.addExponentialLayer(1222.6562_g / (1_cm * 1_cm), 994186.38_cm, 4_km);
-  builder.addExponentialLayer(1144.9069_g / (1_cm * 1_cm), 878153.55_cm, 10_km);
-  builder.addExponentialLayer(1305.5948_g / (1_cm * 1_cm), 636143.04_cm, 40_km);
-  builder.addExponentialLayer(540.1778_g / (1_cm * 1_cm), 772170.16_cm, 100_km);
-  builder.addLinearLayer(1e9_cm, 112.8_km);
-  builder.assemble(env);
-
-  // setup particle stack, and add primary particle
-  setup::Stack stack;
-  stack.Clear();
-  const Code beamCode = Code::Nucleus;
-  unsigned short const A = std::stoi(std::string(argv[1]));
-  unsigned short Z = std::stoi(std::string(argv[2]));
-  auto const mass = particles::GetNucleusMass(A, Z);
-  const HEPEnergyType E0 = 1_GeV * std::stof(std::string(argv[3]));
-  double theta = 0.;
-  auto const thetaRad = theta / 180. * M_PI;
-
-  auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-    return sqrt((Elab - m) * (Elab + m));
-  };
-  HEPMomentumType P0 = elab2plab(E0, mass);
-  auto momentumComponents = [](double thetaRad, HEPMomentumType ptot) {
-    return std::make_tuple(ptot * sin(thetaRad), 0_eV, -ptot * cos(thetaRad));
-  };
-  auto const [px, py, pz] =
-      momentumComponents(theta / 180. * M_PI, phi / 180. * M_PI, P0);
-  auto plab = corsika::MomentumVector(rootCS, {px, py, pz});
-  cout << "input particle: " << beamCode << endl;
-  cout << "input angles: theta=" << theta << endl;
-  cout << "input momentum: " << plab.GetComponents() / 1_GeV << ", norm = " << plab.norm()
-       << endl;
-
-  auto const observationHeight = 0_km + builder.getEarthRadius();
-  auto const injectionHeight = 112.75_km + builder.getEarthRadius();
-  auto const t = -observationHeight * cos(thetaRad) +
-                 sqrt(-units::static_pow<2>(sin(thetaRad) * observationHeight) +
-                      units::static_pow<2>(injectionHeight));
-
-  Point const showerCore{rootCS, 0_m, 0_m, observationHeight};
-  Point const injectionPos =
-      showerCore +
-      Vector<dimensionless_d>{rootCS, {-sin(thetaRad), 0, cos(thetaRad)}} * t;
-
-  std::cout << "point of injection: " << injectionPos.GetCoordinates() << std::endl;
-
-  if (A != 1) {
-    stack.AddParticle(std::make_tuple(beamCode, E0, plab, injectionPos, 0_ns, A, Z));
-
-  } else {
-    if (Z == 1) {
-      stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                   corsika::stack::MomentumVector, geometry::Point,
-                                   units::si::TimeType>{particles::Code::Proton, E0, plab,
-                                                        injectionPos, 0_ns});
-    } else if (Z == 0) {
-      stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                   corsika::stack::MomentumVector, geometry::Point,
-                                   units::si::TimeType>{particles::Code::Neutron, E0,
-                                                        plab, injectionPos, 0_ns});
-    } else {
-      std::cerr << "illegal parameters" << std::endl;
-      return EXIT_FAILURE;
-    }
-  }
-
-  // we make the axis much longer than the inj-core distance since the
-  // profile will go beyond the core, depending on zenith angle
-  std::cout << "shower axis length: " << (showerCore - injectionPos).norm() * 1.5
-            << std::endl;
-
-  environment::ShowerAxis const showerAxis{injectionPos,
-                                           (showerCore - injectionPos) * 1.5, env};
-
-  // setup processes, decays and interactions
-
-  stack.AddParticle(
-      std::tuple<particles::Code, units::si::HEPEnergyType,
-                 corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-          beamCode, E0, plab, injectionPos, 0_ns});
-  //  }
-
-  process::sibyll::Interaction sibyll;
-  process::interaction_counter::InteractionCounter sibyllCounted(sibyll);
-
-  process::sibyll::NuclearInteraction sibyllNuc(sibyll, env);
-  process::interaction_counter::InteractionCounter sibyllNucCounted(sibyllNuc);
-
-  process::pythia::Decay decayPythia;
-
-  // use sibyll decay routine for decays of particles unknown to pythia
-  process::sibyll::Decay decaySibyll{{
-      Code::N1440Plus,
-      Code::N1440MinusBar,
-      Code::N1440_0,
-      Code::N1440_0Bar,
-      Code::N1710Plus,
-      Code::N1710MinusBar,
-      Code::N1710_0,
-      Code::N1710_0Bar,
-
-      Code::Pi1300Plus,
-      Code::Pi1300Minus,
-      Code::Pi1300_0,
-
-      Code::KStar0_1430_0,
-      Code::KStar0_1430_0Bar,
-      Code::KStar0_1430_Plus,
-      Code::KStar0_1430_MinusBar,
-  }};
-
-  decaySibyll.PrintDecayConfig();
-
-  process::on_shell_check::OnShellCheck reset_particle_mass(1.e-3, 1.e-1, false);
-
-  process::track_writer::TrackWriter trackWriter("tracks.dat");
-  process::longitudinal_profile::LongitudinalProfile longprof{showerAxis};
-
-  Plane const obsPlane(showerCore, Vector<dimensionless_d>(rootCS, {0., 0., 1.}));
-  process::observation_plane::ObservationPlane observationLevel(
-      obsPlane, Vector<dimensionless_d>(rootCS, {1., 0., 0.}), "particles.dat");
-
-  process::UrQMD::UrQMD urqmd;
-  process::interaction_counter::InteractionCounter urqmdCounted{urqmd};
-
-  // assemble all processes into an ordered process list
-  struct EnergySwitch {
-    HEPEnergyType cutE_;
-    EnergySwitch(HEPEnergyType cutE)
-        : cutE_(cutE) {}
-    process::SwitchResult operator()(const Particle& p) {
-      if (p.GetEnergy() < cutE_)
-        return process::SwitchResult::First;
-      else
-        return process::SwitchResult::Second;
-    }
-  };
-  auto hadronSequence =
-      process::select(urqmdCounted, process::sequence(sibyllNucCounted, sibyllCounted),
-                      EnergySwitch(55_GeV));
-  auto decaySequence = process::sequence(decayPythia, decaySibyll);
-  stack_inspector::StackInspector<setup::Stack> stackInspect(1000, false, E0);
-  auto sequence = process::sequence(stackInspect, hadronSequence, reset_particle_mass,
-                                    decaySequence, proposalCounted, em_continuous, cut,
-                                    trackWriter, observationLevel, longprof);
-
-  // define air shower object, run simulation
-  setup::Tracking tracking;
-  cascade::Cascade EAS(env, tracking, sequence, stack);
-
-  // to fix the point of first interaction, uncomment the following two lines:
-  //  EAS.forceInteraction();
-
-  EAS.Run();
-
-  cut.ShowResults();
-  em_continuous.showResults();
-  observationLevel.ShowResults();
-  const HEPEnergyType Efinal = cut.GetCutEnergy() + cut.GetInvEnergy() +
-                               cut.GetEmEnergy() + em_continuous.energyLost() +
-                               observationLevel.GetEnergyGround();
-  cout << "total cut energy (GeV): " << Efinal / 1_GeV << endl
-       << "relative difference (%): " << (Efinal / E0 - 1) * 100 << endl;
-  observationLevel.Reset();
-  cut.Reset();
-  em_continuous.reset();
-
-  auto const hists = sibyllCounted.GetHistogram() + sibyllNucCounted.GetHistogram() +
-                     urqmdCounted.GetHistogram() + proposalCounted.GetHistogram();
-
-  hists.saveLab("inthist_lab_verticalEAS.npz");
-  hists.saveCMS("inthist_cms_verticalEAS.npz");
-  longprof.save("longprof_verticalEAS.txt");
-}
diff --git a/tests/common/testTestStack.h b/tests/common/testTestStack.hpp
similarity index 100%
rename from tests/common/testTestStack.h
rename to tests/common/testTestStack.hpp
diff --git a/tests/framework/testCombinedStack.cpp b/tests/framework/testCombinedStack.cpp
index 5ea982873f49ebeb9641a9e7453954646ee31f4f..f90f738d191644b21a57107093adda87f02a7832 100644
--- a/tests/framework/testCombinedStack.cpp
+++ b/tests/framework/testCombinedStack.cpp
@@ -12,7 +12,7 @@
 #include <corsika/framework/stack/SecondaryView.hpp>
 #include <corsika/framework/stack/Stack.hpp>
 
-#include <testTestStack.h> // for testing: simple stack. This is a
+#include <testTestStack.hpp> // for testing: simple stack. This is a
 // test-build, and inluce file is obtained from CMAKE_CURRENT_SOURCE_DIR
 
 #include <iomanip>
diff --git a/tests/framework/testSecondaryView.cpp b/tests/framework/testSecondaryView.cpp
index 197d03825ade6db99a48690db1c9b22cb53620b1..a2a161bd816ab026d67d9b2fff27026325e2c852 100644
--- a/tests/framework/testSecondaryView.cpp
+++ b/tests/framework/testSecondaryView.cpp
@@ -12,7 +12,7 @@
 #include <corsika/framework/stack/Stack.hpp>
 #include <corsika/framework/logging/Logging.hpp>
 
-#include <testTestStack.h> // for testing: simple stack. This is a
+#include <testTestStack.hpp> // for testing: simple stack. This is a
 // test-build, and inluce file is obtained from CMAKE_CURRENT_SOURCE_DIR
 
 #include <iomanip>
diff --git a/tests/framework/testStackInterface.cpp b/tests/framework/testStackInterface.cpp
index b07e378a95ff3dcde952588e38defa4766b2c07e..0e5b49a1a99781238b5679375c5b57cd2e6d5fff 100644
--- a/tests/framework/testStackInterface.cpp
+++ b/tests/framework/testStackInterface.cpp
@@ -10,7 +10,7 @@
 
 #include <corsika/framework/stack/Stack.hpp>
 
-#include <testTestStack.h> // from tests/common
+#include <testTestStack.hpp> // from tests/common
 
 #include <iomanip>
 #include <tuple>
diff --git a/tests/processes/TrackingLine/testTrackingLineStack.h b/tests/processes/TrackingLine/testTrackingLineStack.h
deleted file mode 100644
index 96998fe6ec0e5183729bcd09796ff9b4f7ba1677..0000000000000000000000000000000000000000
--- a/tests/processes/TrackingLine/testTrackingLineStack.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * (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/media/Environment.hpp>
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include <corsika/setup/SetupStack.hpp>
-
-using TestEnvironmentType =
-    corsika::environment::Environment<corsika::environment::Empty>;
-
-template <typename T>
-using SetupGeometryDataInterface =
-    corsika::stack::node::GeometryDataInterface<T, TestEnvironmentType>;
-
-// combine particle data stack with geometry information for tracking
-template <typename StackIter>
-using StackWithGeometryInterface = corsika::CombinedParticleInterface<
-    corsika::detail::ParticleDataStack::PIType, SetupGeometryDataInterface,
-    StackIter>;
-using TestTrackingLineStack = corsika::CombinedStack<
-    typename corsika::detail::ParticleDataStack::StackImpl,
-    GeometryData<TestEnvironmentType>, StackWithGeometryInterface>;
-
-
diff --git a/tests/processes/testNullModel.cc b/tests/processes/testNullModel.cc
deleted file mode 100644
index 853361352819cb59506562578b0ea0c434974770..0000000000000000000000000000000000000000
--- a/tests/processes/testNullModel.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * (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.
- */
-
-#include <catch2/catch.hpp>
-
-#include <corsika/process/NullModel.hpp>
-
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/setup/SetupStack.hpp>
-#include <corsika/setup/SetupTrajectory.hpp>
-
-using namespace corsika::units::si;
-using namespace corsika::null_model;
-using namespace corsika;
-
-TEST_CASE("NullModel", "[processes]") {
-
-  auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen);
-  auto const& cs = *csPtr;
-  [[maybe_unused]] auto const& env_dummy = env;
-  [[maybe_unused]] auto const& node_dummy = nodePtr;
-
-  auto [stack, view] =
-      setup::testing::setupStack(particles::Code::Electron, 0, 0, 100_GeV, nodePtr, cs);
-  [[maybe_unused]] const auto& dummyView = view;
-  auto particle = stack->first();
-
-  geometry::Point const origin(cs, {0_m, 0_m, 0_m});
-  geometry::Vector<units::si::SpeedType::dimension_type> v(cs, 0_m / second, 0_m / second,
-                                                           1_m / second);
-  geometry::Line line(origin, v);
-  geometry::Trajectory<geometry::Line> track(line, 10_s);
-
-  setup::Stack stack;
-  setup::Stack::ParticleType particle = stack.AddParticle(
-      std::tuple<particles::Code, units::si::HEPEnergyType,
-                 corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-          particles::Code::Electron, 100_GeV,
-          corsika::MomentumVector(dummyCS, {0_GeV, 0_GeV, -1_GeV}),
-          geometry::Point(dummyCS, {0_m, 0_m, 10_km}), 0_ns});
-  SECTION("interface") {
-
-    NullModel model(10_m);
-
-    [[maybe_unused]] const process::EProcessReturn ret =
-        model.DoContinuous(particle, track);
-    LengthType const length = model.MaxStepLength(particle, track);
-
-    CHECK((length / 10_m) == Approx(1));
-  }
-}
diff --git a/tests/processes/testObservationPlane.cc b/tests/processes/testObservationPlane.cc
deleted file mode 100644
index 243d091ce1165fcc060a07bf30de9d1f0f273bb8..0000000000000000000000000000000000000000
--- a/tests/processes/testObservationPlane.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * (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.
- */
-
-#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one
-                          // cpp file
-#include <catch2/catch.hpp>
-
-#include <corsika/process/ObservationPlane.hpp>
-
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/setup/SetupStack.h>
-#include <corsika/setup/SetupTrajectory.h>
-
-using namespace corsika::units::si;
-using namespace corsika::observation_plane;
-using namespace corsika;
-using namespace corsika;
-using namespace corsika;
-
-TEST_CASE("ContinuousProcess interface", "[proccesses][observation_plane]") {
-
-  auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen);
-  auto const& cs = *csPtr;
-  [[maybe_unused]] auto const& env_dummy = env;
-  [[maybe_unused]] auto const& node_dummy = nodePtr;
-
-  /*
-    Test with downward going 1_GeV neutrino, starting at 0, 1_m, 10m
-
-    ObservationPlane has origin at 0,0,0
-   */
-
-  auto [stack, viewPtr] =
-      setup::testing::setupStack(particles::Code::NuE, 0, 0, 1_GeV, nodePtr, cs);
-  [[maybe_unused]] setup::StackView& view = *viewPtr;
-  auto particle = stack->GetNextParticle();
-
-  Point const start(cs, {0_m, 1_m, 10_m});
-  Vector<units::si::SpeedType::dimension_type> vec(cs, 0_m / second, 0_m / second,
-                                                   -units::constants::c);
-  Line line(start, vec);
-  Trajectory<Line> track(line, 12_m / units::constants::c);
-
-  // setup particle stack, and add primary particle
-  setup::Stack stack;
-  stack.Clear();
-  {
-    auto elab2plab = [](HEPEnergyType Elab, HEPMassType m) {
-      return sqrt((Elab - m) * (Elab + m));
-    };
-    stack.AddParticle(
-        std::tuple<Code, units::si::HEPEnergyType, corsika::MomentumVector, Point,
-                   units::si::TimeType>{
-            Code::NuMu, 1_GeV,
-            corsika::MomentumVector(
-                rootCS, {0_GeV, 0_GeV, -elab2plab(1_GeV, NuMu::GetMass())}),
-            Point(rootCS, {1_m, 1_m, 10_m}), 0_ns});
-  }
-  auto particle = stack.GetNextParticle();
-
-  SECTION("horizontal plane") {
-
-    Plane const obsPlane(Point(cs, {0_m, 0_m, 0_m}),
-                         Vector<dimensionless_d>(cs, {0., 0., 1.}));
-    ObservationPlane obs(obsPlane, Vector<dimensionless_d>(cs, {1., 0., 0.}),
-                         "particles.dat", true);
-
-    const LengthType length = obs.MaxStepLength(particle, track);
-    const process::EProcessReturn ret = obs.DoContinuous(particle, track);
-
-    REQUIRE(length / 10_m == Approx(1).margin(1e-4));
-    REQUIRE(ret == process::EProcessReturn::eParticleAbsorbed);
-  }
-
-  SECTION("inclined plane") {}
-
-  SECTION("transparent plane") {
-    Plane const obsPlane(Point(cs, {0_m, 0_m, 0_m}),
-                         Vector<dimensionless_d>(cs, {0., 0., 1.}));
-    ObservationPlane obs(obsPlane, Vector<dimensionless_d>(cs, {1., 0., 0.}),
-                         "particles.dat", false);
-
-    const LengthType length = obs.MaxStepLength(particle, track);
-    const process::EProcessReturn ret = obs.DoContinuous(particle, track);
-
-    REQUIRE(length / 10_m == Approx(1).margin(1e-4));
-    REQUIRE(ret == process::EProcessReturn::eOk);
-  }
-}
diff --git a/tests/processes/testParticleCut.cc b/tests/processes/testParticleCut.cc
deleted file mode 100644
index 7385a82b55973c026872aadc217439c5433fe3aa..0000000000000000000000000000000000000000
--- a/tests/processes/testParticleCut.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * (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.
- */
-
-#include <corsika/process/ParticleCut.hpp>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-#include <corsika/framework/utility/CorsikaFenv.hpp>
-
-#include <catch2/catch.hpp>
-#include <corsika/setup/SetupStack.hpp>
-
-using namespace corsika;
-using namespace corsika::particle_cut;
-using namespace corsika::units;
-using namespace corsika::units::si;
-
-TEST_CASE("ParticleCut", "[processes]") {
-  feenableexcept(FE_INVALID);
-  using EnvType = setup::Environment;
-
-  EnvType env;
-  const geometry::CoordinateSystem& rootCS = env.GetCoordinateSystem();
-
-  // setup empty particle stack
-  setup::Stack stack;
-  stack.Clear();
-  // two energies
-  const HEPEnergyType Eabove = 1_TeV;
-  const HEPEnergyType Ebelow = 10_GeV;
-  // list of arbitrary particles
-  const std::vector<particles::Code> particleList = {
-      particles::Code::PiPlus,   particles::Code::PiMinus, particles::Code::KPlus,
-      particles::Code::KMinus,   particles::Code::K0Long,  particles::Code::K0Short,
-      particles::Code::Electron, particles::Code::MuPlus,  particles::Code::NuE,
-      particles::Code::Neutron,  particles::Code::NuMu};
-
-  // common staring point
-  const geometry::Point point0(rootCS, 0_m, 0_m, 0_m);
-
-  SECTION("cut on particle type: inv") {
-
-    ParticleCut cut(20_GeV, false, true);
-    CHECK(cut.GetECut() == 20_GeV);
-
-    // add primary particle to stack
-    auto particle = stack.AddParticle(
-        std::tuple<particles::Code, units::si::HEPEnergyType,
-                   corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-            particles::Code::Proton, Eabove,
-            corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}),
-            geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns});
-    // view on secondary particles
-    corsika::SecondaryView view(particle);
-    // ref. to primary particle through the secondary view.
-    // only this way the secondary view is populated
-    auto projectile = view.GetProjectile();
-    // add secondaries, all with energies above the threshold
-    // only cut is by species
-    for (auto proType : particleList)
-      projectile.AddSecondary(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                         corsika::MomentumVector, geometry::Point,
-                                         units::si::TimeType>{
-          proType, Eabove, corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}),
-          geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns});
-
-    CHECK(view.getEntries() == 9);
-    CHECK(cut.GetNumberInvParticles() == 2);
-    CHECK(cut.GetInvEnergy() / 1_GeV == 2000);
-  }
-
-  SECTION("cut on particle type: em") {
-
-    ParticleCut cut(20_GeV, true, false);
-
-    // add primary particle to stack
-    auto particle = stack.AddParticle(std::make_tuple(
-        particles::Code::Proton, Eabove,
-        corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), point0, 0_ns));
-    // view on secondary particles
-    corsika::setup::StackView view(particle);
-    // ref. to primary particle through the secondary view.
-    // only this way the secondary view is populated
-    auto projectile = view.GetProjectile();
-    // add secondaries, all with energies above the threshold
-    // only cut is by species
-    for (auto proType : particleList) {
-      projectile.AddSecondary(std::make_tuple(
-          proType, Eabove, corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}),
-          point0, 0_ns));
-    }
-    cut.DoSecondaries(view);
-
-    CHECK(view.getEntries() == 10);
-    CHECK(cut.GetNumberEmParticles() == 1);
-    CHECK(cut.GetEmEnergy() / 1_GeV == 1000);
-  }
-
-  SECTION("cut low energy") {
-    ParticleCut cut(20_GeV, true, true);
-
-    // add primary particle to stack
-    auto particle = stack.AddParticle(
-        std::tuple<particles::Code, units::si::HEPEnergyType,
-                   corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-            particles::Code::Proton, Eabove,
-            corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}),
-            geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns});
-    // view on secondary particles
-    corsika::SecondaryView view(particle);
-    // ref. to primary particle through the secondary view.
-    // only this way the secondary view is populated
-    auto projectile = view.GetProjectile();
-    // add secondaries, all with energies below the threshold
-    // only cut is by species
-    for (auto proType : particleList)
-      projectile.AddSecondary(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                         corsika::MomentumVector, geometry::Point,
-                                         units::si::TimeType>{
-          proType, Ebelow, corsika::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}),
-          geometry::Point(rootCS, 0_m, 0_m, 0_m), 0_ns});
-
-    cut.DoSecondaries(view);
-
-    CHECK(view.getEntries() == 1);
-    CHECK(view.getSize() == 13);
-  }
-
-  SECTION("cut on time") {
-    ParticleCut cut(20_GeV, false, false);
-    const TimeType too_late = 1_s;
-
-    // add primary particle to stack
-    auto particle = stack.AddParticle(std::make_tuple(
-        particles::Code::Proton, Eabove,
-        corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}), point0, 1_ns));
-    // view on secondary particles
-    corsika::setup::StackView view(particle);
-    // ref. to primary particle through the secondary view.
-    // only this way the secondary view is populated
-    auto projectile = view.GetProjectile();
-    // add secondaries, all with energies above the threshold
-    // only cut is by species
-    for (auto proType : particleList) {
-      projectile.AddSecondary(std::make_tuple(
-          proType, Eabove, corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}),
-          point0, too_late));
-    }
-    cut.DoSecondaries(view);
-
-    CHECK(view.getEntries() == 0);
-    CHECK(cut.GetCutEnergy() / 1_GeV == 11000);
-    cut.Reset();
-    CHECK(cut.GetCutEnergy() == 0_GeV);
-  }
-
-  corsika::setup::Trajectory const track = setup::testing::make_track<setup::Trajectory>(
-      geometry::Line{point0,
-                     geometry::Vector<units::si::SpeedType::dimension_type>{
-                         rootCS, {0_m / second, 0_m / second, -units::constants::c}}},
-      12_m / units::constants::c);
-
-  SECTION("cut on DoContinous, just invisibles") {
-
-    ParticleCut cut(20_GeV, false, true);
-    CHECK(cut.GetECut() == 20_GeV);
-
-    // add particles, all with energies above the threshold
-    // only cut is by species
-    for (auto proType : particleList) {
-      auto particle = stack.AddParticle(std::make_tuple(
-          proType, Eabove, corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, 0_GeV}),
-          point0, 0_ns));
-      cut.DoContinuous(particle, track);
-    }
-
-    CHECK(stack.getEntries() == 9);
-    CHECK(cut.GetNumberInvParticles() == 2);
-    CHECK(cut.GetInvEnergy() / 1_GeV == 2000);
-  }
-}
diff --git a/tests/processes/testQGSJetII.cc b/tests/processes/testQGSJetII.cc
deleted file mode 100644
index ca203d3f9c555591d7846e0378b7c8a4b67a71a3..0000000000000000000000000000000000000000
--- a/tests/processes/testQGSJetII.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * (c) Copyright 2020 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/process/QGSJetII.hpp>
-
-#include <corsika/framework/random/RNGManager.hpp>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <catch2/catch.hpp>
-
-#include <cstdlib>
-#include <experimental/filesystem>
-#include <iostream>
-
-using namespace corsika;
-using namespace corsika::qgsjetII;
-
-TEST_CASE("QgsjetII", "[processes]") {
-
-  SECTION("Corsika -> QgsjetII") {
-    CHECK(process::qgsjetII::ConvertToQgsjetII(particles::PiMinus::GetCode()) ==
-          process::qgsjetII::QgsjetIICode::PiMinus);
-    CHECK(process::qgsjetII::ConvertToQgsjetIIRaw(particles::Proton::GetCode()) == 2);
-  }
-
-  SECTION("QgsjetII -> Corsika") {
-    CHECK(particles::PiPlus::GetCode() == process::qgsjetII::ConvertFromQgsjetII(
-                                              process::qgsjetII::QgsjetIICode::PiPlus));
-  }
-
-  SECTION("Corsika -> QgsjetII") {
-    CHECK(process::qgsjetII::ConvertToQgsjetII(particles::PiMinus::GetCode()) ==
-          process::qgsjetII::QgsjetIICode::PiMinus);
-    CHECK(process::qgsjetII::ConvertToQgsjetIIRaw(particles::Proton::GetCode()) == 2);
-  }
-
-  SECTION("canInteractInQgsjetII") {
-
-    CHECK(process::qgsjetII::CanInteract(particles::Proton::GetCode()));
-    CHECK(process::qgsjetII::CanInteract(particles::Code::KPlus));
-    CHECK(process::qgsjetII::CanInteract(particles::Nucleus::GetCode()));
-    // CHECK(process::qgsjetII::CanInteract(particles::Helium::GetCode()));
-
-    CHECK_FALSE(process::qgsjetII::CanInteract(particles::EtaC::GetCode()));
-    CHECK_FALSE(process::qgsjetII::CanInteract(particles::SigmaC0::GetCode()));
-  }
-
-  SECTION("cross-section type") {
-
-    CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::Neutron) ==
-          process::qgsjetII::QgsjetIIXSClass::Baryons);
-    CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::K0Long) ==
-          process::qgsjetII::QgsjetIIXSClass::Kaons);
-    CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::Proton) ==
-          process::qgsjetII::QgsjetIIXSClass::Baryons);
-    CHECK(process::qgsjetII::GetQgsjetIIXSCode(particles::Code::PiMinus) ==
-          process::qgsjetII::QgsjetIIXSClass::LightMesons);
-  }
-}
-
-#include <corsika/framework/geometry/Point.hpp>
-#include <corsika/framework/geometry/RootCoordinateSystem.hpp>
-#include <corsika/framework/geometry/Vector.hpp>
-
-#include <corsika/framework/core/PhysicalUnits.hpp>
-
-#include <corsika/framework/core/ParticleProperties.hpp>
-#include <corsika/setup/SetupStack.hpp>
-#include <corsika/setup/SetupTrajectory.hpp>
-
-#include <corsika/media/Environment.hpp>
-#include <corsika/media/HomogeneousMedium.hpp>
-#include <corsika/media/NuclearComposition.hpp>
-
-using namespace corsika::units::si;
-using namespace corsika::units;
-using namespace corsika;
-
-TEST_CASE("QgsjetIIInterface", "[processes]") {
-
-  auto [env, csPtr, nodePtr] = setup::testing::setupEnvironment(particles::Code::Oxygen);
-  [[maybe_unused]] auto const& env_dummy = env;
-  [[maybe_unused]] auto const& node_dummy = nodePtr;
-
-  corsika::random::RNGManager::GetInstance().RegisterRandomStream("qgsjet");
-
-  SECTION("InteractionInterface") {
-
-    setup::Stack stack;
-    const HEPEnergyType E0 = 100_GeV;
-    HEPMomentumType P0 =
-        sqrt(E0 * E0 - particles::Proton::GetMass() * particles::Proton::GetMass());
-    auto plab = corsika::MomentumVector(cs, {0_GeV, 0_GeV, -P0});
-    geometry::Point pos(cs, 0_m, 0_m, 0_m);
-    auto particle =
-        stack.AddParticle(std::tuple<particles::Code, units::si::HEPEnergyType,
-                                     corsika::MomentumVector, geometry::Point,
-                                     units::si::TimeType, unsigned int, unsigned int>{
-            particles::Code::Nucleus, E0, plab, pos, 0_ns, 16, 8});
-    // corsika::MomentumVector, geometry::Point, units::si::TimeType>{
-    //	  particles::Code::PiPlus, E0, plab, pos, 0_ns});
-
-    particle.SetNode(nodePtr);
-    corsika::SecondaryView view(particle);
-    auto projectile = view.GetProjectile();
-
-    Interaction model;
-
-    [[maybe_unused]] const process::EProcessReturn ret = model.DoInteraction(view);
-    [[maybe_unused]] const GrammageType length = model.GetInteractionLength(particle);
-
-    CHECK(length / (1_g / square(1_cm)) == Approx(93.04).margin(0.1));
-
-    /***********************************
-     It as turned out already two times (#291 and #307) that the detailed output of
-    QGSJetII event generation depends on the gfortran version used. This is not reliable
-    and cannot be tested in a unit test here. One related problem was already found (#291)
-    and is realted to undefined behaviour in the evaluation of functions in logical
-    expressions. It is not clear if #307 is the same issue.
-
-     CHECK(view.GetSize() == 14);
-     CHECK(sumCharge(view) == 2);
-    ************************************/
-    auto const secMomSum = sumMomentum(view, projectileMomentum.GetCoordinateSystem());
-    CHECK((secMomSum - projectileMomentum).norm() / projectileMomentum.norm() ==
-          Approx(0).margin(1e-2));
-  }
-}