Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-09 08:41:43

0001 #pragma once
0002 #include <JANA/JApplication.h>
0003 #include <JANA/JObject.h>
0004 #include <JANA/JEventSource.h>
0005 #include <JANA/JEventUnfolder.h>
0006 #include <JANA/JEventProcessor.h>
0007 #include <catch.hpp>
0008 
0009 namespace jana {
0010 namespace timeslice_tests {
0011 
0012 
0013 struct MyHit : public JObject {
0014     int hit_id;
0015     int energy, x, y;
0016 };
0017 
0018 struct MyCluster : public JObject {
0019     int cluster_id;
0020     int energy, x, y;
0021     std::vector<int> hits;
0022 };
0023 
0024 
0025 struct MyTimesliceSource : public JEventSource {
0026 
0027     MyTimesliceSource() { 
0028         SetLevel(JEventLevel::Timeslice);
0029     }
0030 
0031     void Open() override { }
0032 
0033     void GetEvent(std::shared_ptr<JEvent> event) override {
0034         // TODO: Insert something
0035         LOG_INFO(GetLogger()) << "MyTimesliceSource: Emitting " << event->GetEventNumber() << LOG_END;
0036     }
0037 };
0038 
0039 
0040 struct MyTimesliceUnfolder : public JEventUnfolder {
0041 
0042     std::atomic_int init_called_count {0};
0043     mutable std::atomic_int preprocess_called_count {0};
0044     std::atomic_int unfold_called_count {0};
0045     std::atomic_int finish_called_count {0};
0046 
0047     MyTimesliceUnfolder() {
0048         SetParentLevel(JEventLevel::Timeslice);
0049         SetChildLevel(JEventLevel::PhysicsEvent);
0050     }
0051 
0052     virtual void Init() {
0053         init_called_count++;
0054     };
0055 
0056     virtual void Preprocess(const JEvent& /*parent*/) const {
0057         preprocess_called_count++;
0058         // TODO: Are we going to need an omni unfolder?
0059         // TODO: Call protocluster factory
0060     };
0061 
0062     virtual Result Unfold(const JEvent& parent, JEvent& child, int item) {
0063         child.SetEventNumber(parent.GetEventNumber()*10 + item);
0064         LOG << "Unfolding parent=" << parent.GetEventNumber() << ", child=" << child.GetEventNumber() << ", item=" << item << LOG_END;
0065         unfold_called_count++;
0066         // TODO: 
0067 
0068         if (item == 3) {
0069             LOG_INFO(GetLogger()) << "Unfold found item 3, finishing join" << LOG_END;
0070             // TODO: Insert protocluster into child
0071             return Result::NextChildNextParent;
0072         }
0073         return Result::NextChildKeepParent;
0074     }
0075 
0076     virtual void Finish() {
0077         finish_called_count++;
0078     };
0079 
0080 };
0081 
0082 struct MyEventProcessor : public JEventProcessor {
0083 
0084     std::atomic_int init_called_count {0};
0085     std::atomic_int process_called_count {0};
0086     std::atomic_int finish_called_count {0};
0087 
0088     MyEventProcessor() {
0089         SetCallbackStyle(CallbackStyle::ExpertMode);
0090     }
0091 
0092     void Init() override {
0093         init_called_count++;
0094     }
0095 
0096     void ProcessSequential(const JEvent& event) override {
0097         process_called_count++;
0098         LOG_INFO(GetLogger()) << "MyEventProcessor: Processing " << event.GetEventNumber() << LOG_END;
0099         auto clusters = event.Get<MyCluster>("evt");
0100         // TODO: Validate that the clusters make sense
0101         REQUIRE(init_called_count == 1);
0102         REQUIRE(finish_called_count == 0);
0103     }
0104 
0105     void Finish() override {
0106         finish_called_count += 1;
0107     }
0108 
0109 };
0110 
0111 
0112 struct MyProtoClusterFactory : public JFactoryT<MyCluster> {
0113 
0114     int init_call_count = 0;
0115     int change_run_call_count = 0;
0116     int process_call_count = 0;
0117 
0118     MyProtoClusterFactory() {
0119         SetLevel(JEventLevel::Timeslice);
0120         SetTag("ts");
0121     }
0122 
0123     void Init() override {
0124         ++init_call_count;
0125     }
0126 
0127     void ChangeRun(const std::shared_ptr<const JEvent>&) override {
0128         ++change_run_call_count;
0129     }
0130 
0131     void Process(const std::shared_ptr<const JEvent>&) override {
0132         ++process_call_count;
0133         Insert(new MyCluster);
0134         // TODO: Obtain timeslice-level hits
0135     }
0136 };
0137 
0138 
0139 struct MyClusterFactory : public JFactoryT<MyCluster> {
0140 
0141     int init_call_count = 0;
0142     int change_run_call_count = 0;
0143     int process_call_count = 0;
0144 
0145     MyClusterFactory() {
0146         SetLevel(JEventLevel::PhysicsEvent);
0147         SetTag("evt");
0148     }
0149 
0150     void Init() override {
0151         ++init_call_count;
0152     }
0153 
0154     void ChangeRun(const std::shared_ptr<const JEvent>&) override {
0155         ++change_run_call_count;
0156     }
0157 
0158     void Process(const std::shared_ptr<const JEvent>&) override {
0159         ++process_call_count;
0160         Insert(new MyCluster);
0161         // TODO: Obtain timeslice-level protoclusters
0162     }
0163 };
0164 
0165 } // namespace timeslice_tests
0166 
0167 namespace multilevel_source_tests {
0168 
0169 struct MyCalibs {int x=0; };
0170 struct MyControls {int x=0; };
0171 struct MyHits {int x=0; };
0172 
0173 struct MyMultilevelSource : public JEventSource {
0174 
0175     std::vector<std::pair<JEventLevel, int>> data_stream;
0176     size_t data_stream_index = 0;
0177 
0178     Output<MyCalibs> m_calibs_out {this};
0179     Output<MyControls> m_controls_out {this};
0180     Output<MyHits> m_hits_out {this};
0181 
0182     MyMultilevelSource() {
0183         SetCallbackStyle(CallbackStyle::ExpertMode);
0184         SetParentLevels({JEventLevel::Run, JEventLevel::SlowControls});
0185         SetLevel(JEventLevel::PhysicsEvent);
0186 
0187         m_calibs_out.SetLevel(JEventLevel::Run);
0188         m_controls_out.SetLevel(JEventLevel::SlowControls);
0189         m_hits_out.SetLevel(JEventLevel::PhysicsEvent);
0190     }
0191 
0192     Result Emit(JEvent& event) override {
0193 
0194         if (data_stream_index >= data_stream.size()) {
0195             return Result::FailureFinished;
0196         }
0197 
0198         auto container_level = event.GetLevel();
0199         auto data_level = data_stream[data_stream_index].first;
0200 
0201         if (container_level != data_level) {
0202             SetNextEventLevel(data_level);
0203             return JEventSource::Result::FailureLevelChange;
0204         }
0205 
0206         if (data_level == JEventLevel::PhysicsEvent) {
0207             m_hits_out().push_back(new MyHits {data_stream[data_stream_index].second});
0208         }
0209         else if (data_level == JEventLevel::SlowControls) {
0210             m_controls_out().push_back(new MyControls {data_stream[data_stream_index].second});
0211         }
0212         else if (data_level == JEventLevel::Run) {
0213             m_calibs_out().push_back(new MyCalibs {data_stream[data_stream_index].second});
0214         }
0215 
0216         data_stream_index += 1;
0217         return Result::Success;
0218     }
0219 };
0220 
0221 struct MyMultilevelProcessor : public JEventProcessor {
0222 
0223     std::vector<std::tuple<int, int, int>> expected_data_stream;
0224     std::vector<std::tuple<int, int, int>> actual_data_stream;
0225 
0226     Input<MyCalibs> m_calibs_in {this};
0227     Input<MyControls> m_controls_in {this};
0228     Input<MyHits> m_hits_in {this};
0229 
0230     MyMultilevelProcessor() {
0231         SetCallbackStyle(CallbackStyle::ExpertMode);
0232         m_calibs_in.SetLevel(JEventLevel::Run);
0233         m_calibs_in.SetOptional(true);
0234 
0235         m_controls_in.SetLevel(JEventLevel::SlowControls);
0236         m_controls_in.SetOptional(true);
0237 
0238         m_hits_in.SetLevel(JEventLevel::PhysicsEvent);
0239         m_hits_in.SetOptional(true);
0240     }
0241 
0242     void ProcessSequential(const JEvent&) override {
0243 
0244         int calib = m_calibs_in->size() == 0 ? -1 : m_calibs_in->at(0)->x;
0245         int control = m_controls_in->size() == 0 ? -1 : m_controls_in->at(0)->x;
0246         int hit = m_hits_in->size() == 0 ? -1 : m_hits_in->at(0)->x;
0247 
0248         actual_data_stream.push_back({calib, control, hit});
0249     }
0250 
0251     void Finish() override {
0252         REQUIRE(expected_data_stream == actual_data_stream);
0253     }
0254 
0255 };
0256 
0257 
0258 } //namespace multilevel_source_tests
0259 } // namespace jana