Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-29 10:25:01

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/Components/JComponentSummary.h"
0007 #include <JANA/JVersion.h>
0008 #if JANA2_HAVE_PODIO
0009 #include "JANA/Components/JPodioDatabundle.h"
0010 #endif
0011 #include "JANA/Components/JLightweightDatabundle.h"
0012 #include "JANA/Utils/JEventLevel.h"
0013 #include "JANA/Utils/JTypeInfo.h"
0014 #include "JANA/JFactorySet.h"
0015 #include <typeindex>
0016 
0017 
0018 class JEvent;
0019 namespace jana::components {
0020 
0021 // Free function in order to break circular dependence on JEvent
0022 JFactorySet* GetFactorySetAtLevel(const JEvent& event, JEventLevel desired_level);
0023 void FactoryCreate(const JEvent& event, JFactory* factory);
0024 
0025 struct JHasInputs {
0026 
0027     class InputBase;
0028     class VariadicInputBase;
0029 
0030 protected:
0031 
0032     std::vector<InputBase*> m_inputs;
0033     std::vector<VariadicInputBase*> m_variadic_inputs;
0034     std::vector<std::pair<InputBase*, VariadicInputBase*>> m_ordered_inputs;
0035 
0036 public:
0037 
0038     void RegisterInput(InputBase* input) {
0039         m_inputs.push_back(input);
0040         m_ordered_inputs.push_back({input, nullptr});
0041     }
0042 
0043     void RegisterInput(VariadicInputBase* input) {
0044         m_variadic_inputs.push_back(input);
0045         m_ordered_inputs.push_back({nullptr, input});
0046     }
0047 
0048     const std::vector<InputBase*>& GetInputs() { 
0049         return m_inputs; 
0050     }
0051 
0052     const std::vector<VariadicInputBase*>& GetVariadicInputs() { 
0053         return m_variadic_inputs; 
0054     }
0055 
0056     struct InputOptions {
0057         std::string name {""};
0058         JEventLevel level {JEventLevel::None};
0059         bool is_optional {false};
0060     };
0061 
0062     struct VariadicInputOptions {
0063         std::vector<std::string> names {""};
0064         JEventLevel level {JEventLevel::None};
0065         bool is_optional {false};
0066     };
0067 
0068     class InputBase {
0069     protected:
0070         std::type_index m_type_index = std::type_index(typeid(JDatabundle::NoTypeProvided));
0071         std::string m_type_name;
0072         std::string m_databundle_name;
0073         JEventLevel m_level = JEventLevel::None;
0074         bool m_is_optional = false;
0075 
0076     public:
0077 
0078         virtual ~InputBase();
0079 
0080         void SetOptional(bool isOptional) {
0081             m_is_optional = isOptional;
0082         }
0083 
0084         void SetLevel(JEventLevel level) {
0085             m_level = level;
0086         }
0087 
0088         void SetDatabundleName(std::string name) {
0089             m_databundle_name = name;
0090         }
0091 
0092         const std::string& GetTypeName() const {
0093             return m_type_name;
0094         }
0095 
0096         const std::string& GetDatabundleName() const {
0097             return m_databundle_name;
0098         }
0099 
0100         JEventLevel GetLevel() const {
0101             return m_level;
0102         }
0103 
0104         void Configure(const InputOptions& options) {
0105             m_databundle_name = options.name;
0106             m_level = options.level;
0107             m_is_optional = options.is_optional;
0108         }
0109 
0110         void TriggerFactoryCreate(const JEvent& event);
0111         virtual void Populate(const JEvent& event) = 0;
0112     };
0113 
0114     class VariadicInputBase {
0115     public:
0116         enum class EmptyInputPolicy { IncludeNothing, IncludeEverything };
0117 
0118     protected:
0119         std::type_index m_type_index = std::type_index(typeid(JDatabundle::NoTypeProvided));
0120         std::string m_type_name;
0121         std::vector<std::string> m_requested_databundle_names;
0122         std::vector<std::string> m_realized_databundle_names;
0123         JEventLevel m_level = JEventLevel::None;
0124         bool m_is_optional = false;
0125         EmptyInputPolicy m_empty_input_policy = EmptyInputPolicy::IncludeNothing;
0126 
0127     public:
0128 
0129         virtual ~VariadicInputBase();
0130 
0131         void SetOptional(bool isOptional) {
0132             m_is_optional = isOptional;
0133         }
0134 
0135         void SetLevel(JEventLevel level) {
0136             m_level = level;
0137         }
0138 
0139         void SetRequestedDatabundleNames(std::vector<std::string> names) {
0140             m_requested_databundle_names = names;
0141             m_realized_databundle_names = names;
0142             // If options.names are empty, m_realized_databundle_names will be filled later
0143             // Otherwise, m_realized_databundle_names always matches m_requested_databundle_names
0144             // This weirdness is an optimization to avoid having to repopulate m_realized_databundle_names for every event
0145         }
0146 
0147         void SetEmptyInputPolicy(EmptyInputPolicy policy) {
0148             m_empty_input_policy = policy;
0149         }
0150 
0151         const std::string& GetTypeName() const {
0152             return m_type_name;
0153         }
0154 
0155         const std::vector<std::string>& GetRequestedDatabundleNames() const {
0156             return m_requested_databundle_names;
0157         }
0158 
0159         const std::vector<std::string>& GetRealizedDatabundleNames() const {
0160             return m_realized_databundle_names;
0161         }
0162 
0163         JEventLevel GetLevel() const {
0164             return m_level;
0165         }
0166 
0167         void Configure(const VariadicInputOptions& options) {
0168             m_requested_databundle_names = options.names;
0169             m_realized_databundle_names = options.names;
0170             // If options.names are empty, m_realized_databundle_names will be filled later
0171             // Otherwise, m_realized_databundle_names always matches m_requested_databundle_names
0172             // This weirdness is an optimization to avoid having to repopulate m_realized_databundle_names for every event
0173             m_level = options.level;
0174             m_is_optional = options.is_optional;
0175         }
0176 
0177         void TriggerFactoryCreate(const JEvent& event);
0178         virtual void Populate(const JEvent& event) = 0;
0179     };
0180 
0181 
0182     template <typename T>
0183     class Input : public InputBase {
0184 
0185         std::vector<const T*> m_data;
0186 
0187     public:
0188 
0189         Input(JHasInputs* owner) {
0190             owner->RegisterInput(this);
0191             m_type_index = std::type_index(typeid(T));
0192             m_type_name = JTypeInfo::demangle<T>();
0193             m_level = JEventLevel::None;
0194         }
0195 
0196         Input(JHasInputs* owner, const InputOptions& options) {
0197             owner->RegisterInput(this);
0198             m_type_index = std::type_index(typeid(T));
0199             m_type_name = JTypeInfo::demangle<T>();
0200             Configure(options);
0201         }
0202 
0203         void SetTag(std::string tag) {
0204             m_databundle_name = tag;
0205         }
0206 
0207         const std::vector<const T*>& operator()() { return m_data; }
0208         const std::vector<const T*>& operator*() { return m_data; }
0209         const std::vector<const T*>* operator->() { return &m_data; }
0210 
0211 
0212     private:
0213         friend class JComponentT;
0214 
0215         void Populate(const JEvent& event) {
0216 
0217             // Eventually, we might try maintaining a permanent link to the databundle
0218             // instead of having to retrieve it every time. This will only work if we are both on a
0219             // JFactory in the same JFactorySet, though.
0220 
0221             auto facset = GetFactorySetAtLevel(event, m_level);
0222             if (facset == nullptr) {
0223                 if (m_is_optional) {
0224                     return;
0225                 }
0226                 throw JException("Could not find parent at level=" + toString(m_level));
0227             }
0228             auto databundle = facset->GetDatabundle(std::type_index(typeid(T)), m_databundle_name);
0229             if (databundle == nullptr) {
0230                 if (!m_is_optional) {
0231                     facset->Print();
0232                     throw JException("Could not find databundle with type_index=" + JTypeInfo::demangle<T>() + " and tag=" + m_databundle_name);
0233                 }
0234                 m_data.clear();
0235                 return;
0236             };
0237             auto* typed_databundle = dynamic_cast<JLightweightDatabundleT<T>*>(databundle);
0238             if (typed_databundle == nullptr) {
0239                 if (!m_is_optional) {
0240                     facset->Print();
0241                     throw JException("Databundle with shortname '%s' does not inherit from JLightweightDatabundleT<%s>", m_databundle_name.c_str(), JTypeInfo::demangle<T>().c_str());
0242                 }
0243             }
0244             m_data.clear();
0245             m_data.insert(m_data.end(), typed_databundle->GetData().begin(), typed_databundle->GetData().end());
0246         }
0247     };
0248 
0249 #if JANA2_HAVE_PODIO
0250     template <typename PodioT>
0251     class PodioInput : public InputBase {
0252 
0253         const typename PodioT::collection_type* m_data;
0254 
0255     public:
0256 
0257         PodioInput(JHasInputs* owner) {
0258             owner->RegisterInput(this);
0259             m_type_index = std::type_index(typeid(PodioT));
0260             m_type_name = JTypeInfo::demangle<PodioT>();
0261             m_databundle_name = m_type_name;
0262             m_level = JEventLevel::None;
0263         }
0264 
0265         PodioInput(JHasInputs* owner, const InputOptions& options) {
0266             owner->RegisterInput(this);
0267             m_type_index = std::type_index(typeid(PodioT));
0268             m_type_name = JTypeInfo::demangle<PodioT>();
0269             m_databundle_name = m_type_name;
0270             Configure(options);
0271         }
0272 
0273         const typename PodioT::collection_type* operator()() {
0274             return m_data;
0275         }
0276         const typename PodioT::collection_type& operator*() {
0277             return *m_data;
0278         }
0279         const typename PodioT::collection_type* operator->() {
0280             return m_data;
0281         }
0282 
0283         void SetCollectionName(std::string name) {
0284             m_databundle_name = name;
0285         }
0286 
0287         void SetTag(std::string tag) {
0288             m_databundle_name = m_type_name + ":" + tag;
0289         }
0290 
0291         void Populate(const JEvent& event) {
0292             auto facset = GetFactorySetAtLevel(event, m_level);
0293             if (facset == nullptr) {
0294                 if (m_is_optional) {
0295                     return;
0296                 }
0297                 throw JException("Could not find parent at level=" + toString(m_level));
0298             }
0299             auto databundle = facset->GetDatabundle(std::type_index(typeid(PodioT)), m_databundle_name);
0300             if (databundle == nullptr) {
0301                 if (!m_is_optional) {
0302                     facset->Print();
0303                     throw JException("Could not find databundle with type_index=" + JTypeInfo::demangle<PodioT>() + " and tag=" + m_databundle_name);
0304                 }
0305                 // data IS optional, so we exit
0306                 m_data = nullptr;
0307                 return;
0308             };
0309             if (databundle->GetFactory() != nullptr) {
0310                 FactoryCreate(event, databundle->GetFactory());
0311             }
0312             auto* typed_databundle = dynamic_cast<JPodioDatabundle*>(databundle);
0313             if (typed_databundle == nullptr) {
0314                 facset->Print();
0315                 throw JException("Databundle with unique name '%s' does not inherit from JPodioDatabundle", databundle->GetUniqueName().c_str());
0316             }
0317             m_data = dynamic_cast<const typename PodioT::collection_type*>(typed_databundle->GetCollection());
0318             if (m_data == nullptr) {
0319                 throw JException("Databundle with unique name '%s' does not contain %s", databundle->GetUniqueName().c_str(), JTypeInfo::demangle<typename PodioT::collection_type>().c_str());
0320             }
0321         }
0322     };
0323 #endif
0324 
0325 
0326     template <typename T>
0327     class VariadicInput : public VariadicInputBase {
0328 
0329         std::vector<std::vector<const T*>> m_datas;
0330 
0331     public:
0332 
0333         VariadicInput(JHasInputs* owner) {
0334             owner->RegisterInput(this);
0335             m_type_index = std::type_index(typeid(T));
0336             m_type_name = JTypeInfo::demangle<T>();
0337             m_level = JEventLevel::None;
0338         }
0339 
0340         VariadicInput(JHasInputs* owner, const VariadicInputOptions& options) {
0341             owner->RegisterInput(this);
0342             m_type_index = std::type_index(typeid(T));
0343             m_type_name = JTypeInfo::demangle<T>();
0344             Configure(options);
0345         }
0346 
0347         void SetTags(std::vector<std::string> tags) {
0348             m_requested_databundle_names = tags;
0349             m_realized_databundle_names = tags;
0350         }
0351 
0352         const std::vector<std::vector<const T*>>& operator()() { return m_datas; }
0353         const std::vector<std::vector<const T*>>& operator*() { return m_datas; }
0354         const std::vector<std::vector<const T*>>* operator->() { return &m_datas; }
0355 
0356         const std::vector<const T*>& operator()(size_t index) { return m_datas.at(index); }
0357 
0358 
0359     private:
0360         friend class JComponentT;
0361 
0362         void Populate(const JEvent& event) {
0363             m_datas.clear();
0364             auto facset = GetFactorySetAtLevel(event, m_level);
0365             if (facset == nullptr) {
0366                 if (m_is_optional) {
0367                     return;
0368                 }
0369                 throw JException("Could not find parent at level=" + toString(m_level));
0370             }
0371             if (!m_requested_databundle_names.empty()) {
0372                 // We have a nonempty input, so we provide the user exactly the inputs they asked for (some of these may be null IF is_optional=true)
0373                 for (auto& short_or_unique_name : m_requested_databundle_names) {
0374                     auto databundle = facset->GetDatabundle(std::type_index(typeid(T)), short_or_unique_name);
0375                     if (databundle == nullptr) {
0376                         if (!m_is_optional) {
0377                             facset->Print();
0378                             throw JException("Could not find databundle with type_index=" + JTypeInfo::demangle<T>() + " and name=" + short_or_unique_name);
0379                         }
0380                         m_datas.push_back({}); // If a databundle is optional and missing, we still insert an empty vector for it
0381                         continue;
0382                     };
0383                     if (databundle->GetFactory() != nullptr) {
0384                         FactoryCreate(event, databundle->GetFactory());
0385                     }
0386                     auto* typed_databundle = dynamic_cast<JLightweightDatabundleT<T>*>(databundle);
0387                     if (typed_databundle == nullptr) {
0388                         facset->Print();
0389                         throw JException("Databundle with shortname '%s' does not inherit from JLightweightDatabundleT<%s>", short_or_unique_name.c_str(), JTypeInfo::demangle<T>().c_str());
0390                     }
0391                     m_datas.push_back({});
0392                     auto& dest = m_datas.back();
0393                     dest.insert(dest.end(), typed_databundle->GetData().begin(), typed_databundle->GetData().end());
0394                 }
0395             }
0396             else if (m_empty_input_policy == EmptyInputPolicy::IncludeEverything) {
0397                 // We have an empty input and a nontrivial empty input policy
0398                 m_realized_databundle_names.clear();
0399 
0400                 auto databundles = facset->GetDatabundles(std::type_index(typeid(T)));
0401                 for (auto* databundle : databundles) {
0402 
0403                     auto typed_databundle = dynamic_cast<JLightweightDatabundleT<T>*>(databundle);
0404                     if (typed_databundle == nullptr) {
0405                         throw JException("Databundle with name=" + typed_databundle->GetUniqueName() + " does not inherit from JLightweightDatabundleT<" + JTypeInfo::demangle<T>() + ">");
0406                     }
0407                     auto& contents = typed_databundle->GetData();
0408                     m_datas.push_back({}); // Create a destination for this factory's data
0409                     auto& dest = m_datas.back();
0410                     dest.insert(dest.end(), contents.begin(), contents.end());
0411                     if (databundle->HasShortName()) {
0412                         m_realized_databundle_names.push_back(databundle->GetShortName());
0413                     }
0414                     else {
0415                         m_realized_databundle_names.push_back(databundle->GetUniqueName());
0416                     }
0417                 }
0418             }
0419         }
0420     };
0421 
0422 
0423 
0424 #if JANA2_HAVE_PODIO
0425     template <typename PodioT>
0426     class VariadicPodioInput : public VariadicInputBase {
0427 
0428         std::vector<const typename PodioT::collection_type*> m_datas;
0429 
0430     public:
0431 
0432         VariadicPodioInput(JHasInputs* owner) {
0433             owner->RegisterInput(this);
0434             m_type_index = std::type_index(typeid(PodioT));
0435             m_type_name = JTypeInfo::demangle<PodioT>();
0436         }
0437 
0438         VariadicPodioInput(JHasInputs* owner, const VariadicInputOptions& options) {
0439             owner->RegisterInput(this);
0440             m_type_index = std::type_index(typeid(PodioT));
0441             m_type_name = JTypeInfo::demangle<PodioT>();
0442             Configure(options);
0443         }
0444 
0445         const std::vector<const typename PodioT::collection_type*> operator()() {
0446             return m_datas;
0447         }
0448 
0449         void SetRequestedCollectionNames(std::vector<std::string> names) {
0450             m_requested_databundle_names = names;
0451             m_realized_databundle_names = std::move(names);
0452         }
0453 
0454         const std::vector<std::string>& GetRealizedCollectionNames() {
0455             return GetRealizedDatabundleNames();
0456         }
0457 
0458         void Populate(const JEvent& event) {
0459             auto facset = GetFactorySetAtLevel(event, m_level);
0460             if (facset == nullptr) {
0461                 if (m_is_optional) {
0462                     return;
0463                 }
0464                 throw JException("Could not find parent at level=" + toString(m_level));
0465             }
0466             bool need_dynamic_realized_databundle_names = (m_requested_databundle_names.empty()) && (m_empty_input_policy != EmptyInputPolicy::IncludeNothing);
0467             if (need_dynamic_realized_databundle_names) {
0468                 m_realized_databundle_names.clear();
0469             }
0470             m_datas.clear();
0471             if (!m_requested_databundle_names.empty()) {
0472                 for (auto& short_or_unique_name : m_requested_databundle_names) {
0473                     auto databundle = facset->GetDatabundle(std::type_index(typeid(PodioT)), short_or_unique_name);
0474                     if (databundle == nullptr) {
0475                         if (!m_is_optional) {
0476                             facset->Print();
0477                             throw JException("Could not find databundle with type_index=" + JTypeInfo::demangle<PodioT>() + " and name=" + short_or_unique_name);
0478                         }
0479                         m_datas.push_back(nullptr);
0480                         continue;
0481                     }
0482                     if (databundle->GetFactory() != nullptr) {
0483                         FactoryCreate(event, databundle->GetFactory());
0484                     }
0485                     auto* typed_databundle = dynamic_cast<JPodioDatabundle*>(databundle);
0486                     if (typed_databundle == nullptr) {
0487                         facset->Print();
0488                         throw JException("Databundle with name '%s' does not inherit from JPodioDatabundle", short_or_unique_name.c_str());
0489                     }
0490                     auto* typed_collection = dynamic_cast<const typename PodioT::collection_type*>(typed_databundle->GetCollection());
0491                     if (typed_collection == nullptr) {
0492                         throw JException("Databundle with unique name '%s' does not contain %s", short_or_unique_name.c_str(), JTypeInfo::demangle<typename PodioT::collection_type>().c_str());
0493                     }
0494 
0495                     m_datas.push_back(typed_collection); // This MIGHT be nullptr if m_is_optional==true
0496                 }
0497             }
0498             else if (m_empty_input_policy == EmptyInputPolicy::IncludeEverything) {
0499                 auto databundles = facset->GetDatabundles(std::type_index(typeid(PodioT)));
0500                 for (auto* databundle : databundles) {
0501                     if (databundle->GetFactory() != nullptr) {
0502                         FactoryCreate(event, databundle->GetFactory());
0503                     }
0504                     auto typed_databundle = dynamic_cast<JPodioDatabundle*>(databundle);
0505                     if (typed_databundle == nullptr) {
0506                         throw JException("Not a JPodioDatabundle: type_name=%s, unique_name=%s", databundle->GetTypeName().c_str(), databundle->GetUniqueName().c_str());
0507                     }
0508                     auto typed_collection = dynamic_cast<const typename PodioT::collection_type*>(typed_databundle->GetCollection());
0509                     if (typed_collection == nullptr) {
0510                         throw JException("Podio collection is not a %s: type_name=%s, unique_name=%s", JTypeInfo::demangle<PodioT>().c_str(), databundle->GetTypeName().c_str(), databundle->GetUniqueName().c_str());
0511                     }
0512                     m_datas.push_back(typed_collection);
0513 
0514                     if (databundle->HasShortName()) {
0515                         m_realized_databundle_names.push_back(databundle->GetShortName());
0516                     }
0517                     else {
0518                         m_realized_databundle_names.push_back(databundle->GetUniqueName());
0519                     }
0520                 }
0521             }
0522         }
0523     };
0524 #endif
0525 
0526     void WireInputs(JEventLevel component_level,
0527                     const std::vector<JEventLevel>& single_input_levels,
0528                     const std::vector<std::string>& single_input_databundle_names,
0529                     const std::vector<JEventLevel>& variadic_input_levels,
0530                     const std::vector<std::vector<std::string>>& variadic_input_databundle_names) {
0531 
0532         if (m_variadic_inputs.size() == 1 && variadic_input_databundle_names.size() == 0) {
0533             WireInputsCompatibility(component_level, single_input_levels, single_input_databundle_names);
0534             return;
0535         }
0536 
0537         if (!single_input_databundle_names.empty()) {
0538 
0539             // Validate that we have the correct number of input databundle names
0540             if (single_input_databundle_names.size() != m_inputs.size()) {
0541                 throw JException("Wrong number of (nonvariadic) input databundle names! Expected %d, found %d", m_inputs.size(), single_input_databundle_names.size());
0542             }
0543 
0544             size_t i = 0;
0545             for (auto* input : m_inputs) {
0546                 input->SetDatabundleName(single_input_databundle_names.at(i));
0547                 if (single_input_levels.empty()) {
0548                     input->SetLevel(component_level);
0549                 }
0550                 else {
0551                     input->SetLevel(single_input_levels.at(i));
0552                 }
0553                 i += 1;
0554             }
0555         }
0556 
0557         if (!variadic_input_databundle_names.empty()) {
0558 
0559             // Validate that we have the correct number of variadic input databundle names
0560             if (variadic_input_databundle_names.size() != m_variadic_inputs.size()) {
0561                 throw JException("Wrong number of lists of variadic input databundle names! Expected %d, found %d", m_variadic_inputs.size(), variadic_input_databundle_names.size());
0562             }
0563 
0564             size_t i = 0;
0565             for (auto* variadic_input : m_variadic_inputs) {
0566                 variadic_input->SetRequestedDatabundleNames(variadic_input_databundle_names.at(i));
0567                 if (variadic_input_levels.empty()) {
0568                     variadic_input->SetLevel(component_level);
0569                 }
0570                 else {
0571                     variadic_input->SetLevel(variadic_input_levels.at(i));
0572                 }
0573                 i += 1;
0574             }
0575         }
0576     }
0577 
0578     void WireInputsCompatibility(JEventLevel component_level,
0579                     const std::vector<JEventLevel>& single_input_levels,
0580                     const std::vector<std::string>& single_input_databundle_names) {
0581 
0582         // Figure out how many collection names belong to the variadic input
0583         int variadic_databundle_count = single_input_databundle_names.size() - m_inputs.size();
0584         int databundle_name_index = 0;
0585         int databundle_level_index = 0;
0586 
0587         for (auto& pair : m_ordered_inputs) {
0588             auto* single_input = pair.first;
0589             auto* variadic_input = pair.second;
0590             if (single_input != nullptr) {
0591                 single_input->SetDatabundleName(single_input_databundle_names.at(databundle_name_index));
0592                 if (single_input_levels.empty()) {
0593                     single_input->SetLevel(component_level);
0594                 }
0595                 else {
0596                     single_input->SetLevel(single_input_levels.at(databundle_level_index));
0597                 }
0598                 databundle_name_index += 1;
0599                 databundle_level_index += 1;
0600             }
0601             else {
0602                 std::vector<std::string> variadic_databundle_names;
0603                 for (int i=0; i<variadic_databundle_count; ++i) {
0604                     variadic_databundle_names.push_back(single_input_databundle_names.at(databundle_name_index+i));
0605                 }
0606                 variadic_input->SetRequestedDatabundleNames(variadic_databundle_names);
0607                 if (single_input_levels.empty()) {
0608                     variadic_input->SetLevel(component_level);
0609                 }
0610                 else {
0611                     variadic_input->SetLevel(single_input_levels.at(databundle_level_index)); // Last one wins!
0612                 }
0613                 databundle_name_index += variadic_databundle_count;
0614                 databundle_level_index += 1;
0615             }
0616         }
0617     }
0618 
0619     void SummarizeInputs(JComponentSummary::Component& summary) const {
0620         for (const auto* input : m_inputs) {
0621             summary.AddInput(new JComponentSummary::Collection("", input->GetDatabundleName(), input->GetTypeName(), input->GetLevel()));
0622         }
0623         for (const auto* input : m_variadic_inputs) {
0624             for (auto& databundle_name : input->GetRequestedDatabundleNames()) {
0625                 summary.AddInput(new JComponentSummary::Collection("", databundle_name, input->GetTypeName(), input->GetLevel()));
0626             }
0627         }
0628     }
0629 };
0630 
0631 } // namespace jana::components
0632