File indexing completed on 2025-09-17 09:22:23
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 void Init() override {}
0037 void BeginRun(const std::shared_ptr<const JEvent>&) override {}
0038 void Process(const std::shared_ptr<const JEvent>&) override {}
0039 void EndRun() override {}
0040 void Finish() override {}
0041
0042
0043
0044
0045 template <typename T>
0046 void DeclareOutput(std::string short_name, bool owns_data=true);
0047
0048 template <typename T>
0049 void SetData(std::string short_name, std::vector<T*> data);
0050
0051 #if JANA2_HAVE_PODIO
0052
0053 template <typename T>
0054 void DeclarePodioOutput(std::string unique_name, bool owns_data=true);
0055
0056 template <typename T>
0057 void SetCollection(std::string unique_name, typename T::collection_type&& collection);
0058
0059 template <typename T>
0060 void SetCollection(std::string unique_name, std::unique_ptr<typename T::collection_type> collection);
0061
0062 #endif
0063 };
0064
0065
0066
0067 template <typename T>
0068 void JMultifactory::DeclareOutput(std::string short_name, bool owns_data) {
0069
0070 auto* output = new jana::components::Output<T>(this);
0071 output->SetShortName(short_name);
0072 output->SetNotOwnerFlag(!owns_data);
0073 m_owned_outputs.push_back(output);
0074 m_output_index[{std::type_index(typeid(T)), short_name}] = output;
0075 }
0076
0077 template <typename T>
0078 void JMultifactory::SetData(std::string short_name, std::vector<T*> data) {
0079 auto it = m_output_index.find({std::type_index(typeid(T)), short_name});
0080 if (it == m_output_index.end()) {
0081 auto ex = JException("Couldn't find output with short_name '%s'. Hint: Did you call DeclareOutput() in the constructor?", short_name.c_str());
0082 ex.function_name = "JMultifactory::SetData";
0083 ex.type_name = m_type_name;
0084 ex.instance_name = m_prefix;
0085 ex.plugin_name = m_plugin_name;
0086 throw ex;
0087 }
0088 auto* typed_output = dynamic_cast<jana::components::Output<T>*>(it->second);
0089 if (typed_output == nullptr) {
0090 auto ex = JException("OutputBase not castable to Output<T>. Hint: Did you mean to use SetCollection?");
0091 ex.function_name = "JMultifactory::SetData";
0092 ex.type_name = m_type_name;
0093 ex.instance_name = m_prefix;
0094 ex.plugin_name = m_plugin_name;
0095 throw ex;
0096 }
0097 (*typed_output)() = std::move(data);
0098 }
0099
0100
0101 #if JANA2_HAVE_PODIO
0102
0103 template <typename T>
0104 void JMultifactory::DeclarePodioOutput(std::string unique_name, bool owns_data) {
0105 auto* output = new jana::components::PodioOutput<T>(this);
0106 output->SetUniqueName(unique_name);
0107 output->SetSubsetCollection(!owns_data);
0108 m_owned_outputs.push_back(output);
0109 m_output_index[{std::type_index(typeid(T)), unique_name}] = output;
0110 }
0111
0112 template <typename T>
0113 void JMultifactory::SetCollection(std::string unique_name, typename T::collection_type&& collection) {
0114 auto it = m_output_index.find({std::type_index(typeid(T)), unique_name});
0115 if (it == m_output_index.end()) {
0116 auto ex = JException("Couldn't find output with short_name '%s'. Hint: Did you call DeclareOutput() in the constructor?", unique_name.c_str());
0117 ex.function_name = "JMultifactory::SetData";
0118 ex.type_name = m_type_name;
0119 ex.instance_name = m_prefix;
0120 ex.plugin_name = m_plugin_name;
0121 throw ex;
0122 }
0123 auto* typed_output = dynamic_cast<jana::components::PodioOutput<T>*>(it->second);
0124 if (typed_output == nullptr) {
0125 auto ex = JException("Databundle not castable to JLightweightDatabundleT. Hint: Did you mean to use SetCollection?");
0126 ex.function_name = "JMultifactory::SetData";
0127 ex.type_name = m_type_name;
0128 ex.instance_name = m_prefix;
0129 ex.plugin_name = m_plugin_name;
0130 throw ex;
0131 }
0132 *((*typed_output)()) = std::move(collection);
0133 }
0134
0135 template <typename T>
0136 void JMultifactory::SetCollection(std::string unique_name, std::unique_ptr<typename T::collection_type> collection) {
0137 auto it = m_output_index.find({std::type_index(typeid(T)), unique_name});
0138 if (it == m_output_index.end()) {
0139 auto ex = JException("Couldn't find output with short_name '%s'. Hint: Did you call DeclareOutput() in the constructor?", unique_name.c_str());
0140 ex.function_name = "JMultifactory::SetData";
0141 ex.type_name = m_type_name;
0142 ex.instance_name = m_prefix;
0143 ex.plugin_name = m_plugin_name;
0144 throw ex;
0145 }
0146 auto* typed_output = dynamic_cast<jana::components::PodioOutput<T>*>(it->second);
0147 if (typed_output == nullptr) {
0148 auto ex = JException("Databundle not castable to JLightweightDatabundleT. Hint: Did you mean to use SetCollection?");
0149 ex.function_name = "JMultifactory::SetData";
0150 ex.type_name = m_type_name;
0151 ex.instance_name = m_prefix;
0152 ex.plugin_name = m_plugin_name;
0153 throw ex;
0154 }
0155 *((*typed_output)()) = std::move(*collection);
0156 }
0157
0158 #endif
0159
0160
0161
0162