ATLAS Offline Software
Loading...
Searching...
No Matches
safeDecorator.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef IDPVM_safeDecorator_h
6#define IDPVM_safeDecorator_h
13
14
15
21#include "GaudiKernel/EventContext.h"
22
23#include <iostream>
24#include <utility>
25#include <vector>
26
27#include <cstdlib>
28
29namespace IDPVM {
30 // @name roughlyEqual overloaded functions
31 // @{
32 bool roughlyEqual(const int i, const int j);
33 bool roughlyEqual(const unsigned int i, const unsigned int j);
34 bool roughlyEqual(const float i, const float j);
35 // @}
36 // @enum DuplicateBehaviour
41 template<class ContainerType, class VariableType>
42 using WriteKeyAccessorPair = std::pair<SG::WriteDecorHandleKey<ContainerType>, SG::AuxElement::ConstAccessor<VariableType> >;
43 //
44 template<class ContainerType, class VariableType>
45 using WriteAccessorRefPair = std::pair<SG::WriteDecorHandle<ContainerType, VariableType>, SG::AuxElement::ConstAccessor<VariableType>& >;
46
47 template<class ContainerType, class VariableType>
48 using OptionalDecoration = std::pair<SG::WriteDecorHandle<ContainerType, VariableType>, bool >;
49 // create a pair composed of a WriteDecorHandleKey to create a decorator handle
50 // and an accessor to check the availablilty of a decoration
51 template <class T_Parent, class T_Cont, class T>
52 void createDecoratorKeysAndAccessor(T_Parent &parent,
53 const SG::ReadHandleKey<T_Cont> &container_key,
54 const std::string &prefix,
55 const std::vector<std::string> &decor_names,
56 std::vector<WriteKeyAccessorPair<T_Cont, T > > &decor_out) {
57 decor_out.clear();
58 decor_out.reserve(decor_names.size());
59 for (const std::string &a_decor_name: decor_names) {
60 decor_out.emplace_back(SG::WriteDecorHandleKey<T_Cont>(container_key.key()+"."+prefix+a_decor_name),
61 SG::AuxElement::ConstAccessor<T>(prefix+a_decor_name));
62 parent.declare(decor_out.back().first);
63 decor_out.back().first.setOwner(&parent);
64 decor_out.back().first.initialize().ignore();
65 }
66 }
67
68 template <class T_Cont, class T>
69 std::vector<OptionalDecoration<T_Cont,T> >
71 const std::vector<WriteKeyAccessorPair<T_Cont, T > > &keys,
72 const EventContext &ctx,
73 bool verbose=false) {
74 std::vector<OptionalDecoration<T_Cont, T> > out;
75 bool all_available=true;
76 if (!container.empty()) {
77 std::vector<bool> decorate;
78 decorate.reserve(keys.size());
79 for( const WriteKeyAccessorPair<T_Cont, T> &a_key : keys) {
80 decorate.push_back(!a_key.second.isAvailable(*container[0]) );
81 all_available &= !decorate.back();
82 if (verbose && !decorate.back()) {
83 std::cout << "WARNING IDPVM::createDecoratorsIfNeeded: Decoration " << a_key.first.key() <<
84 " already exists; reject update.\n";
85 }
86 }
87 if (!all_available) {
88 std::size_t idx=0;
89 out.reserve(keys.size());
90 for( const WriteKeyAccessorPair<T_Cont, T> &a_key : keys) {
91 assert( idx < decorate.size());
92 out.emplace_back(SG::WriteDecorHandle<T_Cont,T>(a_key.first,ctx), decorate[idx++]);
93 if (not out.back().first.isPresent()) {
94 std::stringstream msg;
95 msg << "Container " << a_key.first.key() << " to be decorated does not exist.";
96 throw std::runtime_error( msg.str() );
97 }
98 }
99 }
100 }
101 return out;
102 }
103
104
105 template <class T_Cont, class T>
106 std::vector<SG::WriteDecorHandle<T_Cont,T> >
108 const EventContext &ctx) {
109 std::vector<SG::WriteDecorHandle<T_Cont,T> > out;
110 out.reserve(keys.size());
111 for( const SG::WriteDecorHandleKey<T_Cont> &a_key : keys) {
112 out.emplace_back(a_key,ctx);
113 if (not out.back().isValid()) {
114 std::stringstream msg;
115 msg << "Failed to create decorator handdle " << a_key.key();
116 throw std::runtime_error( msg.str() );
117 }
118 }
119 return out;
120 }
121
122
123 // convenience method to create several decorators
124 template<class T_Parent, class T_Cont>
125 void createDecoratorKeys(T_Parent &parent,
126 const SG::ReadHandleKey<T_Cont> &container_key,
127 const std::string &prefix,
128 const std::vector<std::string> &decor_names,
129 std::vector<SG::WriteDecorHandleKey<T_Cont> > &decor_out) {
130 decor_out.clear();
131 decor_out.reserve(decor_names.size());
132 for (const std::string &a_decor_name : decor_names) {
133 assert( !a_decor_name.empty() );
134 decor_out.emplace_back(container_key.key()+"."+prefix+a_decor_name);
135 // need to declare handles, otherwise the scheduler would not pick up the data dependencies
136 // introduced by the decorations
137 parent.declare(decor_out.back());
138 decor_out.back().setOwner(&parent);
139 decor_out.back().initialize().ignore();
140 }
141 }
142
143
144 template<class T_Parent, class T_Cont>
145 void addReadDecoratorHandleKeys(T_Parent &parent,
146 const SG::ReadHandleKey<T_Cont> &container_key,
147 const std::string &prefix,
148 const std::vector<std::string> &decor_names,
149 std::vector<SG::ReadDecorHandleKey<T_Cont> > &decor_out) {
150 decor_out.reserve(decor_out.size() + decor_names.size());
151 for (const std::string &a_decor_name : decor_names) {
152 decor_out.emplace_back( container_key.key()+"."+prefix+a_decor_name);
153 parent.declare(decor_out.back());
154 decor_out.back().setOwner(&parent);
155 decor_out.back().initialize().ignore();
156 }
157 }
158
159
160 template <class T_Cont, class T_Cont_Elm, class T>
161 void decorateOrWarnIfUnequal(const T_Cont_Elm& particle,WriteAccessorRefPair<T_Cont, T> &decorator,
162 const T& value) {
163 if (!decorator.second.isAvailable(particle)) {
164 const T existing = decorator.second(particle);
165 if (not IDPVM::roughlyEqual(existing, value)) {
166 std::cout << "WARNING IDPVM::safeDecorator: " << decorator.first.decorKey() <<
167 " Already exists on this object with a different value.\n";
168 }
169 } else {
170 decorator.first(particle) = value;
171 }
172 }
173
174 template <class T_Cont, class T_Cont_Elm, class T>
175 void decorateOrRejectQuietly(const T_Cont_Elm& particle,OptionalDecoration<T_Cont,T> &decorator,
176 const T& value) {
177 if (decorator.second) {
178 decorator.first(particle) = value;
179 }
180 }
181
182 // unsafe method for convenience
183 template <class T_Cont, class T_Cont_Elm, class T>
184 void decorate(const T_Cont_Elm& particle,OptionalDecoration<T_Cont,T> &decorator,
185 const T& value) {
186 decorator.first(particle) = value;
187 }
188
189
190}
191#endif
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
Property holding a SG store/key/clid/attr name from which a ReadDecorHandle is made.
Property holding a SG store/key/clid from which a ReadHandle is made.
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.
bool verbose
Definition hcg.cxx:73
Class to retrieve associated truth from a track, implementing a cached response.
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)
void addReadDecoratorHandleKeys(T_Parent &parent, const SG::ReadHandleKey< T_Cont > &container_key, const std::string &prefix, const std::vector< std::string > &decor_names, std::vector< SG::ReadDecorHandleKey< T_Cont > > &decor_out)
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)
std::pair< SG::WriteDecorHandleKey< ContainerType >, SG::AuxElement::ConstAccessor< VariableType > > WriteKeyAccessorPair
void decorateOrWarnIfUnequal(const T_Cont_Elm &particle, WriteAccessorRefPair< T_Cont, T > &decorator, const T &value)
DuplicateBehaviour
Behaviour in case of trying to add a decoration which previously exists.
@ REJECT_WITH_WARNING
@ REJECT_WARN_IF_UNEQUAL
@ REJECT_QUIETLY
void decorateOrRejectQuietly(const T_Cont_Elm &particle, OptionalDecoration< T_Cont, T > &decorator, const T &value)
bool roughlyEqual(const int i, const int j)
std::vector< SG::WriteDecorHandle< T_Cont, T > > createDecorators(const std::vector< SG::WriteDecorHandleKey< T_Cont > > &keys, const EventContext &ctx)
void decorate(const T_Cont_Elm &particle, OptionalDecoration< T_Cont, T > &decorator, const T &value)
std::pair< SG::WriteDecorHandle< ContainerType, VariableType >, SG::AuxElement::ConstAccessor< VariableType > & > WriteAccessorRefPair
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)
std::pair< SG::WriteDecorHandle< ContainerType, VariableType >, bool > OptionalDecoration
MsgStream & msg
Definition testRead.cxx:32