ATLAS Offline Software
Loading...
Searching...
No Matches
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
17
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
32namespace 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 ),
64 SG::AuxElement::ConstAccessor<T>( 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 >
114 const T_Cont& container,
115 const std::vector< WriteKeyAccessorPair<T_Cont, T > >& keys,
116 bool verbose=false )
117 {
118 bool all_available = true;
119 if( !container.empty() ) {
120 std::vector<bool> decorate;
121 decorate.reserve( keys.size() );
122 for( const WriteKeyAccessorPair< T_Cont, T >& a_key : keys ) {
123 decorate.push_back( !a_key.second.isAvailable( *container[0] ) );
124 all_available &= !decorate.back();
125 if( verbose && !decorate.back() ) {
126 std::cout << "WARNING IDTPM::decorationsAllExist: Decoration "
127 << a_key.first.key() << " already exists; reject update."
128 << std::endl;
129 } // close if( verbose && !decorate.back() )
130 } // close WriteKeyAccessorPair loop
131 } // close if( !container.empty() )
132 return all_available;
133 }
134
136 template< class T_Cont, class T >
137 std::vector< OptionalDecoration< T_Cont,T > >
139 const T_Cont& container,
140 const std::vector< WriteKeyAccessorPair<T_Cont, T > >& keys,
141 const EventContext& ctx,
142 bool verbose=false )
143 {
144 std::vector< OptionalDecoration< T_Cont, T > > out;
145 bool all_available = true;
146 if( !container.empty() ) {
147 std::vector<bool> decorate;
148 decorate.reserve( keys.size() );
149 for( const WriteKeyAccessorPair< T_Cont, T >& a_key : keys ) {
150 decorate.push_back( !a_key.second.isAvailable( *container[0] ) );
151 all_available &= !decorate.back();
152 if( verbose && !decorate.back() ) {
153 std::cout << "WARNING IDTPM::createDecoratorsIfNeeded: Decoration "
154 << a_key.first.key() << " already exists; reject update."
155 << std::endl;
156 } // close if( verbose && !decorate.back() )
157 } // close WriteKeyAccessorPair loop
158
159 if( !all_available ) {
160 std::size_t idx = 0;
161 out.reserve( keys.size() );
162 for( const WriteKeyAccessorPair< T_Cont, T >& a_key : keys ) {
163 assert( idx < decorate.size() );
164 out.emplace_back(
165 SG::WriteDecorHandle< T_Cont,T >( a_key.first, ctx ),
166 decorate[idx++]
167 );
168 if( not out.back().first.isPresent() ) {
169 std::stringstream msg;
170 msg << "Container " << a_key.first.key()
171 << " to be decorated does not exist.";
172 throw std::runtime_error( msg.str() );
173 } // close if( not out.back().first.isPresent() )
174 } // close WriteKeyAccessorPair loop
175 } // close if( !all_available )
176 } // close if( !container.empty() )
177 return out;
178 }
179
181 template< class T_Cont, class T >
182 std::vector< SG::WriteDecorHandle< T_Cont, T > >
184 const std::vector< SG::WriteDecorHandleKey< T_Cont > >& keys,
185 const EventContext& ctx )
186 {
187 std::vector< SG::WriteDecorHandle< T_Cont, T > > out;
188 out.reserve( keys.size() );
189 for( const SG::WriteDecorHandleKey< T_Cont >& a_key : keys ) {
190 out.emplace_back( a_key, ctx );
191 if( not out.back().isValid() ) {
192 std::stringstream msg;
193 msg << "Failed to create decorator handle " << a_key.key();
194 throw std::runtime_error( msg.str() );
195 }
196 } // close SG::WriteDecorHandleKey loop
197 return out;
198 }
199
201 template< class T_Cont, class T_Cont_Elm, class T >
203 const T_Cont_Elm& particle,
205 const T& value )
206 {
207 if( !decorator.second.isAvailable( particle ) ) {
208 const T existing = decorator.second( particle );
209 if( not CxxUtils::fpcompare::equal( existing, value ) ) {
210 std::cout << "WARNING IDTPM::safeDecorator: " << decorator.first.decorKey()
211 << " Already exists on this object with a different value."
212 << std::endl;
213 }
214 } else {
215 decorator.first( particle ) = value;
216 }
217 }
218
220 template< class T_Cont, class T_Cont_Elm, class T >
222 const T_Cont_Elm& particle,
224 const T& value)
225 {
226 if( decorator.second ) {
227 decorator.first( particle ) = value;
228 }
229 }
230
232 template< class T_Cont, class T_Cont_Elm, class T >
234 const T_Cont_Elm& particle,
236 const T& value)
237 {
238 decorator.first( particle ) = value;
239 }
240
241} // namespace IDTPM
242
243#endif // > !INDETTRACKPERFMON_SAFEDECORATOR_H
Base class for elements of a container that can have aux data.
Property holding a SG store/key/clid/attr name from which a ReadDecorHandle is made.
Handle class for reading a decoration on an object.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Handle class for adding a decoration to an object.
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
const std::string & key() const
Return the StoreGate ID for the referenced object.
Property holding a SG store/key/clid/attr name from which a WriteDecorHandle is made.
Handle class for adding a decoration to an object.
Workaround x86 precision issues for FP inequality comparisons.
bool verbose
Definition hcg.cxx:73
bool equal(double a, double b)
Compare two FP numbers, working around x87 precision issues.
Definition fpcompare.h:114
Athena include(s).
std::pair< SG::WriteDecorHandle< ContainerType, VariableType >, bool > OptionalDecoration
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.
std::pair< SG::WriteDecorHandleKey< ContainerType >, SG::AuxElement::ConstAccessor< VariableType > > WriteKeyAccessorPair
Useful declarations.
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
bool decorationsAllExist(const T_Cont &container, const std::vector< WriteKeyAccessorPair< T_Cont, T > > &keys, bool verbose=false)
Like above - FIXME: maybe not needed.
void decorate(const T_Cont_Elm &particle, OptionalDecoration< T_Cont, T > &decorator, const T &value)
unsafe fill decoration method for convenience
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...
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...
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)
create/book the decorations if they do not exist already
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.
std::pair< SG::WriteDecorHandle< ContainerType, VariableType >, SG::AuxElement::ConstAccessor< VariableType > & > WriteAccessorRefPair
MsgStream & msg
Definition testRead.cxx:32