Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:41

0001 // Copyright 2024, Jefferson Science Associates, LLC.
0002 // Subject to the terms in the LICENSE file found in the top-level directory.
0003 
0004 #pragma once
0005 
0006 #include <JANA/Components/JComponent.h>
0007 #include <JANA/Components/JHasInputs.h>
0008 #include <JANA/Components/JHasOutputs.h>
0009 #include <JANA/Components/JHasRunCallbacks.h>
0010 #include <JANA/JEvent.h>
0011 
0012 class JApplication;
0013 class JEventUnfolder : public jana::components::JComponent, 
0014                        public jana::components::JHasRunCallbacks,
0015                        public jana::components::JHasInputs, 
0016                        public jana::components::JHasOutputs {
0017 
0018 private:
0019     int32_t m_last_run_number = -1;
0020     bool m_enable_simplified_callbacks = false;
0021     JEventLevel m_child_level;
0022     int m_child_number = 0;
0023     bool m_call_preprocess_upstream = true;
0024 
0025 
0026 public:
0027     // JEventUnfolder interface
0028     
0029     virtual ~JEventUnfolder() {};
0030  
0031     enum class Result { NextChildNextParent, NextChildKeepParent, KeepChildNextParent };
0032 
0033     virtual void Init() {};
0034     
0035     virtual void Preprocess(const JEvent& /*parent*/) const {};
0036 
0037     virtual Result Unfold(const JEvent& /*parent*/, JEvent& /*child*/, int /*item_nr*/) {
0038         throw JException("Not implemented yet!");
0039     };
0040 
0041     virtual Result Unfold(uint64_t /*parent_nr*/, uint64_t /*child_nr*/, int /*item_nr*/) {
0042         throw JException("Not implemented yet!");
0043     };
0044 
0045     virtual void Finish() {};
0046 
0047 
0048     // Configuration
0049 
0050     void SetParentLevel(JEventLevel level) { m_level = level; }
0051 
0052     void SetChildLevel(JEventLevel level) { m_child_level = level; }
0053 
0054     void SetCallPreprocessUpstream(bool call_upstream) { m_call_preprocess_upstream = call_upstream; }
0055     
0056     JEventLevel GetChildLevel() { return m_child_level; }
0057 
0058 
0059  public:
0060     // Backend
0061     
0062     void DoInit() {
0063         std::lock_guard<std::mutex> lock(m_mutex);
0064         // TODO: Obtain overrides of collection names from param manager
0065         
0066         for (auto* parameter : m_parameters) {
0067             parameter->Configure(*(m_app->GetJParameterManager()), m_prefix);
0068         }
0069         for (auto* service : m_services) {
0070             service->Fetch(m_app);
0071         }
0072         if (m_status == Status::Uninitialized) {
0073             CallWithJExceptionWrapper("JEventUnfolder::Init", [&](){
0074                 Init();
0075             });
0076             m_status = Status::Initialized;
0077         }
0078         else {
0079             throw JException("JEventUnfolder: Attempting to initialize twice or from an invalid state");
0080         }
0081     }
0082 
0083     void DoPreprocess(const JEvent& parent) {
0084         {
0085             std::lock_guard<std::mutex> lock(m_mutex);
0086             if (m_status != Status::Initialized) {
0087                 throw JException("JEventUnfolder: Component needs to be initialized and not finalized before Unfold can be called");
0088                 // TODO: Consider calling Initialize(with_lock=false) like we do elsewhere
0089             }
0090         }
0091         for (auto* input : m_inputs) {
0092             input->PrefetchCollection(parent);
0093         }
0094         if (m_callback_style != CallbackStyle::DeclarativeMode) {
0095             CallWithJExceptionWrapper("JEventUnfolder::Preprocess", [&](){
0096                 Preprocess(parent);
0097             });
0098         }
0099     }
0100 
0101     Result DoUnfold(const JEvent& parent, JEvent& child) {
0102         std::lock_guard<std::mutex> lock(m_mutex);
0103         if (m_status == Status::Initialized) {
0104             if (!m_call_preprocess_upstream) {
0105                 if (!m_enable_simplified_callbacks) {
0106                     CallWithJExceptionWrapper("JEventUnfolder::Preprocess", [&](){
0107                         Preprocess(parent);
0108                     });
0109                 }
0110             }
0111             if (m_last_run_number != parent.GetRunNumber()) {
0112                 for (auto* resource : m_resources) {
0113                     resource->ChangeRun(parent.GetRunNumber(), m_app);
0114                 }
0115                 if (m_callback_style == CallbackStyle::DeclarativeMode) {
0116                     CallWithJExceptionWrapper("JEventUnfolder::ChangeRun", [&](){
0117                         ChangeRun(parent.GetRunNumber());
0118                     });
0119                 }
0120                 else {
0121                     CallWithJExceptionWrapper("JEventUnfolder::ChangeRun", [&](){
0122                         ChangeRun(parent);
0123                     });
0124                 }
0125                 m_last_run_number = parent.GetRunNumber();
0126             }
0127             for (auto* input : m_inputs) {
0128                 input->GetCollection(parent);
0129                 // TODO: This requires that all inputs come from the parent.
0130                 //       However, eventually we will want to support inputs 
0131                 //       that come from the child.
0132             }
0133             for (auto* output : m_outputs) {
0134                 output->Reset();
0135             }
0136             Result result;
0137             child.SetEventIndex(m_child_number);
0138             if (m_enable_simplified_callbacks) {
0139                 CallWithJExceptionWrapper("JEventUnfolder::Unfold", [&](){
0140                     result = Unfold(parent.GetEventNumber(), child.GetEventNumber(), m_child_number);
0141                 });
0142             }
0143             else {
0144                 CallWithJExceptionWrapper("JEventUnfolder::Unfold", [&](){
0145                     result = Unfold(parent, child, m_child_number);
0146                 });
0147             }
0148             for (auto* output : m_outputs) {
0149                 output->InsertCollection(child);
0150             }
0151             m_child_number += 1;
0152             if (result == Result::NextChildNextParent || result == Result::KeepChildNextParent) {
0153                 m_child_number = 0;
0154             }
0155             return result;
0156         }
0157         else {
0158             throw JException("Component needs to be initialized and not finalized before Unfold can be called");
0159         }
0160     }
0161 
0162     void DoFinish() {
0163         std::lock_guard<std::mutex> lock(m_mutex);
0164         if (m_status != Status::Finalized) {
0165             CallWithJExceptionWrapper("JEventUnfolder::Finish", [&](){
0166                 Finish();
0167             });
0168             m_status = Status::Finalized;
0169         }
0170     }
0171 
0172     void Summarize(JComponentSummary& summary) const override {
0173         auto* us = new JComponentSummary::Component( 
0174             "Unfolder", GetPrefix(), GetTypeName(), GetLevel(), GetPluginName());
0175 
0176         for (const auto* input : m_inputs) {
0177             size_t subinput_count = input->names.size();
0178             for (size_t i=0; i<subinput_count; ++i) {
0179                 us->AddInput(new JComponentSummary::Collection("", input->names[i], input->type_name, input->levels[i]));
0180             }
0181         }
0182         for (const auto* output : m_outputs) {
0183             size_t suboutput_count = output->collection_names.size();
0184             for (size_t i=0; i<suboutput_count; ++i) {
0185                 us->AddOutput(new JComponentSummary::Collection("", output->collection_names[i], output->type_name, GetLevel()));
0186             }
0187         }
0188         summary.Add(us);
0189     }
0190 
0191 };
0192 
0193