Back to home page

EIC code displayed by LXR

 
 

    


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

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/Topology/JArrow.h>
0007 #include <JANA/JEventUnfolder.h>
0008 
0009 class JUnfoldArrow : public JArrow {
0010 public:
0011     enum PortIndex {PARENT_IN=0, CHILD_IN=1, CHILD_OUT=2};
0012 
0013 private:
0014     JEventUnfolder* m_unfolder = nullptr;
0015     JEvent* m_parent_event = nullptr;
0016     JEvent* m_child_event = nullptr;
0017 
0018 public:
0019     JUnfoldArrow(std::string name, JEventUnfolder* unfolder) : m_unfolder(unfolder) {
0020         set_name(name);
0021         create_ports(2, 1);
0022         m_next_input_port = PARENT_IN;
0023     }
0024 
0025     void initialize() final {
0026         m_unfolder->DoInit();
0027         LOG_INFO(m_logger) << "Initialized JEventUnfolder '" << m_unfolder->GetTypeName() << "'" << LOG_END;
0028     }
0029 
0030     void finalize() final {
0031         m_unfolder->DoFinish();
0032         LOG_INFO(m_logger) << "Finalized JEventUnfolder '" << m_unfolder->GetTypeName() << "'" << LOG_END;
0033     }
0034 
0035     void fire(JEvent* event, OutputData& outputs, size_t& output_count, JArrow::FireResult& status) final {
0036 
0037         // Take whatever we were given
0038         if (this->m_next_input_port == PARENT_IN) {
0039             assert(m_parent_event == nullptr);
0040             m_parent_event = event;
0041         }
0042         else if (this->m_next_input_port == CHILD_IN) {
0043             assert(m_child_event == nullptr);
0044             m_child_event = event;
0045         }
0046         else {
0047             throw JException("Invalid input port for JEventUnfolder!");
0048         }
0049 
0050         // Check if we should exit early because we don't have a parent event
0051         if (m_parent_event == nullptr) {
0052             m_next_input_port = PARENT_IN;
0053             output_count = 0;
0054             status = JArrow::FireResult::KeepGoing;
0055             return;
0056         }
0057 
0058         // Check if we should exit early because we don't have a child event
0059         if (m_child_event == nullptr) {
0060             m_next_input_port = CHILD_IN;
0061             output_count = 0;
0062             status = JArrow::FireResult::KeepGoing;
0063             return;
0064         }
0065 
0066         // At this point we know we have both inputs, so we can run the unfolder. First we validate 
0067         // that the events we received are at the correct level for the unfolder. Hopefully the only 
0068         // way to end up here is to override the JTopologyBuilder wiring and do it wrong
0069 
0070         if (m_parent_event->GetLevel() != m_unfolder->GetLevel()) {
0071             throw JException("JUnfolder: Expected parent with level %d, got %d", m_unfolder->GetLevel(), m_parent_event->GetLevel());
0072         }
0073 
0074         if (m_child_event->GetLevel() != m_unfolder->GetChildLevel()) {
0075             throw JException("JUnfolder: Expected child with level %d, got %d", m_unfolder->GetChildLevel(), m_child_event->GetLevel());
0076         }
0077 
0078         auto result = m_unfolder->DoUnfold(*m_parent_event, *m_child_event);
0079         LOG_DEBUG(m_logger) << "Unfold succeeded: Parent event = " << m_parent_event->GetEventNumber() << ", child event = " << m_child_event->GetEventNumber() << LOG_END;
0080 
0081         if (result == JEventUnfolder::Result::KeepChildNextParent) {
0082             m_parent_event->Release(); // Decrement the reference count so that this can be recycled
0083             LOG_DEBUG(m_logger) << "Unfold finished with parent event = " << m_parent_event->GetEventNumber() << LOG_END;
0084 
0085             m_parent_event = nullptr;
0086             output_count = 0;
0087             m_next_input_port = PARENT_IN;
0088             status = JArrow::FireResult::KeepGoing;
0089             return;
0090         }
0091         else if (result == JEventUnfolder::Result::NextChildKeepParent) {
0092             m_child_event->SetParent(m_parent_event);
0093             outputs[0] = {m_child_event, CHILD_OUT};
0094             output_count = 1;
0095             m_child_event = nullptr;
0096             m_next_input_port = CHILD_IN;
0097             status = JArrow::FireResult::KeepGoing;
0098             return;
0099         }
0100         else if (result == JEventUnfolder::Result::NextChildNextParent) {
0101             m_child_event->SetParent(m_parent_event);
0102             m_parent_event->Release(); // Decrement the reference count so that this can be recycled
0103             outputs[0] = {m_child_event, CHILD_OUT};
0104             output_count = 1;
0105             LOG_DEBUG(m_logger) << "Unfold finished with parent event = " << m_parent_event->GetEventNumber() << LOG_END;
0106             m_child_event = nullptr;
0107             m_parent_event = nullptr;
0108             m_next_input_port = PARENT_IN;
0109             status = JArrow::FireResult::KeepGoing;
0110             return;
0111         }
0112         else {
0113             throw JException("Unsupported (corrupt?) JEventUnfolder::Result");
0114         }
0115     }
0116 };
0117 
0118