IAP GITLAB

Skip to content
Snippets Groups Projects
LongitudinalProfile.cc 2.48 KiB
/*
 * (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/longitudinal_profile/LongitudinalProfile.h>

#include <corsika/particles/ParticleProperties.h>

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

#include <cmath>
#include <iomanip>
#include <limits>

using namespace corsika::setup;
using Particle = Stack::ParticleType;
using Track = Trajectory;

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

LongitudinalProfile::LongitudinalProfile(environment::ShowerAxis const& shower_axis)
    : shower_axis_{shower_axis}
    , profiles_{static_cast<unsigned int>(shower_axis.maximumX() / dX_) + 1} {}

template <>
corsika::process::EProcessReturn LongitudinalProfile::DoContinuous(Particle const& vP,
                                                                   Track const& vTrack) {
  auto const pid = vP.GetPID();

  GrammageType const grammageStart = shower_axis_.projectedX(vTrack.GetPosition(0));
  GrammageType const grammageEnd = shower_axis_.projectedX(vTrack.GetPosition(1));

  const int binStart = std::ceil(grammageStart / dX_);
  const int binEnd = std::floor(grammageEnd / dX_);

  for (int b = binStart; b <= binEnd; ++b) {
    if (pid == particles::Code::Gamma) {
      profiles_.at(b)[ProfileIndex::Gamma]++;
    } else if (pid == particles::Code::Positron) {
      profiles_.at(b)[ProfileIndex::Positron]++;
    } else if (pid == particles::Code::Electron) {
      profiles_.at(b)[ProfileIndex::Electron]++;
    } else if (pid == particles::Code::MuPlus) {
      profiles_.at(b)[ProfileIndex::MuPlus]++;
    } else if (pid == particles::Code::MuMinus) {
      profiles_.at(b)[ProfileIndex::MuMinus]++;
    } else if (particles::IsHadron(pid)) {
      profiles_.at(b)[ProfileIndex::Hadron]++;
    }
  }

  return corsika::process::EProcessReturn::eOk;
}

void LongitudinalProfile::save(std::string const& filename) {
  std::ofstream f{filename};
  f << "# X / g·cm¯², gamma, e+, e-, mu+, mu-, all hadrons" << std::endl;
  for (size_t b = 0; b < profiles_.size(); ++b) {
    f << std::setprecision(5) << std::setw(11) << b * (dX_ / (1_g / 1_cm / 1_cm));
    for (auto const& N : profiles_.at(b)) {
      f << std::setw(width_) << std::setprecision(precision_) << std::scientific << N;
    }
    f << std::endl;
  }
}