File indexing completed on 2025-10-24 09:25:53
0001
0002
0003
0004
0005 #pragma once
0006
0007 #include <JANA/JFactory.h>
0008 #include <JANA/Components/JHasRunCallbacks.h>
0009 #include <JANA/Components/JLightweightOutput.h>
0010 #include <JANA/JVersion.h>
0011 #include <typeindex>
0012
0013 #if JANA2_HAVE_PODIO
0014 #include "JANA/Components/JPodioOutput.h"
0015 #endif
0016
0017
0018 class JMultifactory : public JFactory {
0019
0020 private:
0021 std::vector<OutputBase*> m_owned_outputs;
0022 std::map<std::pair<std::type_index, std::string>, OutputBase*> m_output_index;
0023
0024 public:
0025 JMultifactory() {
0026 SetCallbackStyle(CallbackStyle::LegacyMode);
0027 }
0028 virtual ~JMultifactory() {
0029 for (auto* output : m_owned_outputs) {
0030 delete output;
0031 }
0032 }
0033
0034
0035
0036 using JFactory::ChangeRun;
0037 virtual void ChangeRun(int32_t) {};
0038
0039
0040
0041
0042 void Init() override {}
0043 void BeginRun(const std::shared_ptr<const JEvent>&) override {}
0044 void Process(const std::shared_ptr<const JEvent>&) override {}
0045 void EndRun() override {}
0046 void Finish() override {}
0047
0048
0049
0050
0051 template <typename T>
0052 void DeclareOutput(std::string short_name, bool owns_data=true);
0053
0054 template <typename T>
0055 void SetData(std::string short_name, std::vector<T*> data);
0056
0057 #if JANA2_HAVE_PODIO
0058
0059 template <typename T>
0060 void DeclarePodioOutput(std::string unique_name, bool owns_data=true);
0061
0062 template <typename T>
0063 void SetCollection(std::string unique_name, typename T::collection_type&& collection);
0064
0065 template <typename T>
0066 void SetCollection(std::string unique_name, std::unique_ptr<typename T::collection_type> collection);
0067
0068 #endif
0069 };
0070
0071
0072
0073 template <typename T>
0074 void JMultifactory::DeclareOutput(std::string short_name, bool owns_data) {
0075
0076 auto* output = new jana::components::Output<T>(this);
0077 output->SetShortName(short_name);
0078 output->SetNotOwnerFlag(!owns_data);
0079 m_owned_outputs.push_back(output);
0080 m_output_index[{std::type_index(typeid(T)), short_name}] = output;
0081 }
0082
0083 template <typename T>
0084 void JMultifactory::SetData(std::string short_name, std::vector<T*> data) {
0085 auto it = m_output_index.find({std::type_index(typeid(T)), short_name});
0086 if (it == m_output_index.end()) {
0087 auto ex = JException("Couldn't find output with short_name '%s'. Hint: Did you call DeclareOutput() in the constructor?", short_name.c_str());
0088 ex.function_name = "JMultifactory::SetData";
0089 ex.type_name = m_type_name;
0090 ex.instance_name = m_prefix;
0091 ex.plugin_name = m_plugin_name;
0092 throw ex;
0093 }
0094 auto* typed_output = dynamic_cast<jana::components::Output<T>*>(it->second);
0095 if (typed_output == nullptr) {
0096 auto ex = JException("OutputBase not castable to Output<T>. Hint: Did you mean to use SetCollection?");
0097 ex.function_name = "JMultifactory::SetData";
0098 ex.type_name = m_type_name;
0099 ex.instance_name = m_prefix;
0100 ex.plugin_name = m_plugin_name;
0101 throw ex;
0102 }
0103 (*typed_output)() = std::move(data);
0104 }
0105
0106
0107 #if JANA2_HAVE_PODIO
0108
0109 template <typename T>
0110 void JMultifactory::DeclarePodioOutput(std::string unique_name, bool owns_data) {
0111 auto* output = new jana::components::PodioOutput<T>(this);
0112 output->SetUniqueName(unique_name);
0113 output->SetSubsetCollection(!owns_data);
0114 m_owned_outputs.push_back(output);
0115 m_output_index[{std::type_index(typeid(T)), unique_name}] = output;
0116 }
0117
0118 template <typename T>
0119 void JMultifactory::SetCollection(std::string unique_name, typename T::collection_type&& collection) {
0120 auto it = m_output_index.find({std::type_index(typeid(T)), unique_name});
0121 if (it == m_output_index.end()) {
0122 auto ex = JException("Couldn't find output with short_name '%s'. Hint: Did you call DeclareOutput() in the constructor?", unique_name.c_str());
0123 ex.function_name = "JMultifactory::SetData";
0124 ex.type_name = m_type_name;
0125 ex.instance_name = m_prefix;
0126 ex.plugin_name = m_plugin_name;
0127 throw ex;
0128 }
0129 auto* typed_output = dynamic_cast<jana::components::PodioOutput<T>*>(it->second);
0130 if (typed_output == nullptr) {
0131 auto ex = JException("Databundle not castable to JLightweightDatabundleT. Hint: Did you mean to use SetCollection?");
0132 ex.function_name = "JMultifactory::SetData";
0133 ex.type_name = m_type_name;
0134 ex.instance_name = m_prefix;
0135 ex.plugin_name = m_plugin_name;
0136 throw ex;
0137 }
0138 *((*typed_output)()) = std::move(collection);
0139 }
0140
0141 template <typename T>
0142 void JMultifactory::SetCollection(std::string unique_name, std::unique_ptr<typename T::collection_type> collection) {
0143 auto it = m_output_index.find({std::type_index(typeid(T)), unique_name});
0144 if (it == m_output_index.end()) {
0145 auto ex = JException("Couldn't find output with short_name '%s'. Hint: Did you call DeclareOutput() in the constructor?", unique_name.c_str());
0146 ex.function_name = "JMultifactory::SetData";
0147 ex.type_name = m_type_name;
0148 ex.instance_name = m_prefix;
0149 ex.plugin_name = m_plugin_name;
0150 throw ex;
0151 }
0152 auto* typed_output = dynamic_cast<jana::components::PodioOutput<T>*>(it->second);
0153 if (typed_output == nullptr) {
0154 auto ex = JException("Databundle not castable to JLightweightDatabundleT. Hint: Did you mean to use SetCollection?");
0155 ex.function_name = "JMultifactory::SetData";
0156 ex.type_name = m_type_name;
0157 ex.instance_name = m_prefix;
0158 ex.plugin_name = m_plugin_name;
0159 throw ex;
0160 }
0161 *((*typed_output)()) = std::move(*collection);
0162 }
0163
0164 #endif
0165
0166
0167
0168