Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-03 10:10:20

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     JEventUnfolder() {
0030         m_type_name = "JEventUnfolder";
0031     }
0032 
0033     virtual ~JEventUnfolder() {};
0034  
0035     enum class Result { NextChildNextParent, NextChildKeepParent, KeepChildNextParent };
0036 
0037     virtual void Preprocess(const JEvent& /*parent*/) const {};
0038 
0039     virtual Result Unfold(const JEvent& /*parent*/, JEvent& /*child*/, int /*item_nr*/) {
0040         throw JException("Not implemented yet!");
0041     };
0042 
0043     virtual Result Unfold(uint64_t /*parent_nr*/, uint64_t /*child_nr*/, int /*item_nr*/) {
0044         throw JException("Not implemented yet!");
0045     };
0046 
0047     virtual void Finish() {};
0048 
0049 
0050     // Configuration
0051 
0052     void SetParentLevel(JEventLevel level) { m_level = level; }
0053 
0054     void SetChildLevel(JEventLevel level) { m_child_level = level; }
0055 
0056     void SetCallPreprocessUpstream(bool call_upstream) { m_call_preprocess_upstream = call_upstream; }
0057     
0058     JEventLevel GetChildLevel() { return m_child_level; }
0059 
0060 
0061  public:
0062     // Backend
0063 
0064     void DoPreprocess(const JEvent& parent) {
0065         {
0066             std::lock_guard<std::mutex> lock(m_mutex);
0067             if (!m_is_initialized) {
0068                 throw JException("JEventUnfolder: Component needs to be initialized and not finalized before Unfold can be called");
0069             }
0070         }
0071         for (auto* input : m_inputs) {
0072             input->TriggerFactoryCreate(parent);
0073         }
0074         for (auto* variadic_input : m_variadic_inputs) {
0075             variadic_input->TriggerFactoryCreate(parent);
0076         }
0077         CallWithJExceptionWrapper("JEventUnfolder::Preprocess", [&](){
0078             Preprocess(parent);
0079         });
0080     }
0081 
0082     Result DoUnfold(const JEvent& parent, JEvent& child) {
0083         std::lock_guard<std::mutex> lock(m_mutex);
0084         if (m_is_initialized) {
0085             if (!m_call_preprocess_upstream) {
0086                 if (!m_enable_simplified_callbacks) {
0087                     CallWithJExceptionWrapper("JEventUnfolder::Preprocess", [&](){
0088                         Preprocess(parent);
0089                     });
0090                 }
0091             }
0092             if (m_last_run_number != parent.GetRunNumber()) {
0093                 for (auto* resource : m_resources) {
0094                     resource->ChangeRun(parent.GetRunNumber(), m_app);
0095                 }
0096                 CallWithJExceptionWrapper("JEventUnfolder::ChangeRun", [&](){
0097                     ChangeRun(parent);
0098                 });
0099                 m_last_run_number = parent.GetRunNumber();
0100             }
0101             for (auto* input : m_inputs) {
0102                 input->Populate(parent);
0103                 // TODO: This requires that all inputs come from the parent.
0104                 //       However, eventually we will want to support inputs 
0105                 //       that come from the child.
0106             }
0107             for (auto* variadic_input : m_variadic_inputs) {
0108                 variadic_input->Populate(parent);
0109             }
0110             Result result;
0111             child.SetEventIndex(m_child_number);
0112             if (m_enable_simplified_callbacks) {
0113                 CallWithJExceptionWrapper("JEventUnfolder::Unfold", [&](){
0114                     result = Unfold(parent.GetEventNumber(), child.GetEventNumber(), m_child_number);
0115                 });
0116             }
0117             else {
0118                 CallWithJExceptionWrapper("JEventUnfolder::Unfold", [&](){
0119                     result = Unfold(parent, child, m_child_number);
0120                 });
0121             }
0122             if (result != Result::KeepChildNextParent) {
0123                 // If the user returns KeepChildNextParent, JANA cannot publish any output databundles (not even empty ones)
0124                 // because on the next call to Unfold(), podio will throw an exception about inserting the collection twice.
0125                 // Any data put in an output databundle will be automatically cleared via OutputBase::Reset() before the next Unfold().
0126                 for (auto* output : GetOutputs()) {
0127                     output->EulerianStore(*child.GetFactorySet());
0128                 }
0129                 for (auto* output : GetVariadicOutputs()) {
0130                     output->EulerianStore(*child.GetFactorySet());
0131                 }
0132             }
0133             m_child_number += 1;
0134             if (result == Result::NextChildNextParent || result == Result::KeepChildNextParent) {
0135                 m_child_number = 0;
0136             }
0137             return result;
0138         }
0139         else {
0140             throw JException("Component needs to be initialized and not finalized before Unfold can be called");
0141         }
0142     }
0143 
0144     void DoFinish() {
0145         std::lock_guard<std::mutex> lock(m_mutex);
0146         if (!m_is_finalized) {
0147             CallWithJExceptionWrapper("JEventUnfolder::Finish", [&](){
0148                 Finish();
0149             });
0150             m_is_finalized = true;
0151         }
0152     }
0153 
0154     void Summarize(JComponentSummary& summary) const override {
0155         auto* us = new JComponentSummary::Component( 
0156             "Unfolder", GetPrefix(), GetTypeName(), GetLevel(), GetPluginName());
0157 
0158         SummarizeInputs(*us);
0159         SummarizeOutputs(*us);
0160         summary.Add(us);
0161     }
0162 
0163 };
0164 
0165