IAP GITLAB

Skip to content
Snippets Groups Projects
cascade_example.cc 7.1 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.
 */

#include <corsika/cascade/Cascade.h>
#include <corsika/process/ProcessSequence.h>
#include <corsika/process/stack_inspector/StackInspector.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/process/tracking_line/TrackingLine.h>

#include <corsika/setup/SetupStack.h>
#include <corsika/setup/SetupTrajectory.h>

#include <corsika/environment/Environment.h>
#include <corsika/environment/HomogeneousMedium.h>
#include <corsika/environment/NuclearComposition.h>
#include <corsika/geometry/Sphere.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/process/sibyll/Decay.h>
#include <corsika/process/sibyll/Interaction.h>
#include <corsika/units/PhysicalUnits.h>
#include <corsika/random/RNGManager.h>

#include <iostream>
#include <limits>
#include <typeinfo>

using namespace corsika;
using namespace corsika::process;
using namespace corsika::units;
using namespace corsika::particles;
using namespace corsika::random;
using namespace corsika::geometry;
using namespace corsika::environment;

using namespace std;
Felix Riehn's avatar
Felix Riehn committed
static EnergyType fEnergy = 0. * 1_GeV;

// FOR NOW: global static variables for ParticleCut process
// this is just wrong...
Felix Riehn's avatar
Felix Riehn committed
static EnergyType fEmEnergy;
static int fEmCount;
Felix Riehn's avatar
Felix Riehn committed
static EnergyType fInvEnergy;
static int fInvCount;
class ProcessEMCut : public corsika::process::ContinuousProcess<ProcessEMCut> {
Felix Riehn's avatar
Felix Riehn committed
public:
  ProcessEMCut() {}
  template <typename Particle>
Felix Riehn's avatar
Felix Riehn committed
  bool isBelowEnergyCut(Particle& p) const {
Felix Riehn's avatar
Felix Riehn committed
    // FOR NOW: center-of-mass energy hard coded
Felix Riehn's avatar
Felix Riehn committed
    const EnergyType Ecm = sqrt(2. * p.GetEnergy() * 0.93827_GeV);
    if (p.GetEnergy() < 50_GeV || Ecm < 10_GeV)
Felix Riehn's avatar
Felix Riehn committed
      return true;
    else
      return false;
  }

Felix Riehn's avatar
Felix Riehn committed
  bool isEmParticle(Code pCode) const {
Felix Riehn's avatar
Felix Riehn committed
    bool is_em = false;
    // FOR NOW: switch
Felix Riehn's avatar
Felix Riehn committed
    switch (pCode) {
      case Code::Electron:
        is_em = true;
        break;
      case Code::Gamma:
        is_em = true;
        break;
      default:
        break;
Felix Riehn's avatar
Felix Riehn committed
    }
    return is_em;
  }

Felix Riehn's avatar
Felix Riehn committed
  void defineEmParticles() const {
    // create bool array identifying em particles
Felix Riehn's avatar
Felix Riehn committed
  bool isInvisible(Code pCode) const {
Felix Riehn's avatar
Felix Riehn committed
    bool is_inv = false;
    // FOR NOW: switch
Felix Riehn's avatar
Felix Riehn committed
    switch (pCode) {
      case Code::NuE:
        is_inv = true;
        break;
      case Code::NuEBar:
        is_inv = true;
        break;
      case Code::NuMu:
        is_inv = true;
        break;
      case Code::NuMuBar:
        is_inv = true;
        break;
      case Code::MuPlus:
        is_inv = true;
        break;
      case Code::MuMinus:
        is_inv = true;
        break;

      default:
        break;
Felix Riehn's avatar
Felix Riehn committed
    }
    return is_inv;
  }

  template <typename Particle>
  LengthType MaxStepLength(Particle& p, setup::Trajectory&) const {
ralfulrich's avatar
ralfulrich committed
    cout << "ProcessCut: MinStep: pid: " << p.GetPID() << endl;
    cout << "ProcessCut: MinStep: energy (GeV): " << p.GetEnergy() / 1_GeV << endl;
Felix Riehn's avatar
Felix Riehn committed
    const Code pid = p.GetPID();
ralfulrich's avatar
ralfulrich committed
    if (isEmParticle(pid) || isInvisible(pid) || isBelowEnergyCut(p)) {
Felix Riehn's avatar
Felix Riehn committed
      cout << "ProcessCut: MinStep: next cut: " << 0. << endl;
Felix Riehn's avatar
Felix Riehn committed
    } else {
      LengthType next_step = 1_m * std::numeric_limits<double>::infinity();
Felix Riehn's avatar
Felix Riehn committed
      cout << "ProcessCut: MinStep: next cut: " << next_step << endl;
      return next_step;
    }
  }

  template <typename Particle, typename Stack>
  EProcessReturn DoContinuous(Particle& p, setup::Trajectory&, Stack&) const {
    cout << "ProcessCut: DoContinuous: " << p.GetPID() << endl;
    const Code pid = p.GetPID();
ralfulrich's avatar
ralfulrich committed
    EProcessReturn ret = EProcessReturn::eOk;
    if (isEmParticle(pid)) {
      cout << "removing em. particle..." << endl;
      fEmEnergy += p.GetEnergy();
      fEmCount += 1;
      p.Delete();
ralfulrich's avatar
ralfulrich committed
      ret = EProcessReturn::eParticleAbsorbed;
    } else if (isInvisible(pid)) {
      cout << "removing inv. particle..." << endl;
      fInvEnergy += p.GetEnergy();
      fInvCount += 1;
      p.Delete();
ralfulrich's avatar
ralfulrich committed
      ret = EProcessReturn::eParticleAbsorbed;
    } else if (isBelowEnergyCut(p)) {
      cout << "removing low en. particle..." << endl;
      fEnergy += p.GetEnergy();
      p.Delete();
ralfulrich's avatar
ralfulrich committed
      ret = EProcessReturn::eParticleAbsorbed;
ralfulrich's avatar
ralfulrich committed
    return ret;
Felix Riehn's avatar
Felix Riehn committed
  void Init() {
    fEmEnergy = 0. * 1_GeV;
    fEmCount = 0;
Felix Riehn's avatar
Felix Riehn committed
    fInvEnergy = 0. * 1_GeV;
Felix Riehn's avatar
Felix Riehn committed
    fInvCount = 0;
    fEnergy = 0. * 1_GeV;
    // defineEmParticles();
Felix Riehn's avatar
Felix Riehn committed
  void ShowResults() {
Felix Riehn's avatar
Felix Riehn committed
    cout << " ******************************" << endl
Felix Riehn's avatar
Felix Riehn committed
         << " ParticleCut: " << endl
         << " energy in em.  component (GeV): " << fEmEnergy / 1_GeV << endl
         << " no. of em.  particles injected: " << fEmCount << endl
         << " energy in inv. component (GeV): " << fInvEnergy / 1_GeV << endl
         << " no. of inv. particles injected: " << fInvCount << endl
         << " ******************************" << endl;
Felix Riehn's avatar
Felix Riehn committed
  EnergyType GetInvEnergy() { return fInvEnergy; }
Felix Riehn's avatar
Felix Riehn committed
  EnergyType GetCutEnergy() { return fEnergy; }
Felix Riehn's avatar
Felix Riehn committed
  EnergyType GetEmEnergy() { return fEmEnergy; }
ralfulrich's avatar
ralfulrich committed
int main() {
  corsika::random::RNGManager::GetInstance().RegisterRandomStream("cascade");
  corsika::environment::Environment env; // dummy environment
  auto& universe = *(env.GetUniverse());
  auto theMedium = corsika::environment::Environment::CreateNode<Sphere>(
      Point{env.GetCoordinateSystem(), 0_m, 0_m, 0_m},
      1_km * std::numeric_limits<double>::infinity());

  using MyHomogeneousModel =
      corsika::environment::HomogeneousMedium<corsika::environment::IMediumModel>;
  theMedium->SetModelProperties<MyHomogeneousModel>(
      1_g / (1_m * 1_m * 1_m),
      corsika::environment::NuclearComposition(
          std::vector<corsika::particles::Code>{corsika::particles::Code::Proton},
          std::vector<float>{1.}));

  universe.AddChild(std::move(theMedium));
  CoordinateSystem& rootCS =
      RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
Felix Riehn's avatar
Felix Riehn committed

  tracking_line::TrackingLine<setup::Stack> tracking(env);
ralfulrich's avatar
ralfulrich committed
  stack_inspector::StackInspector<setup::Stack> p0(true);
  corsika::process::sibyll::Interaction sibyll;
  corsika::process::sibyll::Decay decay;
  ProcessEMCut cut;
  const auto sequence = p0 << sibyll << decay << cut;
  corsika::cascade::Cascade EAS(env, tracking, sequence, stack);

  stack.Clear();
  auto particle = stack.NewParticle();
  hep::MomentumType P0 = sqrt(E0 * E0 - 0.93827_GeV * 0.93827_GeV);
  auto plab = stack::super_stupid::MomentumVector(rootCS, 0. * 1_GeV, 0. * 1_GeV, P0);
  particle.SetEnergy(E0);
Felix Riehn's avatar
Felix Riehn committed
  particle.SetPID(Code::Proton);
ralfulrich's avatar
ralfulrich committed
  particle.SetTime(0_ns);
  Point p(rootCS, 0_m, 0_m, 0_m);
  particle.SetPosition(p);
  EAS.Init();
  EAS.Run();
  cout << "Result: E0="
       << E0 / 1_GeV
       //<< "GeV, particles below energy threshold =" << p1.GetCount()
ralfulrich's avatar
ralfulrich committed
       << endl;
  cout << "total energy below threshold (GeV): " //<< p1.GetEnergy() / 1_GeV
       << std::endl;
Felix Riehn's avatar
Felix Riehn committed
  cout << "total energy (GeV): "
       << (cut.GetCutEnergy() + cut.GetInvEnergy() + cut.GetEmEnergy()) / 1_GeV << endl;