diff --git a/corsika/detail/setup/SetupStack.hpp b/corsika/detail/setup/SetupStack.hpp index 2b40ccbdb0eafcc2c48ead0dc437c1314d6e2286..bec6c0aa1595a59d20f0ef044827e39608e23440 100644 --- a/corsika/detail/setup/SetupStack.hpp +++ b/corsika/detail/setup/SetupStack.hpp @@ -20,61 +20,76 @@ namespace corsika { namespace setup::detail { - - // ------------------------------------------ - // add geometry node data to stack. This is fundamentally needed - // for robust tracking through multiple volumes. - - // the GeometryNode stack needs to know the type of geometry-nodes from the - // environment: - template <typename TStackIter> - using SetupGeometryDataInterface = - typename node::MakeGeometryDataInterface<TStackIter, setup::Environment>::type; - - // combine particle data stack with geometry information for tracking - template <typename TStackIter> - using StackWithGeometryInterface = - CombinedParticleInterface<VectorStack::pi_type, SetupGeometryDataInterface, - TStackIter>; - - using StackWithGeometry = - CombinedStack<typename VectorStack::stack_data_type, - node::GeometryData<setup::Environment>, StackWithGeometryInterface, - DefaultSecondaryProducer>; - - // ------------------------------------------ - // add weight data to stack. This is fundamentally needed - // for thinning. - - // the "pure" weight stack (interface) - template <typename TStackIter> - using SetupWeightDataInterface = - typename weights::MakeWeightDataInterface<TStackIter>::type; - - // combine geometry-node-vector data stack with weight information for tracking - template <typename TStackIter> - using StackWithWeightInterface = - CombinedParticleInterface<StackWithGeometry::pi_type, SetupWeightDataInterface, - TStackIter>; - - // the combined stack data: particle + geometry + weight - using StackWithWeight = - CombinedStack<typename StackWithGeometry::stack_data_type, weights::WeightData, - StackWithWeightInterface, DefaultSecondaryProducer>; - - // ------------------------------------------ - // Add [OPTIONAL] history data to stack, too. - // This keeps the entire lineage of particles in memory. - - template <typename TStackIter> - using StackWithHistoryInterface = - CombinedParticleInterface<StackWithWeight::pi_type, - history::HistoryEventDataInterface, TStackIter>; - - using StackWithHistory = - CombinedStack<typename StackWithWeight::stack_data_type, - history::HistoryEventData, StackWithHistoryInterface, - history::HistorySecondaryProducer>; + template <typename TEnvironment = setup::Environment> + class StackGenerator { + private: + using env_type = TEnvironment; + + // ------------------------------------------ + // add geometry node data to stack. This is fundamentally needed + // for robust tracking through multiple volumes. + + // the GeometryNode stack needs to know the type of geometry-nodes from the + // environment: + + template <typename TStackIter> + using SetupGeometryDataInterface = + typename node::MakeGeometryDataInterface<TStackIter, env_type>::type; + + // combine particle data stack with geometry information for tracking + template <typename TStackIter> + using StackWithGeometryInterface = + CombinedParticleInterface<VectorStack::pi_type, SetupGeometryDataInterface, + TStackIter>; + + using StackWithGeometry = + CombinedStack<typename VectorStack::stack_data_type, + node::GeometryData<env_type>, StackWithGeometryInterface, + DefaultSecondaryProducer>; + + template <class T> + using StackWithGeometry_PI_type = typename StackWithGeometry::template pi_type<T>; + + // ------------------------------------------ + // add weight data to stack. This is fundamentally needed + // for thinning. + + // the "pure" weight stack (interface) + template <typename TStackIter> + using SetupWeightDataInterface = + typename weights::MakeWeightDataInterface<TStackIter>::type; + + // combine geometry-node-vector data stack with weight information for tracking + template <typename TStackIter> + using StackWithWeightInterface = + CombinedParticleInterface<StackWithGeometry_PI_type, SetupWeightDataInterface, + TStackIter>; + + public: + // the combined stack data: particle + geometry + weight + using StackWithWeight = + CombinedStack<typename StackWithGeometry::stack_data_type, weights::WeightData, + StackWithWeightInterface, DefaultSecondaryProducer>; + + private: + template <typename T> + using StackWithWeight_PI_type = typename StackWithWeight::template pi_type<T>; + + // ------------------------------------------ + // Add [OPTIONAL] history data to stack, too. + // This keeps the entire lineage of particles in memory. + + template <typename TStackIter> + using StackWithHistoryInterface = + CombinedParticleInterface<StackWithWeight_PI_type, + history::HistoryEventDataInterface, TStackIter>; + + public: + using StackWithHistory = + CombinedStack<typename StackWithWeight::stack_data_type, + history::HistoryEventData, StackWithHistoryInterface, + history::HistorySecondaryProducer>; + }; } // namespace setup::detail diff --git a/corsika/setup/SetupStack.hpp b/corsika/setup/SetupStack.hpp index 9028c2ab175127d07f3c430bbbba5edb5c82722d..7d1894e4cd8c00fa88ec290e4032a11cc5550d1b 100644 --- a/corsika/setup/SetupStack.hpp +++ b/corsika/setup/SetupStack.hpp @@ -24,18 +24,21 @@ namespace corsika::setup { /* * the version with history */ - using Stack = detail::StackWithHistory; + template <typename TEnvironment> + using Stack = typename detail::StackGenerator<TEnvironment>::StackWithWeight; #else // WITH_HISTORY /* * the version without history (and geometry data and weights) */ - using Stack = detail::StackWithWeight; + template <typename TEnvironment> + using Stack = typename detail::StackGenerator<TEnvironment>::StackWithWeight; #endif // the correct secondary stack view - using StackView = typename Stack::stack_view_type; + template <typename TEnvironment> + using StackView = typename Stack<TEnvironment>::stack_view_type; } // namespace corsika::setup diff --git a/examples/em_shower.cpp b/examples/em_shower.cpp index 615b840c18d53d1d9d6bfc4ec92c0203e9c3619b..fe67c6477184f4f7d17e66b94c6ba52d8d12695a 100644 --- a/examples/em_shower.cpp +++ b/examples/em_shower.cpp @@ -110,7 +110,7 @@ int main(int argc, char** argv) { set_energy_production_threshold(pcode, energy); // setup particle stack, and add primary particle - setup::Stack stack; + setup::Stack<EnvType> stack; stack.clear(); const Code beamCode = Code::Electron; auto const mass = get_mass(beamCode);