Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-22 09:13:33

0001 // Copyright 2023, 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/JEventFolder.h>
0007 #include <JANA/Topology/JArrow.h>
0008 
0009 class JFoldArrow : public JArrow {
0010 public:
0011     enum PortIndex {CHILD_IN=0, CHILD_OUT=1, PARENT_OUT=2};
0012 
0013 private:
0014     JEventFolder* m_folder = nullptr;
0015 
0016     JEventLevel m_parent_level;
0017     JEventLevel m_child_level;
0018 
0019 public:
0020     JFoldArrow(
0021         std::string name,
0022         JEventLevel parent_level,
0023         JEventLevel child_level)
0024 
0025       : m_parent_level(parent_level),
0026         m_child_level(child_level)
0027     {
0028         SetName(name);
0029         AddPort("child_in", child_level, PortDirection::In).SetEnforcesOrdering(true);
0030         AddPort("child_out", child_level, PortDirection::Out);
0031         AddPort("parent_out", parent_level, PortDirection::Out);
0032         m_next_input_port = CHILD_IN;
0033     }
0034 
0035     void SetFolder(JEventFolder* folder) {
0036         m_folder = folder;
0037     }
0038 
0039     void Initialize() final {
0040         if (m_folder != nullptr) {
0041             m_folder->DoInit();
0042             LOG_INFO(m_logger) << "Initialized JEventFolder '" << m_folder->GetTypeName() << "'" << LOG_END;
0043         }
0044         else {
0045             LOG_INFO(m_logger) << "Initialized JEventFolder (trivial)" << LOG_END;
0046         }
0047     }
0048 
0049     void Finalize() final {
0050         if (m_folder != nullptr) {
0051             m_folder->DoFinish();
0052             LOG_INFO(m_logger) << "Finalized JEventFolder '" << m_folder->GetTypeName() << "'" << LOG_END;
0053         }
0054         else {
0055             LOG_INFO(m_logger) << "Finalized JEventFolder (trivial)" << LOG_END;
0056         }
0057     }
0058 
0059     void Fire(JEvent* event, OutputData& outputs, size_t& output_count, JArrow::FireResult& status) final {
0060 
0061         assert(m_next_input_port == CHILD_IN);
0062 
0063         // Check that child is at the correct event level
0064         if (event->GetLevel() != m_child_level) {
0065             throw JException("JFoldArrow received a child with the wrong event level");
0066         }
0067 
0068         if (m_folder != nullptr) {
0069             auto parent = const_cast<JEvent*>(&event->GetParent(m_parent_level));
0070             m_folder->DoFold(*event, *parent);
0071         }
0072 
0073         status = JArrow::FireResult::KeepGoing;
0074         outputs[0] = {event, CHILD_OUT};
0075         output_count = 1;
0076 
0077         auto* released_parent = event->ReleaseParent(m_parent_level);
0078         if (released_parent != nullptr) {
0079             // JEvent::ReleaseParent() returns nullptr if there are remaining references
0080             // to the parent event. If non-null, we are completely done with the parent
0081             // and are free to return it to the pool. In the future we could have the pool
0082             // itself handle the logic for releasing parents, in which case we could avoid
0083             // trivial JEventFolders.
0084 
0085             outputs[1] = {released_parent, PARENT_OUT};
0086             output_count = 2;
0087         }
0088     }
0089 
0090 };
0091 
0092