File indexing completed on 2025-01-30 10:11:49
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 }
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 }
0239