IAP GITLAB

Skip to content
Snippets Groups Projects
Decay.h 8.51 KiB
Newer Older

/**
 * (c) Copyright 2018 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.
 */

ralfulrich's avatar
ralfulrich committed
#ifndef _include_corsika_process_sibyll_decay_h_
#define _include_corsika_process_sibyll_decay_h_
ralfulrich's avatar
ralfulrich committed
#include <corsika/process/DecayProcess.h>
#include <corsika/process/sibyll/ParticleConversion.h>
#include <corsika/process/sibyll/SibStack.h>

#include <corsika/setup/SetupStack.h>
#include <corsika/setup/SetupTrajectory.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/particles/ParticleProperties.h>
namespace corsika::process {

  namespace sibyll {

ralfulrich's avatar
ralfulrich committed
    class Decay : public corsika::process::DecayProcess<Decay> {
ralfulrich's avatar
ralfulrich committed
      Decay() {}
      ~Decay() { std::cout << "Sibyll::Decay n=" << fCount << std::endl; }
        setHadronsUnstable();
ralfulrich's avatar
ralfulrich committed
        setTrackedParticlesStable();
      void setTrackedParticlesStable() {
           Sibyll is hadronic generator
           only hadrons decay
         */
        // set particles unstable
        setHadronsUnstable();
        // make tracked particles stable
        std::cout << "Interaction: setting tracked hadrons stable.." << std::endl;
        const std::vector<corsika::particles::Code> particleList = {
            particles::Code::PiPlus, particles::Code::PiMinus, particles::Code::KPlus,
            particles::Code::KMinus, particles::Code::K0Long,  particles::Code::K0Short};

        for (auto p : particleList) {
          // set particle stable by setting table value negative
          const int sibid = process::sibyll::ConvertToSibyllRaw(p);
          s_csydec_.idb[sibid - 1] = (-1) * abs(s_csydec_.idb[sibid - 1]);
        }
      }

      void setUnstable(const corsika::particles::Code pCode) {
ralfulrich's avatar
ralfulrich committed
        int s_id = process::sibyll::ConvertToSibyllRaw(pCode);
        s_csydec_.idb[s_id - 1] = abs(s_csydec_.idb[s_id - 1]);
      }

      void setStable(const corsika::particles::Code pCode) {
ralfulrich's avatar
ralfulrich committed
        int s_id = process::sibyll::ConvertToSibyllRaw(pCode);
        s_csydec_.idb[s_id - 1] = (-1) * abs(s_csydec_.idb[s_id - 1]);
      }

ralfulrich's avatar
ralfulrich committed
        // name? also makes EM particles stable
ralfulrich's avatar
ralfulrich committed
        std::cout << "Decay: setting all particles stable.." << std::endl;
Felix Riehn's avatar
Felix Riehn committed

        // loop over all particles in sibyll
        // should be changed to loop over human readable list
        // i.e. corsika::particles::ListOfParticles()
        for (auto& p : corsika2sibyll) {
          // std::cout << (int)p << std::endl;
          const int sibCode = (int)p;
          // skip unknown and antiparticles
          if (sibCode < 1) continue;
          s_csydec_.idb[sibCode - 1] = -1 * abs(s_csydec_.idb[sibCode - 1]);
        }

        using std::cout;
        using std::endl;
        // using namespace corsika::io;
        using namespace corsika::units::si;

        // name? also makes EM particles stable

        // loop over all particles in sibyll
        // should be changed to loop over human readable list
        // i.e. corsika::particles::ListOfParticles()
        std::cout << "Sibyll: setting hadrons unstable.." << std::endl;
        // make ALL particles unstable, then set EM stable
          // std::cout << (int)p << std::endl;
          // skip unknown and antiparticles
          if (sibCode < 1) continue;
          // std::cout << "Sibyll: Decay: setting " << ConvertFromSibyll(
          // static_cast<SibyllCode> ( sibCode ) ) << " unstable" << std::endl;
          s_csydec_.idb[sibCode - 1] = abs(s_csydec_.idb[sibCode - 1]);
          // std::cout << "decay table value: " << s_csydec_.idb[ sibCode - 1 ] <<
          // std::endl;
        }
        // set Leptons and Proton and Neutron stable
        // use stack to loop over particles
        const std::vector<corsika::particles::Code> particleList = {
            corsika::particles::Code::Proton,   corsika::particles::Code::Neutron,
            corsika::particles::Code::Electron, corsika::particles::Code::Positron,
            corsika::particles::Code::NuE,      corsika::particles::Code::NuEBar,
            corsika::particles::Code::MuMinus,  corsika::particles::Code::MuPlus,
            corsika::particles::Code::NuMu,     corsika::particles::Code::NuMuBar};

        for (auto p : particleList) {
          // set particle stable by setting table value negative
          //	cout << "Sibyll: setting " << p.GetPID() << "(" << s_id << ")"
          //     << " stable in Sibyll .." << endl;
          const int sibid = process::sibyll::ConvertToSibyllRaw(p);
          s_csydec_.idb[sibid - 1] = (-1) * abs(s_csydec_.idb[sibid - 1]);
        }
      }
Felix Riehn's avatar
Felix Riehn committed

