File indexing completed on 2026-06-09 08:41:38
0001
0002
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, PARENT_OUT=3};
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 SetName(name);
0021 auto parent_level = unfolder->GetLevel();
0022 auto child_level = unfolder->GetChildLevel();
0023 AddPort("parent_in", parent_level, PortDirection::In);
0024 AddPort("child_in", child_level, PortDirection::In);
0025 AddPort("child_out", child_level, PortDirection::Out).SetEstablishesOrdering(true);
0026
0027
0028
0029 AddPort("parent_out", parent_level, PortDirection::Out);
0030 m_next_input_port = GetPortIndex("parent_in");
0031 }
0032
0033 void Initialize() final {
0034 m_unfolder->DoInit();
0035 LOG_INFO(m_logger) << "Initialized JEventUnfolder '" << m_unfolder->GetTypeName() << "'" << LOG_END;
0036 }
0037
0038 void Finalize() final {
0039 m_unfolder->DoFinish();
0040 LOG_INFO(m_logger) << "Finalized JEventUnfolder '" << m_unfolder->GetTypeName() << "'" << LOG_END;
0041 }
0042
0043 void Fire(JEvent* event, OutputData& outputs, size_t& output_count, JArrow::FireResult& status) final {
0044
0045
0046 if (this->m_next_input_port == PARENT_IN) {
0047 assert(m_parent_event == nullptr);
0048 m_parent_event = event;
0049 }
0050 else if (this->m_next_input_port == CHILD_IN) {
0051 assert(m_child_event == nullptr);
0052 m_child_event = event;
0053 }
0054 else {
0055 throw JException("Invalid input port for JEventUnfolder!");
0056 }
0057
0058
0059 if (m_parent_event == nullptr) {
0060 m_next_input_port = PARENT_IN;
0061 output_count = 0;
0062 status = JArrow::FireResult::KeepGoing;
0063 return;
0064 }
0065
0066
0067 if (m_child_event == nullptr) {
0068 m_next_input_port = CHILD_IN;
0069 output_count = 0;
0070 status = JArrow::FireResult::KeepGoing;
0071 return;
0072 }
0073
0074
0075
0076
0077
0078 if (m_parent_event->GetLevel() != m_unfolder->GetLevel()) {
0079 throw JException("JUnfolder: Expected parent with level %s, got %s", toString(m_unfolder->GetLevel()).c_str(), toString(m_parent_event->GetLevel()).c_str());
0080 }
0081
0082 if (m_child_event->GetLevel() != m_unfolder->GetChildLevel()) {
0083 throw JException("JUnfolder: Expected child with level %s, got %s", toString(m_unfolder->GetChildLevel()).c_str(), toString(m_child_event->GetLevel()).c_str());
0084 }
0085
0086 auto result = m_unfolder->DoUnfold(*m_parent_event, *m_child_event);
0087 LOG_DEBUG(m_logger) << "Unfold succeeded: Parent event = " << m_parent_event->GetEventNumber() << ", child event = " << m_child_event->GetEventNumber() << LOG_END;
0088
0089 if (result == JEventUnfolder::Result::KeepChildNextParent) {
0090
0091
0092 int child_count = m_parent_event->GetChildCount();
0093 LOG_DEBUG(m_logger) << "Unfold finished with parent event = " << m_parent_event->GetEventNumber() << " (" << child_count << " children emitted)";
0094
0095 if (child_count > 0) {
0096
0097 m_parent_event = nullptr;
0098 output_count = 0;
0099 m_next_input_port = PARENT_IN;
0100 status = JArrow::FireResult::KeepGoing;
0101 return;
0102 }
0103 else {
0104
0105 output_count = 1;
0106 outputs[0] = {m_parent_event, PARENT_OUT};
0107 m_parent_event = nullptr;
0108 m_next_input_port = PARENT_IN;
0109 status = JArrow::FireResult::KeepGoing;
0110 return;
0111 }
0112 }
0113 else if (result == JEventUnfolder::Result::NextChildKeepParent) {
0114 m_child_event->SetParent(m_parent_event);
0115 outputs[0] = {m_child_event, CHILD_OUT};
0116 output_count = 1;
0117 m_child_event = nullptr;
0118 m_next_input_port = CHILD_IN;
0119 status = JArrow::FireResult::KeepGoing;
0120 return;
0121 }
0122 else if (result == JEventUnfolder::Result::NextChildNextParent) {
0123 m_child_event->SetParent(m_parent_event);
0124 outputs[0] = {m_child_event, CHILD_OUT};
0125 outputs[1] = {m_parent_event, PARENT_OUT};
0126 output_count = 2;
0127 LOG_DEBUG(m_logger) << "Unfold finished with parent event = " << m_parent_event->GetEventNumber() << LOG_END;
0128 m_child_event = nullptr;
0129 m_parent_event = nullptr;
0130 m_next_input_port = PARENT_IN;
0131 status = JArrow::FireResult::KeepGoing;
0132 return;
0133 }
0134 else {
0135 throw JException("Unsupported (corrupt?) JEventUnfolder::Result");
0136 }
0137 }
0138 };
0139
0140