File indexing completed on 2025-07-14 09:12:16
0001
0002
0003
0004
0005 #pragma once
0006
0007 #include "JANA/Components/JComponentSummary.h"
0008 #include "JANA/Utils/JEventLevel.h"
0009 #include <JANA/JEvent.h>
0010 #include <JANA/JMultifactory.h>
0011
0012 namespace jana::components {
0013
0014
0015
0016 struct JHasOutputs {
0017 public:
0018 struct OutputBase;
0019
0020 protected:
0021 std::vector<OutputBase*> m_outputs;
0022
0023 public:
0024 void RegisterOutput(OutputBase* output) {
0025 m_outputs.push_back(output);
0026 }
0027
0028 struct OutputBase {
0029 std::string type_name;
0030 std::vector<std::string> collection_names;
0031 JEventLevel level = JEventLevel::None;
0032 bool is_variadic = false;
0033
0034 virtual void CreateHelperFactory(JMultifactory& fac) = 0;
0035 virtual void SetCollection(JMultifactory& fac) = 0;
0036 virtual void InsertCollection(JEvent& event) = 0;
0037 virtual void Reset() = 0;
0038 };
0039
0040 template <typename T>
0041 class Output : public OutputBase {
0042 std::vector<T*> m_data;
0043 bool is_not_owner = false;
0044
0045 public:
0046 Output(JHasOutputs* owner, std::string default_tag_name="") {
0047 owner->RegisterOutput(this);
0048 this->collection_names.push_back(default_tag_name);
0049 this->type_name = JTypeInfo::demangle<T>();
0050 }
0051
0052 void SetTag(std::string tag) {
0053 this->collection_names.clear();
0054 this->collection_names.push_back(tag);
0055 }
0056
0057 std::vector<T*>& operator()() { return m_data; }
0058
0059 void SetNotOwnerFlag(bool not_owner=true) { is_not_owner = not_owner; }
0060
0061 protected:
0062
0063 void CreateHelperFactory(JMultifactory& fac) override {
0064 fac.DeclareOutput<T>(this->collection_names[0]);
0065 }
0066
0067 void SetCollection(JMultifactory& fac) override {
0068 fac.SetData<T>(this->collection_names[0], this->m_data);
0069 }
0070
0071 void InsertCollection(JEvent& event) override {
0072 auto fac = event.Insert(m_data, this->collection_names[0]);
0073 fac->SetNotOwnerFlag(is_not_owner);
0074 }
0075 void Reset() override { }
0076
0077 };
0078
0079
0080 #if JANA2_HAVE_PODIO
0081 template <typename PodioT>
0082 class PodioOutput : public OutputBase {
0083
0084 std::unique_ptr<typename PodioT::collection_type> m_data;
0085
0086 public:
0087
0088 PodioOutput(JHasOutputs* owner, std::string default_collection_name="") {
0089 owner->RegisterOutput(this);
0090 this->collection_names.push_back(default_collection_name);
0091 this->type_name = JTypeInfo::demangle<PodioT>();
0092 }
0093
0094 std::unique_ptr<typename PodioT::collection_type>& operator()() { return m_data; }
0095
0096 void SetCollectionName(std::string name) {
0097 this->collection_names.clear();
0098 this->collection_names.push_back(name);
0099 }
0100
0101 protected:
0102
0103 void CreateHelperFactory(JMultifactory& fac) override {
0104 fac.DeclarePodioOutput<PodioT>(this->collection_names[0]);
0105 }
0106
0107 void SetCollection(JMultifactory& fac) override {
0108 if (m_data == nullptr) {
0109 throw JException("JOmniFactory: SetCollection failed due to missing output collection '%s'", this->collection_names[0].c_str());
0110
0111 }
0112 fac.SetCollection<PodioT>(this->collection_names[0], std::move(this->m_data));
0113 }
0114
0115 void InsertCollection(JEvent& event) override {
0116 event.InsertCollection<PodioT>(std::move(*m_data), this->collection_names[0]);
0117 }
0118
0119 void Reset() override {
0120 m_data = std::move(std::make_unique<typename PodioT::collection_type>());
0121 }
0122 };
0123
0124
0125 template <typename PodioT>
0126 class VariadicPodioOutput : public OutputBase {
0127
0128 std::vector<std::unique_ptr<typename PodioT::collection_type>> m_data;
0129
0130 public:
0131
0132 VariadicPodioOutput(JHasOutputs* owner, std::vector<std::string> default_collection_names={}) {
0133 owner->RegisterOutput(this);
0134 this->collection_names = default_collection_names;
0135 this->type_name = JTypeInfo::demangle<PodioT>();
0136 this->is_variadic = true;
0137 }
0138
0139 std::vector<std::unique_ptr<typename PodioT::collection_type>>& operator()() { return m_data; }
0140
0141 void SetCollectionNames(std::vector<std::string> names) {
0142 this->collection_names = names;
0143 }
0144
0145 protected:
0146
0147 void CreateHelperFactory(JMultifactory& fac) override {
0148 for (auto& coll_name : this->collection_names) {
0149 fac.DeclarePodioOutput<PodioT>(coll_name);
0150 }
0151 }
0152
0153 void SetCollection(JMultifactory& fac) override {
0154 if (m_data.size() != this->collection_names.size()) {
0155 throw JException("JOmniFactory: VariadicPodioOutput SetCollection failed: Declared %d collections, but provided %d.", this->collection_names.size(), m_data.size());
0156
0157 }
0158 size_t i = 0;
0159 for (auto& coll_name : this->collection_names) {
0160 fac.SetCollection<PodioT>(coll_name, std::move(this->m_data[i++]));
0161 }
0162 }
0163
0164 void InsertCollection(JEvent& event) override {
0165 if (m_data.size() != this->collection_names.size()) {
0166 throw JException("VariadicPodioOutput InsertCollection failed: Declared %d collections, but provided %d.", this->collection_names.size(), m_data.size());
0167
0168 }
0169 size_t i = 0;
0170 for (auto& coll_name : this->collection_names) {
0171 event.InsertCollection<PodioT>(std::move(*(m_data[i++])), coll_name);
0172 }
0173 }
0174
0175 void Reset() override {
0176 m_data.clear();
0177 for (auto& coll_name : this->collection_names) {
0178 m_data.push_back(std::make_unique<typename PodioT::collection_type>());
0179 }
0180 }
0181 };
0182 #endif
0183
0184
0185 void WireOutputs(JEventLevel component_level, const std::vector<std::string>& single_output_databundle_names, const std::vector<std::vector<std::string>>& variadic_output_databundle_names) {
0186 size_t single_output_index = 0;
0187 size_t variadic_output_index = 0;
0188
0189 for (auto* output : m_outputs) {
0190 output->collection_names.clear();
0191 output->level = component_level;
0192 if (output->is_variadic) {
0193 output->collection_names = variadic_output_databundle_names.at(variadic_output_index++);
0194 }
0195 else {
0196 output->collection_names.push_back(single_output_databundle_names.at(single_output_index++));
0197 }
0198 }
0199 }
0200
0201 void SummarizeOutputs(JComponentSummary::Component& summary) const {
0202 for (const auto* output : m_outputs) {
0203 size_t suboutput_count = output->collection_names.size();
0204 for (size_t i=0; i<suboutput_count; ++i) {
0205 summary.AddOutput(new JComponentSummary::Collection("", output->collection_names[i], output->type_name, output->level));
0206 }
0207 }
0208 }
0209
0210 };
0211
0212
0213 }