File indexing completed on 2025-05-11 08:57:26
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 <ranges>
0031 #include <stdexcept>
0032 #include <type_traits>
0033 #include <utility>
0034
0035 namespace k4FWCore {
0036
0037 namespace details {
0038
0039 template <typename Signature, typename Traits_> struct Consumer;
0040
0041 template <typename... In, typename Traits_>
0042 struct Consumer<void(const In&...), Traits_>
0043 : Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_> {
0044 using Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_>::DataHandleMixin;
0045
0046 static_assert(((std::is_base_of_v<podio::CollectionBase, In> || isVectorLike_v<In>)&&...),
0047 "Consumer input types must be EDM4hep collections or vectors of collection pointers");
0048
0049 template <typename T> using InputHandle_t = Gaudi::Functional::details::InputHandle_t<Traits_, T>;
0050
0051 std::tuple<std::vector<InputHandle_t<typename EventStoreType<In>::type>>...> m_inputs;
0052 std::array<Gaudi::Property<std::vector<DataObjID>>, sizeof...(In)> m_inputLocations{};
0053
0054 using base_class = Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_>;
0055
0056 using KeyValues = typename base_class::KeyValues;
0057
0058 template <typename IArgs, std::size_t... I>
0059 Consumer(std::string name, ISvcLocator* locator, const IArgs& inputs, std::index_sequence<I...>)
0060 : base_class(std::move(name), locator),
0061
0062
0063
0064
0065 m_inputLocations{Gaudi::Property<std::vector<DataObjID>>{
0066 this, std::get<I>(inputs).first, to_DataObjID(std::get<I>(inputs).second),
0067 [this](Gaudi::Details::PropertyBase&) {
0068 std::vector<InputHandle_t<EventStoreType_t>> handles;
0069 for (auto& value : this->m_inputLocations[I].value()) {
0070 auto handle = InputHandle_t<EventStoreType_t>(value, this);
0071 handles.push_back(std::move(handle));
0072 }
0073 std::get<I>(m_inputs) = std::move(handles);
0074 },
0075 Gaudi::Details::Property::ImmediatelyInvokeHandler{true}}...} {}
0076
0077 Consumer(std::string name, ISvcLocator* locator,
0078 Gaudi::Functional::details::RepeatValues_<KeyValues, sizeof...(In)> const& inputs)
0079 : Consumer(std::move(name), locator, inputs, std::index_sequence_for<In...>{}) {}
0080
0081
0082 StatusCode execute(const EventContext& ctx) const final {
0083 try {
0084 filter_evtcontext_tt<In...>::apply(*this, ctx, m_inputs);
0085 return Gaudi::Functional::FilterDecision::PASSED;
0086 } catch (GaudiException& e) {
0087 (e.code() ? this->warning() : this->error()) << e.tag() << " : " << e.message() << endmsg;
0088 return e.code();
0089 }
0090 }
0091
0092
0093 virtual void operator()(const In&...) const = 0;
0094
0095
0096
0097
0098
0099
0100 auto inputLocations(size_t i) const {
0101 if (i >= sizeof...(In)) {
0102 throw std::out_of_range("Called inputLocations with an index out of range, index: " + std::to_string(i) +
0103 ", number of inputs: " + std::to_string(sizeof...(In)));
0104 }
0105 return m_inputLocations[i] | std::views::transform([](const DataObjID& id) -> const auto& { return id.key(); });
0106 }
0107
0108
0109
0110
0111
0112 auto inputLocations(std::string_view name) const {
0113 auto it = std::ranges::find_if(m_inputLocations, [&name](const auto& prop) { return prop.name() == name; });
0114 if (it == m_inputLocations.end()) {
0115 throw std::runtime_error("Called inputLocations with an unknown name");
0116 }
0117 return it->value() | std::views::transform([](const DataObjID& id) -> const auto& { return id.key(); });
0118 }
0119 static constexpr std::size_t inputLocationsSize() { return sizeof...(In); }
0120 };
0121
0122 }
0123
0124 template <typename Signature, typename Traits_ = Gaudi::Functional::Traits::useDefaults>
0125 using Consumer = details::Consumer<Signature, Traits_>;
0126
0127 }
0128
0129 #endif