Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:41:12

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         SetEventLevels({JEventLevel::Run, JEventLevel::SlowControls, JEventLevel::PhysicsEvent});
0185 
0186         m_calibs_out.SetLevel(JEventLevel::Run);
0187         m_controls_out.SetLevel(JEventLevel::SlowControls);
0188         m_hits_out.SetLevel(JEventLevel::PhysicsEvent);
0189     }
0190 
0191     Result Emit(JEvent& event) override {
0192 
0193         if (data_stream_index >= data_stream.size()) {
0194             return Result::FailureFinished;
0195         }
0196 
0197         auto container_level = event.GetLevel();
0198         auto data_level = data_stream[data_stream_index].first;
0199 
0200         if (container_level != data_level) {
0201             SetNextEventLevel(data_level);
0202             return JEventSource::Result::FailureLevelChange;
0203         }
0204 
0205         if (data_level == JEventLevel::PhysicsEvent) {
0206             m_hits_out().push_back(new MyHits {data_stream[data_stream_index].second});
0207         }
0208         else if (data_level == JEventLevel::SlowControls) {
0209             m_controls_out().push_back(new MyControls {data_stream[data_stream_index].second});
0210         }
0211         else if (data_level == JEventLevel::Run) {
0212             m_calibs_out().push_back(new MyCalibs {data_stream[data_stream_index].second});
0213         }
0214 
0215         data_stream_index += 1;
0216         return Result::Success;
0217     }
0218 };
0219 
0220 struct MyMultilevelProcessor : public JEventProcessor {
0221 
0222     std::vector<std::tuple<int, int, int>> expected_data_stream;
0223     std::vector<std::tuple<int, int, int>> actual_data_stream;
0224 
0225     Input<MyCalibs> m_calibs_in {this};
0226     Input<MyControls> m_controls_in {this};
0227     Input<MyHits> m_hits_in {this};
0228 
0229     MyMultilevelProcessor() {
0230         SetCallbackStyle(CallbackStyle::ExpertMode);
0231         m_calibs_in.SetLevel(JEventLevel::Run);
0232         m_calibs_in.SetOptional(true);
0233 
0234         m_controls_in.SetLevel(JEventLevel::SlowControls);
0235         m_controls_in.SetOptional(true);
0236 
0237         m_hits_in.SetLevel(JEventLevel::PhysicsEvent);
0238         m_hits_in.SetOptional(true);
0239     }
0240 
0241     void ProcessSequential(const JEvent&) override {
0242 
0243         int calib = m_calibs_in->size() == 0 ? -1 : m_calibs_in->at(0)->x;
0244         int control = m_controls_in->size() == 0 ? -1 : m_controls_in->at(0)->x;
0245         int hit = m_hits_in->size() == 0 ? -1 : m_hits_in->at(0)->x;
0246 
0247         actual_data_stream.push_back({calib, control, hit});
0248     }
0249 
0250     void Finish() override {
0251         REQUIRE(expected_data_stream == actual_data_stream);
0252     }
0253 
0254 };
0255 
0256 
0257 } //namespace multilevel_source_tests
0258 } // namespace jana