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