Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /jana2/src/programs/unit_tests/Components/UnfoldTests.cc was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 
0002 #include <catch.hpp>
0003 #include <JANA/JEventProcessor.h>
0004 #include <JANA/Topology/JUnfoldArrow.h>
0005 #include <JANA/Topology/JFoldArrow.h>
0006 
0007 #if JANA2_HAVE_PODIO
0008 #include <PodioDatamodel/ExampleHitCollection.h>
0009 #endif
0010 
0011 namespace jana {
0012 namespace unfoldtests {
0013 
0014 
0015 struct TestUnfolder : public JEventUnfolder {
0016     mutable std::vector<int> preprocessed_event_nrs;
0017     mutable std::vector<JEventLevel> preprocessed_event_levels;
0018     std::vector<int> unfolded_parent_nrs;
0019     std::vector<JEventLevel> unfolded_parent_levels;
0020     std::vector<int> unfolded_child_nrs;
0021     std::vector<JEventLevel> unfolded_child_levels;
0022 
0023     TestUnfolder() {
0024         SetParentLevel(JEventLevel::Timeslice);
0025         SetChildLevel(JEventLevel::PhysicsEvent);
0026     }
0027 
0028     void Preprocess(const JEvent& parent) const override {
0029         LOG << "Preprocessing " << parent.GetLevel() << " event " << parent.GetEventNumber() << LOG_END;
0030         preprocessed_event_nrs.push_back(parent.GetEventNumber());
0031         preprocessed_event_levels.push_back(parent.GetLevel());
0032     }
0033 
0034     Result Unfold(const JEvent& parent, JEvent& child, int iter) override {
0035         auto child_nr = iter + 100 + parent.GetEventNumber();
0036         unfolded_parent_nrs.push_back(parent.GetEventNumber());
0037         unfolded_parent_levels.push_back(parent.GetLevel());
0038         unfolded_child_nrs.push_back(child_nr);
0039         unfolded_child_levels.push_back(child.GetLevel());
0040         child.SetEventNumber(child_nr);
0041         LOG << "Unfolding " << parent.GetLevel() << " event " << parent.GetEventNumber() << " into " << child.GetLevel() << " " << child_nr << "; iter=" << iter << LOG_END;
0042         return (iter == 2 ? Result::NextChildNextParent : Result::NextChildKeepParent);
0043     }
0044 };
0045 
0046 TEST_CASE("UnfoldTests_Basic") {
0047 
0048     JApplication app;
0049     app.Initialize();
0050     auto jcm = app.GetService<JComponentManager>();
0051 
0052     JEventPool parent_pool {jcm, 5, 1, JEventLevel::Timeslice};
0053     JEventPool child_pool {jcm, 5, 1, JEventLevel::PhysicsEvent};
0054     JEventQueue parent_queue {3, 1};
0055     JEventQueue child_queue {3, 1};
0056 
0057     auto ts1 = parent_pool.Pop(0);
0058     ts1->SetEventNumber(17);
0059 
0060     auto ts2 = parent_pool.Pop(0);
0061     ts2->SetEventNumber(28);
0062 
0063     parent_queue.Push(ts1, 0);
0064     parent_queue.Push(ts2, 0);
0065 
0066     TestUnfolder unfolder;
0067     JUnfoldArrow arrow("sut", &unfolder);
0068     arrow.attach(&parent_queue, JUnfoldArrow::PARENT_IN);
0069     arrow.attach(&child_pool, JUnfoldArrow::CHILD_IN);
0070     arrow.attach(&child_queue, JUnfoldArrow::CHILD_OUT);
0071 
0072     arrow.initialize();
0073     arrow.execute( 0); // First call to execute() picks up the parent and exits early
0074     auto result = arrow.execute( 0); // Second call to execute() picks up the child, calls Unfold(), and emits the newly parented child
0075     REQUIRE(result == JArrow::FireResult::KeepGoing);
0076     REQUIRE(child_queue.GetSize(0) == 1);
0077     REQUIRE(unfolder.preprocessed_event_nrs.size() == 0);
0078     REQUIRE(unfolder.unfolded_parent_nrs.size() == 1);
0079     REQUIRE(unfolder.unfolded_parent_nrs[0] == 17);
0080     REQUIRE(unfolder.unfolded_parent_levels[0] == JEventLevel::Timeslice);
0081     REQUIRE(unfolder.unfolded_child_nrs.size() == 1);
0082     REQUIRE(unfolder.unfolded_child_nrs[0] == 117);
0083     REQUIRE(unfolder.unfolded_child_levels[0] == JEventLevel::PhysicsEvent);
0084 
0085 }
0086 
0087 TEST_CASE("FoldArrowTests") {
0088 
0089     JApplication app;
0090     app.Initialize();
0091     auto jcm = app.GetService<JComponentManager>();
0092 
0093     // We only use these to obtain preconfigured JEvents
0094     JEventPool parent_pool {jcm, 5, 1, JEventLevel::Timeslice};
0095     JEventPool child_pool {jcm, 5, 1, JEventLevel::PhysicsEvent};
0096 
0097     // We set up our test cases by putting events on these queues
0098     JEventQueue child_in(5, 1);
0099     JEventQueue child_out(5, 1);
0100     JEventQueue parent_out(5, 1);
0101 
0102     JFoldArrow arrow("sut", JEventLevel::Timeslice, JEventLevel::PhysicsEvent);
0103     arrow.attach(&child_in, JFoldArrow::CHILD_IN);
0104     arrow.attach(&child_out, JFoldArrow::CHILD_OUT);
0105     arrow.attach(&parent_out, JFoldArrow::PARENT_OUT);
0106     arrow.initialize();
0107 
0108     SECTION("One-to-one relationship between timeslices and events") {
0109 
0110         auto ts1 = parent_pool.Pop(0);
0111         ts1->SetEventNumber(17);
0112         REQUIRE(ts1->GetLevel() == JEventLevel::Timeslice);
0113 
0114         auto ts2 = parent_pool.Pop(0);
0115         ts2->SetEventNumber(28);
0116 
0117         auto evt1 = child_pool.Pop(0);
0118         evt1->SetEventNumber(111);
0119 
0120         auto evt2 = child_pool.Pop(0);
0121         evt2->SetEventNumber(112);
0122 
0123 
0124         evt1->SetParent(ts1);
0125         ts1->Release(); // One-to-one
0126         child_in.Push(evt1, 0);
0127 
0128         evt2->SetParent(ts2);
0129         ts2->Release(); // One-to-one
0130         child_in.Push(evt2, 0);
0131     
0132         arrow.execute(0);
0133 
0134         REQUIRE(child_in.GetSize(0) == 1);
0135         REQUIRE(child_out.GetSize(0) == 1);
0136         REQUIRE(parent_out.GetSize(0) == 1);
0137 
0138     }
0139 
0140 
0141     SECTION("One-to-two relationship between timeslices and events") {
0142 
0143         auto ts1 = parent_pool.Pop(0);
0144         ts1->SetEventNumber(17);
0145         REQUIRE(ts1->GetLevel() == JEventLevel::Timeslice);
0146 
0147         auto ts2 = parent_pool.Pop(0);
0148         ts2->SetEventNumber(28);
0149 
0150         auto evt1 = child_pool.Pop(0);
0151         evt1->SetEventNumber(111);
0152 
0153         auto evt2 = child_pool.Pop(0);
0154         evt2->SetEventNumber(112);
0155 
0156         auto evt3 = child_pool.Pop(0);
0157         evt3->SetEventNumber(113);
0158 
0159         auto evt4 = child_pool.Pop(0);
0160         evt4->SetEventNumber(114);
0161 
0162 
0163         evt1->SetParent(ts1);
0164         evt2->SetParent(ts1);
0165         ts1->Release(); // One-to-two
0166         
0167         evt3->SetParent(ts2);
0168         evt4->SetParent(ts2);
0169         ts2->Release(); // One-to-two
0170    
0171         child_in.Push(evt1, 0);
0172         child_in.Push(evt2, 0);
0173         child_in.Push(evt3, 0);
0174         child_in.Push(evt4, 0);
0175 
0176         arrow.execute(0);
0177 
0178         REQUIRE(child_in.GetSize(0) == 3);
0179         REQUIRE(child_out.GetSize(0) == 1);
0180         REQUIRE(parent_out.GetSize(0) == 0);
0181 
0182         arrow.execute(0);
0183 
0184         REQUIRE(child_in.GetSize(0) == 2);
0185         REQUIRE(child_out.GetSize(0) == 2);
0186         REQUIRE(parent_out.GetSize(0) == 1);
0187 
0188         arrow.execute(0);
0189 
0190         REQUIRE(child_in.GetSize(0) == 1);
0191         REQUIRE(child_out.GetSize(0) == 3);
0192         REQUIRE(parent_out.GetSize(0) == 1);
0193 
0194         arrow.execute(0);
0195 
0196         REQUIRE(child_in.GetSize(0) == 0);
0197         REQUIRE(child_out.GetSize(0) == 4);
0198         REQUIRE(parent_out.GetSize(0) == 2);
0199     }
0200 
0201 
0202 }
0203 
0204 
0205 class NoOpUnfolder : public JEventUnfolder {
0206 #if JANA2_HAVE_PODIO
0207     PodioOutput<ExampleHit> m_hits_out {this}; 
0208     // We never insert these hits, and that should be fine 
0209     // because they should never get pushed to the frame
0210 #endif
0211 
0212 public:
0213     NoOpUnfolder() {
0214         SetParentLevel(JEventLevel::Timeslice);
0215         SetChildLevel(JEventLevel::PhysicsEvent);
0216     }
0217     Result Unfold(const JEvent&, JEvent&, int) {
0218         return Result::KeepChildNextParent;
0219     }
0220 };
0221 
0222 class PhysEvtProc : public JEventProcessor {
0223     int m_events_seen = 0;
0224 public:
0225     PhysEvtProc() {
0226         SetCallbackStyle(CallbackStyle::ExpertMode);
0227     }
0228     void ProcessSequential(const JEvent&) {
0229         m_events_seen += 1;
0230     }
0231     void Finish() {
0232         REQUIRE(m_events_seen == 0);
0233     }
0234 };
0235 
0236 class TimesliceProc : public JEventProcessor {
0237     int m_events_seen = 0;
0238 public:
0239     TimesliceProc() {
0240         SetLevel(JEventLevel::Timeslice);
0241         SetCallbackStyle(CallbackStyle::ExpertMode);
0242     }
0243     void ProcessSequential(const JEvent&) {
0244         m_events_seen += 1;
0245     }
0246     void Finish() {
0247         REQUIRE(m_events_seen == 10);
0248     }
0249 };
0250 
0251 TEST_CASE("NoOpUnfolder_Tests") {
0252     JApplication app;
0253     auto source = new JEventSource();
0254     source->SetLevel(JEventLevel::Timeslice);
0255     app.Add(source);
0256     app.Add(new NoOpUnfolder);
0257     app.Add(new PhysEvtProc);
0258     app.Add(new TimesliceProc);
0259     app.SetParameterValue("jana:nevents", 10);
0260     app.SetParameterValue("jana:loglevel", "debug");
0261     app.Run();
0262 }
0263 
0264 
0265 } // namespace arrowtests
0266 } // namespace jana
0267 
0268 
0269 
0270