From 450c7e0c823f81fbf6191edc579f952d8738c49c Mon Sep 17 00:00:00 2001
From: Maximilian Reininghaus <maximilian.reininghaus@kit.edu>
Date: Mon, 17 Dec 2018 18:30:38 +0100
Subject: [PATCH] correct units in sibyll process interface

---
 Documentation/Examples/cascade_example.cc   |  10 +-
 Framework/Cascade/Cascade.h                 |   8 +-
 Framework/Geometry/Line.h                   |   2 -
 Framework/ProcessSequence/ProcessSequence.h |   2 +-
 Processes/Sibyll/Decay.h                    |  34 +-
 Processes/Sibyll/Interaction.h              | 426 ++++++++++----------
 Processes/Sibyll/ParticleConversion.h       |   2 +-
 Processes/Sibyll/SibStack.h                 | 134 +++---
 Processes/Sibyll/sibyll2.3c.cc              |   1 -
 9 files changed, 297 insertions(+), 322 deletions(-)

diff --git a/Documentation/Examples/cascade_example.cc b/Documentation/Examples/cascade_example.cc
index f8eb408b6..6d36ce8f0 100644
--- a/Documentation/Examples/cascade_example.cc
+++ b/Documentation/Examples/cascade_example.cc
@@ -200,7 +200,6 @@ public:
 private:
 };
 
