Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-14 09:12:16

0001 // Copyright 2023, Jefferson Science Associates, LLC.
0002 // Subject to the terms in the LICENSE file found in the top-level directory.
0003 // Created by Nathan Brei
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                 // Otherwise this leads to a PODIO segfault
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                 // Otherwise this leads to a PODIO segfault
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                 // Otherwise this leads to a PODIO segfault
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 } // namespace jana::components