The Gaudi Framework  master (37c0b60a)
SplittingTransformer.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2023 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 
21 namespace Gaudi::Functional {
22 
23  template <typename Container>
25  template <typename 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>
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 
45  const KeyValues& outputs )
46  : base_class( std::move( name ), locator, inputs )
47  , m_outputLocations(
48  this, outputs.first, details::to_DataObjID( outputs.second ),
49  [this]( Gaudi::Details::PropertyBase& ) {
50  this->m_outputs =
51  details::make_vector_of_handles<decltype( this->m_outputs )>( this, m_outputLocations );
52  if constexpr ( details::is_optional_v<Out> ) { // handle constructor does not (yet) allow to
53  // set optional flag... so
54  // do it explicitly here...
55  std::for_each( this->m_outputs.begin(), this->m_outputs.end(),
56  []( auto& h ) { h.setOptional( true ); } );
57  }
58  },
60 
62  : SplittingTransformer( std::move( name ), locator, std::forward_as_tuple( input ), output ) {
63  static_assert( N == 1, "single input argument requires single input signature" );
64  }
65 
66  // accessor to output Locations
67  const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n].key(); }
68  unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
69 
70  // derived classes can NOT implement execute
71  StatusCode execute() override final {
72  try {
73  // TODO:FIXME: how does operator() know the number and order of expected outputs?
74  auto out = details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs );
75  if ( out.size() != m_outputs.size() ) {
76  throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
77  " containers, got " + std::to_string( out.size() ) + " instead",
78  this->name(), StatusCode::FAILURE );
79  }
80  for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
82  } catch ( GaudiException& e ) {
83  if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
84  return e.code();
85  }
86  }
87 
88  // TODO/FIXME: how does the callee know in which order to produce the outputs?
89  // (note: 'missing' items can be specified by making Out an std::optional<Out>,
90  // and only those entries which contain an Out are stored)
91  virtual vector_of_<Out> operator()( const In&... ) const = 0;
92 
93  private:
94  template <typename T>
97  Gaudi::Property<std::vector<DataObjID>> m_outputLocations; // TODO/FIXME for now: use a call-back to update the
98  // actual handles!
99  };
100 
101  template <typename Out, typename... In, typename Traits_>
102  class SplittingTransformer<vector_of_<Out>( const In&... ), Traits_, false>
105 
106  public:
107  constexpr static std::size_t N = base_class::N_in;
108  using KeyValue = typename base_class::KeyValue;
109  using KeyValues = typename base_class::KeyValues;
110 
112  const KeyValues& outputs )
113  : base_class( std::move( name ), locator, inputs )
114  , m_outputLocations(
115  this, outputs.first, details::to_DataObjID( outputs.second ),
116  [this]( Gaudi::Details::PropertyBase& ) {
117  this->m_outputs =
118  details::make_vector_of_handles<decltype( this->m_outputs )>( this, m_outputLocations );
119  if constexpr ( details::is_optional_v<Out> ) { // handle constructor does not (yet) allow to
120  // set optional flag... so
121  // do it explicitly here...
122  std::for_each( this->m_outputs.begin(), this->m_outputs.end(),
123  []( auto& h ) { h.setOptional( true ); } );
124  }
125  },
127 
129  : SplittingTransformer( std::move( name ), locator, std::forward_as_tuple( input ), output ) {
130  static_assert( N == 1, "single input argument requires single input signature" );
131  }
132 
133  // accessor to output Locations
134  const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n].key(); }
135  unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
136 
137  // derived classes can NOT implement execute
138  StatusCode execute( const EventContext& ctx ) const override final {
139  try {
140  // TODO:FIXME: how does operator() know the number and order of expected outputs?
141  auto out = details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs );
142  if ( out.size() != m_outputs.size() ) {
143  throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
144  " containers, got " + std::to_string( out.size() ) + " instead",
145  this->name(), StatusCode::FAILURE );
146  }
147  for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
148  return FilterDecision::PASSED;
149  } catch ( GaudiException& e ) {
150  if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
151  return e.code();
152  }
153  }
154 
155  // TODO/FIXME: how does the callee know in which order to produce the outputs?
156  // (note: 'missing' items can be specified by making Out an std::optional<Out>,
157  // and only those entries which contain an Out are stored)
158  virtual vector_of_<Out> operator()( const In&... ) const = 0;
159 
160  private:
161  template <typename T>
164  Gaudi::Property<std::vector<DataObjID>> m_outputLocations; // TODO/FIXME for now: use a call-back to update the
165  // actual handles!
166  };
167 
168  } // namespace details
169 
170  template <typename Signature, typename Traits_ = Traits::useDefaults>
172 
173 } // namespace Gaudi::Functional
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::KeyValues
typename base_class::KeyValues KeyValues
Definition: SplittingTransformer.h:109
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::m_outputs
std::vector< OutputHandle< Out > > m_outputs
Definition: SplittingTransformer.h:96
std::for_each
T for_each(T... args)
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::KeyValue
typename base_class::KeyValue KeyValue
Definition: SplittingTransformer.h:108
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:95
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::SplittingTransformer
SplittingTransformer(std::string name, ISvcLocator *locator, const RepeatValues_< KeyValue, N > &inputs, const KeyValues &outputs)
Definition: SplittingTransformer.h:111
std::string
STL class.
IOTest.N
N
Definition: IOTest.py:112
std::move
T move(T... args)
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::KeyValues
typename base_class::KeyValues KeyValues
Definition: SplittingTransformer.h:42
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::outputLocation
const std::string & outputLocation(unsigned int n) const
Definition: SplittingTransformer.h:67
std::vector
STL class.
ISvcLocator
Definition: ISvcLocator.h:46
GaudiException
Definition: GaudiException.h:31
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::SplittingTransformer
SplittingTransformer(std::string name, ISvcLocator *locator, const RepeatValues_< KeyValue, N > &inputs, const KeyValues &outputs)
Definition: SplittingTransformer.h:44
Gaudi::Functional::details::SplittingTransformer
Definition: SplittingTransformer.h:31
std::tuple
Gaudi::Units::second
constexpr double second
Definition: SystemOfUnits.h:139
gaudirun.output
output
Definition: gaudirun.py:521
Gaudi::Functional::details::to_DataObjID
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
Definition: details.h:114
Gaudi::Functional::vector_of_
std::vector< Container > vector_of_
Definition: SplittingMergingTransformer.h:23
GaudiException::message
virtual const std::string & message() const
error message to be printed
Definition: GaudiException.h:68
Gaudi::Functional::details::make_vector_of_handles
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< DataObjID > &init)
Definition: details.h:435
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::m_outputs
std::vector< OutputHandle< Out > > m_outputs
Definition: SplittingTransformer.h:163
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::operator()
virtual vector_of_< Out > operator()(const In &...) const =0
GaudiPython.Pythonizations.ctx
ctx
Definition: Pythonizations.py:578
StatusCode
Definition: StatusCode.h:65
Gaudi::tagged_bool_ns::tagged_bool
Definition: TaggedBool.h:16
details
Definition: AnyDataWrapper.h:19
AlgSequencer.h
h
Definition: AlgSequencer.py:31
std::to_string
T to_string(T... args)
Gaudi::Functional::details::filter_evtcontext_t::apply
static auto apply(const Algorithm &algo, Handles &handles)
Definition: details.h:472
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::SplittingTransformer
SplittingTransformer(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValues &output)
Definition: SplittingTransformer.h:128
Gaudi::Functional::FilterDecision::PASSED
@ PASSED
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::outputLocationSize
unsigned int outputLocationSize() const
Definition: SplittingTransformer.h:135
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::m_outputLocations
Gaudi::Property< std::vector< DataObjID > > m_outputLocations
Definition: SplittingTransformer.h:97
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::operator()
virtual vector_of_< Out > operator()(const In &...) const =0
Gaudi::Functional
Definition: Consumer.h:19
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
GaudiException::tag
virtual const std::string & tag() const
name tag for the exception, or exception type
Definition: GaudiException.h:77
utilities.h
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: SplittingTransformer.h:71
cpluginsvc.n
n
Definition: cpluginsvc.py:234
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::outputLocation
const std::string & outputLocation(unsigned int n) const
Definition: SplittingTransformer.h:134
GaudiException::code
virtual const StatusCode & code() const
StatusCode for Exception.
Definition: GaudiException.h:86
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: SplittingTransformer.h:138
std
STL namespace.
EventContext
Definition: EventContext.h:34
Gaudi::Functional::details::RepeatValues_
decltype(get_values_helper< Value >(std::make_index_sequence< N >())) RepeatValues_
Definition: details.h:162
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:162
Gaudi::Functional::details::DataHandleMixin
Definition: details.h:506
std::size_t
details.h
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::outputLocationSize
unsigned int outputLocationSize() const
Definition: SplittingTransformer.h:68
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
Gaudi::Functional::vector_of_optional_
std::vector< std::optional< Container > > vector_of_optional_
Definition: SplittingMergingTransformer.h:25
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, false >::m_outputLocations
Gaudi::Property< std::vector< DataObjID > > m_outputLocations
Definition: SplittingTransformer.h:164
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::KeyValue
typename base_class::KeyValue KeyValue
Definition: SplittingTransformer.h:41
FunctionalFilterDecision.h
Gaudi::Functional::details::OutputHandle_t
Gaudi::cpp17::detected_or_t< DataObjectWriteHandle< T >, detail2::OutputHandle_t, Tr, T > OutputHandle_t
Definition: details.h:423
Gaudi::Functional::details::filter_evtcontext
typename filter_evtcontext_t< In... >::type filter_evtcontext
Definition: details.h:503
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:37
Gaudi::Functional::details::put
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: details.h:168
Gaudi::Functional::details::SplittingTransformer< vector_of_< Out >(const In &...), Traits_, true >::SplittingTransformer
SplittingTransformer(std::string name, ISvcLocator *locator, const KeyValue &input, const KeyValues &output)
Definition: SplittingTransformer.h:61
PrepareBase.out
out
Definition: PrepareBase.py:20