File indexing completed on 2025-01-18 10:17:33
0001
0002
0003
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
0026
0027 };
0028
0029 struct VariadicInputOptions {
0030 std::vector<std::string> names {""};
0031 std::vector<JEventLevel> levels {JEventLevel::None};
0032 bool is_optional {false};
0033
0034
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
0044
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
0054
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
0073
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 this->names.push_back("");
0091
0092 this->levels.push_back(JEventLevel::None);
0093 }
0094
0095 Input(JHasInputs* owner, const InputOptions& options) {
0096 owner->RegisterInput(this);
0097 this->type_name = JTypeInfo::demangle<T>();
0098 Configure(options);
0099 }
0100
0101 const std::vector<const T*>& operator()() { return m_data; }
0102 const std::vector<const T*>& operator*() { return m_data; }
0103 const std::vector<const T*>* operator->() { return &m_data; }
0104
0105
0106 private:
0107 friend class JComponentT;
0108
0109 void GetCollection(const JEvent& event) {
0110 auto& level = this->levels[0];
0111 m_data.clear();
0112 if (level == event.GetLevel() || level == JEventLevel::None) {
0113 event.Get<T>(m_data, this->names[0], !this->is_optional);
0114 }
0115 else {
0116 if (this->is_optional && !event.HasParent(level)) return;
0117 event.GetParent(level).template Get<T>(m_data, this->names[0], !this->is_optional);
0118 }
0119 }
0120 void PrefetchCollection(const JEvent& event) {
0121 auto& level = this->levels[0];
0122 auto& name = this->names[0];
0123 if (level == event.GetLevel() || level == JEventLevel::None) {
0124 event.GetFactory<T>(name, !this->is_optional)->Create(event.shared_from_this());
0125 }
0126 else {
0127 if (this->is_optional && !event.HasParent(level)) return;
0128 event.GetParent(level).template GetFactory<T>(name, !this->is_optional)->Create(event.shared_from_this());
0129 }
0130 }
0131 };
0132
0133 #if JANA2_HAVE_PODIO
0134 template <typename PodioT>
0135 class PodioInput : public InputBase {
0136
0137 const typename PodioT::collection_type* m_data;
0138
0139 public:
0140
0141 PodioInput(JHasInputs* owner) {
0142 owner->RegisterInput(this);
0143 this->type_name = JTypeInfo::demangle<PodioT>();
0144 this->names.push_back(this->type_name);
0145 this->levels.push_back(JEventLevel::None);
0146 }
0147
0148 PodioInput(JHasInputs* owner, const InputOptions& options) {
0149 owner->RegisterInput(this);
0150 this->type_name = JTypeInfo::demangle<PodioT>();
0151 Configure(options);
0152 }
0153
0154 const typename PodioT::collection_type* operator()() {
0155 return m_data;
0156 }
0157 const typename PodioT::collection_type& operator*() {
0158 return *m_data;
0159 }
0160 const typename PodioT::collection_type* operator->() {
0161 return m_data;
0162 }
0163
0164 void GetCollection(const JEvent& event) {
0165 auto& level = this->levels[0];
0166 auto& name = this->names[0];
0167 if (level == event.GetLevel() || level == JEventLevel::None) {
0168 m_data = event.GetCollection<PodioT>(name, !this->is_optional);
0169 }
0170 else {
0171 if (this->is_optional && !event.HasParent(level)) return;
0172 m_data = event.GetParent(level).template GetCollection<PodioT>(name, !this->is_optional);
0173 }
0174 }
0175
0176 void PrefetchCollection(const JEvent& event) {
0177 auto& level = this->levels[0];
0178 auto& name = this->names[0];
0179 if (level == event.GetLevel() || level == JEventLevel::None) {
0180 event.GetCollection<PodioT>(name, !this->is_optional);
0181 }
0182 else {
0183 if (this->is_optional && !event.HasParent(level)) return;
0184 event.GetParent(level).template GetCollection<PodioT>(name, !this->is_optional);
0185 }
0186 }
0187 };
0188
0189
0190 template <typename PodioT>
0191 class VariadicPodioInput : public InputBase {
0192
0193 std::vector<const typename PodioT::collection_type*> m_data;
0194
0195 public:
0196
0197 VariadicPodioInput(JHasInputs* owner) {
0198 owner->RegisterInput(this);
0199 this->type_name = JTypeInfo::demangle<PodioT>();
0200 this->is_variadic = true;
0201 }
0202
0203 VariadicPodioInput(JHasInputs* owner, const VariadicInputOptions& options) {
0204 owner->RegisterInput(this);
0205 this->type_name = JTypeInfo::demangle<PodioT>();
0206 this->is_variadic = true;
0207 ConfigureVariadic(options);
0208 }
0209
0210 const std::vector<const typename PodioT::collection_type*> operator()() {
0211 return m_data;
0212 }
0213
0214 void GetCollection(const JEvent& event) {
0215 m_data.clear();
0216 if (names.size() != levels.size()) {
0217 throw JException("Misconfigured VariadicPodioInput: names.size()=%d, levels.size()=%d", names.size(), levels.size());
0218 }
0219 for (size_t i=0; i<names.size(); i++) {
0220 auto& coll_name = names[i];
0221 auto& level = levels[i];
0222 if (level == event.GetLevel() || level == JEventLevel::None) {
0223 m_data.push_back(event.GetCollection<PodioT>(coll_name, !this->is_optional));
0224 }
0225 else {
0226 if (this->is_optional && !event.HasParent(level)) return;
0227 m_data.push_back(event.GetParent(level).template GetCollection<PodioT>(coll_name, !this->is_optional));
0228 }
0229 }
0230 }
0231
0232 void PrefetchCollection(const JEvent& event) {
0233 if (names.size() != levels.size()) {
0234 throw JException("Misconfigured VariadicPodioInput: names.size()=%d, levels.size()=%d", names.size(), levels.size());
0235 }
0236 for (size_t i=0; i<names.size(); i++) {
0237 auto& coll_name = names[i];
0238 auto& level = levels[i];
0239 if (level == event.GetLevel() || level == JEventLevel::None) {
0240 event.GetCollection<PodioT>(coll_name, !this->is_optional);
0241 }
0242 else {
0243 if (this->is_optional && !event.HasParent(level)) return;
0244 event.GetParent(level).template GetCollection<PodioT>(coll_name, !this->is_optional);
0245 }
0246 }
0247 }
0248 };
0249 #endif
0250 };
0251
0252 }
0253