IAP GITLAB

Skip to content
Snippets Groups Projects
testCascade.cc 5.01 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/testCascade.h>
#include <corsika/cascade/Cascade.h>
#include <corsika/process/ProcessSequence.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/process/null_model/NullModel.h>
#include <corsika/process/stack_inspector/StackInspector.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/process/tracking_line/TrackingLine.h>
ralfulrich's avatar
ralfulrich committed
#include <corsika/particles/ParticleProperties.h>

#include <corsika/geometry/Point.h>
Ralf Ulrich's avatar
Ralf Ulrich committed
#include <corsika/geometry/RootCoordinateSystem.h>
#include <corsika/geometry/Vector.h>

Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
#include <corsika/environment/HomogeneousMedium.h>
#include <corsika/environment/NuclearComposition.h>

#include <catch2/catch.hpp>

using namespace corsika::process;
using namespace corsika::units;
using namespace corsika::units::si;
using namespace corsika::geometry;

#include <iostream>
using namespace std;

auto MakeDummyEnv() {
  TestEnvironmentType env; // dummy environment
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
  auto& universe = *(env.GetUniverse());

  auto theMedium = TestEnvironmentType::CreateNode<Sphere>(
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
      Point{env.GetCoordinateSystem(), 0_m, 0_m, 0_m},
      100_km * std::numeric_limits<double>::infinity());
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed

  using MyHomogeneousModel = environment::HomogeneousMedium<environment::IMediumModel>;
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
  theMedium->SetModelProperties<MyHomogeneousModel>(
      environment::NuclearComposition(
          std::vector<particles::Code>{particles::Code::Proton}, std::vector<float>{1.}));
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed

  universe.AddChild(std::move(theMedium));

  return env;
}

class ProcessSplit : public process::InteractionProcess<ProcessSplit> {
ralfulrich's avatar
ralfulrich committed

  int fCalls = 0;
  ProcessSplit(GrammageType const X0)
      : fX0(X0) {}
  template <typename Particle>
  corsika::units::si::GrammageType GetInteractionLength(Particle const&) const {
ralfulrich's avatar
ralfulrich committed
  }
  template <typename TProjectile>
  corsika::process::EProcessReturn DoInteraction(TProjectile& vP) {
    fCalls++;
    const HEPEnergyType E = vP.GetEnergy();
    vP.AddSecondary(
        std::tuple<particles::Code, units::si::HEPEnergyType,
                   corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
            vP.GetPID(), E / 2, vP.GetMomentum(), vP.GetPosition(), vP.GetTime()});
    vP.AddSecondary(
        std::tuple<particles::Code, units::si::HEPEnergyType,
                   corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
            vP.GetPID(), E / 2, vP.GetMomentum(), vP.GetPosition(), vP.GetTime()});
    return EProcessReturn::eInteracted;
  }

  void Init() { fCalls = 0; }

  int GetCalls() const { return fCalls; }
};

class ProcessCut : public process::SecondariesProcess<ProcessCut> {
ralfulrich's avatar
ralfulrich committed

  int fCount = 0;
  int fCalls = 0;
  HEPEnergyType fEcrit;
      : fEcrit(e) {}
  template <typename TStack>
  EProcessReturn DoSecondaries(TStack& vS) {
ralfulrich's avatar
ralfulrich committed
    fCalls++;
    auto p = vS.begin();
    while (p != vS.end()) {
      HEPEnergyType E = p.GetEnergy();
      if (E < fEcrit) {
        p.Delete();
        fCount++;
      } else {
        ++p; // next particle
      }
ralfulrich's avatar
ralfulrich committed
    }
    cout << "ProcessCut::DoSecondaries size=" << vS.GetSize() << " count=" << fCount
         << endl;
  void Init() {
    fCalls = 0;
  int GetCount() const { return fCount; }
ralfulrich's avatar
ralfulrich committed
  int GetCalls() const { return fCalls; }
};

TEST_CASE("Cascade", "[Cascade]") {

  HEPEnergyType E0 = 100_GeV;

  random::RNGManager& rmng = random::RNGManager::GetInstance();
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
  rmng.RegisterRandomStream("cascade");
Maximilian Reininghaus's avatar
Maximilian Reininghaus committed
  auto env = MakeDummyEnv();
  auto const& rootCS = env.GetCoordinateSystem();
  tracking_line::TrackingLine tracking;
  stack_inspector::StackInspector<TestCascadeStack> stackInspect(1, true, E0);
ralfulrich's avatar
ralfulrich committed
  null_model::NullModel nullModel;
ralfulrich's avatar
ralfulrich committed

  const GrammageType X0 = 20_g / square(1_cm);
ralfulrich's avatar
ralfulrich committed
  const HEPEnergyType Ecrit = 85_MeV;
  ProcessSplit split(X0);
  ProcessCut cut(Ecrit);
  auto sequence = nullModel << stackInspect << split << cut;
  TestCascadeStack stack;
ralfulrich's avatar
ralfulrich committed
  stack.AddParticle(
      std::tuple<particles::Code, units::si::HEPEnergyType,
                 corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{
          particles::Code::Electron, E0,
          corsika::stack::MomentumVector(rootCS, {0_GeV, 0_GeV, -1_GeV}),
          Point(rootCS, {0_m, 0_m, 10_km}), 0_ns});

  cascade::Cascade<tracking_line::TrackingLine, decltype(sequence), TestCascadeStack,
                   TestCascadeStackView>
      EAS(env, tracking, sequence, stack);

  SECTION("full cascade") {
    EAS.Run();

    CHECK(cut.GetCount() == 2048);
    CHECK(cut.GetCalls() == 2047);
    CHECK(split.GetCalls() == 2047);
  }

  SECTION("forced interaction") {
    EAS.SetNodes();
    EAS.forceInteraction();
    CHECK(stack.GetSize() == 2);
    CHECK(split.GetCalls() == 1);
  }