Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:38

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         if (m_status != Status::Uninitialized) {
0065             throw JException("JEventUnfolder: Attempting to initialize twice or from an invalid state");
0066         }
0067         // TODO: Obtain overrides of collection names from param manager
0068         for (auto* parameter : m_parameters) {
0069             parameter->Configure(*(m_app->GetJParameterManager()), m_prefix);
0070         }
0071         for (auto* service : m_services) {
0072             service->Fetch(m_app);
0073         }
0074         CallWithJExceptionWrapper("JEventUnfolder::Init", [&](){Init();});
0075         m_status = Status::Initialized;
0076     }
0077 
0078     void DoPreprocess(const JEvent& parent) {
0079         {
0080             std::lock_guard<std::mutex> lock(m_mutex);
0081             if (m_status != Status::Initialized) {
0082                 throw JException("JEventUnfolder: Component needs to be initialized and not finalized before Unfold can be called");
0083                 // TODO: Consider calling Initialize(with_lock=false) like we do elsewhere
0084             }
0085         }
0086         for (auto* input : m_inputs) {
0087             input->PrefetchCollection(parent);
0088         }
0089         if (m_callback_style != CallbackStyle::DeclarativeMode) {
0090             CallWithJExceptionWrapper("JEventUnfolder::Preprocess", [&](){
0091                 Preprocess(parent);
0092             });
0093         }
0094     }
0095 
0096     Result DoUnfold(const JEvent& parent, JEvent& child) {
0097         std::lock_guard<std::mutex> lock(m_mutex);
0098         if (m_status == Status::Initialized) {
0099             if (!m_call_preprocess_upstream) {
0100                 if (!m_enable_simplified_callbacks) {
0101                     CallWithJExceptionWrapper("JEventUnfolder::Preprocess", [&](){
0102                         Preprocess(parent);
0103                     });
0104                 }
0105             }
0106             if (m_last_run_number != parent.GetRunNumber()) {
0107                 for (auto* resource : m_resources) {
0108                     resource->ChangeRun(parent.GetRunNumber(), m_app);
0109                 }
0110                 if (m_callback_style == CallbackStyle::DeclarativeMode) {
0111                     CallWithJExceptionWrapper("JEventUnfolder::ChangeRun", [&](){
0112                         ChangeRun(parent.GetRunNumber());
0113                     });
0114                 }
0115                 else {
0116                     CallWithJExceptionWrapper("JEventUnfolder::ChangeRun", [&](){
0117                         ChangeRun(parent);
0118                     });
0119                 }
0120                 m_last_run_number = parent.GetRunNumber();
0121             }
0122             for (auto* input : m_inputs) {
0123                 input->GetCollection(parent);
0124                 // TODO: This requires that all inputs come from the parent.
0125                 //       However, eventually we will want to support inputs 
0126                 //       that come from the child.
0127             }
0128             for (auto* output : m_outputs) {
0129                 output->Reset();
0130             }
0131             Result result;
0132             child.SetEventIndex(m_child_number);
0133             if (m_enable_simplified_callbacks) {
0134                 CallWithJExceptionWrapper("JEventUnfolder::Unfold", [&](){
0135                     result = Unfold(parent.GetEventNumber(), child.GetEventNumber(), m_child_number);
0136                 });
0137             }
0138             else {
0139                 CallWithJExceptionWrapper("JEventUnfolder::Unfold", [&](){
0140                     result = Unfold(parent, child, m_child_number);
0141                 });
0142             }
0143             for (auto* output : m_outputs) {
0144                 output->InsertCollection(child);
0145             }
0146             m_child_number += 1;
0147             if (result == Result::NextChildNextParent || result == Result::KeepChildNextParent) {
0148                 m_child_number = 0;
0149             }
0150             return result;
0151         }
0152         else {
0153             throw JException("Component needs to be initialized and not finalized before Unfold can be called");
0154         }
0155     }
0156 
0157     void DoFinish() {
0158         std::lock_guard<std::mutex> lock(m_mutex);
0159         if (m_status != Status::Finalized) {
0160             CallWithJExceptionWrapper("JEventUnfolder::Finish", [&](){
0161                 Finish();
0162             });
0163             m_status = Status::Finalized;
0164         }
0165     }
0166 
0167     void Summarize(JComponentSummary& summary) const override {
0168         auto* us = new JComponentSummary::Component( 
0169             "Unfolder", GetPrefix(), GetTypeName(), GetLevel(), GetPluginName());
0170 
0171         for (const auto* input : m_inputs) {
0172             size_t subinput_count = input->names.size();
0173             for (size_t i=0; i<subinput_count; ++i) {
0174                 us->AddInput(new JComponentSummary::Collection("", input->names[i], input->type_name, input->levels[i]));
0175             }
0176         }
0177         for (const auto* output : m_outputs) {
0178             size_t suboutput_count = output->collection_names.size();
0179             for (size_t i=0; i<suboutput_count; ++i) {
0180                 us->AddOutput(new JComponentSummary::Collection("", output->collection_names[i], output->type_name, GetLevel()));
0181             }
0182         }
0183         summary.Add(us);
0184     }
0185 
0186 };
0187 
0188