      corsika::units::si::TimeType GetLifetime(Particle& p) {
        using std::cout;
        using std::endl;
        using namespace corsika::units::si;

Felix Riehn's avatar
Felix Riehn committed
        corsika::units::hep::EnergyType E = p.GetEnergy();
        corsika::units::hep::MassType m = corsika::particles::GetMass(p.GetPID());

        const double gamma = E / m;

        const corsika::units::si::TimeType t0 =
            corsika::particles::GetLifetime(p.GetPID());
        const auto mkin =
            (E * E - p.GetMomentum().squaredNorm()); // delta_mass(p.GetMomentum(), E, m);
        cout << "Decay: code: " << p.GetPID() << endl;
ralfulrich's avatar
ralfulrich committed
        cout << "Decay: MinStep: t0: " << t0 << endl;
        cout << "Decay: MinStep: energy: " << E / 1_GeV << " GeV" << endl;
        cout << "Decay: momentum: " << p.GetMomentum().GetComponents() / 1_GeV << " GeV"
             << endl;
        cout << "Decay: momentum: shell mass-kin. inv. mass " << mkin / 1_GeV / 1_GeV
             << " " << m / 1_GeV * m / 1_GeV << endl;
        // cout << "Decay: sib mass: " << s_mass1_.am2[
        // process::sibyll::ConvertToSibyllRaw(p.GetPID()) ] << endl;
        auto sib_id = process::sibyll::ConvertToSibyllRaw(p.GetPID());
        cout << "Decay: sib mass: " << get_sibyll_mass2(sib_id) << endl;
ralfulrich's avatar
ralfulrich committed
        cout << "Decay: MinStep: gamma: " << gamma << endl;
        cout << "Decay: MinStep: tau: " << lifetime << endl;
ralfulrich's avatar
ralfulrich committed
        return lifetime;
Felix Riehn's avatar
Felix Riehn committed

      template <typename Particle, typename Stack>
      void DoDecay(Particle& p, Stack& s) {
ralfulrich's avatar
ralfulrich committed
        using corsika::geometry::Point;
        using namespace corsika::units::si;
ralfulrich's avatar
ralfulrich committed
	// TODO: this should be done in a central, common place. Not here..
#ifndef CORSIKA_OSX
        feenableexcept(FE_INVALID);
ralfulrich's avatar
ralfulrich committed
#endif
Felix Riehn's avatar
Felix Riehn committed
        SibStack ss;
        ss.Clear();
        // copy particle to sibyll stack
        auto pin = ss.NewParticle();
ralfulrich's avatar
ralfulrich committed
        const corsika::particles::Code pCode = p.GetPID();
        pin.SetPID(process::sibyll::ConvertToSibyllRaw(pCode));
Felix Riehn's avatar
Felix Riehn committed
        pin.SetEnergy(p.GetEnergy());
        pin.SetMomentum(p.GetMomentum());
        // setting particle mass with Corsika values, may be inconsistent with sibyll
        // internal values
	// TODO: #warning setting particle mass with Corsika values, may be inconsistent with sibyll internal values
        pin.SetMass(corsika::particles::GetMass(pCode));
ralfulrich's avatar
ralfulrich committed
        // remember position
        Point decayPoint = p.GetPosition();
        TimeType t0 = p.GetTime();
        // remove original particle from corsika stack
Felix Riehn's avatar
Felix Riehn committed
        p.Delete();
        // set all particles/hadrons unstable
ralfulrich's avatar
ralfulrich committed
        // setHadronsUnstable();
        setUnstable(pCode);
Felix Riehn's avatar
Felix Riehn committed
        // call sibyll decay
ralfulrich's avatar
ralfulrich committed
        std::cout << "Decay: calling Sibyll decay routine.." << std::endl;
Felix Riehn's avatar
Felix Riehn committed
        decsib_();
ralfulrich's avatar
ralfulrich committed
        // reset to stable
        setStable(pCode);
Felix Riehn's avatar
Felix Riehn committed
        // print output
        int print_unit = 6;
        sib_list_(print_unit);
Felix Riehn's avatar
Felix Riehn committed
        // copy particles from sibyll stack to corsika
        for (auto& psib : ss) {
          // FOR NOW: skip particles that have decayed in Sibyll, move to iterator?
Felix Riehn's avatar
Felix Riehn committed
          // add to corsika stack
          auto pnew = s.NewParticle();
          pnew.SetEnergy(psib.GetEnergy());
          pnew.SetPID(process::sibyll::ConvertFromSibyll(psib.GetPID()));
          pnew.SetMomentum(psib.GetMomentum());
ralfulrich's avatar
ralfulrich committed
          pnew.SetPosition(decayPoint);
          pnew.SetTime(t0);
Felix Riehn's avatar
Felix Riehn committed
        }
        // empty sibyll stack
        ss.Clear();
ralfulrich's avatar
ralfulrich committed
	// TODO: this should be done in a central, common place. Not here..
#ifndef CORSIKA_OSX
        fedisableexcept(FE_INVALID);
ralfulrich's avatar
ralfulrich committed
#endif
Felix Riehn's avatar
Felix Riehn committed
  } // namespace sibyll
} // namespace corsika::process