| The Gaudi Framework v32r1 (f65d50dc)

SplittingTransformer.h
Go to the documentation of this file.
1 #ifndef SPLITTING_TRANSFORMER_H
2 #define SPLITTING_TRANSFORMER_H
3
4 #include <functional>
5 #include <optional>
6 #include <string>
7 #include <vector>
8
9 #include "GaudiAlg/FunctionalDetails.h"
10 #include "GaudiAlg/FunctionalUtilities.h"
11
12 namespace Gaudi::Functional {
13
14 template <typename Container>
15 using vector_of_ = std::vector<Container>;
16 template <typename Container>
17 using vector_of_optional_ = std::vector<std::optional<Container>>;
18
19 namespace details {
20
21 template <typename Signature, typename Traits_, bool isLegacy>
22 class SplittingTransformer;
23
25 template <typename Out, typename... In, typename Traits_>
26 class SplittingTransformer<vector_of_<Out>( const In&... ), Traits_, true>
27 : public details::DataHandleMixin<void, std::tuple<In...>, Traits_> {
28 using base_class = details::DataHandleMixin<void, std::tuple<In...>, Traits_>;
29
30 public:
31 constexpr static std::size_t N = base_class::N_in;
32 using KeyValue = typename base_class::KeyValue;
33 using KeyValues = typename base_class::KeyValues;
34
35 SplittingTransformer( const std::string& name, ISvcLocator* locator, const std::array<KeyValue, N>& inputs,
36 const KeyValues& outputs )
37 : base_class( name, locator, inputs )
38 , m_outputLocations(
39 this, outputs.first, outputs.second,
40 [=]( Gaudi::Details::PropertyBase& ) {
41 this->m_outputs =
42 details::make_vector_of_handles<decltype( this->m_outputs )>( this, m_outputLocations );
43 if constexpr ( details::is_optional_v<Out> ) { // handle constructor does not (yet) allow to
44 // set optional flag... so
45 // do it explicitly here...
46 std::for_each( this->m_outputs.begin(), this->m_outputs.end(),
47 []( auto& h ) { h.setOptional( true ); } );
48 }
49 },
50 Gaudi::Details::Property::ImmediatelyInvokeHandler{true} ) {}
51
52 SplittingTransformer( const std::string& name, ISvcLocator* locator, const KeyValue& input,
53 const KeyValues& output )
54 : SplittingTransformer( name, locator, std::array<KeyValue, 1>{input}, output ) {
55 static_assert( N == 1, "single input argument requires single input signature" );
56 }
57
58 // accessor to output Locations
59 const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n]; }
60 unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
61
62 // derived classes can NOT implement execute
63 StatusCode execute() override final {
64 try {
65 // TODO:FIXME: how does operator() know the number and order of expected outputs?
66 auto out = details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs );
67 if ( out.size() != m_outputs.size() ) {
68 throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
69 " containers, got " + std::to_string( out.size() ) + " instead",
70 this->name(), StatusCode::FAILURE );
71 }
72 for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
73 return StatusCode::SUCCESS;
74 } catch ( GaudiException& e ) {
75 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
76 return e.code();
77 }
78 }
79
80 // TODO/FIXME: how does the callee know in which order to produce the outputs?
81 // (note: 'missing' items can be specified by making Out an boost::optional<Out>,
82 // and only those entries which contain an Out are stored)
83 virtual vector_of_<Out> operator()( const In&... ) const = 0;
84
85 private:
86 template <typename T>
87 using OutputHandle = details::OutputHandle_t<Traits_, details::remove_optional_t<T>>;
88 std::vector<OutputHandle<Out>> m_outputs;
89 Gaudi::Property<std::vector<std::string>> m_outputLocations; // TODO/FIXME for now: use a call-back to update the
90 // actual handles!
91 };
92
93 template <typename Out, typename... In, typename Traits_>
94 class SplittingTransformer<vector_of_<Out>( const In&... ), Traits_, false>
95 : public details::DataHandleMixin<void, std::tuple<In...>, Traits_> {
96 using base_class = details::DataHandleMixin<void, std::tuple<In...>, Traits_>;
97
98 public:
99 constexpr static std::size_t N = base_class::N_in;
100 using KeyValue = typename base_class::KeyValue;
101 using KeyValues = typename base_class::KeyValues;
102
103 SplittingTransformer( const std::string& name, ISvcLocator* locator, const std::array<KeyValue, N>& inputs,
104 const KeyValues& outputs )
105 : base_class( name, locator, inputs )
106 , m_outputLocations(
107 this, outputs.first, outputs.second,
108 [=]( Gaudi::Details::PropertyBase& ) {
109 this->m_outputs =
110 details::make_vector_of_handles<decltype( this->m_outputs )>( this, m_outputLocations );
111 if constexpr ( details::is_optional_v<Out> ) { // handle constructor does not (yet) allow to
112 // set optional flag... so
113 // do it explicitly here...
114 std::for_each( this->m_outputs.begin(), this->m_outputs.end(),
115 []( auto& h ) { h.setOptional( true ); } );
116 }
117 },
118 Gaudi::Details::Property::ImmediatelyInvokeHandler{true} ) {}
119
120 SplittingTransformer( const std::string& name, ISvcLocator* locator, const KeyValue& input,
121 const KeyValues& output )
122 : SplittingTransformer( name, locator, std::array<KeyValue, 1>{input}, output ) {
123 static_assert( N == 1, "single input argument requires single input signature" );
124 }
125
126 // accessor to output Locations
127 const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n]; }
128 unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
129
130 // derived classes can NOT implement execute
131 StatusCode execute( const EventContext& ctx ) const override final {
132 try {
133 // TODO:FIXME: how does operator() know the number and order of expected outputs?
134 auto out = details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs );
135 if ( out.size() != m_outputs.size() ) {
136 throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
137 " containers, got " + std::to_string( out.size() ) + " instead",
138 this->name(), StatusCode::FAILURE );
139 }
140 for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
141 return StatusCode::SUCCESS;
142 } catch ( GaudiException& e ) {
143 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
144 return e.code();
145 }
146 }
147
148 // TODO/FIXME: how does the callee know in which order to produce the outputs?
149 // (note: 'missing' items can be specified by making Out an boost::optional<Out>,
150 // and only those entries which contain an Out are stored)
151 virtual vector_of_<Out> operator()( const In&... ) const = 0;
152
153 private:
154 template <typename T>
155 using OutputHandle = details::OutputHandle_t<Traits_, details::remove_optional_t<T>>;
156 std::vector<OutputHandle<Out>> m_outputs;
157 Gaudi::Property<std::vector<std::string>> m_outputLocations; // TODO/FIXME for now: use a call-back to update the
158 // actual handles!
159 };
160
161 } // namespace details
162
163 template <typename Signature, typename Traits_ = Traits::useDefaults>
164 using SplittingTransformer = details::SplittingTransformer<Signature, Traits_, details::isLegacy<Traits_>>;
165
166 } // namespace Gaudi::Functional
167
168 #endif
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::outputLocation
const std::string & outputLocation(unsigned int n) const
Definition: SplittingTransformer.h:59
Gaudi::Functional::details::DataHandleMixin< void, std::tuple< In... >, Traits_ >
Definition: FunctionalDetails.h:484
GaudiException
Define general base for Gaudi exception.
Definition: GaudiException.h:21
ISvcLocator
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:41
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::outputLocationSize
unsigned int outputLocationSize() const
Definition: SplittingTransformer.h:128
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:352
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::SplittingTransformer
SplittingTransformer(const std::string &name, ISvcLocator *locator, const KeyValue &input, const KeyValues &output)
Definition: SplittingTransformer.h:52
gaudirun.output
output
Definition: gaudirun.py:484
Gaudi::Details::Property::ImmediatelyInvokeHandler
Gaudi::tagged_bool< class ImmediatelyInvokeHandler_tag > ImmediatelyInvokeHandler
Definition: Property.h:141
std::to_string
T to_string(T... args)
GaudiException::message
virtual const std::string & message() const
error message to be printed
Definition: GaudiException.h:58
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::m_outputLocations
Gaudi::Property< std::vector< std::string > > m_outputLocations
Definition: SplittingTransformer.h:157
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
std
STL namespace.
std::size_t
EventContext
This class represents an entry point to all the event specific data.
Definition: EventContext.h:24
Gaudi::Functional
Definition: Consumer.h:8
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::SplittingTransformer
SplittingTransformer(const std::string &name, ISvcLocator *locator, const std::array< KeyValue, N > &inputs, const KeyValues &outputs)
Definition: SplittingTransformer.h:103
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::m_outputLocations
Gaudi::Property< std::vector< std::string > > m_outputLocations
Definition: SplittingTransformer.h:89
Gaudi::Units::second
constexpr double second
Definition: SystemOfUnits.h:121
std::string
STL class.
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:210
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::SplittingTransformer
SplittingTransformer(const std::string &name, ISvcLocator *locator, const std::array< KeyValue, N > &inputs, const KeyValues &outputs)
Definition: SplittingTransformer.h:35
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::m_outputs
std::vector< OutputHandle< Out > > m_outputs
Definition: SplittingTransformer.h:156
IOTest.N
int N
Definition: IOTest.py:99
Gaudi::Functional::details::DataHandleMixin
Definition: FunctionalDetails.h:390
details
Definition: AnyDataWrapper.h:10
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
FunctionalUtilities.h
Gaudi::Functional::details::SplittingTransformer
Definition: SplittingTransformer.h:22
Gaudi::Functional::details::filter_evtcontext_t::apply
static auto apply(const Algorithm &algo, Handles &handles)
Definition: FunctionalDetails.h:353
Gaudi::Functional::vector_of_
details::template vector_of_const_< Container > vector_of_
Definition: ListTransformer.h:9
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::OutputHandle
details::OutputHandle_t< Traits_, details::remove_optional_t< T > > OutputHandle
Definition: SplittingTransformer.h:155
std::move
T move(T... args)
std::tuple
std::pair< std::string, std::string >
GaudiException::code
virtual const StatusCode & code() const
StatusCode for Exception.
Definition: GaudiException.h:76
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::SplittingTransformer
SplittingTransformer(const std::string &name, ISvcLocator *locator, const KeyValue &input, const KeyValues &output)
Definition: SplittingTransformer.h:120
Containers::array
struct GAUDI_API array
Parametrisation class for redirection array - like implementation.
Definition: KeyedObjectManager.h:27
std::vector
STL class.
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: SplittingTransformer.h:63
Gaudi::Functional::details::OutputHandle_t
Gaudi::cpp17::detected_or_t< DataObjectWriteHandle< T >, detail2::OutputHandle_t, Tr, T > OutputHandle_t
Definition: FunctionalDetails.h:309
Gaudi::Functional::details::put
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: FunctionalDetails.h:121
std::array
STL class.
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::outputLocationSize
unsigned int outputLocationSize() const
Definition: SplittingTransformer.h:60
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::OutputHandle
details::OutputHandle_t< Traits_, details::remove_optional_t< T > > OutputHandle
Definition: SplittingTransformer.h:87
std::for_each
T for_each(T... args)
Gaudi::Functional::details::make_vector_of_handles
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< std::string > &init)
Definition: FunctionalDetails.h:320
Gaudi
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::m_outputs
std::vector< OutputHandle< Out > > m_outputs
Definition: SplittingTransformer.h:88
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::outputLocation
const std::string & outputLocation(unsigned int n) const
Definition: SplittingTransformer.h:127
FunctionalDetails.h
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: SplittingTransformer.h:131