The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
Transformer.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 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"
17#include <tuple>
18#include <utility>
19
20// Adapt an Algorithm (by default, Gaudi::Algorithm) so that derived classes
21// a) do not need to access the event store, and have to explicitly
22// state their data dependencies
23// b) are encouraged not to have state which depends on the events
24// (eg. histograms, counters will have to be mutable)
25
26namespace Gaudi ::Functional {
27
28 namespace details {
29
30 template <typename Signature, typename Traits_, bool isLegacy>
32
33 // general N -> 1 algorithms
34 template <typename Out, typename... In, typename Traits_>
35 struct Transformer<Out( const In&... ), Traits_, true>
36 : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
37 using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
38
39 // derived classes can NOT implement execute
40 StatusCode execute() override final {
41 try {
42 if constexpr ( sizeof...( In ) == 0 ) {
43 put( std::get<0>( this->m_outputs ), ( *this )() );
44 } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
45 put( std::get<0>( this->m_outputs ), ( *this )( Gaudi::Hive::currentContext() ) );
46 } else {
47 put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
48 }
49 return FilterDecision::PASSED;
50 } catch ( GaudiException& e ) {
51 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
52 return e.code();
53 }
54 }
55
56 // instead they MUST implement this operator
57 virtual Out operator()( const In&... ) const = 0;
58 };
59
60 template <typename Out, typename... In, typename Traits_>
61 struct Transformer<Out( const In&... ), Traits_, false>
62 : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
63 using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
64
65 // derived classes can NOT implement execute
66 StatusCode execute( const EventContext& ctx ) const override final {
67 try {
68 if constexpr ( sizeof...( In ) == 0 ) {
69 put( std::get<0>( this->m_outputs ), ( *this )() );
70 } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
71 put( std::get<0>( this->m_outputs ), ( *this )( ctx ) );
72 } else {
73 put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
74 }
75 return FilterDecision::PASSED;
76 } catch ( GaudiException& e ) {
77 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
78 return e.code();
79 }
80 }
81
82 // instead they MUST implement this operator
83 virtual Out operator()( const In&... ) const = 0;
84 };
85
86 //
87 // general N -> M algorithms
88 //
89 template <typename Signature, typename Traits_, bool isLegacy>
91
92 template <typename... Out, typename... In, typename Traits_>
93 struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, true>
94 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
95 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
96
97 // derived classes can NOT implement execute
98 StatusCode execute() override final {
99 try {
100 std::apply(
101 [this]( auto&... ohandle ) {
102 if constexpr ( sizeof...( In ) == 0 ) {
103 std::apply( [&ohandle...](
104 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
105 std::as_const( *this )() );
106 } else {
107 std::apply( [&ohandle...](
108 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
109 filter_evtcontext_t<In...>::apply( std::as_const( *this ), this->m_inputs ) );
110 }
111 },
112 this->m_outputs );
113 return FilterDecision::PASSED;
114 } catch ( GaudiException& e ) {
115 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
116 return e.code();
117 }
118 }
119
120 // instead they MUST implement this operator
121 virtual std::tuple<Out...> operator()( const In&... ) const = 0;
122 };
123
124 template <typename... Out, typename... In, typename Traits_>
125 struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, false>
126 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
127 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
128
129 // derived classes can NOT implement execute
130 StatusCode execute( const EventContext& ctx ) const override final {
131 try {
132 std::apply(
133 [this, &ctx]( auto&... ohandle ) {
134 if constexpr ( sizeof...( In ) == 0 ) {
135 std::apply( [&ohandle...](
136 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
137 ( *this )() );
138 } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
139 std::apply( [&ohandle...](
140 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
141 ( *this )( ctx ) );
142 } else {
143 std::apply( [&ohandle...](
144 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
145 filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
146 }
147 },
148 this->m_outputs );
149 return FilterDecision::PASSED;
150 } catch ( GaudiException& e ) {
151 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
152 return e.code();
153 }
154 }
155
156 // instead they MUST implement this operator
157 virtual std::tuple<Out...> operator()( const In&... ) const = 0;
158 };
159
160 //
161 // general N -> M algorithms with filter functionality
162 //
163 template <typename Signature, typename Traits_, bool isLegacy>
165
166 template <typename... Out, typename... In, typename Traits_>
167 struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, true>
168 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
169 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
170
171 // derived classes can NOT implement execute
172 StatusCode execute() override final {
173 try {
174 return std::apply(
175 [&]( auto&... ohandle ) {
176 return std::apply(
177 [&ohandle...]( bool passed, auto&&... data ) {
178 ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
179 return passed;
180 },
181 filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
182 },
183 this->m_outputs )
184 ? FilterDecision::PASSED
185 : FilterDecision::FAILED;
186 } catch ( GaudiException& e ) {
187 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
188 return e.code();
189 }
190 }
191
192 // instead they MUST implement this operator
193 virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
194 };
195
196 template <typename... Out, typename... In, typename Traits_>
197 struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, false>
198 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
199 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
200
201 // derived classes can NOT implement execute
202 StatusCode execute( const EventContext& ctx ) const override final {
203 try {
204 return std::apply(
205 [&]( auto&... ohandle ) {
206 return std::apply(
207 [&ohandle...]( bool passed, auto&&... data ) {
208 ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
209 return passed;
210 },
211 filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
212 },
213 this->m_outputs )
214 ? FilterDecision::PASSED
215 : FilterDecision::FAILED;
216 } catch ( GaudiException& e ) {
217 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
218 return e.code();
219 }
220 }
221
222 // instead they MUST implement this operator
223 virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
224 };
225 } // namespace details
226
227 template <typename Signature, typename Traits_ = Traits::useDefaults>
229
230 template <typename Signature, typename Traits_ = Traits::useDefaults>
232
233 template <typename Signature, typename Traits_ = Traits::useDefaults>
235
236} // 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.
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
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isFailure() const
Definition StatusCode.h:129
details::MultiTransformer< Signature, Traits_, details::isLegacy< Traits_ > > MultiTransformer
details::Transformer< Signature, Traits_, details::isLegacy< Traits_ > > Transformer
details::MultiTransformerFilter< Signature, Traits_, details::isLegacy< Traits_ > > MultiTransformerFilter
GAUDI_API const EventContext & currentContext()
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.
StatusCode execute(const EventContext &ctx) const override final
Definition Transformer.h:66