From a7738b9ce57feba6c227fbaa2e82a91cb220d3cf Mon Sep 17 00:00:00 2001 From: ralfulrich <ralf.ulrich@kit.edu> Date: Sat, 19 Sep 2020 01:50:04 +0200 Subject: [PATCH] make first almost real version of history work --- Setup/CMakeLists.txt | 2 +- Setup/SetupStack.h | 3 +- Stack/History/CMakeLists.txt | 10 +- Stack/History/Event.hpp | 21 +++- Stack/History/HSecondaryView.hpp | 41 +++---- Stack/History/HistoryStackExtension.h | 2 +- .../{testHistory.cc => testHistoryStack.cc} | 31 ++--- Stack/History/testHistoryView.cc | 106 ++++++++++++++++++ 8 files changed, 174 insertions(+), 42 deletions(-) rename Stack/History/{testHistory.cc => testHistoryStack.cc} (69%) create mode 100644 Stack/History/testHistoryView.cc diff --git a/Setup/CMakeLists.txt b/Setup/CMakeLists.txt index e198d90cd..f8490cc2f 100644 --- a/Setup/CMakeLists.txt +++ b/Setup/CMakeLists.txt @@ -20,7 +20,7 @@ target_link_libraries ( CORSIKAgeometry NuclearStackExtension GeometryNodeStackExtension - # CORSIKAhistory + CORSIKAhistory ) target_include_directories ( diff --git a/Setup/SetupStack.h b/Setup/SetupStack.h index aeef45dce..5c22321b0 100644 --- a/Setup/SetupStack.h +++ b/Setup/SetupStack.h @@ -8,10 +8,10 @@ #pragma once +#include <corsika/history/HistoryStackExtension.h> #include <corsika/stack/CombinedStack.h> #include <corsika/stack/node/GeometryNodeStackExtension.h> #include <corsika/stack/nuclear_extension/NuclearStackExtension.h> -#include <corsika/history/HistoryStackExtension.h> #include <corsika/setup/SetupEnvironment.h> @@ -33,7 +33,6 @@ namespace corsika::setup { ...event... >::type; */ - // combine particle data stack with geometry information for tracking template <typename TStackIter> using StackWithGeometryInterface = corsika::stack::CombinedParticleInterface< diff --git a/Stack/History/CMakeLists.txt b/Stack/History/CMakeLists.txt index 63b6b602c..d2ca77365 100644 --- a/Stack/History/CMakeLists.txt +++ b/Stack/History/CMakeLists.txt @@ -37,9 +37,15 @@ install ( # ---------------- # code unit testing -CORSIKA_ADD_TEST(testHistory) +CORSIKA_ADD_TEST(testHistoryStack) target_link_libraries ( - testHistory + testHistoryStack + CORSIKAhistory + CORSIKAtesting + ) +CORSIKA_ADD_TEST(testHistoryView) +target_link_libraries ( + testHistoryView CORSIKAhistory CORSIKAtesting ) diff --git a/Stack/History/Event.hpp b/Stack/History/Event.hpp index ebb5d3a2a..be8d72d4e 100644 --- a/Stack/History/Event.hpp +++ b/Stack/History/Event.hpp @@ -14,22 +14,35 @@ #include <iostream> #include <optional> #include <vector> +#include <memory> namespace corsika::history { struct Event { size_t const projectileIndex_; //!< reference to projectile - std::vector<SecondaryParticle> secondaries; - + std::vector<SecondaryParticle> secondaries_; + //std::shared_ptr<Event> parent_event_; + // meta information, could also be in a separate class std::optional<corsika::particles::Code> - targetCode; // cannot be const, value set only after construction + targetCode_; // cannot be const, value set only after construction public: - Event(size_t projectileIndex) + Event(const size_t projectileIndex) : projectileIndex_{projectileIndex} { std::cout << "Event created (index = " << projectileIndex_ << ")" << std::endl; } + + void addSecondary(units::si::HEPEnergyType energy, + geometry::Vector<units::si::hepmomentum_d> momentum, + particles::Code pid) { + secondaries_.emplace_back(energy, momentum, pid); + } + + void setTargetCode(const particles::Code t) { targetCode_=t; } + }; + using EvtPtr = std::shared_ptr<history::Event>; + } // namespace corsika::history diff --git a/Stack/History/HSecondaryView.hpp b/Stack/History/HSecondaryView.hpp index 1abf8cf6b..4552cc2df 100644 --- a/Stack/History/HSecondaryView.hpp +++ b/Stack/History/HSecondaryView.hpp @@ -17,32 +17,35 @@ 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> { + template <typename TView> + class HSecondaryView : public TView { + std::shared_ptr<Event> event_; - - using BaseSecondaryViewType = - detail::SecondaryViewTypeFromIterator<TParticleIterator>; - + + using StackIterator = typename TView::StackIteratorValue; + public: - HSecondaryView(TParticleIterator& p) - : BaseSecondaryViewType{p} - , event_{std::make_shared<Event>(p.GetIndex())} {} + HSecondaryView(StackIterator& p) + : TView(p), + event_{std::make_shared<Event>(p.GetIndex())} { + p.SetEvent(event_); // here an entry on the main particle stack obtains its Event + // RU: what seems to missing to me right now, at 2am..., is the + // actual back reference to the parent event. This needs to be added. + } 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()); + auto s = TView::AddSecondary( + std::forward<Args...>(args...)); + // store particles at production time here + // RU: consider if we can call + // TView::AddSecondary twice instead: 1. for particle at production time + // , 2. dynamic particle ... not sure, but would be extremely flexible. + event_->addSecondary(s.GetEnergy(), s.GetMomentum(), s.GetPID()); } - void SetTarget(particles::Code targetCode) { event_->targetCode = targetCode; } + // it is probably better to have one method "GetEvent()" and then one can always call GetEvent().set/getWhatever(...) + void SetTarget(const particles::Code targetCode) { event_->setTargetCode(targetCode); } }; } // namespace corsika::history diff --git a/Stack/History/HistoryStackExtension.h b/Stack/History/HistoryStackExtension.h index 58de264c1..294a53780 100644 --- a/Stack/History/HistoryStackExtension.h +++ b/Stack/History/HistoryStackExtension.h @@ -72,7 +72,7 @@ namespace corsika::history { void SetParticleData() {} // nullptr, already by design // create a new particle as secondary of a parent - void SetParticleData(HistoryDataInterface& parent) { SetParticleData(); } + void SetParticleData(HistoryDataInterface& /*parent*/) { SetParticleData(); } void SetEvent(const std::shared_ptr<TEvent>& v) { GetStackData().SetEvent(GetIndex(), v); diff --git a/Stack/History/testHistory.cc b/Stack/History/testHistoryStack.cc similarity index 69% rename from Stack/History/testHistory.cc rename to Stack/History/testHistoryStack.cc index ebc201ebe..fcb9934e4 100644 --- a/Stack/History/testHistory.cc +++ b/Stack/History/testHistoryStack.cc @@ -9,8 +9,6 @@ #include <corsika/history/HistoryStackExtension.h> #include <corsika/stack/CombinedStack.h> #include <corsika/stack/dummy/DummyStack.h> -#include <corsika/history/Event.hpp> -#include <corsika/history/HSecondaryView.hpp> #include <catch2/catch.hpp> @@ -19,10 +17,25 @@ using namespace corsika; using namespace corsika::stack; +// this is our dummy environment, it only knows its trivial BaseNodeType +class DummyEvent { +private: + size_t parent_; + std::vector<int> secondaries_; + +public: + DummyEvent() {} + DummyEvent(const size_t parent) { parent_ = parent; } + + size_t getParentIndex() { return parent_; } + void addSecondary(const int particle) { secondaries_.push_back(particle); } + int multiplicity() const { return secondaries_.size(); } +}; + // the GeometryNode stack needs to know the type of geometry-nodes from the DummyEnv: template <typename TStackIter> using DummyHistoryDataInterface = - typename history::MakeHistoryDataInterface<TStackIter, history::Event>::type; + typename history::MakeHistoryDataInterface<TStackIter, DummyEvent>::type; // combine dummy stack with geometry information for tracking template <typename TStackIter> @@ -32,10 +45,10 @@ using StackWithHistoryInterface = using TestStack = corsika::stack::CombinedStack<typename stack::dummy::DummyStack::StackImpl, - history::HistoryData<history::Event>, + history::HistoryData<DummyEvent>, StackWithHistoryInterface>; -using EvtPtr = std::shared_ptr<history::Event>; +using EvtPtr = std::shared_ptr<DummyEvent>; TEST_CASE("HistoryStackExtension", "[stack]") { @@ -50,12 +63,4 @@ TEST_CASE("HistoryStackExtension", "[stack]") { EvtPtr evt = p.GetEvent(); CHECK(evt == nullptr); } - - SECTION("write event") { - history::HSecondaryView hview{p}; - - hview.AddSecondary(std::tuple<dummy::NoData>{noData}); - } - - // REQUIRE(pout.GetPID() == particles::Code::Electron); } diff --git a/Stack/History/testHistoryView.cc b/Stack/History/testHistoryView.cc new file mode 100644 index 000000000..673921696 --- /dev/null +++ b/Stack/History/testHistoryView.cc @@ -0,0 +1,106 @@ +/* + * (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. + */ + +#include <corsika/history/HistoryStackExtension.h> +#include <corsika/history/Event.hpp> +#include <corsika/history/HSecondaryView.hpp> + +#include <corsika/stack/CombinedStack.h> +#include <corsika/stack/dummy/DummyStack.h> +#include <corsika/stack/nuclear_extension/NuclearStackExtension.h> + +#include <catch2/catch.hpp> + +#include <iostream> + +using namespace corsika; +using namespace corsika::stack; +using namespace corsika::geometry; +using namespace corsika::units::si; + +/** + Need to replicate setup::SetupStack in a maximally simplified + way, but with real particle data + */ + +// the GeometryNode stack needs to know the type of geometry-nodes from the DummyEnv: +template <typename TStackIter> +using HistoryDataInterface = + typename history::MakeHistoryDataInterface<TStackIter, history::Event>::type; + +// combine dummy stack with geometry information for tracking +template <typename TStackIter> +using StackWithHistoryInterface = corsika::stack::CombinedParticleInterface< + stack::nuclear_extension::ParticleDataStack::PIType, HistoryDataInterface, + TStackIter>; + +using TestStack = corsika::stack::CombinedStack< + typename stack::nuclear_extension::ParticleDataStack::StackImpl, + history::HistoryData<history::Event>, StackWithHistoryInterface>; + +/* + See Issue 161 + + unfortunately clang does not support this in the same way (yet) as + gcc, so we have to distinguish here. If clang cataches up, we + could remove the clang branch here and also in + corsika::Cascade. The gcc code is much more generic and + universal. If we could do the gcc version, we won't had to define + StackView globally, we could do it with MakeView whereever it is + actually needed. Keep an eye on this! + */ +#if defined(__clang__) +using TestStackView = corsika::stack::SecondaryView<typename TestStack::StackImpl, + StackWithHistoryInterface>; +#elif defined(__GNUC__) || defined(__GNUG__) +using TestStackView = corsika::stack::MakeView<TestStack>::type; +#endif + +TEST_CASE("HistoryStackExtension", "[stack]") { + + geometry::CoordinateSystem& dummyCS = + geometry::RootCoordinateSystem::GetInstance().GetRootCoordinateSystem(); + + TestStack s; + + SECTION("add lone particle") { + + auto p = s.AddParticle( + std::tuple<particles::Code, units::si::HEPEnergyType, + corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ + particles::Code::Electron, 1.5_GeV, + corsika::stack::MomentumVector(dummyCS, {1_GeV, 1_GeV, 1_GeV}), + Point(dummyCS, {1 * meter, 1 * meter, 1 * meter}), 100_s}); + + CHECK(s.GetSize() == 1); + corsika::history::EvtPtr evt = p.GetEvent(); + CHECK(evt == nullptr); + } + + SECTION("generate event") { + auto p = s.AddParticle( + std::tuple<particles::Code, units::si::HEPEnergyType, + corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ + particles::Code::Electron, 1.5_GeV, + corsika::stack::MomentumVector(dummyCS, {1_GeV, 1_GeV, 1_GeV}), + Point(dummyCS, {1 * meter, 1 * meter, 1 * meter}), 100_s}); + + history::HSecondaryView<TestStackView> hview(p); + + hview.AddSecondary( + std::tuple<particles::Code, units::si::HEPEnergyType, + corsika::stack::MomentumVector, geometry::Point, units::si::TimeType>{ + particles::Code::Electron, 1.5_GeV, + corsika::stack::MomentumVector(dummyCS, {1_GeV, 1_GeV, 1_GeV}), + Point(dummyCS, {1 * meter, 1 * meter, 1 * meter}), 100_s}); + + // ... continue actual real test here an below ... + } + + // REQUIRE(pout.GetPID() == particles::Code::Electron); +} -- GitLab