Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:36:43

0001 #pragma once
0002 #include "JANA/Components/JDatabundle.h"
0003 #include "JANA/JFactorySet.h"
0004 #include <JANA/Components/JHasOutputs.h>
0005 #include <JANA/Components/JLightweightDatabundle.h>
0006 #include <JANA/Utils/JTypeInfo.h>
0007 #include <typeindex>
0008 
0009 namespace jana::components {
0010 
0011 template <typename T>
0012 class Output : public JHasOutputs::OutputBase {
0013     std::vector<T*> m_transient_data;
0014     std::vector<T*>* m_external_data = nullptr; // This is a hack for JFactoryT
0015     JLightweightDatabundleT<T>* m_databundle; // Just so that we have a typed reference
0016 
0017 public:
0018     Output(JHasOutputs* owner, std::string short_name="") {
0019         owner->RegisterOutput(this);
0020         m_databundle = new JLightweightDatabundleT<T>();
0021         m_databundle->SetTypeName(JTypeInfo::demangle<T>());
0022         m_databundle->SetTypeIndex(std::type_index(typeid(T)));
0023         m_databundle->SetShortName(short_name);
0024         SetDatabundle(m_databundle);
0025         // Factory will be set by JFactorySet, not here
0026     }
0027 
0028     Output(JHasOutputs* owner, std::vector<T*>* external_data, std::string short_name="") {
0029         owner->RegisterOutput(this);
0030         m_databundle = new JLightweightDatabundleT<T>(external_data);
0031         m_databundle->SetTypeName(JTypeInfo::demangle<T>());
0032         m_databundle->SetTypeIndex(std::type_index(typeid(T)));
0033         m_databundle->SetShortName(short_name);
0034         m_external_data = external_data;
0035         SetDatabundle(m_databundle);
0036         // Factory will be set by JFactorySet, not here
0037     }
0038 
0039     void SetNotOwnerFlag(bool not_owner) {
0040         m_databundle->SetNotOwnerFlag(not_owner);
0041     }
0042 
0043     std::vector<T*>& operator()() { return (m_external_data == nullptr) ? m_transient_data : *m_external_data; }
0044 
0045     JLightweightDatabundleT<T>& GetDatabundle() { return *m_databundle; }
0046 
0047     void LagrangianStore(JFactorySet&, JDatabundle::Status status) override {
0048         if (m_external_data == nullptr) {
0049             m_databundle->GetData() = std::move(m_transient_data);
0050         }
0051         m_databundle->SetStatus(status);
0052     }
0053 
0054     void EulerianStore(JFactorySet& facset) override {
0055         JLightweightDatabundleT<T>* typed_bundle = nullptr;
0056         auto bundle = facset.GetDatabundle(m_databundle->GetTypeIndex(), m_databundle->GetUniqueName());
0057 
0058         if (bundle == nullptr) {
0059             // No databundle present. In this case we simply use m_podio_databundle as a template
0060             typed_bundle = new JLightweightDatabundleT<T>(*m_databundle);
0061             facset.Add(typed_bundle);
0062         }
0063         else {
0064             typed_bundle = dynamic_cast<JLightweightDatabundleT<T>*>(bundle);
0065             if (typed_bundle == nullptr) {
0066                 // Wrong databundle present
0067                 throw JException("Databundle with unique_name '%s' is not a JLightweightDatabundleT<%s>", m_databundle->GetUniqueName().c_str(), m_databundle->GetTypeName().c_str());
0068             }
0069         }
0070         if (m_external_data == nullptr) {
0071             typed_bundle->GetData() = std::move(m_transient_data);
0072         }
0073         else {
0074             typed_bundle->GetData() = std::move(*m_external_data);
0075         }
0076         typed_bundle->SetStatus(JDatabundle::Status::Inserted);
0077         auto fac = typed_bundle->GetFactory();
0078         if (fac != nullptr) {
0079             UpdateFactoryStatusOnEulerianStore(fac);
0080         }
0081     }
0082 };
0083 
0084 
0085 template <typename T>
0086 class VariadicOutput : public JHasOutputs::VariadicOutputBase {
0087     std::vector<std::vector<T*>> m_transient_datas;
0088     bool m_not_owner_flag = false;
0089 
0090 public:
0091     VariadicOutput(JHasOutputs* owner, std::string short_name="") {
0092         owner->RegisterOutput(this);
0093         auto* databundle = new JLightweightDatabundleT<T>();
0094         databundle->SetTypeName(JTypeInfo::demangle<T>());
0095         databundle->SetTypeIndex(std::type_index(typeid(T)));
0096         databundle->SetShortName(short_name);
0097         GetDatabundles().push_back(databundle);
0098         // Factory will be set by JFactorySet, not here
0099     }
0100 
0101     void SetNotOwnerFlag(bool not_owner) {
0102         m_not_owner_flag = not_owner;
0103         // We store this so that we can reapply it in case the user
0104         // calls SetShortNames() afterwards
0105         for (auto* db : GetDatabundles()) {
0106             auto typed_db = static_cast<JLightweightDatabundleT<T>*>(db);
0107             typed_db->SetNotOwnerFlag(not_owner);
0108         }
0109     }
0110 
0111     std::vector<std::vector<T*>>& operator()() { return m_transient_datas; }
0112     std::vector<std::vector<T*>>* operator->() { return &m_transient_datas; }
0113 
0114     void SetShortNames(std::vector<std::string> short_names) override {
0115         for (auto& db : GetDatabundles()) {
0116             delete db;
0117         }
0118         GetDatabundles().clear();
0119         m_transient_datas.clear();
0120         for (const std::string& name : short_names) {
0121             auto databundle = new JLightweightDatabundleT<T>;
0122             databundle->SetShortName(name);
0123             databundle->SetTypeName(JTypeInfo::demangle<T>());
0124             databundle->SetTypeIndex(std::type_index(typeid(T)));
0125             databundle->SetNotOwnerFlag(m_not_owner_flag);
0126             GetDatabundles().push_back(databundle);
0127             m_transient_datas.push_back({});
0128         }
0129     }
0130     void SetUniqueNames(std::vector<std::string> unique_names) override {
0131         for (auto& db : GetDatabundles()) {
0132             delete db;
0133         }
0134         GetDatabundles().clear();
0135         m_transient_datas.clear();
0136         for (const std::string& name : unique_names) {
0137             auto databundle = new JLightweightDatabundleT<T>;
0138             databundle->SetUniqueName(name);
0139             databundle->SetTypeName(JTypeInfo::demangle<T>());
0140             databundle->SetTypeIndex(std::type_index(typeid(T)));
0141             databundle->SetNotOwnerFlag(m_not_owner_flag);
0142             GetDatabundles().push_back(databundle);
0143             m_transient_datas.push_back({});
0144         }
0145 
0146     }
0147 
0148     void LagrangianStore(JFactorySet&, JDatabundle::Status status) override {
0149         if (m_transient_datas.size() != GetDatabundles().size()) {
0150             throw JException("Wrong number of output vectors in variadic output: Expected %d, found %d", GetDatabundles().size(), m_transient_datas.size());
0151         }
0152         size_t i=0;
0153         for (auto* databundle : GetDatabundles()) {
0154             JLightweightDatabundleT<T>* typed_bundle = dynamic_cast<JLightweightDatabundleT<T>*>(databundle);
0155             if (typed_bundle == nullptr) {
0156                 throw JException("Databundle is not a JLightweightDatabundleT (Hint: This is an internal error)");
0157             }
0158             typed_bundle->GetData() = std::move(m_transient_datas.at(i));
0159             typed_bundle->SetStatus(status);
0160             i += 1;
0161         }
0162     }
0163 
0164     void EulerianStore(JFactorySet& facset) override {
0165 
0166         if (m_transient_datas.size() != GetDatabundles().size()) {
0167             throw JException("Wrong number of output vectors in variadic output: Expected %d, found %d", GetDatabundles().size(), m_transient_datas.size());
0168         }
0169         size_t i=0;
0170         for (auto* databundle_prototype : GetDatabundles()) {
0171             JLightweightDatabundleT<T>* typed_databundle = nullptr;
0172             auto* databundle = facset.GetDatabundle(databundle_prototype->GetUniqueName());
0173             if (databundle == nullptr) {
0174                 auto* typed_databundle_prototype = dynamic_cast<JLightweightDatabundleT<T>*>(databundle_prototype);
0175                 typed_databundle = new JLightweightDatabundleT<T>(*typed_databundle_prototype);
0176                 facset.Add(typed_databundle);
0177             }
0178             else {
0179                 typed_databundle = dynamic_cast<JLightweightDatabundleT<T>*>(databundle);
0180                 if (typed_databundle == nullptr) {
0181                     throw JException("Databundle with unique_name '%s' is not a JLightweightDatabundle<%s>", databundle_prototype->GetUniqueName().c_str(), JTypeInfo::demangle<T>().c_str());
0182                 }
0183             }
0184             typed_databundle->GetData() = std::move(m_transient_datas.at(i));
0185             typed_databundle->SetStatus(JDatabundle::Status::Inserted);
0186 
0187             auto fac = typed_databundle->GetFactory();
0188             if (fac != nullptr) {
0189                 UpdateFactoryStatusOnEulerianStore(fac);
0190             }
0191             i += 1;
0192         }
0193     }
0194 };
0195 
0196 } // jana::components
0197 
0198 template <typename T> using Output = jana::components::Output<T>;
0199 template <typename T> using VariadicOutput = jana::components::VariadicOutput<T>;