diff --git a/Framework/StackInterface/StackIteratorInterface.h b/Framework/StackInterface/StackIteratorInterface.h index 5213e30d4cead0cf5f2170f3a70cdc03c2974e3a..2aa5de8897c89e2b52c71a9d67b6066cdb5ba9ef 100644 --- a/Framework/StackInterface/StackIteratorInterface.h +++ b/Framework/StackInterface/StackIteratorInterface.h @@ -10,6 +10,11 @@ #include <corsika/stack/ParticleBase.h> +namespace corsika::history { + template <typename T> + class HSecondaryView; // forward decl. for befriending +} + namespace corsika::stack { template <typename StackDataType, template <typename> typename ParticleInterface> @@ -76,6 +81,9 @@ namespace corsika::stack { friend class SecondaryView<StackDataType, ParticleInterface>; // access for SecondaryView + template <typename T> + friend class corsika::history::HSecondaryView; + private: unsigned int fIndex = 0; StackType* fData = 0; // info: Particles and StackIterators become invalid when parent diff --git a/Stack/History/CMakeLists.txt b/Stack/History/CMakeLists.txt index 8b327411f1a2885333e251cf56ef35c059b255e2..63b6b602c676ed58fbf82aa0360c4f0a95e356eb 100644 --- a/Stack/History/CMakeLists.txt +++ b/Stack/History/CMakeLists.txt @@ -1,7 +1,7 @@ set ( SETUP_HEADERS Event.hpp - HStackView.hpp + HSecondaryView.hpp HistoryStackExtension.h SecondaryParticle.hpp ) diff --git a/Stack/History/Event.hpp b/Stack/History/Event.hpp index 82d949a7be94c72edee3fd0f5927990b50bdd6c0..ebb5d3a2abf4ecbc2e5c908060079461bbb2112a 100644 --- a/Stack/History/Event.hpp +++ b/Stack/History/Event.hpp @@ -9,17 +9,16 @@ #pragma once #include <corsika/particles/ParticleProperties.h> -#include <corsika/stack/Stack.h> #include <corsika/history/SecondaryParticle.hpp> +#include <iostream> #include <optional> #include <vector> namespace corsika::history { - template <typename TStackIterator> - class Event { - TStackIterator const projectile_; //!< reference to projectile + struct Event { + size_t const projectileIndex_; //!< reference to projectile std::vector<SecondaryParticle> secondaries; // meta information, could also be in a separate class @@ -27,8 +26,10 @@ namespace corsika::history { targetCode; // cannot be const, value set only after construction public: - Event(TStackIterator projectile) - : projectile_{projectile} {} + Event(size_t projectileIndex) + : projectileIndex_{projectileIndex} { + std::cout << "Event created (index = " << projectileIndex_ << ")" << std::endl; + } }; } // namespace corsika::history diff --git a/Stack/History/HSecondaryView.hpp b/Stack/History/HSecondaryView.hpp new file mode 100644 index 0000000000000000000000000000000000000000..1abf8cf6b1e9039320f54beace738bdac9b9367c --- /dev/null +++ b/Stack/History/HSecondaryView.hpp @@ -0,0 +1,48 @@ +/* + * (c) Copyright 2018 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/stack/SecondaryView.h> +#include <corsika/history/Event.hpp> + +#include <memory> +#include <type_traits> +#include <utility> + +namespace corsika::history { + + namespace detail { + template <typename TParticleIterator> + using SecondaryViewTypeFromIterator = + decltype(stack::SecondaryView{std::declval<TParticleIterator&>()}); + } + + template <typename TParticleIterator> + class HSecondaryView : public detail::SecondaryViewTypeFromIterator<TParticleIterator> { + std::shared_ptr<Event> event_; + + using BaseSecondaryViewType = + detail::SecondaryViewTypeFromIterator<TParticleIterator>; + + public: + HSecondaryView(TParticleIterator& p) + : BaseSecondaryViewType{p} + , event_{std::make_shared<Event>(p.GetIndex())} {} + + template <typename... Args> + void AddSecondary(Args&&... args) { + auto const s = BaseSecondaryViewType::AddSecondary( + std::forward<Args...>(args...), event_); // what if event is not last argument? + event_->secondaries.emplace_back(s.GetEnergy(), s.GetMomentum(), s.GetParticleID()); + } + + void SetTarget(particles::Code targetCode) { event_->targetCode = targetCode; } + }; + +} // namespace corsika::history diff --git a/Stack/History/HStackView.hpp b/Stack/History/HStackView.hpp deleted file mode 100644 index c5a7e104829f082ac8459476a75dc74f6bd3040c..0000000000000000000000000000000000000000 --- a/Stack/History/HStackView.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (c) Copyright 2018 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/stack/history/Event.hpp> - -#include <memory> - -namespace corsika::history { - - template <typename TStackView> - class HStackView : public TStackView { - std::shared_ptr<Event<typename TStackView::StackIteratorValue>> event_; - - public: - template <typename... Args> - EventBuilder(Args&&... args) - : TStackView{std::forward<Args>(args)} - , event_{std::make_shared<Event>()} {} - - template <typename... Args> - void AddSecondary(Args&&... args) { - auto const s = TStackView::AddSecondary( - std::forward<Args>(args), event_); // what if event is not last argument? - event_->secondaries.emplace_back(s.GetEnergy(), s.GetMomentum(), s.GetParticleID()); - } - - void SetTarget(corsika::particles::ParticleCode targetCode) { - event_->targetCode = targetCode; - } - }; - -} // namespace corsika::history diff --git a/Stack/History/HistoryStackExtension.h b/Stack/History/HistoryStackExtension.h index d12632d9e28a4c556794c48cc3859342ae89defb..58de264c14dd5404bb4e59086cb5f5345f400a8e 100644 --- a/Stack/History/HistoryStackExtension.h +++ b/Stack/History/HistoryStackExtension.h @@ -49,7 +49,6 @@ namespace corsika::history { private: std::vector<std::shared_ptr<TEvent>> event_; }; - /** * @class HistoryDataInterface @@ -69,17 +68,16 @@ namespace corsika::history { using T::GetIndex; public: - // create a new particle from scratch - void SetParticleData() { } // nullptr, already by design + void SetParticleData() {} // nullptr, already by design // create a new particle as secondary of a parent - void SetParticleData(HistoryDataInterface& parent) { - SetEvent(std::make_shared<TEvent>(parent.GetEvent())); - GetEvent().getParent().addSecondary(GetEvent()); + void SetParticleData(HistoryDataInterface& parent) { SetParticleData(); } + + void SetEvent(const std::shared_ptr<TEvent>& v) { + GetStackData().SetEvent(GetIndex(), v); } - void SetEvent(const std::shared_ptr<TEvent>& v) { GetStackData().SetEvent(GetIndex(), v); } std::shared_ptr<TEvent> GetEvent() const { return GetStackData().GetEvent(GetIndex()); } diff --git a/Stack/History/SecondaryParticle.hpp b/Stack/History/SecondaryParticle.hpp index 319eeaa2484b63f00a0a461cdee5fbf662535579..f1a2831d82fe8c7a1071116096b55e766488b71f 100644 --- a/Stack/History/SecondaryParticle.hpp +++ b/Stack/History/SecondaryParticle.hpp @@ -29,7 +29,9 @@ namespace corsika::history { // - polarization? public: - SecondaryParticle(units::si::HEPEnergyType energy, geometry::Vector<units::si::hepmomentum_d> momentum, particles::Code pid) + SecondaryParticle(units::si::HEPEnergyType energy, + geometry::Vector<units::si::hepmomentum_d> momentum, + particles::Code pid) : energy_{energy} , momentum_{momentum} , pid_{pid} {} diff --git a/Stack/History/testHistory.cc b/Stack/History/testHistory.cc index 468ca6415a63e5e684bed13d658e986b4226c7ab..ebc201ebee1936791ad330a9b1757c7639404a28 100644 --- a/Stack/History/testHistory.cc +++ b/Stack/History/testHistory.cc @@ -7,63 +7,55 @@ */ #include <corsika/history/HistoryStackExtension.h> -#include <corsika/stack/dummy/DummyStack.h> #include <corsika/stack/CombinedStack.h> - -using namespace corsika; -using namespace corsika::stack; +#include <corsika/stack/dummy/DummyStack.h> +#include <corsika/history/Event.hpp> +#include <corsika/history/HSecondaryView.hpp> #include <catch2/catch.hpp> #include <iostream> -using namespace std; - -// this is our dummy environment, it only knows its trivial BaseNodeType -class DummyEvent { -public: - DummyEvent() {} - DummyEvent(const std::shared_ptr<DummyEvent>& parent) { - parent_ = parent; - //parent.addSecondary(); - } - std::shared_ptr<DummyEvent> getParent() { return parent_; } - void addSecondary(const std::shared_ptr<DummyEvent>& particle) { secondaries_.push_back(particle); } - - int multiplicity() const { return secondaries_.size(); } - -private: - std::shared_ptr<DummyEvent> parent_; - std::vector<std::shared_ptr<DummyEvent>> secondaries_; -}; +using namespace corsika; +using namespace corsika::stack; // the GeometryNode stack needs to know the type of geometry-nodes from the DummyEnv: template <typename TStackIter> -using DummyHistoryDataInterface = typename history::MakeHistoryDataInterface<TStackIter, DummyEvent>::type; - +using DummyHistoryDataInterface = + typename history::MakeHistoryDataInterface<TStackIter, history::Event>::type; // combine dummy stack with geometry information for tracking template <typename TStackIter> -using StackWithHistoryInterface = corsika::stack::CombinedParticleInterface< - dummy::DummyStack::PIType, - DummyHistoryDataInterface, TStackIter>; +using StackWithHistoryInterface = + corsika::stack::CombinedParticleInterface<dummy::DummyStack::PIType, + DummyHistoryDataInterface, TStackIter>; -using TestStack = corsika::stack::CombinedStack< - typename stack::dummy::DummyStack::StackImpl, - history::HistoryData<DummyEvent>, - StackWithHistoryInterface>; +using TestStack = + corsika::stack::CombinedStack<typename stack::dummy::DummyStack::StackImpl, + history::HistoryData<history::Event>, + StackWithHistoryInterface>; +using EvtPtr = std::shared_ptr<history::Event>; TEST_CASE("HistoryStackExtension", "[stack]") { const dummy::NoData noData; - + TestStack s; + + auto p = s.AddParticle(std::tuple<dummy::NoData>{noData}); + + SECTION("add lone particle") { + CHECK(s.GetSize() == 1); + + EvtPtr evt = p.GetEvent(); + CHECK(evt == nullptr); + } + SECTION("write event") { + history::HSecondaryView hview{p}; - TestStack s; - s.AddParticle(std::tuple<dummy::NoData>{noData}); - REQUIRE(s.GetSize() == 1); + hview.AddSecondary(std::tuple<dummy::NoData>{noData}); } - //REQUIRE(pout.GetPID() == particles::Code::Electron); + // REQUIRE(pout.GetPID() == particles::Code::Electron); }