IAP GITLAB

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • AirShowerPhysics/corsika
  • rulrich/corsika
  • AAAlvesJr/corsika
  • Andre/corsika
  • arrabito/corsika
  • Nikos/corsika
  • olheiser73/corsika
  • AirShowerPhysics/papers/corsika
  • pranav/corsika
9 results
Show changes
Showing
with 982 additions and 92 deletions
/*
* (c) Copyright 2020 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/modules/qgsjetII/ParticleConversion.hpp>
#include <qgsjet-II-04.hpp>
#include <corsika/framework/core/ParticleProperties.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
#include <corsika/framework/random/RNGManager.hpp>
#include <corsika/framework/utility/COMBoost.hpp>
#include <corsika/framework/utility/CorsikaData.hpp>
#include <boost/filesystem/path.hpp>
#include <random>
namespace corsika::qgsjetII {
class InteractionModel {
public:
InteractionModel(boost::filesystem::path dataPath = corsika_data("QGSJetII"));
~InteractionModel();
/**
* Throws exception if invalid system is passed.
*
* @param beamId
* @param targetId
*/
bool isValid(Code const beamId, Code const targetId, HEPEnergyType const sqrtS) const;
/**
* Return the QGSJETII inelastic/production cross section.
*
* This cross section must correspond to the process described in doInteraction.
* Allowed targets are: nuclei or single nucleons (p,n,hydrogen).
*
* @param projectile is the Code of the projectile
* @param target is the Code of the target
* @param sqrtSnn is the center-of-mass energy (per nucleon pair)
* @param Aprojectile is the mass number of the projectils, if it is a nucleus
* @param Atarget is the mass number of the target, if it is a nucleus
*
* @return inelastic cross section.
*/
CrossSectionType getCrossSection(Code const projectile, Code const target,
FourMomentum const& projectileP4,
FourMomentum const& targetP4) const;
/**
* Returns inelastic AND elastic cross sections.
*
* These cross sections must correspond to the process described in doInteraction
* AND elastic scattering (sigma_tot = sigma_inel + sigma_el).
*
* @param projectile is the Code of the projectile
* @param target is the Code of the target
* @param projectileP4: four-momentum of projectile
* @param targetP4: four-momentum of target
*
* @return a tuple of: inelastic cross section, elastic cross section
*/
std::tuple<CrossSectionType, CrossSectionType> getCrossSectionInelEla(
Code const projectile, Code const target, FourMomentum const& projectileP4,
FourMomentum const& targetP4) const;
/**
* In this function QGSJETII is called to produce one event.
*
* The event is copied (and boosted) into the shower lab frame.
*/
template <typename TSecondaries>
void doInteraction(TSecondaries&, Code const projectile, Code const target,
FourMomentum const& projectileP4, FourMomentum const& targetP4);
private:
int count_ = 0;
QgsjetIIHadronType alternate_ =
QgsjetIIHadronType::PiPlusType; // for pi0, rho0 projectiles
corsika::default_prng_type& rng_ =
corsika::RNGManager<>::getInstance().getRandomStream("qgsjet");
std::bernoulli_distribution bernoulli_;
static size_t constexpr maxMassNumber_ = 208;
static HEPEnergyType constexpr sqrtSmin_ = 10_GeV;
};
} // namespace corsika::qgsjetII
#include <corsika/detail/modules/qgsjetII/InteractionModel.inl>
/*
* (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.
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
......@@ -15,13 +14,13 @@
namespace corsika::qgsjetII {
/**
These are the possible secondaries produced by QGSJetII
* These are the possible secondaries produced by QGSJetII.
*/
enum class QgsjetIICode : int8_t;
using QgsjetIICodeIntType = std::underlying_type<QgsjetIICode>::type;
/**
These are the possible projectile for which QGSJetII knwos cross section
* These are the possible projectile for which QGSJetII knwos cross section.
*/
enum class QgsjetIIXSClass : int8_t {
CannotInteract = 0,
......@@ -32,7 +31,7 @@ namespace corsika::qgsjetII {
using QgsjetIIXSClassIntType = std::underlying_type<QgsjetIIXSClass>::type;
/**
These are the only possible projectile types in QGSJetII
* These are the only possible projectile types in QGSJetII.
*/
enum class QgsjetIIHadronType : int8_t {
UndefinedType = 0,
......@@ -58,41 +57,44 @@ namespace corsika::qgsjetII {
namespace corsika::qgsjetII {
QgsjetIICode constexpr convertToQgsjetII(Code pCode) {
QgsjetIICode constexpr convertToQgsjetII(Code const pCode) {
return corsika2qgsjetII[static_cast<CodeIntType>(pCode)];
}
Code constexpr convertFromQgsjetII(QgsjetIICode pCode) {
auto const pCodeInt = static_cast<QgsjetIICodeIntType>(pCode);
auto const corsikaCode = qgsjetII2corsika[pCodeInt - minQgsjetII];
Code constexpr convertFromQgsjetII(QgsjetIICode const code) {
auto const codeInt = static_cast<QgsjetIICodeIntType>(code);
auto const corsikaCode = qgsjetII2corsika[codeInt - minQgsjetII];
if (corsikaCode == Code::Unknown) {
throw std::runtime_error(std::string("QGSJETII/CORSIKA conversion of pCodeInt=")
.append(std::to_string(pCodeInt))
.append(std::to_string(codeInt))
.append(" impossible"));
}
return corsikaCode;
}
QgsjetIICodeIntType constexpr convertToQgsjetIIRaw(Code pCode) {
return static_cast<QgsjetIICodeIntType>(convertToQgsjetII(pCode));
QgsjetIICodeIntType constexpr convertToQgsjetIIRaw(Code const code) {
return static_cast<QgsjetIICodeIntType>(convertToQgsjetII(code));
}
QgsjetIIXSClass constexpr getQgsjetIIXSCode(Code pCode) {
// if (pCode == corsika::particles::Code::Nucleus)
// static_cast(QgsjetIIXSClassIntType>();
return corsika2qgsjetIIXStype[static_cast<CodeIntType>(pCode)];
QgsjetIIXSClass constexpr getQgsjetIIXSCode(Code const code) {
return is_nucleus(code) ? QgsjetIIXSClass::Baryons
: corsika2qgsjetIIXStype[static_cast<CodeIntType>(code)];
}
QgsjetIIXSClassIntType constexpr getQgsjetIIXSCodeRaw(Code pCode) {
return static_cast<QgsjetIIXSClassIntType>(getQgsjetIIXSCode(pCode));
QgsjetIIXSClassIntType constexpr getQgsjetIIXSCodeRaw(Code const code) {
return is_nucleus(code)
? static_cast<QgsjetIIXSClassIntType>(QgsjetIIXSClass::Baryons)
: static_cast<QgsjetIIXSClassIntType>(getQgsjetIIXSCode(code));
}
bool constexpr canInteract(Code pCode) {
return getQgsjetIIXSCode(pCode) != QgsjetIIXSClass::CannotInteract;
bool constexpr canInteract(Code const code) {
if (is_nucleus(code)) return true;
return getQgsjetIIXSCode(code) != QgsjetIIXSClass::CannotInteract;
}
QgsjetIIHadronType constexpr getQgsjetIIHadronType(Code pCode) {
return corsika2qgsjetIIHadronType[static_cast<CodeIntType>(pCode)];
QgsjetIIHadronType constexpr getQgsjetIIHadronType(Code const code) {
if (is_nucleus(code)) return QgsjetIIHadronType::NucleusType;
return corsika2qgsjetIIHadronType[static_cast<CodeIntType>(code)];
}
} // namespace corsika::qgsjetII
/*
* (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.
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
......@@ -50,16 +49,16 @@ namespace corsika::qgsjetII {
}
};
template <typename StackIteratorInterface>
class FragmentsInterface : public corsika::ParticleBase<StackIteratorInterface> {
template <typename TStackIterator>
class FragmentsInterface : public corsika::ParticleBase<TStackIterator> {
using corsika::ParticleBase<StackIteratorInterface>::getStackData;
using corsika::ParticleBase<StackIteratorInterface>::getIndex;
using corsika::ParticleBase<TStackIterator>::getStackData;
using corsika::ParticleBase<TStackIterator>::getIndex;
public:
void setParticleData(const int vSize) { setFragmentSize(vSize); }
void setParticleData(FragmentsInterface<StackIteratorInterface>& /*parent*/,
void setParticleData(FragmentsInterface<TStackIterator>& /*parent*/,
const int vSize) {
setFragmentSize(vSize);
}
......
/*
* (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.
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
......@@ -44,17 +43,17 @@ namespace corsika::qgsjetII {
void decrementSize();
};
template <typename StackIteratorInterface>
class ParticleInterface : public corsika::ParticleBase<StackIteratorInterface> {
template <typename TStackIterator>
class ParticleInterface : public corsika::ParticleBase<TStackIterator> {
using corsika::ParticleBase<StackIteratorInterface>::getStackData;
using corsika::ParticleBase<StackIteratorInterface>::getIndex;
using corsika::ParticleBase<TStackIterator>::getStackData;
using corsika::ParticleBase<TStackIterator>::getIndex;
public:
void setParticleData(const int vID, const HEPEnergyType vE, const MomentumVector& vP,
const HEPMassType);
void setParticleData(ParticleInterface<StackIteratorInterface>& /*parent*/,
const int vID, const HEPEnergyType vE, const MomentumVector& vP,
void setParticleData(ParticleInterface<TStackIterator>& /*parent*/, const int vID,
const HEPEnergyType vE, const MomentumVector& vP,
const HEPMassType);
void setEnergy(const HEPEnergyType v);
......
/*
* (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.
*/
#pragma once
#include <corsika/framework/random/RNGManager.hpp>
#include <random>
namespace qgsjetII {
double rndm_interface() {
static corsika::default_prng_type& rng =
corsika::RNGManager::getInstance().getRandomStream("qgsjet");
std::uniform_real_distribution<double> dist;
return dist(rng);
}
} // namespace qgsjetII
/*
* (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.
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
......@@ -42,7 +41,7 @@ extern struct {
} qgarr55_;
/**
Small helper class to provide a data-directory name in the format qgsjetII expects
* Small helper class to provide a data-directory name in the format qgsjetII expects.
*/
class datadir {
private:
......@@ -60,41 +59,33 @@ void qgaini_(
const char* datdir); // Note: there is a length limiation 132 from fortran-qgsjet here
/**
@function qgini_
additional initialization procedure per event
@parameter e0n - interaction energy (per hadron/nucleon),
@parameter icp0 - hadron type (+-1 - pi+-, +-2 - p(p~), +-3 - n(n~), +-4 - K+-, +-5 -
K_l/s),
@parameter iap - projectile mass number (1 - for a hadron),
@parameter iat - target mass number
*/
* Additional initialization procedure per event.
*
* @param e0n - interaction energy (per hadron/nucleon),
* @param icp0 - hadron type (+-1 - pi+-, +-2 - p(p~), +-3 - n(n~), +-4 - K+-, +-5 -
* K_l/s),
* @param iap - projectile mass number (1 - for a hadron),
* @param iat - target mass number
*/
void qgini_(const double& e0n, const int& icp0, const int& iap, const int& iat);
/**
@function qgconf_
generate one event configuration
*/
* Generate one event configuration.
*/
void qgconf_();
/**
@function qgsect_
hadron-nucleus (hadron-nucleus) particle production cross section
@parameter e0n lab. energy per projectile nucleon (hadron)
@parameter icz hadron class (1 - pion, 2 - nucleon, 3 - kaon)
@parameter iap projectile mass number (1=<iap<=iapmax),
@parameter iat target mass number (1=<iat<=iapmax)
* Hadron-nucleus (hadron-nucleus) particle production cross section.
*
* @param e0n lab. energy per projectile nucleon (hadron)
* @param icz hadron class (1 - pion, 2 - nucleon, 3 - kaon)
* @param iap0 projectile mass number (1=<iap<=iapmax),
* @param iat0 target mass number (1=<iat<=iapmax)
*/
double qgsect_(const double& e0n, const int& icz, const int& iap0, const int& iat0);
/**
@function qgran
link to random number generation
* Link to random number generation.
*/
double qgran_(int&);
}
......
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/modules/radio/RadioProcess.hpp>
#include <corsika/framework/geometry/QuantityVector.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
namespace corsika {
template <typename TRadioDetector, typename TPropagator>
class CoREAS final
: public RadioProcess<TRadioDetector, CoREAS<TRadioDetector, TPropagator>,
TPropagator> {
public:
// an identifier for which algorithm was used
static constexpr auto algorithm = "CoREAS";
/**
* Construct a new CoREAS instance.
*
* This forwards the detector and other arguments to
* the RadioProcess parent.
*
*/
template <typename... TArgs>
CoREAS(TRadioDetector& detector, TArgs&&... args)
: RadioProcess<TRadioDetector, CoREAS, TPropagator>(detector, args...) {}
/**
* Simulate the radio emission from a particle across a track.
*
* This must be provided by the TRadioImpl.
*
* @param particle The current particle.
* @param track The current track.
*
*/
template <typename Particle>
ProcessReturn simulate(Step<Particle> const& step);
static constexpr auto emConstant_{1.0 / (4.0 * M_PI) / (constants::epsilonZero) /
constants::c};
using Base =
RadioProcess<TRadioDetector, CoREAS<TRadioDetector, TPropagator>, TPropagator>;
using Base::observers_;
}; // end of class CoREAS
} // namespace corsika
#include <corsika/detail/modules/radio/CoREAS.inl>
/*
* (c) Copyright 2024 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/framework/geometry/Plane.hpp>
#include <corsika/modules/radio/RadioProcess.hpp>
namespace corsika {
/*!
* Wrapper for a radio process which turns the production of signal on and off depending
* on where the currently-emitting particle is in space. A function with signature `bool
* Fcn(Point const&)` must be given which turns this on and off
*/
template <class TUnderlyingProcess>
class LimitedRadioProcess
: public ContinuousProcess<LimitedRadioProcess<TUnderlyingProcess>> {
//! define the default constructor for the function signature
static auto constexpr default_functor = [](Point const&) { return true; };
public:
//! The signature of the if-statement that decides if this RadioProcess should be
//! called
using functor_signature = bool(Point const&);
LimitedRadioProcess(TUnderlyingProcess&& process,
std::function<functor_signature> runThis);
// This function wraps the one from RadioProcess and runs it depending on output of
// `runThis_`
template <typename Particle>
ProcessReturn doContinuous(Step<Particle> const& step, bool const);
// This process just returns the one from RadioProcess since it would be more work to
// turn this on and off than to just feed-through
template <typename Particle, typename Track>
LengthType getMaxStepLength(Particle const& vParticle, Track const& vTrack) const;
private:
TUnderlyingProcess process_;
std::function<functor_signature> const runThis_{default_functor};
};
} // namespace corsika
#include <corsika/detail/modules/radio/LimitedRadioProcess.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/output/BaseOutput.hpp>
#include <corsika/output/ParquetStreamer.hpp>
#include <corsika/framework/process/ContinuousProcess.hpp>
#include <corsika/framework/core/Step.hpp>
#include <corsika/setup/SetupStack.hpp>
#include <corsika/setup/SetupTrajectory.hpp>
namespace corsika {
/**
* The base interface for radio emission processes.
*
* TRadioImpl is the concrete implementation of the radio algorithm.
* TObserverCollection is the detector instance that stores observers
* and is responsible for managing the output writing.
*/
template <typename TObserverCollection, typename TRadioImpl, typename TPropagator>
class RadioProcess : public ContinuousProcess<
RadioProcess<TObserverCollection, TRadioImpl, TPropagator>>,
public BaseOutput {
/*
* A collection of filter objects for deciding on valid particles and tracks.
*/
// std::vector<std::function<bool(ParticleType&, TrackType const&)>> filters_;
/**
* Get a reference to the underlying radio implementation.
*/
TRadioImpl& implementation();
/**
* Get a const reference to the underlying implementation.
*/
TRadioImpl const& implementation() const;
protected:
TObserverCollection& observers_; ///< The radio observers we store into.
TPropagator propagator_; ///< The propagator implementation.
unsigned int showerId_{0}; ///< The current event ID.
ParquetStreamer output_; //!< The parquet streamer for this process.
public:
using axistype = std::vector<long double>;
/**
* Construct a new RadioProcess.
*/
RadioProcess(TObserverCollection& observers, TPropagator& propagator);
/**
* Perform the continuous process (radio emission).
*
* This handles filtering individual particle tracks
* before passing them to `Simulate`.`
*
* @param particle The current particle.
* @param track The current track.
*/
template <typename Particle>
ProcessReturn doContinuous(Step<Particle> const& step, bool const);
/**
* Return the maximum step length for this particle and track.
*
* This must be provided by the TRadioImpl.
*
* @param particle The current particle.
* @param track The current track.
*
* @returns The maximum length of this track.
*/
template <typename Particle, typename Track>
LengthType getMaxStepLength(Particle const& vParticle, Track const& vTrack) const;
/**
* Called at the start of each library.
*/
void startOfLibrary(boost::filesystem::path const& directory) final override;
/**
* Called at the end of each shower.
*/
virtual void endOfShower(unsigned int const) final override;
/**
* Called at the end of each library.
*
*/
void endOfLibrary() final override {}
/**
* Get the configuration of this output.
*/
YAML::Node getConfig() const final;
}; // END: class RadioProcess
} // namespace corsika
#include <corsika/detail/modules/radio/RadioProcess.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/modules/radio/RadioProcess.hpp>
#include <corsika/framework/geometry/QuantityVector.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
namespace corsika {
/**
* A concrete implementation of the ZHS algorithm.
*/
template <typename TRadioDetector, typename TPropagator>
class ZHS final : public RadioProcess<TRadioDetector, ZHS<TRadioDetector, TPropagator>,
TPropagator> {
public:
// an identifier for which algorithm was used
static constexpr auto algorithm = "ZHS";
/**
* Construct a new ZHS instance.
*
* This forwards the detector and other arguments to
* the RadioProcess parent.
*
*/
template <typename... TArgs>
ZHS(TRadioDetector& detector, TArgs&&... args)
: RadioProcess<TRadioDetector, ZHS, TPropagator>(detector, args...) {}
/**
* Simulate the radio emission from a particle across a track.
*
* This must be provided by the TRadioImpl.
*
* @param particle The current particle.
* @param track The current track.
*
*/
template <typename Particle>
ProcessReturn simulate(Step<Particle> const& step);
static constexpr auto emConstant_{1.0 / (4.0 * M_PI) / (constants::epsilonZero) /
constants::c};
private:
using Base =
RadioProcess<TRadioDetector, ZHS<TRadioDetector, TPropagator>, TPropagator>;
using Base::observers_;
}; // END: class ZHS
} // namespace corsika
#include <corsika/detail/modules/radio/ZHS.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
namespace corsika {
/**
* The base interface for radio detectors.
* At the moment it is a collection of observers with the same implementation.
*/
template <typename TObserverImpl>
class ObserverCollection {
/**
* The collection of observers used in this simulation.
*/
std::vector<TObserverImpl> observers_;
public:
/**
* Add an observer to this radio process.
*
* @param observer The observer to add
*/
void addObserver(TObserverImpl const& observer);
/**
* Get the specific observer at that place in the collection
*
* @param index in the collection
*/
TObserverImpl& at(std::size_t const i);
TObserverImpl const& at(std::size_t const i) const;
/**
* Get the number of observerss in the collection
*/
int size() const;
/**
* Get a *non*-const reference to the collection of observers.
*
* @returns An iterable mutable reference to the observers.
*/
std::vector<TObserverImpl>& getObservers();
/**
* Get a const reference to the collection of observers.
*
* @returns An iterable mutable reference to the observers.
*/
std::vector<TObserverImpl> const& getObservers() const;
/**
* Reset all the observer waveforms.
*/
void reset();
}; // END: class RadioDetector
} // namespace corsika
#include <corsika/detail/modules/radio/detectors/ObserverCollection.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <boost/filesystem.hpp>
#include <corsika/framework/geometry/Point.hpp>
#include <corsika/framework/core/PhysicalGeometry.hpp>
#include <corsika/output/ParquetStreamer.hpp>
namespace corsika {
/**
* A common abstract interface for radio oberservers.
*
* All concrete observer implementations should be of
* type Observer<T> where T is a concrete observer implementation.
*
*/
template <typename TObserverImpl>
class Observer {
protected:
std::string const name_; ///< The name/identifier of this observer.
Point const location_; ///< The location of this observer.
CoordinateSystemPtr const
coordinateSystem_; ///< The coordinate system of the observer
public:
using axistype = std::vector<long double>;
/**
* \brief Construct a base observer instance.
*
* @param name A name for this observer.
* @param location The location of this observer.
*
*/
Observer(std::string const& name, Point const& location,
CoordinateSystemPtr const& coordinateSystem);
/**
* Receive a signal at this observer.
*
* This is a general implementation call that must be specialized
* for the particular observer implementation and usage.
*
*/
template <typename... TVArgs>
void receive(TVArgs&&... args);
/**
* Get the location of this observer.
*/
Point const& getLocation() const;
/**
* Get the name of this name observer.
*
* This is used in producing the output data file.
*/
std::string const& getName() const;
/**
* Reset the observer before starting a new simulation.
*/
void reset();
/**
* Return a reference to the x-axis labels (i.e. time or frequency).
*
* This should be an xtensor-convertible type with
* a ->data() method that converts to a raw pointer.
*/
axistype getAxis() const;
/**
* Return a reference to the underlying waveform data for X polarization.
*
* This is used when writing the observer information to disk
* and will be converted to a 32-bit float before writing.
*/
std::vector<double> const& getWaveformX() const;
/**
* Return a reference to the underlying waveform data for Y polarization.
*
* This is used when writing the observer information to disk
* and will be converted to a 32-bit float before writing.
*/
std::vector<double> const& getWaveformY() const;
/**
* Return a reference to the underlying waveform data for Z polarization.
*
* This is used when writing the observer information to disk
* and will be converted to a 32-bit float before writing.
*/
std::vector<double> const& getWaveformZ() const;
/**
* Get a reference to the underlying radio implementation.
*/
TObserverImpl& implementation();
}; // END: class Observer final
} // namespace corsika
#include <corsika/detail/modules/radio/observers/Observer.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/modules/radio/observers/Observer.hpp>
#include <yaml-cpp/yaml.h>
#include <vector>
namespace corsika {
/**
* An implementation of a time-domain observer that has a customized
* start time, sampling rate, and waveform duration.
*
*/
class TimeDomainObserver : public Observer<TimeDomainObserver> {
TimeType const start_time_; ///< The start time of this waveform.
TimeType const duration_; ///< The duration of this waveform.
InverseTimeType const sample_rate_; ///< The sampling rate of this observer.
TimeType const ground_hit_time_; ///< The time the primary particle hits the ground.
uint64_t const num_bins_; ///< The number of bins used.
std::vector<double> waveformEX_; ///< EX polarization.
std::vector<double> waveformEY_; ///< EY polarization.
std::vector<double> waveformEZ_; ///< EZ polarization.
std::vector<long double> const
time_axis_; ///< The time axis corresponding to the electric field.
public:
// import the methods from the observer
using Observer<TimeDomainObserver>::getName;
using Observer<TimeDomainObserver>::getLocation;
/**
* Construct a new TimeDomainObserver.
*
* @param name The name of this observer.
* @param location The location of this observer.
* @param coordinateSystem The coordinate system of this observer.
* @param start_time The starting time of this waveform.
* @param duration The duration of this waveform.
* @param sample_rate The sample rate of this waveform.
* @param ground_hit_time The time the primary particle hits the ground on a
* straight vertical line.
*
*/
TimeDomainObserver(std::string const& name, Point const& location,
CoordinateSystemPtr coordinateSystem, TimeType const& start_time,
TimeType const& duration, InverseTimeType const& sample_rate,
TimeType const ground_hit_time);
/**
* Receive an electric field at this observer.
*
* This assumes that the observer will receive
* an *instantaneous* electric field modeled as a delta function (or timebin).
*
* @param time The (global) time at which this signal is received.
* @param receive_vector The incident unit vector. (not used at the moment)
* @param field The incident electric field vector.
*
*/
// TODO: rethink this method a bit. If the endpoint is at the end of the observer
// resolution then you get the startpoint signal but you lose the endpoint signal!
void receive(TimeType const time, Vector<dimensionless_d> const& receive_vector,
ElectricFieldVector const& efield);
void receive(TimeType const time, Vector<dimensionless_d> const& receive_vector,
VectorPotential const& vectorP);
/**
* Return the time-units of each waveform for X polarization
*
* This returns them in nanoseconds for ease of use.
*/
auto const& getWaveformX() const;
/**
* Return the time-units of each waveform for Y polarization
*
* This returns them in nanoseconds for ease of use.
*/
auto const& getWaveformY() const;
/**
* Return the time-units of each waveform for Z polarization
*
* This returns them in nanoseconds for ease of use.
*/
auto const& getWaveformZ() const;
/**
* Return a label that indicates that this is a time
* domain observer
*
* This returns the string "Time".
*/
std::string const getDomainLabel();
/**
* Creates time-units of each waveform.
*
* It creates them in nanoseconds for ease of use.
*/
std::vector<long double> createTimeAxis() const;
/**
* Return the time-units of each waveform.
*
* This returns them in nanoseconds for ease of use.
*/
auto const getAxis() const;
/**
* Returns the sampling rate of the time domain observer.
*/
InverseTimeType const& getSampleRate() const;
/**
* Returns the start time of detection for the time domain observer.
*/
TimeType const& getStartTime() const;
/**
* Reset the observer before starting a new simulation.
*/
void reset();
/**
* Return a YAML configuration for this observer.
*/
YAML::Node getConfig() const;
}; // END: class TimeDomainObserver
} // namespace corsika
#include <corsika/detail/modules/radio/observers/TimeDomainObserver.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/media/Environment.hpp>
#include <corsika/framework/geometry/Point.hpp>
#include <corsika/framework/geometry/Vector.hpp>
#include <corsika/framework/core/PhysicalConstants.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
#include <corsika/modules/radio/propagators/RadioPropagator.hpp>
namespace corsika {
/**
* This class implements a dummy propagator that uses
* the straight-line (vector) between the particle
* location and the observer as the trajectory.
* It is intended mainly for fast testing as it only
* works with 2 points in a uniform refractive index
* atmospheric profile.
*
*/
template <typename TEnvironment>
class DummyTestPropagator final
: public RadioPropagator<DummyTestPropagator<TEnvironment>, TEnvironment> {
using Base = RadioPropagator<DummyTestPropagator<TEnvironment>, TEnvironment>;
using SignalPathCollection = typename Base::SignalPathCollection;
public:
/**
* Construct a new SimplePropagator with a given environment.
*
*/
DummyTestPropagator(TEnvironment const& env);
/**
* Return the collection of paths from `source` to `destination`.
* Hence, the signal propagated from the
* emission point to the observer location.
*
*/
template <typename Particle>
SignalPathCollection propagate(Particle const& particle, Point const& source,
Point const& destination);
private:
std::deque<Point> points;
std::vector<double> rindex;
}; // End: SimplePropagator
template <typename TEnvironment>
DummyTestPropagator<TEnvironment> make_dummy_test_radio_propagator(
TEnvironment const& env) {
return DummyTestPropagator<TEnvironment>(env);
}
} // namespace corsika
#include <corsika/detail/modules/radio/propagators/DummyTestPropagator.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/media/Environment.hpp>
#include <corsika/framework/geometry/Point.hpp>
#include <corsika/framework/geometry/Vector.hpp>
#include <corsika/framework/core/PhysicalConstants.hpp>
#include <corsika/framework/core/PhysicalUnits.hpp>
#include <corsika/modules/radio/propagators/RadioPropagator.hpp>
namespace corsika {
/**
* This class implements a basic propagator that uses
* the straight-line (vector) between the particle
* location and the observer as the trajectory.
* To calculate the time delay of the signal, a basic
* numerical integration scheme based on Simpson's rule
* takes place. This propagator is slow and not
* recommended for big showers simulations.
*
* This is what is used in ZHAireS and CoREAS in C7.
*/
template <typename TEnvironment>
class NumericalIntegratingPropagator final
: public RadioPropagator<NumericalIntegratingPropagator<TEnvironment>,
TEnvironment> {
using Base =
RadioPropagator<NumericalIntegratingPropagator<TEnvironment>, TEnvironment>;
using SignalPathCollection = typename Base::SignalPathCollection;
public:
/**
* Construct a new StraightPropagator with a given environment.
*
*/
NumericalIntegratingPropagator(TEnvironment const& env, LengthType const stepsize);
/**
* Return the collection of paths from `start` to `end`.
* or from 'source' which is the emission point to 'destination'
* which is the location of the observer
*/
template <typename Particle>
SignalPathCollection propagate(Particle const& particle, Point const& source,
Point const& destination) const;
private:
LengthType const stepsize_;
}; // End: StraightPropagator
template <typename TEnvironment>
NumericalIntegratingPropagator<TEnvironment>
make_numerical_integrating_radio_propagator(TEnvironment const& env,
LengthType const stepsize) {
return NumericalIntegratingPropagator<TEnvironment>(env, stepsize);
}
} // namespace corsika
#include <corsika/detail/modules/radio/propagators/NumericalIntegratingPropagator.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <vector>
#include <corsika/framework/geometry/Path.hpp>
#include <corsika/modules/radio/propagators/SignalPath.hpp>
namespace corsika {
/**
* Radio propagators are used to calculate the propagation
* paths from particles to observers. Any class that wants
* to be used as a RadioPropagator must implement the
* following methods:
*
* SignalPathCollection Propagate(Particle const& particle,
* Point const& source,
Point const& destination) const
*/
template <typename TImpl, typename TEnvironment>
class RadioPropagator {
protected:
// Since we typically know roughly how many paths will
// be computed for a given propagator, we use a std::vector here.
using SignalPathCollection = std::vector<SignalPath> const;
TEnvironment const& env_; ///< The environment.
public:
/**
* Construct a new RadioPropagator instance.
*/
RadioPropagator(TEnvironment const& env);
}; // class RadioPropagator
} // namespace corsika
#include <corsika/detail/modules/radio/propagators/RadioPropagator.inl>
/*
* (c) Copyright 2022 CORSIKA Project, corsika-project@lists.kit.edu
*
* This software is distributed under the terms of the 3-clause BSD license.
* See file LICENSE for a full version of the license.
*/
#pragma once
#include <corsika/framework/geometry/Path.hpp>
#include <corsika/framework/geometry/Vector.hpp>
namespace corsika {
/**
* Store the photon signal path between two points.
*
* This is basically a container class
*/
struct SignalPath final : public Path {
// TODO: discuss if we need average refractivity or average refractive index
TimeType const propagation_time_; ///< The total propagation time.
double const average_refractive_index_; ///< The average refractive index.
double const refractive_index_source_; ///< The refractive index at the source.
double const
refractive_index_destination_; ///< The refractive index at the destination point.
Vector<dimensionless_d> const emit_; ///< The (unit-length) emission vector.
Vector<dimensionless_d> const receive_; ///< The (unit-length) receive vector.
LengthType const
R_distance_; ///< The distance from the point of emission to an observer. TODO:
///< optical path, not geometrical! (probably)
/**
* Create a new SignalPath instance.
*/
SignalPath(TimeType const propagation_time, double const average_refractive_index,
double const refractive_index_source,
double const refractive_index_destination,
Vector<dimensionless_d> const& emit,
Vector<dimensionless_d> const& receive, LengthType const R_distance,
std::deque<Point> const& points);
}; // END: class SignalPath final
} // namespace corsika
#include <corsika/detail/modules/radio/propagators/SignalPath.inl>
\ No newline at end of file