ATLAS Offline Software
SafeDecorator.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #ifndef INDETTRACKPERFMON_SAFEDECORATOR_H
6 #define INDETTRACKPERFMON_SAFEDECORATOR_H
7 
23 #include "GaudiKernel/EventContext.h"
24 #include "CxxUtils/fpcompare.h" // for equal
25 
26 #include <iostream>
27 #include <utility>
28 #include <vector>
29 #include <cmath>
30 #include <cstdlib>
31 
32 namespace IDTPM {
33 
35  template< class ContainerType, class VariableType >
37  std::pair< SG::WriteDecorHandleKey<ContainerType>,
39  //
40  template< class ContainerType, class VariableType >
42  std::pair< SG::WriteDecorHandle<ContainerType, VariableType>,
44  //
45  template< class ContainerType, class VariableType >
47  std::pair< SG::WriteDecorHandle<ContainerType, VariableType>, bool >;
48 
51  template< class T_Parent, class T_Cont, class T >
53  T_Parent& parent,
54  const SG::ReadHandleKey< T_Cont >& container_key,
55  const std::string& prefix,
56  const std::vector< std::string >& decor_names,
57  std::vector< WriteKeyAccessorPair<T_Cont, T > >& decor_out )
58  {
59  decor_out.clear();
60  decor_out.reserve( decor_names.size() );
61  for( const std::string& a_decor_name: decor_names ) {
62  decor_out.emplace_back(
63  SG::WriteDecorHandleKey< T_Cont >( container_key.key()+"."+prefix+a_decor_name ),
65  );
66  parent.declare( decor_out.back().first );
67  decor_out.back().first.setOwner( &parent );
68  decor_out.back().first.initialize().ignore();
69  }
70  }
71 
74  template< class T_Parent, class T_Cont >
76  T_Parent& parent,
77  const SG::ReadHandleKey< T_Cont >& container_key,
78  const std::string& prefix,
79  const std::vector< std::string >& decor_names,
80  std::vector< SG::WriteDecorHandleKey< T_Cont > >& decor_out)
81  {
82  decor_out.clear();
83  decor_out.reserve( decor_names.size() );
84  for (const std::string &a_decor_name : decor_names) {
85  assert( !a_decor_name.empty() );
86  decor_out.emplace_back( container_key.key()+"."+prefix+a_decor_name );
87  // need to declare handles, otherwise the scheduler would not
88  // pick up the data dependencies introduced by the decorations
89  parent.declare( decor_out.back() );
90  decor_out.back().setOwner(&parent);
91  decor_out.back().initialize().ignore();
92  }
93  }
94 
96  /*template<class T_Parent, class T_Cont>
97  void addReadDecoratorHandleKeys(T_Parent &parent,
98  const SG::ReadHandleKey<T_Cont> &container_key,
99  const std::string &prefix,
100  const std::vector<std::string> &decor_names,
101  std::vector<SG::ReadDecorHandleKey<T_Cont> > &decor_out) {
102  decor_out.reserve(decor_out.size() + decor_names.size());
103  for (const std::string &a_decor_name : decor_names) {
104  decor_out.emplace_back( container_key.key()+"."+prefix+a_decor_name);
105  parent.declare(decor_out.back());
106  decor_out.back().setOwner(&parent);
107  decor_out.back().initialize().ignore();
108  }
109  }*/
110 
112  template< class T_Cont, class T >
113  std::vector< OptionalDecoration< T_Cont,T > >
115  const T_Cont& container,
116  const std::vector< WriteKeyAccessorPair<T_Cont, T > >& keys,
117  const EventContext& ctx,
118  bool verbose=false )
119  {
120  std::vector< OptionalDecoration< T_Cont, T > > out;
121  bool all_available = true;
122  if( !container.empty() ) {
123  std::vector<bool> decorate;
124  decorate.reserve( keys.size() );
125  for( const WriteKeyAccessorPair< T_Cont, T >& a_key : keys ) {
126  decorate.push_back( !a_key.second.isAvailable( *container[0] ) );
127  all_available &= !decorate.back();
128  if( verbose && !decorate.back() ) {
129  std::cout << "WARNING IDTPM::createDecoratorsIfNeeded: Decoration "
130  << a_key.first.key() << " already exists; reject update."
131  << std::endl;
132  } // close if( verbose && !decorate.back() )
133  } // close WriteKeyAccessorPair loop
134 
135  if( !all_available ) {
136  std::size_t idx = 0;
137  out.reserve( keys.size() );
138  for( const WriteKeyAccessorPair< T_Cont, T >& a_key : keys ) {
139  assert( idx < decorate.size() );
140  out.emplace_back(
141  SG::WriteDecorHandle< T_Cont,T >( a_key.first, ctx ),
142  decorate[idx++]
143  );
144  if( not out.back().first.isPresent() ) {
145  std::stringstream msg;
146  msg << "Container " << a_key.first.key()
147  << " to be decorated does not exist.";
148  throw std::runtime_error( msg.str() );
149  } // close if( not out.back().first.isPresent() )
150  } // close WriteKeyAccessorPair loop
151  } // close if( !all_available )
152  } // close if( !container.empty() )
153  return out;
154  }
155 
157  template< class T_Cont, class T >
158  std::vector< SG::WriteDecorHandle< T_Cont, T > >
160  const std::vector< SG::WriteDecorHandleKey< T_Cont > >& keys,
161  const EventContext& ctx )
162  {
163  std::vector< SG::WriteDecorHandle< T_Cont, T > > out;
164  out.reserve( keys.size() );
165  for( const SG::WriteDecorHandleKey< T_Cont >& a_key : keys ) {
166  out.emplace_back( a_key, ctx );
167  if( not out.back().isValid() ) {
168  std::stringstream msg;
169  msg << "Failed to create decorator handle " << a_key.key();
170  throw std::runtime_error( msg.str() );
171  }
172  } // close SG::WriteDecorHandleKey loop
173  return out;
174  }
175 
177  template< class T_Cont, class T_Cont_Elm, class T >
179  const T_Cont_Elm& particle,
181  const T& value )
182  {
183  if( !decorator.second.isAvailable( particle ) ) {
184  const T existing = decorator.second( particle );
185  if( not CxxUtils::fpcompare::equal( existing, value ) ) {
186  std::cout << "WARNING IDTPM::safeDecorator: " << decorator.first.decorKey()
187  << " Already exists on this object with a different value."
188  << std::endl;
189  }
190  } else {
191  decorator.first( particle ) = value;
192  }
193  }
194 
196  template< class T_Cont, class T_Cont_Elm, class T >
198  const T_Cont_Elm& particle,
200  const T& value)
201  {
202  if( decorator.second ) {
203  decorator.first( particle ) = value;
204  }
205  }
206 
208  template< class T_Cont, class T_Cont_Elm, class T >
209  void decorate(
210  const T_Cont_Elm& particle,
212  const T& value)
213  {
214  decorator.first( particle ) = value;
215  }
216 
217 } // namespace IDTPM
218 
219 #endif // > !INDETTRACKPERFMON_SAFEDECORATOR_H
SG::WriteDecorHandleKey
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Definition: StoreGate/StoreGate/WriteDecorHandleKey.h:89
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
ReadDecorHandleKey.h
Property holding a SG store/key/clid/attr name from which a ReadDecorHandle is made.
IDTPM::decorate
void decorate(const T_Cont_Elm &particle, OptionalDecoration< T_Cont, T > &decorator, const T &value)
unsafe fill decoration method for convenience
Definition: SafeDecorator.h:209
IDTPM::createDecorators
std::vector< SG::WriteDecorHandle< T_Cont, T > > createDecorators(const std::vector< SG::WriteDecorHandleKey< T_Cont > > &keys, const EventContext &ctx)
similar to createDecoratorsIfNeeded, but without the checking if decorations already exist
Definition: SafeDecorator.h:159
IDTPM::decorateOrRejectQuietly
void decorateOrRejectQuietly(const T_Cont_Elm &particle, OptionalDecoration< T_Cont, T > &decorator, const T &value)
Safe method to fill the decoration if decor flag is true.
Definition: SafeDecorator.h:197
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
athena.value
value
Definition: athena.py:124
IDTPM::createDecoratorsIfNeeded
std::vector< OptionalDecoration< T_Cont, T > > createDecoratorsIfNeeded(const T_Cont &container, const std::vector< WriteKeyAccessorPair< T_Cont, T > > &keys, const EventContext &ctx, bool verbose=false)
Like above - FIXME: maybe not needed.
Definition: SafeDecorator.h:114
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
SG::ReadHandleKey< T_Cont >
CxxUtils::fpcompare::equal
bool equal(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition: fpcompare.h:114
IDTPM::createDecoratorKeys
void createDecoratorKeys(T_Parent &parent, const SG::ReadHandleKey< T_Cont > &container_key, const std::string &prefix, const std::vector< std::string > &decor_names, std::vector< SG::WriteDecorHandleKey< T_Cont > > &decor_out)
like createDecoratorKeysAndAccessor but without the accessor to check the availablilty of a decoratio...
Definition: SafeDecorator.h:75
WriteDecorHandleKey.h
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
IDTPM::decorateOrWarnIfUnequal
void decorateOrWarnIfUnequal(const T_Cont_Elm &particle, WriteAccessorRefPair< T_Cont, T > &decorator, const T &value)
Fill the decoration if it deas not exist or it has a different value.
Definition: SafeDecorator.h:178
IDTPM::WriteAccessorRefPair
std::pair< SG::WriteDecorHandle< ContainerType, VariableType >, SG::AuxElement::ConstAccessor< VariableType > & > WriteAccessorRefPair
Definition: SafeDecorator.h:43
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
fpcompare.h
Workaround x86 precision issues for FP inequality comparisons.
WriteDecorHandle.h
Handle class for adding a decoration to an object.
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
test_pyathena.parent
parent
Definition: test_pyathena.py:15
IDTPM::createDecoratorKeysAndAccessor
void createDecoratorKeysAndAccessor(T_Parent &parent, const SG::ReadHandleKey< T_Cont > &container_key, const std::string &prefix, const std::vector< std::string > &decor_names, std::vector< WriteKeyAccessorPair< T_Cont, T > > &decor_out)
create a pair composed of a WriteDecorHandleKey to create a decorator handle and an accessor to check...
Definition: SafeDecorator.h:52
IDTPM::WriteKeyAccessorPair
std::pair< SG::WriteDecorHandleKey< ContainerType >, SG::AuxElement::ConstAccessor< VariableType > > WriteKeyAccessorPair
Useful declarations.
Definition: SafeDecorator.h:38
python.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:297
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
ReadDecorHandle.h
Handle class for reading a decoration on an object.
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
IDTPM::OptionalDecoration
std::pair< SG::WriteDecorHandle< ContainerType, VariableType >, bool > OptionalDecoration
Definition: SafeDecorator.h:47
IDTPM
Athena include(s).
Definition: IPlotsDefinitionSvc.h:25
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
AuxElement.h
Base class for elements of a container that can have aux data.