File indexing completed on 2026-09-07 09:32:33
0001 #include <JANA/JApplication.h>
0002 #include <JANA/JEventSource.h>
0003 #include <JANA/JEventUnfolder.h>
0004 #include <JANA/JEventProcessor.h>
0005
0006 #include <catch.hpp>
0007 #include <cstdio>
0008 #include <cstdlib>
0009 #include <vector>
0010
0011 namespace jana::integration_tests::hierarchical_ownership {
0012
0013 static constexpr uint64_t CANARY = 0xABCDEF0123456789ULL;
0014
0015 struct BlockData {
0016 std::vector<uint64_t> samples;
0017 uint64_t canary = CANARY;
0018 };
0019
0020 struct FrameRef {
0021 const BlockData* block;
0022 int frame_index;
0023 };
0024
0025 struct TimesliceSource : JEventSource {
0026 TimesliceSource() {
0027 SetLevel(JEventLevel::Timeslice);
0028 SetCallbackStyle(CallbackStyle::ExpertMode);
0029 }
0030 Result Emit(JEvent& event) override {
0031 auto* block = new BlockData;
0032 block->samples.assign(100000, event.GetEventNumber());
0033 event.Insert(block);
0034 return Result::Success;
0035 }
0036 };
0037
0038 struct FrameUnfolder : JEventUnfolder {
0039 FrameUnfolder() {
0040 SetParentLevel(JEventLevel::Timeslice);
0041 SetChildLevel(JEventLevel::PhysicsEvent);
0042 }
0043 Result Unfold(const JEvent& parent, JEvent& child, int child_idx) override {
0044 child.Insert(new FrameRef{parent.GetSingle<BlockData>(), child_idx});
0045
0046
0047 return child_idx == 2 ? Result::NextChildNextParent : Result::NextChildKeepParent;
0048 }
0049 };
0050
0051 struct FrameProcessor : JEventProcessor {
0052 FrameProcessor() { SetCallbackStyle(CallbackStyle::ExpertMode); }
0053 void ProcessSequential(const JEvent& event) override {
0054 const auto* ref = event.GetSingle<FrameRef>();
0055 REQUIRE(ref->block->canary == CANARY);
0056 }
0057 };
0058
0059 TEST_CASE("ParentEventOutlivesChildren") {
0060
0061 JApplication app;
0062 app.SetParameterValue("jana:nevents", 10);
0063 app.SetParameterValue("nthreads", 1);
0064 app.Add(new TimesliceSource);
0065 app.Add(new FrameUnfolder);
0066 app.Add(new FrameProcessor);
0067 app.Run();
0068 }
0069
0070 }