Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:11:49

0001 // Copyright 2024, 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 #include <JANA/JEvent.h>
0007 
0008 
0009 namespace jana::components {
0010 
0011 struct JHasInputs {
0012 protected:
0013 
0014     struct InputBase;
0015     std::vector<InputBase*> m_inputs;
0016 
0017     void RegisterInput(InputBase* input) {
0018         m_inputs.push_back(input);
0019     }
0020     
0021     struct InputOptions {
0022         std::string name {""};
0023         JEventLevel level {JEventLevel::None};
0024         bool is_optional {false};
0025         // bool is_shortcircuiting {false};
0026         // bool contains_single_item {false};
0027     };
0028 
0029     struct VariadicInputOptions {
0030         std::vector<std::string> names {""};
0031         std::vector<JEventLevel> levels {JEventLevel::None};
0032         bool is_optional {false};
0033         // bool is_shortcircuiting {false};
0034         // bool contains_single_item {false};
0035     };
0036 
0037     struct InputBase {
0038         std::string type_name;
0039         std::vector<std::string> names;
0040         std::vector<JEventLevel> levels;
0041         bool is_variadic = false;
0042         bool is_optional = false;
0043         //bool is_shortcircuiting = false;
0044         //bool contains_single_item = false;
0045 
0046 
0047         void Configure(const InputOptions& options) {
0048             this->names.clear();
0049             this->names.push_back(options.name);
0050             this->levels.clear();
0051             this->levels.push_back(options.level);
0052             this->is_optional = options.is_optional;
0053             // this->is_shortcircuiting = options.is_shortcircuiting;
0054             // this->contains_single_item = options.contains_single_item;
0055         }
0056 
0057         void ConfigureVariadic(const VariadicInputOptions& options) {
0058             if (!is_variadic) { throw JException("Setting variadic options on non-variadic input"); }
0059             this->names = options.names;
0060             if (options.levels.size() == options.names.size()) {
0061                 this->levels = options.levels;
0062             }
0063             else if (options.levels.size() == 0) {
0064                 for (size_t i=0; i<names.size(); ++i) {
0065                     this->levels.push_back(JEventLevel::None);
0066                 }
0067             }
0068             else {
0069                 throw JException("Wrong number of levels provided!");
0070             }
0071             this->is_optional = options.is_optional;
0072             // this->is_shortcircuiting = options.is_shortcircuiting;
0073             // this->contains_single_item = options.contains_single_item;
0074         }
0075 
0076         virtual void GetCollection(const JEvent& event) = 0;
0077         virtual void PrefetchCollection(const JEvent& event) = 0;
0078     };
0079 
0080     template <typename T>
0081     class Input : public InputBase {
0082 
0083         std::vector<const T*> m_data;
0084 
0085     public:
0086 
0087         Input(JHasInputs* owner) {
0088             owner->RegisterInput(this);
0089             this->type_name = JTypeInfo::demangle<T>();
0090         }
0091 
0092         Input(JHasInputs* owner, const InputOptions& options) {
0093             owner->RegisterInput(this);
0094             this->type_name = JTypeInfo::demangle<T>();
0095             Configure(options);
0096         }
0097 
0098         const std::vector<const T*>& operator()() { return m_data; }
0099 
0100 
0101     private:
0102         friend class JComponentT;
0103 
0104         void GetCollection(const JEvent& event) {
0105             auto& level = this->levels[0];
0106             if (level == event.GetLevel() || level == JEventLevel::None) {
0107                 m_data = event.Get<T>(this->names[0], !this->is_optional);
0108             }
0109             else {
0110                 if (this->is_optional && !event.HasParent(level)) return;
0111                 m_data = event.GetParent(level).template Get<T>(this->names[0], !this->is_optional);
0112             }
0113         }
0114         void PrefetchCollection(const JEvent& event) {
0115             auto& level = this->levels[0];
0116             auto& name = this->names[0];
0117             if (level == event.GetLevel() || level == JEventLevel::None) {
0118                 event.Get<T>(name, !this->is_optional);
0119             }
0120             else {
0121                 if (this->is_optional && !event.HasParent(level)) return;
0122                 event.GetParent(level).template Get<T>(name, !this->is_optional);
0123             }
0124         }
0125     };
0126 
0127 #if JANA2_HAVE_PODIO
0128     template <typename PodioT>
0129     class PodioInput : public InputBase {
0130 
0131         const typename PodioT::collection_type* m_data;
0132 
0133     public:
0134 
0135         PodioInput(JHasInputs* owner) {
0136             owner->RegisterInput(this);
0137             this->type_name = JTypeInfo::demangle<PodioT>();
0138         }
0139 
0140         PodioInput(JHasInputs* owner, const InputOptions& options) {
0141             owner->RegisterInput(this);
0142             this->type_name = JTypeInfo::demangle<PodioT>();
0143             Configure(options);
0144         }
0145 
0146         const typename PodioT::collection_type* operator()() {
0147             return m_data;
0148         }
0149 
0150         void GetCollection(const JEvent& event) {
0151             auto& level = this->levels[0];
0152             auto& name = this->names[0];
0153             if (level == event.GetLevel() || level == JEventLevel::None) {
0154                 m_data = event.GetCollection<PodioT>(name, !this->is_optional);
0155             }
0156             else {
0157                 if (this->is_optional && !event.HasParent(level)) return;
0158                 m_data = event.GetParent(level).template GetCollection<PodioT>(name, !this->is_optional);
0159             }
0160         }
0161 
0162         void PrefetchCollection(const JEvent& event) {
0163             auto& level = this->levels[0];
0164             auto& name = this->names[0];
0165             if (level == event.GetLevel() || level == JEventLevel::None) {
0166                 event.GetCollection<PodioT>(name, !this->is_optional);
0167             }
0168             else {
0169                 if (this->is_optional && !event.HasParent(level)) return;
0170                 event.GetParent(level).template GetCollection<PodioT>(name, !this->is_optional);
0171             }
0172         }
0173     };
0174 
0175 
0176     template <typename PodioT>
0177     class VariadicPodioInput : public InputBase {
0178 
0179         std::vector<const typename PodioT::collection_type*> m_data;
0180 
0181     public:
0182 
0183         VariadicPodioInput(JHasInputs* owner) {
0184             owner->RegisterInput(this);
0185             this->type_name = JTypeInfo::demangle<PodioT>();
0186             this->is_variadic = true;
0187         }
0188 
0189         VariadicPodioInput(JHasInputs* owner, const VariadicInputOptions& options) {
0190             owner->RegisterInput(this);
0191             this->type_name = JTypeInfo::demangle<PodioT>();
0192             this->is_variadic = true;
0193             ConfigureVariadic(options);
0194         }
0195 
0196         const std::vector<const typename PodioT::collection_type*> operator()() {
0197             return m_data;
0198         }
0199 
0200         void GetCollection(const JEvent& event) {
0201             m_data.clear();
0202             if (names.size() != levels.size()) {
0203                 throw JException("Misconfigured VariadicPodioInput: names.size()=%d, levels.size()=%d", names.size(), levels.size());
0204             }
0205             for (size_t i=0; i<names.size(); i++) {
0206                 auto& coll_name = names[i];
0207                 auto& level = levels[i];
0208                 if (level == event.GetLevel() || level == JEventLevel::None) {
0209                     m_data.push_back(event.GetCollection<PodioT>(coll_name, !this->is_optional));
0210                 }
0211                 else {
0212                     if (this->is_optional && !event.HasParent(level)) return;
0213                     m_data.push_back(event.GetParent(level).template GetCollection<PodioT>(coll_name, !this->is_optional));
0214                 }
0215             }
0216         }
0217 
0218         void PrefetchCollection(const JEvent& event) {
0219             if (names.size() != levels.size()) {
0220                 throw JException("Misconfigured VariadicPodioInput: names.size()=%d, levels.size()=%d", names.size(), levels.size());
0221             }
0222             for (size_t i=0; i<names.size(); i++) {
0223                 auto& coll_name = names[i];
0224                 auto& level = levels[i];
0225                 if (level == event.GetLevel() || level == JEventLevel::None) {
0226                     event.GetCollection<PodioT>(coll_name, !this->is_optional);
0227                 }
0228                 else {
0229                     if (this->is_optional && !event.HasParent(level)) return;
0230                     event.GetParent(level).template GetCollection<PodioT>(coll_name, !this->is_optional);
0231                 }
0232             }
0233         }
0234     };
0235 #endif
0236 };
0237 
0238 } // namespace jana::components
0239