-
 int main() {
   corsika::environment::Environment env; // dummy environment
   auto& universe = *(env.GetUniverse());
@@ -224,13 +223,13 @@ int main() {
   tracking_line::TrackingLine<setup::Stack> tracking(env);
   stack_inspector::StackInspector<setup::Stack> p0(true);
 
-  corsika::process::sibyll::Interaction/*<setup::Stack>,setup::Trajectory>*/ p1;
+  corsika::process::sibyll::Interaction /*<setup::Stack>,setup::Trajectory>*/ p1;
   corsika::process::sibyll::Decay p2;
   ProcessEMCut p3;
   const auto sequence = /*p0 +*/ p1 + p2 + p3;
   setup::Stack stack;
 
-  corsika::cascade::Cascade EAS(tracking, sequence, stack);
+  corsika::cascade::Cascade EAS(env, tracking, sequence, stack);
 
   stack.Clear();
   auto particle = stack.NewParticle();
@@ -246,8 +245,9 @@ int main() {
   particle.SetPosition(p);
   EAS.Init();
   EAS.Run();
-  cout << "Result: E0=" << E0 / 1_GeV
-    //<< "GeV, particles below energy threshold =" << p1.GetCount()
+  cout << "Result: E0="
+       << E0 / 1_GeV
+       //<< "GeV, particles below energy threshold =" << p1.GetCount()
        << endl;
   cout << "total energy below threshold (GeV): " //<< p1.GetEnergy() / 1_GeV
        << std::endl;
diff --git a/Framework/Cascade/Cascade.h b/Framework/Cascade/Cascade.h
index 24f86db66..0edd50502 100644
--- a/Framework/Cascade/Cascade.h
+++ b/Framework/Cascade/Cascade.h
@@ -18,7 +18,6 @@
 #include <corsika/random/UniformRealDistribution.h>
 #include <corsika/setup/SetupTrajectory.h>
 #include <corsika/units/PhysicalUnits.h>
-#include <corsika/environment/Environment.h>
 
 #include <type_traits>
 
@@ -58,7 +57,7 @@ namespace corsika::cascade {
 
     void Step(Particle& particle) {
       using namespace corsika::units::si;
-      
+
       // determine geometric tracking
       corsika::setup::Trajectory step = fTracking.GetTrack(particle);
 
@@ -158,12 +157,7 @@ namespace corsika::cascade {
     Stack& fStack;
     corsika::environment::Environment const& fEnvironment;
     corsika::random::RNG& fRNG =
-<<<<<<< HEAD
         corsika::random::RNGManager::GetInstance().GetRandomStream("cascade");
-=======
-          corsika::random::RNGManager::GetInstance().GetRandomStream("cascade");
-
->>>>>>> e9023467d9ae486f2436418f2004da612ebd02a7
   };
 
 } // namespace corsika::cascade
diff --git a/Framework/Geometry/Line.h b/Framework/Geometry/Line.h
index 5abf841ec..1b45f535a 100644
--- a/Framework/Geometry/Line.h
+++ b/Framework/Geometry/Line.h
@@ -31,8 +31,6 @@ namespace corsika::geometry {
         , v0(pV0) {}
 
     Point GetPosition(corsika::units::si::TimeType t) const { return r0 + v0 * t; }
-    
-    Point PositionFromArclength(corsika::units::si::LengthType l) const { return r0 + v0.normalized() * l; }
 
     Point PositionFromArclength(corsika::units::si::LengthType l) const {
       return r0 + v0.normalized() * l;
diff --git a/Framework/ProcessSequence/ProcessSequence.h b/Framework/ProcessSequence/ProcessSequence.h
index 30a9c09af..d58c14b50 100644
--- a/Framework/ProcessSequence/ProcessSequence.h
+++ b/Framework/ProcessSequence/ProcessSequence.h
@@ -361,7 +361,7 @@ namespace corsika::process {
   OPSEQ(DecayProcess, DecayProcess)
 
   template <typename A, typename B>
-    struct is_process_sequence<corsika::process::ProcessSequence<A, B> > {
+  struct is_process_sequence<corsika::process::ProcessSequence<A, B> > {
     static const bool value = true;
   };
 
diff --git a/Processes/Sibyll/Decay.h b/Processes/Sibyll/Decay.h
index cc13040b3..13524a1a0 100644
--- a/Processes/Sibyll/Decay.h
+++ b/Processes/Sibyll/Decay.h
@@ -1,9 +1,9 @@
 #ifndef _include_corsika_process_sibyll_decay_h_
 #define _include_corsika_process_sibyll_decay_h_
 
-#include <corsika/process/sibyll/SibStack.h>
-#include <corsika/process/sibyll/ParticleConversion.h>
 #include <corsika/process/DecayProcess.h>
+#include <corsika/process/sibyll/ParticleConversion.h>
+#include <corsika/process/sibyll/SibStack.h>
 #include <corsika/setup/SetupTrajectory.h>
 
 #include <corsika/particles/ParticleProperties.h>
@@ -57,8 +57,8 @@ namespace corsika::process {
 
     void setTrackedParticlesStable() {
       /*
-	Sibyll is hadronic generator
-	only hadrons decay
+        Sibyll is hadronic generator
+        only hadrons decay
       */
       // set particles unstable
       setHadronsUnstable();
@@ -71,12 +71,12 @@ namespace corsika::process {
       ds.NewParticle().SetPID(particles::Code::KMinus);
       ds.NewParticle().SetPID(particles::Code::K0Long);
       ds.NewParticle().SetPID(particles::Code::K0Short);
-      
+
       for (auto& p : ds) {
-	int s_id = process::sibyll::ConvertToSibyllRaw(p.GetPID());
-	// set particle stable by setting table value negative
-	s_csydec_.idb[s_id - 1] = (-1) * abs(s_csydec_.idb[s_id - 1]);
-	p.Delete();
+        int s_id = process::sibyll::ConvertToSibyllRaw(p.GetPID());
+        // set particle stable by setting table value negative
+        s_csydec_.idb[s_id - 1] = (-1) * abs(s_csydec_.idb[s_id - 1]);
+        p.Delete();
       }
     }
 
@@ -84,7 +84,7 @@ namespace corsika::process {
     public:
       Decay() {}
       void Init() {
-	setHadronsUnstable();
+        setHadronsUnstable();
         setTrackedParticlesStable();
       }
 
@@ -110,11 +110,11 @@ namespace corsika::process {
       friend void setHadronsUnstable();
 
       template <typename Particle>
-      double GetLifetime(Particle& p) const {
+      corsika::units::si::TimeType GetLifetime(Particle& p) const {
         corsika::units::hep::EnergyType E = p.GetEnergy();
         corsika::units::hep::MassType m = corsika::particles::GetMass(p.GetPID());
 
-        //const MassDensityType density = 1.25e-3 * kilogram / (1_cm * 1_cm * 1_cm);
+        // const MassDensityType density = 1.25e-3 * kilogram / (1_cm * 1_cm * 1_cm);
 
         const double gamma = E / m;
 
@@ -126,11 +126,11 @@ namespace corsika::process {
         // return as column density
         // const double x0 = density * t0 * gamma * constants::c / kilogram * 1_cm * 1_cm;
         // cout << "Decay: MinStep: x0: " << x0 << endl;
-	const double lifetime = gamma*t0 / 1_s;
-	cout << "Decay: MinStep: tau: " << lifetime << endl;
-        //int a = 1;
-        //const double x = -x0 * log(s_rndm_(a));
-        //cout << "Decay: next decay: " << x << endl;
+        corsika::units::si::TimeType const lifetime = gamma * t0;
+        cout << "Decay: MinStep: tau: " << lifetime << endl;
+        // int a = 1;
+        // const double x = -x0 * log(s_rndm_(a));
+        // cout << "Decay: next decay: " << x << endl;
         return lifetime;
       }
 
diff --git a/Processes/Sibyll/Interaction.h b/Processes/Sibyll/Interaction.h
index c0ceb87dd..87a2a0541 100644
--- a/Processes/Sibyll/Interaction.h
+++ b/Processes/Sibyll/Interaction.h
@@ -6,278 +6,262 @@
 //#include <corsika/setup/SetupStack.h>
 //#include <corsika/setup/SetupTrajectory.h>
 
+#include <corsika/process/sibyll/ParticleConversion.h>
 #include <corsika/process/sibyll/SibStack.h>
 #include <corsika/process/sibyll/sibyll2.3c.h>
-#include <corsika/process/sibyll/ParticleConversion.h>
 
 #include <corsika/particles/ParticleProperties.h>
-#include <corsika/units/PhysicalUnits.h>
 #include <corsika/random/RNGManager.h>
+#include <corsika/units/PhysicalUnits.h>
 
 using namespace corsika;
 using namespace corsika::process::sibyll;
 using namespace corsika::units::si;
 
-
 namespace corsika::process::sibyll {
 
   // template <typename Stack, typename Track>
-  //template <typename Stack>
-  class Interaction : public corsika::process::InteractionProcess<Interaction> { // <Stack,Track>> {    
+  // template <typename Stack>
+  class Interaction
+      : public corsika::process::InteractionProcess<Interaction> { // <Stack,Track>> {
 
-    //typedef typename Stack::ParticleType Particle;
-    //typedef typename corsika::setup::Stack::ParticleType Particle;
-    //typedef corsika::setup::Trajectory Track;
+    // typedef typename Stack::ParticleType Particle;
+    // typedef typename corsika::setup::Stack::ParticleType Particle;
+    // typedef corsika::setup::Trajectory Track;
 
   public:
-
     Interaction() {}
     ~Interaction() {}
-    
+
     void Init() {
       corsika::random::RNGManager& rmng = corsika::random::RNGManager::GetInstance();
       rmng.RegisterRandomStream("s_rndm");
-      
+
       // test random number generator
       std::cout << "Interaction: "
-		<< " test sequence of random numbers." << std::endl;
+                << " test sequence of random numbers." << std::endl;
       int a = 0;
       for (int i = 0; i < 8; ++i) std::cout << i << " " << s_rndm_(a) << std::endl;
-      
+
       // initialize Sibyll
       sibyll_ini_();
     }
 
-    //void setTrackedParticlesStable();
+    // void setTrackedParticlesStable();
 
     template <typename Particle, typename Track>
-    double GetInteractionLength(Particle& p, Track&) const {
-      
-    // coordinate system, get global frame of reference
-    CoordinateSystem& rootCS = RootCoordinateSystem::GetInstance().GetRootCS();
-    
-    const particles::Code corsikaBeamId = p.GetPID();
-
-    // beam particles for sibyll : 1, 2, 3 for p, pi, k
-    // read from cross section code table
-    int kBeam = process::sibyll::GetSibyllXSCode(corsikaBeamId);
-
-    bool kInteraction = process::sibyll::CanInteract(corsikaBeamId);
-
-    /*
-       the target should be defined by the Environment,
-       ideally as full particle object so that the four momenta
-       and the boosts can be defined..
-     */
-    // target nuclei: A < 18
-    // FOR NOW: assume target is oxygen
-    int kTarget = 16;
-
-    EnergyType Etot = p.GetEnergy() + kTarget * corsika::particles::Proton::GetMass();
-    super_stupid::MomentumVector Ptot(
-        rootCS, {0.0_newton_second, 0.0_newton_second, 0.0_newton_second});
-    // FOR NOW: assume target is at rest
-    super_stupid::MomentumVector pTarget(
-        rootCS, {0.0_newton_second, 0.0_newton_second, 0.0_newton_second});
-    Ptot += p.GetMomentum();
-    Ptot += pTarget;
-    // calculate cm. energy
-    EnergyType sqs = sqrt(Etot * Etot - Ptot.squaredNorm() * constants::cSquared);
-    double Ecm = sqs / 1_GeV;
-
-    std::cout << "Interaction: "
-              << "MinStep: input en: " << p.GetEnergy() / 1_GeV << endl
-              << " beam can interact:" << kBeam << endl
-              << " beam XS code:" << kBeam << endl
-              << " beam pid:" << p.GetPID() << endl
-              << " target mass number:" << kTarget << std::endl;
-
-    double int_length = 0;
-    if (kInteraction) {
-
-      double prodCrossSection, dummy, dum1, dum2, dum3, dum4;
-      double dumdif[3];
-
-      if (kTarget == 1)
-        sib_sigma_hp_(kBeam, Ecm, dum1, dum2, prodCrossSection, dumdif, dum3, dum4);
-      else
-        sib_sigma_hnuc_(kBeam, kTarget, Ecm, prodCrossSection, dummy);
-
-      std::cout << "Interaction: "
-                << "MinStep: sibyll return: " << prodCrossSection << std::endl;
-      CrossSectionType sig = prodCrossSection * 1_mbarn;
-      std::cout << "Interaction: "
-                << "MinStep: CrossSection (mb): " << sig / 1_mbarn << std::endl;
+    corsika::units::si::GrammageType GetInteractionLength(Particle& p, Track&) const {
 
-      const MassType nucleon_mass = 0.93827_GeV / corsika::units::si::constants::cSquared;
-      std::cout << "Interaction: "
-                << "nucleon mass " << nucleon_mass << std::endl;
-      // calculate interaction length in medium
-      int_length = kTarget * (nucleon_mass / 1_g) / (sig / 1_cmeter / 1_cmeter);
-      // pick random step lenth
-      std::cout << "Interaction: "
-                << "interaction length (g/cm2): " << int_length << std::endl;
-    } else
-      int_length = std::numeric_limits<double>::infinity();
-
-    /*
-      what are the units of the output? slant depth or 3space length?
-
-    */
-    return int_length;
-    //
-    // int a = 0;
-    // const double next_step = -int_length * log(s_rndm_(a));
-    // std::cout << "Interaction: "
-    //        << "next step (g/cm2): " << next_step << std::endl;
-    // return next_step;
-    }
-      
-
-    template <typename Particle, typename Stack>
-    corsika::process::EProcessReturn DoInteraction(Particle& p, Stack& s) const {
-        cout << "ProcessSibyll: "
-         << "DoInteraction: " << p.GetPID() << " interaction? "
-         << process::sibyll::CanInteract(p.GetPID()) << endl;
-    if (process::sibyll::CanInteract(p.GetPID())) {
-      cout << "defining coordinates" << endl;
       // coordinate system, get global frame of reference
       CoordinateSystem& rootCS = RootCoordinateSystem::GetInstance().GetRootCS();
 
-      QuantityVector<length_d> const coordinates{0_m, 0_m, 0_m};
-      Point pOrig(rootCS, coordinates);
+      const particles::Code corsikaBeamId = p.GetPID();
+
+      // beam particles for sibyll : 1, 2, 3 for p, pi, k
+      // read from cross section code table
+      int kBeam = process::sibyll::GetSibyllXSCode(corsikaBeamId);
+
+      bool kInteraction = process::sibyll::CanInteract(corsikaBeamId);
 
       /*
          the target should be defined by the Environment,
          ideally as full particle object so that the four momenta
          and the boosts can be defined..
-
-         here we need: GetTargetMassNumber() or GetTargetPID()??
-                       GetTargetMomentum() (zero in EAS)
-      */
-      // FOR NOW: set target to proton
-      int kTarget = 1; // env.GetTargetParticle().GetPID();
-
-      cout << "defining target momentum.." << endl;
-      // FOR NOW: target is always at rest
-      const EnergyType Etarget = 0. * 1_GeV + corsika::particles::Proton::GetMass();
-      const auto pTarget = super_stupid::MomentumVector(
-          rootCS, 0. * 1_GeV / constants::c, 0. * 1_GeV / constants::c,
-          0. * 1_GeV / constants::c);
-      cout << "target momentum (GeV/c): "
-           << pTarget.GetComponents() / 1_GeV * constants::c << endl;
-      cout << "beam momentum (GeV/c): "
-           << p.GetMomentum().GetComponents() / 1_GeV * constants::c << endl;
-
-      // get energy of particle from stack
-      /*
-        stack is in GeV in lab. frame
-        convert to GeV in cm. frame
-        (assuming proton at rest as target AND
-        assuming no pT, i.e. shower frame-z is aligned with hadron-int-frame-z)
-      */
-      // total energy: E_beam + E_target
-      // in lab. frame: E_beam + m_target*c**2
-      EnergyType E = p.GetEnergy();
-      EnergyType Etot = E + Etarget;
-      // total momentum
-      super_stupid::MomentumVector Ptot = p.GetMomentum(); // + pTarget;
-      // invariant mass, i.e. cm. energy
-      EnergyType Ecm = sqrt(Etot * Etot -
-                            Ptot.squaredNorm() *
-                                constants::cSquared); // sqrt( 2. * E * 0.93827_GeV );
-      /*
-       get transformation between Stack-frame and SibStack-frame
-       for EAS Stack-frame is lab. frame, could be different for CRMC-mode
-       the transformation should be derived from the input momenta
-     */
-      const double gamma = Etot / Ecm;
-      const auto gambet = Ptot / (Ecm / constants::c);
+       */
+      // target nuclei: A < 18
+      // FOR NOW: assume target is oxygen
+      int kTarget = 16;
+
+      EnergyType Etot = p.GetEnergy() + kTarget * corsika::particles::Proton::GetMass();
+      super_stupid::MomentumVector Ptot(rootCS, {0.0_Ns, 0.0_Ns, 0.0_Ns});
+      // FOR NOW: assume target is at rest
+      super_stupid::MomentumVector pTarget(rootCS, {0.0_Ns, 0.0_Ns, 0.0_Ns});
+      Ptot += p.GetMomentum();
+      Ptot += pTarget;
+      // calculate cm. energy
+      EnergyType sqs = sqrt(Etot * Etot - Ptot.squaredNorm() * constants::cSquared);
+      double Ecm = sqs / 1_GeV;
 
       std::cout << "Interaction: "
-                << " DoDiscrete: gamma:" << gamma << endl;
-      std::cout << "Interaction: "
-                << " DoDiscrete: gambet:" << gambet.GetComponents() << endl;
+                << "MinStep: input en: " << p.GetEnergy() / 1_GeV << endl
+                << " beam can interact:" << kBeam << endl
+                << " beam XS code:" << kBeam << endl
+                << " beam pid:" << p.GetPID() << endl
+                << " target mass number:" << kTarget << std::endl;
 
-      int kBeam = process::sibyll::ConvertToSibyllRaw(p.GetPID());
+      if (kInteraction) {
 
-      std::cout << "Interaction: "
-                << " DoInteraction: E(GeV):" << E / 1_GeV << " Ecm(GeV): " << Ecm / 1_GeV
-                << std::endl;
-      if (E < 8.5_GeV || Ecm < 10_GeV) {
+        double prodCrossSection, dummy, dum1, dum2, dum3, dum4;
+        double dumdif[3];
+
+        if (kTarget == 1)
+          sib_sigma_hp_(kBeam, Ecm, dum1, dum2, prodCrossSection, dumdif, dum3, dum4);
+        else
+          sib_sigma_hnuc_(kBeam, kTarget, Ecm, prodCrossSection, dummy);
+
+        std::cout << "Interaction: "
+                  << "MinStep: sibyll return: " << prodCrossSection << std::endl;
+        CrossSectionType sig = prodCrossSection * 1_mbarn;
+        std::cout << "Interaction: "
+                  << "MinStep: CrossSection (mb): " << sig / 1_mbarn << std::endl;
+
+        const MassType nucleon_mass =
+            0.93827_GeV / corsika::units::si::constants::cSquared;
+        std::cout << "Interaction: "
+                  << "nucleon mass " << nucleon_mass << std::endl;
+        // calculate interaction length in medium
+        GrammageType int_length = kTarget * nucleon_mass / sig;
+        // pick random step lenth
         std::cout << "Interaction: "
-                  << " DoInteraction: dropping particle.." << std::endl;
-        p.Delete();
+                  << "interaction length (g/cm2): " << int_length << std::endl;
+
+        return int_length;
       } else {
-        // Sibyll does not know about units..
-        double sqs = Ecm / 1_GeV;
-        // running sibyll, filling stack
-        sibyll_(kBeam, kTarget, sqs);
-        // running decays
-        //setTrackedParticlesStable();
-        decsib_();
-        // print final state
-        int print_unit = 6;
-        sib_list_(print_unit);
-
-        // delete current particle
-        p.Delete();
-
-        // add particles from sibyll to stack
-        // link to sibyll stack
-        SibStack ss;
-
-        // SibStack does not know about momentum yet so we need counter to access momentum
-        // array in Sibyll
-        int i = -1;
-        super_stupid::MomentumVector Ptot_final(
-            rootCS, {0.0_newton_second, 0.0_newton_second, 0.0_newton_second});
-        for (auto& psib : ss) {
-          ++i;
-          // skip particles that have decayed in Sibyll
-          if (abs(s_plist_.llist[i]) > 100) continue;
-
-          // transform energy to lab. frame, primitve
-          // compute beta_vec * p_vec
-          // arbitrary Lorentz transformation based on sibyll routines
-          const auto gammaBetaComponents = gambet.GetComponents();
-          const auto pSibyllComponents = psib.GetMomentum().GetComponents();
-          EnergyType en_lab = 0. * 1_GeV;
-          MomentumType p_lab_components[3];
-          en_lab = psib.GetEnergy() * gamma;
-          EnergyType pnorm = 0. * 1_GeV;
-          for (int j = 0; j < 3; ++j)
-            pnorm += (pSibyllComponents[j] * gammaBetaComponents[j] * constants::c) /
-                     (gamma + 1.);
-          pnorm += psib.GetEnergy();
-
-          for (int j = 0; j < 3; ++j) {
-            p_lab_components[j] = pSibyllComponents[j] - (-1) * pnorm *
-                                                             gammaBetaComponents[j] /
-                                                             constants::c;
-            en_lab -=
-                (-1) * pSibyllComponents[j] * gammaBetaComponents[j] * constants::c;
-          }
+        return std::numeric_limits<double>::infinity() * 1_g / (1_cm * 1_cm);
+      }
+    }
 
-          // add to corsika stack
-          auto pnew = s.NewParticle();
-          pnew.SetEnergy(en_lab);
-          pnew.SetPID(process::sibyll::ConvertFromSibyll(psib.GetPID()));
+    template <typename Particle, typename Stack>
+    corsika::process::EProcessReturn DoInteraction(Particle& p, Stack& s) const {
+      cout << "ProcessSibyll: "
+           << "DoInteraction: " << p.GetPID() << " interaction? "
+           << process::sibyll::CanInteract(p.GetPID()) << endl;
+      if (process::sibyll::CanInteract(p.GetPID())) {
+        cout << "defining coordinates" << endl;
+        // coordinate system, get global frame of reference
+        CoordinateSystem& rootCS = RootCoordinateSystem::GetInstance().GetRootCS();
+
+        QuantityVector<length_d> const coordinates{0_m, 0_m, 0_m};
+        Point pOrig(rootCS, coordinates);
+
+        /*
+           the target should be defined by the Environment,
+           ideally as full particle object so that the four momenta
+           and the boosts can be defined..
+
+           here we need: GetTargetMassNumber() or GetTargetPID()??
+                         GetTargetMomentum() (zero in EAS)
+        */
+        // FOR NOW: set target to proton
+        int kTarget = 1; // env.GetTargetParticle().GetPID();
+
+        cout << "defining target momentum.." << endl;
+        // FOR NOW: target is always at rest
+        const EnergyType Etarget = 0. * 1_GeV + corsika::particles::Proton::GetMass();
+        const auto pTarget = super_stupid::MomentumVector(
+            rootCS, 0. * 1_GeV / constants::c, 0. * 1_GeV / constants::c,
+            0. * 1_GeV / constants::c);
+        cout << "target momentum (GeV/c): "
+             << pTarget.GetComponents() / 1_GeV * constants::c << endl;
+        cout << "beam momentum (GeV/c): "
+             << p.GetMomentum().GetComponents() / 1_GeV * constants::c << endl;
+
+        // get energy of particle from stack
+        /*
+          stack is in GeV in lab. frame
+          convert to GeV in cm. frame
+          (assuming proton at rest as target AND
+          assuming no pT, i.e. shower frame-z is aligned with hadron-int-frame-z)
+        */
+        // total energy: E_beam + E_target
+        // in lab. frame: E_beam + m_target*c**2
+        EnergyType E = p.GetEnergy();
+        EnergyType Etot = E + Etarget;
+        // total momentum
+        super_stupid::MomentumVector Ptot = p.GetMomentum(); // + pTarget;
+        // invariant mass, i.e. cm. energy
+        EnergyType Ecm =
+            sqrt(Etot * Etot - Ptot.squaredNorm() *
+                                   constants::cSquared); // sqrt( 2. * E * 0.93827_GeV );
+        /*
+         get transformation between Stack-frame and SibStack-frame
+         for EAS Stack-frame is lab. frame, could be different for CRMC-mode
+         the transformation should be derived from the input momenta
+       */
+        const double gamma = Etot / Ecm;
+        const auto gambet = Ptot / (Ecm / constants::c);
+
+        std::cout << "Interaction: "
+                  << " DoDiscrete: gamma:" << gamma << endl;
+        std::cout << "Interaction: "
+                  << " DoDiscrete: gambet:" << gambet.GetComponents() << endl;
+
+        int kBeam = process::sibyll::ConvertToSibyllRaw(p.GetPID());
 
-          corsika::geometry::QuantityVector<momentum_d> p_lab_c{
-              p_lab_components[0], p_lab_components[1], p_lab_components[2]};
-          pnew.SetMomentum(super_stupid::MomentumVector(rootCS, p_lab_c));
-          Ptot_final += pnew.GetMomentum();
+        std::cout << "Interaction: "
+                  << " DoInteraction: E(GeV):" << E / 1_GeV
+                  << " Ecm(GeV): " << Ecm / 1_GeV << std::endl;
+        if (E < 8.5_GeV || Ecm < 10_GeV) {
+          std::cout << "Interaction: "
+                    << " DoInteraction: dropping particle.." << std::endl;
+          p.Delete();
+        } else {
+          // Sibyll does not know about units..
+          double sqs = Ecm / 1_GeV;
+          // running sibyll, filling stack
+          sibyll_(kBeam, kTarget, sqs);
+          // running decays
+          // setTrackedParticlesStable();
+          decsib_();
+          // print final state
+          int print_unit = 6;
+          sib_list_(print_unit);
+
+          // delete current particle
+          p.Delete();
+
+          // add particles from sibyll to stack
+          // link to sibyll stack
+          SibStack ss;
+
+          // SibStack does not know about momentum yet so we need counter to access
+          // momentum array in Sibyll
+          int i = -1;
+          super_stupid::MomentumVector Ptot_final(rootCS, {0.0_Ns, 0.0_Ns, 0.0_Ns});
+          for (auto& psib : ss) {
+            ++i;
+            // skip particles that have decayed in Sibyll
+            if (abs(s_plist_.llist[i]) > 100) continue;
+
+            // transform energy to lab. frame, primitve
+            // compute beta_vec * p_vec
+            // arbitrary Lorentz transformation based on sibyll routines
+            const auto gammaBetaComponents = gambet.GetComponents();
+            const auto pSibyllComponents = psib.GetMomentum().GetComponents();
+            EnergyType en_lab = 0. * 1_GeV;
+            MomentumType p_lab_components[3];
+            en_lab = psib.GetEnergy() * gamma;
+            EnergyType pnorm = 0. * 1_GeV;
+            for (int j = 0; j < 3; ++j)
+              pnorm += (pSibyllComponents[j] * gammaBetaComponents[j] * constants::c) /
+                       (gamma + 1.);
+            pnorm += psib.GetEnergy();
+
+            for (int j = 0; j < 3; ++j) {
+              p_lab_components[j] = pSibyllComponents[j] -
+                                    (-1) * pnorm * gammaBetaComponents[j] / constants::c;
+              en_lab -=
+                  (-1) * pSibyllComponents[j] * gammaBetaComponents[j] * constants::c;
+            }
+
+            // add to corsika stack
+            auto pnew = s.NewParticle();
+            pnew.SetEnergy(en_lab);
+            pnew.SetPID(process::sibyll::ConvertFromSibyll(psib.GetPID()));
+
+            corsika::geometry::QuantityVector<momentum_d> p_lab_c{
+                p_lab_components[0], p_lab_components[1], p_lab_components[2]};
+            pnew.SetMomentum(super_stupid::MomentumVector(rootCS, p_lab_c));
+            Ptot_final += pnew.GetMomentum();
+          }
+          // cout << "tot. momentum final (GeV/c): " << Ptot_final.GetComponents() / 1_GeV
+          // * constants::c << endl;
         }
-        // cout << "tot. momentum final (GeV/c): " << Ptot_final.GetComponents() / 1_GeV *
-        // constants::c << endl;
       }
+      return process::EProcessReturn::eOk;
     }
-    return process::EProcessReturn::eOk;
-    }
-
   };
-  
-}
+
+} // namespace corsika::process::sibyll
 
 #endif
diff --git a/Processes/Sibyll/ParticleConversion.h b/Processes/Sibyll/ParticleConversion.h
index e5e76c3b3..cd96f83d5 100644
--- a/Processes/Sibyll/ParticleConversion.h
+++ b/Processes/Sibyll/ParticleConversion.h
@@ -25,7 +25,7 @@ namespace corsika::process::sibyll {
 
 #include <corsika/process/sibyll/Generated.inc>
 
-  bool constexpr  KnownBySibyll(corsika::particles::Code pCode) {
+  bool constexpr KnownBySibyll(corsika::particles::Code pCode) {
     return isKnown[static_cast<corsika::particles::CodeIntType>(pCode)];
   }
 
diff --git a/Processes/Sibyll/SibStack.h b/Processes/Sibyll/SibStack.h
index 4c0326a92..f79fe7da3 100644
--- a/Processes/Sibyll/SibStack.h
+++ b/Processes/Sibyll/SibStack.h
@@ -1,8 +1,8 @@
 #ifndef _include_sibstack_h_
 #define _include_sibstack_h_
 
-#include <corsika/process/sibyll/sibyll2.3c.h>
 #include <corsika/process/sibyll/ParticleConversion.h>
+#include <corsika/process/sibyll/sibyll2.3c.h>
 #include <corsika/stack/Stack.h>
 #include <corsika/units/PhysicalUnits.h>
 
@@ -14,75 +14,75 @@ using namespace corsika::units::si;
 using namespace corsika::geometry;
 
 namespace corsika::process::sibyll {
-  
-class SibStackData {
 
-public:
-  void Init();
+  class SibStackData {
+
+  public:
+    void Init();
 
-  void Clear() { s_plist_.np = 0; }
+    void Clear() { s_plist_.np = 0; }
 
-  int GetSize() const { return s_plist_.np; }
+    int GetSize() const { return s_plist_.np; }
 #warning check actual capacity of sibyll stack
-  int GetCapacity() const { return 8000; }
-
-  void SetId(const int i, const int v) { s_plist_.llist[i] = v; }
-  void SetEnergy(const int i, const EnergyType v) { s_plist_.p[3][i] = v / 1_GeV; }
-  void SetMomentum(const int i, const super_stupid::MomentumVector& v) {
-    auto tmp = v.GetComponents();
-    for (int idx = 0; idx < 3; ++idx)
-      s_plist_.p[idx][i] = tmp[idx] / 1_GeV * constants::c;
-  }
-
-  int GetId(const int i) const { return s_plist_.llist[i]; }
-
-  EnergyType GetEnergy(const int i) const { return s_plist_.p[3][i] * 1_GeV; }
-
-  super_stupid::MomentumVector GetMomentum(const int i) const {
-    CoordinateSystem& rootCS = RootCoordinateSystem::GetInstance().GetRootCS();
-    corsika::geometry::QuantityVector<momentum_d> components{
-        s_plist_.p[0][i] * 1_GeV / constants::c,
-        s_plist_.p[1][i] * 1_GeV / constants::c,
-        s_plist_.p[2][i] * 1_GeV / constants::c};
-    super_stupid::MomentumVector v1(rootCS, components);
-    return v1;
-  }
-
-  void Copy(const int i1, const int i2) {
-    s_plist_.llist[i1] = s_plist_.llist[i2];
-    s_plist_.p[3][i1] = s_plist_.p[3][i2];
-  }
-
-protected:
-  void IncrementSize() { s_plist_.np++; }
-  void DecrementSize() {
-    if (s_plist_.np > 0) { s_plist_.np--; }
-  }
-};
-
-template <typename StackIteratorInterface>
-class ParticleInterface : public ParticleBase<StackIteratorInterface> {
-  using ParticleBase<StackIteratorInterface>::GetStackData;
-  using ParticleBase<StackIteratorInterface>::GetIndex;
-
-public:
-  void SetEnergy(const EnergyType v) { GetStackData().SetEnergy(GetIndex(), v); }
-  EnergyType GetEnergy() const { return GetStackData().GetEnergy(GetIndex()); }
-  void SetPID(const int v) { GetStackData().SetId(GetIndex(), v); }
-  corsika::process::sibyll::SibyllCode GetPID() const {
-    return static_cast<corsika::process::sibyll::SibyllCode>(
-        GetStackData().GetId(GetIndex()));
-  }
-  super_stupid::MomentumVector GetMomentum() const {
-    return GetStackData().GetMomentum(GetIndex());
-  }
-  void SetMomentum(const super_stupid::MomentumVector& v) {
-    GetStackData().SetMomentum(GetIndex(), v);
-  }
-};
-
-typedef Stack<SibStackData, ParticleInterface> SibStack;
-
-}
+    int GetCapacity() const { return 8000; }
+
+    void SetId(const int i, const int v) { s_plist_.llist[i] = v; }
+    void SetEnergy(const int i, const EnergyType v) { s_plist_.p[3][i] = v / 1_GeV; }
+    void SetMomentum(const int i, const super_stupid::MomentumVector& v) {
+      auto tmp = v.GetComponents();
+      for (int idx = 0; idx < 3; ++idx)
+        s_plist_.p[idx][i] = tmp[idx] / 1_GeV * constants::c;
+    }
+
+    int GetId(const int i) const { return s_plist_.llist[i]; }
+
+    EnergyType GetEnergy(const int i) const { return s_plist_.p[3][i] * 1_GeV; }
+
+    super_stupid::MomentumVector GetMomentum(const int i) const {
+      CoordinateSystem& rootCS = RootCoordinateSystem::GetInstance().GetRootCS();
+      corsika::geometry::QuantityVector<momentum_d> components{
+          s_plist_.p[0][i] * 1_GeV / constants::c,
+          s_plist_.p[1][i] * 1_GeV / constants::c,
+          s_plist_.p[2][i] * 1_GeV / constants::c};
+      super_stupid::MomentumVector v1(rootCS, components);
+      return v1;
+    }
+
+    void Copy(const int i1, const int i2) {
+      s_plist_.llist[i1] = s_plist_.llist[i2];
+      s_plist_.p[3][i1] = s_plist_.p[3][i2];
+    }
+
+  protected:
+    void IncrementSize() { s_plist_.np++; }
+    void DecrementSize() {
+      if (s_plist_.np > 0) { s_plist_.np--; }
+    }
+  };
+
+  template <typename StackIteratorInterface>
+  class ParticleInterface : public ParticleBase<StackIteratorInterface> {
+    using ParticleBase<StackIteratorInterface>::GetStackData;
+    using ParticleBase<StackIteratorInterface>::GetIndex;
+
+  public:
+    void SetEnergy(const EnergyType v) { GetStackData().SetEnergy(GetIndex(), v); }
+    EnergyType GetEnergy() const { return GetStackData().GetEnergy(GetIndex()); }
+    void SetPID(const int v) { GetStackData().SetId(GetIndex(), v); }
+    corsika::process::sibyll::SibyllCode GetPID() const {
+      return static_cast<corsika::process::sibyll::SibyllCode>(
+          GetStackData().GetId(GetIndex()));
+    }
+    super_stupid::MomentumVector GetMomentum() const {
+      return GetStackData().GetMomentum(GetIndex());
+    }
+    void SetMomentum(const super_stupid::MomentumVector& v) {
+      GetStackData().SetMomentum(GetIndex(), v);
+    }
+  };
+
+  typedef Stack<SibStackData, ParticleInterface> SibStack;
+
+} // namespace corsika::process::sibyll
 
 #endif
diff --git a/Processes/Sibyll/sibyll2.3c.cc b/Processes/Sibyll/sibyll2.3c.cc
index 336617fbf..77ad30527 100644
--- a/Processes/Sibyll/sibyll2.3c.cc
+++ b/Processes/Sibyll/sibyll2.3c.cc
@@ -2,7 +2,6 @@
 
 #include <corsika/random/RNGManager.h>
 
-
 double s_rndm_(int&) {
   static corsika::random::RNG& rmng =
       corsika::random::RNGManager::GetInstance().GetRandomStream("s_rndm");
-- 
GitLab