File indexing completed on 2026-06-04 08:41:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef FWCORE_CONSUMER_H
0020 #define FWCORE_CONSUMER_H
0021
0022 #include "Gaudi/Functional/details.h"
0023 #include "Gaudi/Functional/utilities.h"
0024 #include "GaudiKernel/FunctionalFilterDecision.h"
0025
0026
0027
0028 #include "k4FWCore/FunctionalUtils.h"
0029
0030 #include <algorithm>
0031 #include <stdexcept>
0032 #include <type_traits>
0033 #include <utility>
0034 #include <variant>
0035
0036 namespace k4FWCore {
0037
0038 namespace details {
0039
0040 template <typename Signature, typename Traits_>
0041 struct Consumer;
0042
0043 template <typename... In, typename Traits_>
0044 struct Consumer<void(const In&...), Traits_>
0045 : Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_> {
0046 using Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_>::DataHandleMixin;
0047
0048 static_assert(((std::is_base_of_v<podio::CollectionBase, In> || isVectorLike_v<In> ||
0049 std::is_same_v<In, EventContext>) &&
0050 ...),
0051 "Consumer input types must be EDM4hep collections or vectors of collection pointers");
0052
0053 static constexpr size_t N_in = filter_evtcontext<In...>::size;
0054
0055 using base_class = Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_>;
0056
0057 using KeyValue = base_class::KeyValue;
0058 using KeyValues = base_class::KeyValues;
0059
0060 template <typename T>
0061 using InputHandle_t = Gaudi::Functional::details::InputHandle_t<Traits_, T>;
0062
0063 tuple_of_handle_vec_t<InputHandle_t, filter_evtcontext_t<In...>> m_inputs;
0064
0065 std::array<Gaudi::Property<DataObjID>, N_in> m_inputLocationsSingle;
0066 std::array<Gaudi::Property<std::vector<DataObjID>>, N_in> m_inputLocationsVector;
0067
0068 template <typename IArgs, std::size_t... I>
0069 Consumer(std::string name, ISvcLocator* locator, const IArgs& inputs, std::index_sequence<I...>)
0070 : base_class(std::move(name), locator),
0071
0072
0073
0074
0075 m_inputLocationsSingle{makeInputPropSingle<InputHandle_t<EventStoreType_t>, KeyValue>(
0076 std::get<I>(inputs), std::get<I>(m_inputs), this)...},
0077 m_inputLocationsVector{makeInputPropVector<InputHandle_t<EventStoreType_t>, KeyValues>(
0078 std::get<I>(inputs), std::get<I>(m_inputs), this)...} {}
0079
0080 Consumer(std::string name, ISvcLocator* locator,
0081 const Gaudi::Functional::details::RepeatValues_<std::variant<KeyValue, KeyValues>, N_in>& inputs)
0082 : Consumer(std::move(name), locator, inputs, std::make_index_sequence<N_in>{}) {}
0083
0084 StatusCode execute(const EventContext& ctx) const final {
0085 try {
0086 filter_evtcontext<In...>::apply(*this, ctx, m_inputs);
0087 return Gaudi::Functional::FilterDecision::PASSED;
0088 } catch (GaudiException& e) {
0089 (e.code() ? this->warning() : this->error()) << e.tag() << " : " << e.message() << endmsg;
0090 return e.code();
0091 }
0092 }
0093
0094 virtual void operator()(const In&...) const = 0;
0095
0096
0097
0098
0099
0100
0101 auto inputLocations(size_t i) const {
0102 if (i >= N_in) {
0103 throw std::out_of_range("Called inputLocations with an index out of range, index: " + std::to_string(i) +
0104 ", number of inputs: " + std::to_string(N_in));
0105 }
0106 std::vector<std::string> names;
0107 if (!m_inputLocationsSingle[i].name().empty()) {
0108 names.push_back(m_inputLocationsSingle[i].value().key());
0109 } else {
0110 for (const auto& id : m_inputLocationsVector[i].value()) {
0111 names.push_back(id.key());
0112 }
0113 }
0114 return names;
0115 }
0116
0117
0118
0119
0120
0121 auto inputLocations(std::string_view name) const {
0122 std::vector<std::string> names;
0123 const auto it =
0124 std::ranges::find_if(m_inputLocationsVector, [&name](const auto& prop) { return prop.name() == name; });
0125 if (it != m_inputLocationsVector.end()) {
0126 for (const auto& id : it->value()) {
0127 names.push_back(id.key());
0128 }
0129 } else {
0130 const auto it2 =
0131 std::ranges::find_if(m_inputLocationsSingle, [&name](const auto& prop) { return prop.name() == name; });
0132 if (it2 == m_inputLocationsSingle.end()) {
0133 throw std::out_of_range("Called inputLocations with a name that does not exist: " + std::string(name));
0134 } else {
0135 names.push_back(it2->value().key());
0136 }
0137 }
0138 return names;
0139 }
0140 static constexpr std::size_t inputLocationsSize() { return N_in; }
0141 };
0142
0143 }
0144
0145 template <typename Signature, typename Traits_ = Gaudi::Functional::Traits::useDefaults>
0146 using Consumer = details::Consumer<Signature, Traits_>;
0147
0148 }
0149
0150 #endif