IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 0a2d2a10 authored by Antonio Augusto Alves Junior's avatar Antonio Augusto Alves Junior Committed by ralfulrich
Browse files

[refactory-2020] stack implementations: updated

parent 01efa4c1
No related branches found
No related tags found
1 merge request!280Refactory 2020
...@@ -15,350 +15,378 @@ ...@@ -15,350 +15,378 @@
#include <corsika/framework/geometry/Vector.hpp> #include <corsika/framework/geometry/Vector.hpp>
#include <corsika/stack/SuperStupidStack.hpp> #include <corsika/stack/SuperStupidStack.hpp>
#include <corsika/logging/Logging.h>
#include <algorithm> #include <algorithm>
#include <tuple> #include <tuple>
#include <vector> #include <vector>
namespace corsika { namespace corsika {
/** /**
* @namespace nuclear_extension * @namespace nuclear_extension
* *
* Add A and Z data to existing stack of particle properties. * Add A and Z data to existing stack (currently SuperStupidStack) of particle
* * properties. This is done via inheritance, not via CombinedStack since the nuclear
* Only for Code::Nucleus particles A and Z are stored, not for all * data is stored ONLY when needed (for nuclei) and not for all particles. Thus, this is
* normal elementary particles. * a new, derived Stack object.
* *
* Thus in your code, make sure to always check <code> * Only for Code::Nucleus particles A and Z are stored, not for all
* particle.GetPID()==Code::Nucleus </code> before attempting to * normal elementary particles.
* read any nuclear information. *
* * Thus in your code, make sure to always check <code>
* * particle.GetPID()==Code::Nucleus </code> before attempting to
*/ * read any nuclear information.
*
typedef corsika::Vector<hepmomentum_d> MomentumVector; *
*/
namespace nuclear_extension {
/** /**
* @class NuclearParticleInterface * @class NuclearParticleInterface
* *
* Define ParticleInterface for NuclearStackExtension Stack derived from * Define ParticleInterface for NuclearStackExtension Stack derived from
* ParticleInterface of Inner stack class * ParticleInterface of Inner stack class
*/ */
template <template <typename> typename InnerParticleInterface, template < template <typename> class InnerParticleInterface, typename StackIteratorInterface>
typename StackIteratorInterface> struct NuclearParticleInterface : public InnerParticleInterface<StackIteratorInterface> {
class NuclearParticleInterface
: public InnerParticleInterface<StackIteratorInterface> { typedef InnerParticleInterface<StackIteratorInterface> super_type;
protected:
using InnerParticleInterface<StackIteratorInterface>::GetStackData;
using InnerParticleInterface<StackIteratorInterface>::GetIndex; public:
public:
void SetParticleData( typedef std::tuple<
const std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, corsika::Code, corsika::units::si::HEPEnergyType,
corsika::Point, TimeType>& v) { momentum_type, corsika::Point,
if (std::get<0>(v) == corsika::Code::Nucleus) { corsika::units::si::TimeType> particle_data_type;
std::ostringstream err;
err << "NuclearStackExtension: no A and Z specified for new Nucleus!"; typedef std::tuple<
throw std::runtime_error(err.str()); corsika::Code, corsika::units::si::HEPEnergyType,
} momentum_type, corsika::Point,
InnerParticleInterface<StackIteratorInterface>::SetParticleData(v); corsika::units::si::TimeType,
SetNucleusRef(-1); // this is not a nucleus unsigned short, unsigned short> altenative_particle_data_type;
}
void SetParticleData( typedef corsika::Vector<corsika::units::si::hepmomentum_d> momentum_type;
const std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector,
corsika::Point, TimeType, unsigned short, unsigned short>& v) { void setParticleData(particle_data_type const& v) {
const unsigned short A = std::get<5>(v);
const unsigned short Z = std::get<6>(v); if (std::get<0>(v) == corsika::Code::Nucleus) {
if (std::get<0>(v) != corsika::Code::Nucleus || A == 0 || Z == 0) { std::ostringstream err;
std::ostringstream err; err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
err << "NuclearStackExtension: no A and Z specified for new Nucleus!"; throw std::runtime_error(err.str());
throw std::runtime_error(err.str()); }
}
SetNucleusRef(GetStackData().GetNucleusNextRef()); // store this nucleus data ref super_type::setParticleData(v);
SetNuclearA(A); setNucleusRef(-1); // this is not a nucleus
SetNuclearZ(Z); }
InnerParticleInterface<StackIteratorInterface>::SetParticleData(
std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, void setParticleData( altenative_particle_data_type const& v)
corsika::Point, TimeType>{std::get<0>(v), std::get<1>(v), {
std::get<2>(v), std::get<3>(v), const unsigned short A = std::get<5>(v);
std::get<4>(v)}); const unsigned short Z = std::get<6>(v);
} if (std::get<0>(v) != corsika::Code::Nucleus || A == 0 || Z == 0) {
std::ostringstream err;
void SetParticleData( err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
InnerParticleInterface<StackIteratorInterface>& p, throw std::runtime_error(err.str());
const std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, }
corsika::Point, TimeType>& v) { setNucleusRef(super_type::GetStackData().getNucleusNextRef()); // store this nucleus data ref
if (std::get<0>(v) == corsika::Code::Nucleus) { setNuclearA(A);
std::ostringstream err; setNuclearZ(Z);
err << "NuclearStackExtension: no A and Z specified for new Nucleus!"; super_type::setParticleData(particle_data_type{std::get<0>(v), std::get<1>(v),
throw std::runtime_error(err.str()); std::get<2>(v), std::get<3>(v), std::get<4>(v)});
} }
InnerParticleInterface<StackIteratorInterface>::SetParticleData(
p, std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, void setParticleData( super_type& p, particle_data_type const& v)
corsika::Point, TimeType>{std::get<0>(v), std::get<1>(v), {
std::get<2>(v), std::get<3>(v), if (std::get<0>(v) == corsika::Code::Nucleus) {
std::get<4>(v)}); std::ostringstream err;
SetNucleusRef(-1); // this is not a nucleus err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
} throw std::runtime_error(err.str());
}
void SetParticleData(
InnerParticleInterface<StackIteratorInterface>& p, super_type::setParticleData(p, particle_data_type{std::get<0>(v), std::get<1>(v),
const std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, std::get<2>(v), std::get<3>(v), std::get<4>(v)});
corsika::Point, TimeType, unsigned short, unsigned short>& v) {
const unsigned short A = std::get<5>(v); setNucleusRef(-1); // this is not a nucleus
const unsigned short Z = std::get<6>(v); }
if (std::get<0>(v) != corsika::Code::Nucleus || A == 0 || Z == 0) {
std::ostringstream err; void setParticleData( super_type& p, altenative_particle_data_type const& v) {
err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
throw std::runtime_error(err.str()); const unsigned short A = std::get<5>(v);
} const unsigned short Z = std::get<6>(v);
SetNucleusRef(GetStackData().GetNucleusNextRef()); // store this nucleus data ref
SetNuclearA(A); if (std::get<0>(v) != corsika::Code::Nucleus || A == 0 || Z == 0) {
SetNuclearZ(Z); std::ostringstream err;
InnerParticleInterface<StackIteratorInterface>::SetParticleData( err << "NuclearStackExtension: no A and Z specified for new Nucleus!";
p, std::tuple<corsika::Code, HEPEnergyType, corsika::MomentumVector, throw std::runtime_error(err.str());
corsika::Point, TimeType>{std::get<0>(v), std::get<1>(v), }
std::get<2>(v), std::get<3>(v),
std::get<4>(v)}); setNucleusRef(super_type::GetStackData().getNucleusNextRef()); // store this nucleus data ref
} setNuclearA(A);
setNuclearZ(Z);
/** super_type::setParticleData(p, particle_data_type{std::get<0>(v), std::get<1>(v),
* @name individual setters std::get<2>(v), std::get<3>(v),
* @{ std::get<4>(v)});
*/ }
void SetNuclearA(const unsigned short vA) {
GetStackData().SetNuclearA(GetIndex(), vA); std::string as_string() const {
} return fmt::format(
void SetNuclearZ(const unsigned short vZ) { "{}, nuc({})", super_type::as_string(),
GetStackData().SetNuclearZ(GetIndex(), vZ); (isNucleus() ? fmt::format("A={}, Z={}", getNuclearA(), getNuclearZ())
} : "n/a"));
/// @} }
/** /**
* @name individual getters * @name individual setters
* @{ * @{
*/ */
int GetNuclearA() const { return GetStackData().GetNuclearA(GetIndex()); } void setNuclearA(const unsigned short vA) {
int GetNuclearZ() const { return GetStackData().GetNuclearZ(GetIndex()); } super_type::GetStackData().setNuclearA(super_type::GetIndex(), vA);
/// @} }
void setNuclearZ(const unsigned short vZ) {
/** super_type::GetStackData().setNuclearZ(super_type::GetIndex(), vZ);
* Overwrite normal GetParticleMass function with nuclear version }
*/ /// @}
HEPMassType GetMass() const {
if (InnerParticleInterface<StackIteratorInterface>::GetPID() == /**
corsika::Code::Nucleus) * @name individual getters
return corsika::nucleus_mass(GetNuclearA(), GetNuclearZ()); * @{
return InnerParticleInterface<StackIteratorInterface>::GetMass(); */
} int getNuclearA() const { return super_type::GetStackData().getNuclearA(super_type::GetIndex()); }
/** int getNuclearZ() const { return super_type::GetStackData().getNuclearZ(super_type::GetIndex()); }
* Overwirte normal GetChargeNumber function with nuclear version /// @}
**/
int16_t GetChargeNumber() const { /**
if (InnerParticleInterface<StackIteratorInterface>::GetPID() == * Overwrite normal GetParticleMass function with nuclear version
corsika::Code::Nucleus) */
return GetNuclearZ(); corsika::units::si::HEPMassType getMass() const {
return InnerParticleInterface<StackIteratorInterface>::GetChargeNumber(); if (super_type::GetPID() ==
} corsika::Code::Nucleus)
return corsika::GetNucleusMass(getNuclearA(), getNuclearZ());
int GetNucleusRef() const { return GetStackData().GetNucleusRef(GetIndex()); } return super_type::getMass();
}
protected: /**
void SetNucleusRef(const int vR) { GetStackData().SetNucleusRef(GetIndex(), vR); } * Overwirte normal GetChargeNumber function with nuclear version
}; **/
int16_t getChargeNumber() const {
/** if (super_type::GetPID() ==
* @class NuclearStackExtension corsika::Code::Nucleus)
* return getNuclearZ();
* Memory implementation of adding nuclear inforamtion to the return super_type::getChargeNumber();
* existing particle stack defined in class InnerStackImpl. }
*
* Inside the NuclearStackExtension class there is a dedicated int getNucleusRef() const {
* fNucleusRef index, where fNucleusRef[i] is referring to the return super_type::GetStackData().getNucleusRef(GetIndex());
* correct A and Z for a specific particle index i. fNucleusRef[i] } // LCOV_EXCL_LINE
* == -1 means that this is not a nucleus, and a subsequent call to
* GetNucleusA would produce an exception. protected:
*/
template <typename InnerStackImpl> void setNucleusRef(const int vR) {
class NuclearStackExtensionImpl : public InnerStackImpl { super_type::GetStackData().setNucleusRef(super_type::GetIndex(), vR);
}
public:
void Init() { InnerStackImpl::Init(); } bool isNucleus() const {
void Dump() { InnerStackImpl::Dump(); } return super_type::GetStackData().isNucleus(super_type::GetIndex());
}
void Clear() { };
InnerStackImpl::Clear();
fNucleusRef.clear(); /**
fNuclearA.clear(); * @class NuclearStackExtension
fNuclearZ.clear(); *
} * Memory implementation of adding nuclear inforamtion to the
* existing particle stack defined in class InnerStackImpl.
unsigned int GetSize() const { return fNucleusRef.size(); } *
unsigned int GetCapacity() const { return fNucleusRef.capacity(); } * Inside the NuclearStackExtension class there is a dedicated
* fNucleusRef index, where fNucleusRef[i] is referring to the
void SetNuclearA(const unsigned int i, const unsigned short vA) { * correct A and Z for a specific particle index i. fNucleusRef[i]
fNuclearA[GetNucleusRef(i)] = vA; * == -1 means that this is not a nucleus, and a subsequent call to
} * GetNucleusA would produce an exception.
void SetNuclearZ(const unsigned int i, const unsigned short vZ) { */
fNuclearZ[GetNucleusRef(i)] = vZ; template <typename InnerStackImpl>
} class NuclearStackExtensionImpl : public InnerStackImpl {
void SetNucleusRef(const unsigned int i, const int v) { fNucleusRef[i] = v; }
typedef InnerStackImpl super_type;
int GetNuclearA(const unsigned int i) const { return fNuclearA[GetNucleusRef(i)]; }
int GetNuclearZ(const unsigned int i) const { return fNuclearZ[GetNucleusRef(i)]; } public:
// this function will create new storage for Nuclear Properties, and return the
// reference to it typedef std::vector<int> nucleus_ref_type;
int GetNucleusNextRef() { typedef std::vector<unsigned short> nuclear_a_type;
fNuclearA.push_back(0); typedef std::vector<unsigned short> nuclear_z_type;
fNuclearZ.push_back(0);
return fNuclearA.size() - 1;
} NuclearStackExtensionImpl()= default;
int GetNucleusRef(const unsigned int i) const { NuclearStackExtensionImpl( NuclearStackExtensionImpl<InnerStackImpl> const&)= default;
if (fNucleusRef[i] >= 0) return fNucleusRef[i];
std::ostringstream err; NuclearStackExtensionImpl( NuclearStackExtensionImpl<InnerStackImpl> &&)= default;
err << "NuclearStackExtension: no nucleus at ref=" << i;
throw std::runtime_error(err.str()); NuclearStackExtensionImpl<InnerStackImpl>&
} operator=( NuclearStackExtensionImpl<InnerStackImpl> const&)= default;
/** NuclearStackExtensionImpl<InnerStackImpl>&
* Function to copy particle at location i1 in stack to i2 operator=( NuclearStackExtensionImpl<InnerStackImpl> &&)= default;
*/
void Copy(const unsigned int i1, const unsigned int i2) { void init() {
// index range check super_type::init();
if (i1 >= GetSize() || i2 >= GetSize()) { }
std::ostringstream err;
err << "NuclearStackExtension: trying to access data beyond size of stack!"; void dump() {
throw std::runtime_error(err.str()); super_type::dump();
} }
// copy internal particle data p[i2] = p[i1]
InnerStackImpl::Copy(i1, i2); void clear() {
// check if any of p[i1] or p[i2] was a Code::Nucleus super_type::clear();
const int ref1 = fNucleusRef[i1]; nucleusRef_.clear();
const int ref2 = fNucleusRef[i2]; nuclearA_.clear();
if (ref2 < 0) { nuclearZ_.clear();
if (ref1 >= 0) { }
// i1 is nucleus, i2 is not
fNucleusRef[i2] = GetNucleusNextRef(); unsigned int getSize() const {
fNuclearA[fNucleusRef[i2]] = fNuclearA[ref1]; return nucleusRef_.size();
fNuclearZ[fNucleusRef[i2]] = fNuclearZ[ref1]; }
} else {
// neither i1 nor i2 are nuclei unsigned int getCapacity() const {
} return nucleusRef_.capacity();
} else { }
if (ref1 >= 0) {
// both are nuclei, i2 is overwritten with nucleus i1 void setNuclearA(const unsigned int i, const unsigned short vA) {
// fNucleusRef stays the same, but A and Z data is overwritten nuclearA_[getNucleusRef(i)] = vA;
fNuclearA[ref2] = fNuclearA[ref1]; }
fNuclearZ[ref2] = fNuclearZ[ref1];
} else { void setNuclearZ(const unsigned int i, const unsigned short vZ) {
// i2 is overwritten with non-nucleus i1 nuclearZ_[getNucleusRef(i)] = vZ;
fNucleusRef[i2] = -1; // flag as non-nucleus }
fNuclearA.erase(fNuclearA.cbegin() + ref2); // remove data for i2
fNuclearZ.erase(fNuclearZ.cbegin() + ref2); // remove data for i2 void setNucleusRef(const unsigned int i, const int v) {
const int n = fNucleusRef.size(); // update fNucleusRef: indices above ref2 nucleusRef_[i] = v;
// must be decremented by 1 }
for (int i = 0; i < n; ++i) {
if (fNucleusRef[i] > ref2) { fNucleusRef[i] -= 1; } int getNuclearA(const unsigned int i) const {
} return nuclearA_[getNucleusRef(i)];
} }
}
} int getNuclearZ(const unsigned int i) const {
return nuclearZ_[getNucleusRef(i)];
/** }
* Function to copy particle at location i2 in stack to i1 // this function will create new storage for Nuclear Properties, and return the
*/ // reference to it
void Swap(const unsigned int i1, const unsigned int i2) { int getNucleusNextRef() {
// index range check nuclearA_.push_back(0);
if (i1 >= GetSize() || i2 >= GetSize()) { nuclearZ_.push_back(0);
std::ostringstream err; return nuclearA_.size() - 1;
err << "NuclearStackExtension: trying to access data beyond size of stack!"; }
throw std::runtime_error(err.str());
} int getNucleusRef(const unsigned int i) const {
// swap original particle data if (nucleusRef_[i] >= 0) return nucleusRef_[i];
InnerStackImpl::Swap(i1, i2); std::ostringstream err;
// swap corresponding nuclear reference data err << "NuclearStackExtension: no nucleus at ref=" << i;
std::swap(fNucleusRef[i2], fNucleusRef[i1]); throw std::runtime_error(err.str());
} }
void IncrementSize() { bool isNucleus(const unsigned int i) const { return nucleusRef_[i] >= 0; }
InnerStackImpl::IncrementSize();
fNucleusRef.push_back(-1); /**
} * Function to copy particle at location i1 in stack to i2
*/
void DecrementSize() { void copy(const unsigned int i1, const unsigned int i2) {
InnerStackImpl::DecrementSize(); // index range check
if (fNucleusRef.size() > 0) { if (i1 >= getSize() || i2 >= getSize()) {
const int ref = fNucleusRef.back(); std::ostringstream err;
fNucleusRef.pop_back(); err << "NuclearStackExtension: trying to access data beyond size of stack!";
if (ref >= 0) { throw std::runtime_error(err.str());
fNuclearA.erase(fNuclearA.begin() + ref); }
fNuclearZ.erase(fNuclearZ.begin() + ref); // copy internal particle data p[i2] = p[i1]
const int n = fNucleusRef.size(); super_type::copy(i1, i2);
for (int i = 0; i < n; ++i) { // check if any of p[i1] or p[i2] was a Code::Nucleus
if (fNucleusRef[i] >= ref) { fNucleusRef[i] -= 1; } const int ref1 = nucleusRef_[i1];
} const int ref2 = nucleusRef_[i2];
} if (ref2 < 0) {
} if (ref1 >= 0) {
} // i1 is nucleus, i2 is not
nucleusRef_[i2] = getNucleusNextRef();
private: nuclearA_[nucleusRef_[i2]] = nuclearA_[ref1];
/// the actual memory to store particle data nuclearZ_[nucleusRef_[i2]] = nuclearZ_[ref1];
} else {
std::vector<int> fNucleusRef; // neither i1 nor i2 are nuclei
std::vector<unsigned short> fNuclearA; }
std::vector<unsigned short> fNuclearZ; } else {
if (ref1 >= 0) {
}; // end class NuclearStackExtensionImpl // both are nuclei, i2 is overwritten with nucleus i1
// fNucleusRef stays the same, but A and Z data is overwritten
// template<typename StackIteratorInterface> nuclearA_[ref2] = nuclearA_[ref1];
// using NuclearParticleInterfaceType<StackIteratorInterface> = nuclearZ_[ref2] = nuclearZ_[ref1];
// NuclearParticleInterface< ,StackIteratorInterface> } else {
// i2 is overwritten with non-nucleus i1
// works, but requires stupd _PI class nucleusRef_[i2] = -1; // flag as non-nucleus
// template<typename SS> using TEST = nuclearA_.erase(nuclearA_.cbegin() + ref2); // remove data for i2
// NuclearParticleInterface<corsika::super_stupid::SuperStupidStack::PIType, nuclearZ_.erase(nuclearZ_.cbegin() + ref2); // remove data for i2
// SS>; const int n = nucleusRef_.size(); // update fNucleusRef: indices above ref2
template <typename InnerStack, template <typename> typename _PI> // must be decremented by 1
using NuclearStackExtension = for (int i = 0; i < n; ++i) {
Stack<NuclearStackExtensionImpl<typename InnerStack::StackImpl>, _PI>; if (nucleusRef_[i] > ref2) { nucleusRef_[i] -= 1; }
}
// ---- }
}
// I'm dont't manage to do this properly....... }
/*
template<typename TT, typename SS> using TESTi = typename /**
NuclearParticleInterface<TT::template PIType, SS>::ExtendedParticleInterface; * Function to copy particle at location i2 in stack to i1
template<typename TT, typename SS> using TEST1 = TESTi<TT, SS>; */
template<typename SS> using TEST2 = TEST1<typename void swap(const unsigned int i1, const unsigned int i2) {
corsika::super_stupid::SuperStupidStack, SS>; // index range check
if (i1 >= getSize() || i2 >= getSize()) {
using NuclearStackExtension = Stack<NuclearStackExtensionImpl<typename std::ostringstream err;
InnerStack::StackImpl>, TEST2>; err << "NuclearStackExtension: trying to access data beyond size of stack!";
*/ throw std::runtime_error(err.str());
/* }
// .... this should be fixed .... // swap original particle data
super_type::swap(i1, i2);
template <typename InnerStack, typename SS=StackIteratorInterface> // swap corresponding nuclear reference data
//using NuclearStackExtension = Stack<NuclearStackExtensionImpl<typename std::swap(nucleusRef_[i2], nucleusRef_[i1]);
InnerStack::StackImpl>, NuclearParticleInterface<typename InnerStack::template PIType, }
StackIteratorInterface>::ExtendedParticleInterface>; using NuclearStackExtension =
Stack<NuclearStackExtensionImpl<typename InnerStack::StackImpl>, TEST1<typename void incrementSize() {
corsika::super_stupid::SuperStupidStack, SS> >; super_type::incrementSize();
nucleusRef_.push_back(-1);
//template <typename InnerStack> }
// using NuclearStackExtension = Stack<NuclearStackExtensionImpl<typename
InnerStack::StackImpl>, TEST<typename void decrementSize() {
corsika::super_stupid::SuperStupidStack::PIType>>; super_type::decrementSize();
//using NuclearStackExtension = Stack<NuclearStackExtensionImpl<typename if (nucleusRef_.size() > 0) {
InnerStack::StackImpl>, TEST>; const int ref = nucleusRef_.back();
*/ nucleusRef_.pop_back();
if (ref >= 0) {
} // namespace nuclear_extension nuclearA_.erase(nuclearA_.begin() + ref);
nuclearZ_.erase(nuclearZ_.begin() + ref);
const int n = nucleusRef_.size();
for (int i = 0; i < n; ++i) {
if (nucleusRef_[i] >= ref) { nucleusRef_[i] -= 1; }
}
}
}
}
private:
/// the actual memory to store particle data
nucleus_ref_type nucleusRef_;
nuclear_a_type nuclearA_;
nuclear_z_type nuclearZ_;
}; // end class NuclearStackExtensionImpl
template <typename InnerStack, template <typename> typename _PI>
using NuclearStackExtension =
Stack<NuclearStackExtensionImpl<typename InnerStack::StackImpl>, _PI> ;
//
template <typename StackIter>
using ExtendedParticleInterfaceType = NuclearParticleInterface<SuperStupidStack, StackIter>;
// the particle data stack with extra nuclear information:
using ParticleDataStack = NuclearStackExtension<SuperStupidStack, ExtendedParticleInterfaceType>;
} // namespace corsika } // namespace corsika
...@@ -22,193 +22,259 @@ ...@@ -22,193 +22,259 @@
namespace corsika { namespace corsika {
typedef corsika::Vector<hepmomentum_d> MomentumVector;
/**
namespace super_stupid { * Example of a particle object on the stack.
*/
/**
* Example of a particle object on the stack. template <typename StackIteratorInterface>
*/ struct ParticleInterface : public ParticleBase<StackIteratorInterface> {
template <typename StackIteratorInterface> private:
class ParticleInterface : public ParticleBase<StackIteratorInterface> {
typedef corsika::ParticleBase<StackIteratorInterface> super_type;
protected:
using corsika::ParticleBase<StackIteratorInterface>::GetStack; public:
using corsika::ParticleBase<StackIteratorInterface>::GetStackData;
typedef corsika::Vector<corsika::units::si::hepmomentum_d> momentum_vector_type;
public:
using corsika::ParticleBase<StackIteratorInterface>::GetIndex; std::string as_string() const {
using namespace corsika::units::si;
public: return fmt::format("particle: i={}, PID={}, E={}GeV", super_type::GetIndex(),
void SetParticleData(const std::tuple<corsika::Code, HEPEnergyType, MomentumVector, particles::GetName(this->getPID()), this->getEnergy() / 1_GeV);
corsika::Point, TimeType>& v) { }
SetPID(std::get<0>(v));
SetEnergy(std::get<1>(v)); void setParticleData( std::tuple<corsika::Code, corsika::units::si::HEPEnergyType,
SetMomentum(std::get<2>(v)); momentum_vector_type, corsika::Point, corsika::units::si::TimeType> const& v) {
SetPosition(std::get<3>(v)); this->setPID(std::get<0>(v));
SetTime(std::get<4>(v)); this->setEnergy(std::get<1>(v));
} this->setMomentum(std::get<2>(v));
/* this->setPosition(std::get<3>(v));
void SetParticleData(const corsika::Code vDataPID, this->setTime(std::get<4>(v));
const HEPEnergyType vDataE, }
const MomentumVector& vMomentum,
const corsika::Point& vPosition, void setParticleData( ParticleInterface<StackIteratorInterface> const&,
const TimeType vTime) { std::tuple<corsika::Code, corsika::units::si::HEPEnergyType,
}*/ momentum_vector_type, corsika::Point, corsika::units::si::TimeType> const& v) {
this->setPID(std::get<0>(v));
void SetParticleData(ParticleInterface<StackIteratorInterface>&, this->setEnergy(std::get<1>(v));
const std::tuple<corsika::Code, HEPEnergyType, MomentumVector, this->setMomentum(std::get<2>(v));
corsika::Point, TimeType>& v) { this->setPosition(std::get<3>(v));
SetPID(std::get<0>(v)); this->setTime(std::get<4>(v));
SetEnergy(std::get<1>(v)); }
SetMomentum(std::get<2>(v));
SetPosition(std::get<3>(v)); /// individual setters
SetTime(std::get<4>(v)); void setPID(const corsika::Code id) {
} super_type::GetStackData().setPID(super_type::GetIndex(), id);
/* void SetParticleData(ParticleInterface<StackIteratorInterface>&, }
const corsika::Code vDataPID, void setEnergy(const corsika::units::si::HEPEnergyType& e) {
const HEPEnergyType vDataE, super_type::GetStackData().setEnergy(super_type::GetIndex(), e);
const MomentumVector& vMomentum, }
const corsika::Point& vPosition, void setMomentum(const momentum_vector_type& v) {
const TimeType vTime) { super_type::GetStackData().setMomentum(super_type::GetIndex(), v);
SetPID(vDataPID); }
SetEnergy(vDataE); void setPosition(const corsika::Point& v) {
SetMomentum(vMomentum); super_type::GetStackData().setPosition(super_type::GetIndex(), v);
SetPosition(vPosition); }
SetTime(vTime); void setTime(const corsika::units::si::TimeType& v) {
}*/ super_type::GetStackData().setTime(super_type::GetIndex(), v);
}
/// individual setters
void SetPID(const corsika::Code id) { GetStackData().SetPID(GetIndex(), id); } /// individual getters
void SetEnergy(const HEPEnergyType& e) { GetStackData().SetEnergy(GetIndex(), e); } corsika::Code getPID() const {
void SetMomentum(const MomentumVector& v) { return super_type::GetStackData().getPID(super_type::GetIndex());
GetStackData().SetMomentum(GetIndex(), v); }
} corsika::units::si::HEPEnergyType getEnergy() const {
void SetPosition(const corsika::Point& v) { return super_type::GetStackData().getEnergy(super_type::GetIndex());
GetStackData().SetPosition(GetIndex(), v); }
} momentum_vector_type getMomentum() const {
void SetTime(const TimeType& v) { GetStackData().SetTime(GetIndex(), v); } return super_type::GetStackData().getMomentum(super_type::GetIndex());
}
/// individual getters corsika::Point getPosition() const {
corsika::Code GetPID() const { return GetStackData().GetPID(GetIndex()); } return super_type::GetStackData().getPosition(super_type::GetIndex());
HEPEnergyType GetEnergy() const { return GetStackData().GetEnergy(GetIndex()); } }
MomentumVector GetMomentum() const { corsika::units::si::TimeType getTime() const {
return GetStackData().GetMomentum(GetIndex()); return super_type::GetStackData().getTime(super_type::GetIndex());
} }
corsika::Point GetPosition() const { /**
return GetStackData().GetPosition(GetIndex()); * @name derived quantities
} *
TimeType GetTime() const { return GetStackData().GetTime(GetIndex()); } * @{
/** */
* @name derived quantities corsika::Vector<corsika::units::si::dimensionless_d> getDirection() const {
* return this->getMomentum() / this->getEnergy();
* @{ }
*/
corsika::Vector<dimensionless_d> GetDirection() const { corsika::units::si::HEPMassType getMass() const {
return GetMomentum() / GetEnergy(); return corsika::GetMass(this->getPID());
} }
HEPMassType GetMass() const { return corsika::mass(GetPID()); }
int16_t GetChargeNumber() const { return corsika::charge_number(GetPID()); } int16_t getChargeNumber() const {
///@} return corsika::GetChargeNumber(this->getPID());
}; }
///@}
/** };
* Memory implementation of the most simple (stupid) particle stack object.
*/ /**
* Memory implementation of the most simple (stupid) particle stack object.
class SuperStupidStackImpl { *
*/
public:
void Init() {} class SuperStupidStackImpl {
void Dump() const {}
public:
void Clear() {
fDataPID.clear(); typedef corsika::Vector<corsika::units::si::hepmomentum_d> momentum_type;
fDataE.clear(); typedef std::vector<corsika::Code> code_vector_type;
fMomentum.clear(); typedef std::vector<corsika::units::si::HEPEnergyType> energy_vector_type;
fPosition.clear(); typedef std::vector<corsika::Point> point_vector_type;
fTime.clear(); typedef std::vector<corsika::units::si::TimeType> time_vector_type;
} typedef std::vector<momentum_type> momentum_vector_type;
unsigned int GetSize() const { return fDataPID.size(); } SuperStupidStackImpl()=default;
unsigned int GetCapacity() const { return fDataPID.size(); }
SuperStupidStackImpl( SuperStupidStackImpl const& other)=default;
void SetPID(const unsigned int i, const corsika::Code id) { fDataPID[i] = id; }
void SetEnergy(const unsigned int i, const HEPEnergyType e) { fDataE[i] = e; } SuperStupidStackImpl( SuperStupidStackImpl && other)=default;
void SetMomentum(const unsigned int i, const MomentumVector& v) {
fMomentum[i] = v;
} SuperStupidStackImpl& operator=( SuperStupidStackImpl const& other)=default;
void SetPosition(const unsigned int i, const corsika::Point& v) {
fPosition[i] = v; SuperStupidStackImpl& operator=( SuperStupidStackImpl && other)=default;
}
void SetTime(const unsigned int i, const TimeType& v) { fTime[i] = v; }
void init() {}
corsika::Code GetPID(const unsigned int i) const { return fDataPID[i]; } void dump() const {}
HEPEnergyType GetEnergy(const unsigned int i) const { return fDataE[i]; }
MomentumVector GetMomentum(const unsigned int i) const { return fMomentum[i]; } void clear() {
corsika::Point GetPosition(const unsigned int i) const { return fPosition[i]; } dataPID_.clear();
TimeType GetTime(const unsigned int i) const { return fTime[i]; } dataE_.clear();
momentum_.clear();
/** position_.clear();
* Function to copy particle at location i2 in stack to i1 time_.clear();
*/ }
void Copy(const unsigned int i1, const unsigned int i2) {
fDataPID[i2] = fDataPID[i1]; unsigned int getSize() const { return dataPID_.size(); }
fDataE[i2] = fDataE[i1]; unsigned int getCapacity() const { return dataPID_.size(); }
fMomentum[i2] = fMomentum[i1];
fPosition[i2] = fPosition[i1]; void setPID(size_t i, const corsika::Code id) {
fTime[i2] = fTime[i1]; dataPID_[i] = id;
} }
void setEnergy(size_t i, corsika::units::si::HEPEnergyType const& e) {
/** dataE_[i] = e;
* Function to copy particle at location i2 in stack to i1 }
*/ void setMomentum(size_t i, momentum_type const& v) {
void Swap(const unsigned int i1, const unsigned int i2) { momentum_[i] = v;
std::swap(fDataPID[i2], fDataPID[i1]); }
std::swap(fDataE[i2], fDataE[i1]); void setPosition(size_t i, corsika::Point const& v) {
std::swap(fMomentum[i2], fMomentum[i1]); position_[i] = v;
std::swap(fPosition[i2], fPosition[i1]); }
std::swap(fTime[i2], fTime[i1]); void setTime(size_t i, corsika::units::si::TimeType const& v) {
} time_[i] = v;
}
void IncrementSize() {
using corsika::Code; corsika::Code getPID(size_t i) const {
using corsika::Point; return dataPID_[i];
fDataPID.push_back(Code::Unknown); }
fDataE.push_back(0 * electronvolt);
CoordinateSystem& dummyCS = corsika::units::si::HEPEnergyType getEnergy(size_t i) const {
RootCoordinateSystem::getInstance().GetRootCoordinateSystem(); return dataE_[i];
fMomentum.push_back(MomentumVector( }
dummyCS, {0 * electronvolt, 0 * electronvolt, 0 * electronvolt}));
fPosition.push_back(Point(dummyCS, {0 * meter, 0 * meter, 0 * meter})); momentum_type getMomentum(size_t i) const {
fTime.push_back(0 * second); return momentum_[i];
} }
void DecrementSize() { corsika::Point getPosition(size_t i) const {
if (fDataE.size() > 0) { return position_[i];
fDataPID.pop_back(); }
fDataE.pop_back(); corsika::units::si::TimeType getTime(size_t i) const {
fMomentum.pop_back(); return time_[i];
fPosition.pop_back(); }
fTime.pop_back();
} corsika::units::si::HEPEnergyType getDataE(size_t i) const {
} return dataE_[i];
}
private:
/// the actual memory to store particle data void setDataE(size_t i, corsika::units::si::HEPEnergyType const& dataE) {
dataE_[i] = dataE;
std::vector<corsika::Code> fDataPID; }
std::vector<HEPEnergyType> fDataE;
std::vector<MomentumVector> fMomentum; corsika::Code getDataPid(size_t i) const {
std::vector<corsika::Point> fPosition; return dataPID_;
std::vector<TimeType> fTime; }
}; // end class SuperStupidStackImpl void setDataPid(size_t i, corsika::Code const& dataPid) {
dataPID_[i] = dataPid;
typedef Stack<SuperStupidStackImpl, ParticleInterface> SuperStupidStack; }
/**
} // namespace super_stupid * Function to copy particle at location i2 in stack to i1
*/
void copy(size_t i1, size_t i2) {
dataPID_[i2] = dataPID_[i1];
dataE_[i2] = dataE_[i1];
momentum_[i2] = momentum_[i1];
position_[i2] = position_[i1];
time_[i2] = time_[i1];
}
/**
* FIXME: change to iterators.
* Function to copy particle at location i2 in stack to i1
*/
void swap(size_t i1, size_t i2) {
std::swap(dataPID_[i2] , dataPID_[i1]);
std::swap(dataE_[i2] , dataE_[i1]);
std::swap(momentum_[i2], momentum_[i1]);
std::swap(position_[i2], position_[i1]);
std::swap(time_[i2] , time_[i1]);
}
void incrementSize() {
using corsika::Point;
using corsika::Code;
dataPID_.push_back(Code::Unknown);
dataE_.push_back(0 * corsika::units::si::electronvolt);
CoordinateSystem& dummyCS = RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
momentum_.push_back(momentum_type( dummyCS,
{0 * corsika::units::si::electronvolt, 0 * corsika::units::si::electronvolt,
0 * corsika::units::si::electronvolt}));
position_.push_back(
Point(dummyCS, {0 * corsika::units::si::meter, 0 * corsika::units::si::meter,
0 * corsika::units::si::meter}));
time_.push_back(0 * corsika::units::si::second);
}
void decrementSize() {
if (dataE_.size() > 0) {
dataPID_.pop_back();
dataE_.pop_back();
momentum_.pop_back();
position_.pop_back();
time_.pop_back();
}
}
private:
/// the actual memory to store particle data
code_vector_type dataPID_;
energy_vector_type dataE_;
std::vector<momentum_type> momentum_;
std::vector<corsika::Point> position_;
std::vector<corsika::units::si::TimeType> time_;
}; // end class SuperStupidStackImpl
typedef Stack<SuperStupidStackImpl, ParticleInterface> SuperStupidStack;
} // namespace corsika } // namespace corsika
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment