The Gaudi Framework  master (34daa81a)
Loading...
Searching...
No Matches
SplittingTransformer.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#pragma once
12
13#include "details.h"
14#include "utilities.h"
16#include <functional>
17#include <optional>
18#include <string>
19#include <vector>
20
21namespace Gaudi::Functional {
22
23 template <typename Container>
24 using vector_of_ = std::vector<Container>;
25 template <typename Container>
26 using vector_of_optional_ = std::vector<std::optional<Container>>;
27
28 namespace details {
29
30 template <typename Signature, typename Traits_, bool isLegacy>
32
34 template <typename Out, typename... In, typename Traits_>
35 class SplittingTransformer<vector_of_<Out>( const In&... ), Traits_, true>
36 : public details::DataHandleMixin<std::tuple<>, filter_evtcontext<In...>, Traits_> {
38
39 public:
40 constexpr static std::size_t N = base_class::N_in;
41 using KeyValue = typename base_class::KeyValue;
42 using KeyValues = typename base_class::KeyValues;
43
44 SplittingTransformer( std::string name, ISvcLocator* locator, const RepeatValues_<KeyValue, N>& inputs,
45 const KeyValues& outputs )
46 : base_class( std::move( name ), locator, inputs )
48 this, outputs.first, details::to_DataObjID( outputs.second ),
49 [this]( Gaudi::Details::PropertyBase& ) {
50 this->m_outputs =
52 },
54
55 SplittingTransformer( std::string name, ISvcLocator* locator, const KeyValue& input, const KeyValues& output )
56 : SplittingTransformer( std::move( name ), locator, std::forward_as_tuple( input ), output ) {
57 static_assert( N == 1, "single input argument requires single input signature" );
58 }
59
60 // accessor to output Locations
61 const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n].key(); }
62 unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
63
64 // derived classes can NOT implement execute
65 StatusCode execute() override final {
66 try {
67 // TODO:FIXME: how does operator() know the number and order of expected outputs?
68 auto out = details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs );
69 if ( out.size() != m_outputs.size() ) {
70 throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
71 " containers, got " + std::to_string( out.size() ) + " instead",
72 this->name(), StatusCode::FAILURE );
73 }
74 for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
76 } catch ( GaudiException& e ) {
77 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
78 return e.code();
79 }
80 }
81
82 // TODO/FIXME: how does the callee know in which order to produce the outputs?
83 // (note: 'missing' items can be specified by making Out an std::optional<Out>,
84 // and only those entries which contain an Out are stored)
85 virtual vector_of_<Out> operator()( const In&... ) const = 0;
86
87 private:
88 template <typename T>
90 std::vector<OutputHandle<Out>> m_outputs;
91 Gaudi::Property<std::vector<DataObjID>> m_outputLocations; // TODO/FIXME for now: use a call-back to update the
92 // actual handles!
93 };
94
95 template <typename Out, typename... In, typename Traits_>
96 class SplittingTransformer<vector_of_<Out>( const In&... ), Traits_, false>
97 : public details::DataHandleMixin<std::tuple<>, filter_evtcontext<In...>, Traits_> {
99
100 public:
101 constexpr static std::size_t N = base_class::N_in;
102 using KeyValue = typename base_class::KeyValue;
103 using KeyValues = typename base_class::KeyValues;
104
105 SplittingTransformer( std::string name, ISvcLocator* locator, const RepeatValues_<KeyValue, N>& inputs,
106 const KeyValues& outputs )
107 : base_class( std::move( name ), locator, inputs )
109 this, outputs.first, details::to_DataObjID( outputs.second ),
110 [this]( Gaudi::Details::PropertyBase& ) {
111 this->m_outputs =
113 },
115
116 SplittingTransformer( std::string name, ISvcLocator* locator, const KeyValue& input, const KeyValues& output )
117 : SplittingTransformer( std::move( name ), locator, std::forward_as_tuple( input ), output ) {
118 static_assert( N == 1, "single input argument requires single input signature" );
119 }
120
121 // accessor to output Locations
122 const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n].key(); }
123 unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
124
125 // derived classes can NOT implement execute
126 StatusCode execute( const EventContext& ctx ) const override final {
127 try {
128 // TODO:FIXME: how does operator() know the number and order of expected outputs?
129 auto out = details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs );
130 if ( out.size() != m_outputs.size() ) {
131 throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
132 " containers, got " + std::to_string( out.size() ) + " instead",
133 this->name(), StatusCode::FAILURE );
134 }
135 for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
137 } catch ( GaudiException& e ) {
138 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
139 return e.code();
140 }
141 }
142
143 // TODO/FIXME: how does the callee know in which order to produce the outputs?
144 // (note: 'missing' items can be specified by making Out an std::optional<Out>,
145 // and only those entries which contain an Out are stored)
146 virtual vector_of_<Out> operator()( const In&... ) const = 0;
147
148 private:
149 template <typename T>
151 std::vector<OutputHandle<Out>> m_outputs;
152 Gaudi::Property<std::vector<DataObjID>> m_outputLocations; // TODO/FIXME for now: use a call-back to update the
153 // actual handles!
154 };
155
156 } // namespace details
157
158 template <typename Signature, typename Traits_ = Traits::useDefaults>
160
161} // namespace Gaudi::Functional
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
This class represents an entry point to all the event specific data.
SplittingTransformer(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValues &output)
SplittingTransformer(std::string name, ISvcLocator *locator, const RepeatValues_< KeyValue, N > &inputs, const KeyValues &outputs)
details::DataHandleMixin< std::tuple<>, filter_evtcontext< In... >, Traits_ > base_class
SplittingTransformer(std::string name, ISvcLocator *locator, const RepeatValues_< KeyValue, N > &inputs, const KeyValues &outputs)
details::DataHandleMixin< std::tuple<>, filter_evtcontext< In... >, Traits_ > base_class
SplittingTransformer(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValues &output)
Implementation of property with value of concrete type.
Definition PropertyFwd.h:27
Define general base for Gaudi exception.
virtual const std::string & message() const
error message to be printed
virtual const StatusCode & code() const
StatusCode for Exception.
virtual const std::string & tag() const
name tag for the exception, or exception type
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isFailure() const
Definition StatusCode.h:129
constexpr static const auto FAILURE
Definition StatusCode.h:100
Gaudi::tagged_bool< class ImmediatelyInvokeHandler_tag > ImmediatelyInvokeHandler
Definition Property.h:23
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
Definition details.h:106
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition details.h:162
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< DataObjID > &init)
Definition details.h:467
typename detail2::OutputHandle< T, Tr, DataObjectWriteHandle >::type OutputHandle_t
Definition details.h:455
decltype(get_values_helper< Value >(std::make_index_sequence< N >())) RepeatValues_
Definition details.h:158
typename filter_evtcontext_t< In... >::type filter_evtcontext
Definition details.h:534
std::vector< Container > vector_of_
std::vector< std::optional< Container > > vector_of_optional_
details::SplittingTransformer< Signature, Traits_, details::isLegacy< Traits_ > > SplittingTransformer
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
STL namespace.
static auto apply(const Algorithm &algo, const EventContext &ctx, Handles &handles)
Definition details.h:504