ATLAS Offline Software
Loading...
Searching...
No Matches
SystematicsHandles/SystematicsHandles/CopyHelpers.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7
8#ifndef SYSTEMATICS_HANDLES__COPY_HELPERS_H
9#define SYSTEMATICS_HANDLES__COPY_HELPERS_H
10
18
19#include <memory>
20
21namespace CP
22{
23 namespace detail
24 {
26 template <typename T>
28 {
29 template <class, class> class checker;
30
31 template <typename C>
32 static std::true_type test_iparticle(checker<C, decltype((*(const xAOD::IParticle**)nullptr) = ((C*)nullptr)->at(0))> *);
33
34 template <typename C>
35 static std::false_type test_iparticle(...);
36
37 template <typename C>
38 static std::true_type test_container(checker<C, decltype((*(const SG::AuxVectorBase**)nullptr) = ((C*)nullptr))>*);
39
40 template <typename C>
41 static std::false_type test_container(...);
42
47 static const int value = ( std::is_same< std::true_type, decltype( test_iparticle< T >( nullptr ) ) >::value ?
48 1 : ( std::is_same< std::true_type, decltype( test_container< T >( nullptr ) ) >::value ?
49 2 : 3 ) );
50 };
51
59 template<typename T, int type = ContainerType<T>::value>
61 {
62 static_assert ((type==1)||(type==2)||(type==3),
63 "Type can not be shallow copied");
64 };
65
66 template<typename T>
67 struct ShallowCopy<T,1>
68 {
70 public:
71 typedef std::decay<decltype(
72 *(std::declval<EL::AnaAlgorithm>().evtStore()))>::type StoreType;
73
74 static StatusCode
75 getCopy (MsgStream& msgStream, StoreType& store,
76 T*& object, const T *inputObject,
77 const std::string& outputName, const std::string& auxName)
78 {
79 // Define the msg(...) function as a lambda.
80 // Suppress thread-checker warning because this provides just a wrapper to MsgStream.
81 const auto msg = [&] ATLAS_NOT_THREAD_SAFE (MSG::Level lvl) -> MsgStream& {
82 msgStream << lvl;
83 return msgStream;
84 };
85
86 // Make sure that we get a valid pointer.
87 assert (inputObject != nullptr);
88
89 // Handle the case when the input object is a view container.
90 if( ! inputObject->getConstStore() ) {
91
92 // Decide how to handle the container.
93 if( inputObject->size() ) {
94 // Get the pointer to the "owning container" from the first
95 // element.
96 const T* originContainer =
97 dynamic_cast< const T* >( ( *inputObject )[ 0 ]->container() );
98 // Make sure that every element in the view container has the same
99 // parent.
100 for( size_t i = 1; i < inputObject->size(); ++i ) {
101 if( ( *inputObject )[ i ]->container() != originContainer ) {
102 ANA_MSG_ERROR( "Not all elements of the received view "
103 "container come from the same container!" );
104 return StatusCode::FAILURE;
105 }
106 }
107 // Postfix for the shallow-copy container of the origin container.
108 static const char* const ORIGIN_POSTFIX = "_ShallowCopyOrigin";
109 // Make a shallow copy of the origin container.
110 auto originCopy = xAOD::shallowCopyContainer( *originContainer );
111 if( ( ! originCopy.first ) || ( ! originCopy.second ) ) {
112 ANA_MSG_ERROR( "Failed to shallow copy the origin of a view "
113 << "container, meant for: " << outputName );
114 return StatusCode::FAILURE;
115 }
116 // ...and record it.
117 ANA_CHECK( store.record( originCopy.first,
118 outputName + ORIGIN_POSTFIX ) );
119 ANA_CHECK( store.record( originCopy.second,
120 outputName + ORIGIN_POSTFIX + "Aux." ) );
121 // Make a view copy on top of it.
122 auto viewCopy = std::make_unique< T >( SG::VIEW_ELEMENTS );
123 auto viewCopyPtr = viewCopy.get();
124 for( const auto* element : *inputObject ) {
125 viewCopy->push_back( originCopy.first->at( element->index() ) );
126 }
127 // Set the origin links on it. Note that
128 // xAOD::setOriginalObjectLink's "container version" doesn't work
129 // with view containers, we have to call this function one-by-one
130 // on the elements.
131 for( size_t i = 0; i < inputObject->size(); ++i ) {
132 if( ! xAOD::setOriginalObjectLink( *( ( *inputObject )[ i ] ),
133 *( ( *viewCopy )[ i ] ) ) ) {
134 return StatusCode::FAILURE;
135 }
136 }
137 // Finally, record the view container with the requested name.
138 ANA_CHECK( store.record( viewCopy.release(), outputName ) );
139 // The copy is done.
140 object = viewCopyPtr;
141 return StatusCode::SUCCESS;
142 } else {
143 // If the container was empty, then let's just make a new empty
144 // container, and that's that...
145 auto viewCopy = std::make_unique< T >( SG::VIEW_ELEMENTS );
146 auto viewCopyPtr = viewCopy.get();
147 ANA_CHECK( store.record( viewCopy.release(), outputName ) );
148 // The copy is done.
149 object = viewCopyPtr;
150 return StatusCode::SUCCESS;
151 }
152
153 } else {
154
155 // We can just copy the container as is.
156 auto copy = xAOD::shallowCopyContainer( *inputObject );
157 if (!copy.first || !copy.second)
158 {
159 ANA_MSG_ERROR ("failed to shallow copy object: " << outputName);
160 ANA_MSG_ERROR ("likely shallow copying a view container");
161 return StatusCode::FAILURE;
162 }
163
164 if (!xAOD::setOriginalObjectLink (*inputObject, *copy.first)) {
165 return StatusCode::FAILURE;
166 }
167
168 ANA_CHECK (store.record (copy.second, auxName));
169 ANA_CHECK (store.record (copy.first, outputName));
170 object = copy.first;
171 return StatusCode::SUCCESS;
172 }
173 }
174 };
175
176 template<typename T>
177 struct ShallowCopy<T,2>
178 {
180 public:
181 typedef std::decay<decltype(
182 *(std::declval<EL::AnaAlgorithm>().evtStore()))>::type StoreType;
183
184 static StatusCode
185 getCopy (MsgStream& msgStream, StoreType& store,
186 T*& object, const T *inputObject,
187 const std::string& outputName, const std::string& auxName)
188 {
189 // Define the msg(...) function as a lambda.
190 // Suppress thread-checker warning because this provides just a wrapper to MsgStream.
191 const auto msg = [&] ATLAS_NOT_THREAD_SAFE (MSG::Level lvl) -> MsgStream& {
192 msgStream << lvl;
193 return msgStream;
194 };
195
196 // Make sure that we get a valid pointer.
197 assert (inputObject != nullptr);
198
199 // Handle the case when the input object is a view container.
200 if( ! inputObject->getConstStore() ) {
201
202 // Decide how to handle the container.
203 if( inputObject->size() ) {
204 // Get the pointer to the "owning container" from the first
205 // element.
206 const T* originContainer =
207 dynamic_cast< const T* >( ( *inputObject )[ 0 ]->container() );
208 // Make sure that every element in the view container has the same
209 // parent.
210 for( size_t i = 1; i < inputObject->size(); ++i ) {
211 if( ( *inputObject )[ i ]->container() != originContainer ) {
212 ANA_MSG_ERROR( "Not all elements of the received view "
213 "container come from the same container!" );
214 return StatusCode::FAILURE;
215 }
216 }
217 // Postfix for the shallow-copy container of the origin container.
218 static const char* const ORIGIN_POSTFIX = "_ShallowCopyOrigin";
219 // Make a shallow copy of the origin container.
220 auto originCopy = xAOD::shallowCopyContainer( *originContainer );
221 if( ( ! originCopy.first ) || ( ! originCopy.second ) ) {
222 ANA_MSG_ERROR( "Failed to shallow copy the origin of a view "
223 << "container, meant for: " << outputName );
224 return StatusCode::FAILURE;
225 }
226 // ...and record it.
227 ANA_CHECK( store.record( originCopy.first,
228 outputName + ORIGIN_POSTFIX ) );
229 ANA_CHECK( store.record( originCopy.second,
230 outputName + ORIGIN_POSTFIX +
231 "Aux." ) );
232 // Make a view copy on top of it.
233 auto viewCopy = std::make_unique< T >( SG::VIEW_ELEMENTS );
234 auto viewCopyPtr = viewCopy.get();
235 for( const auto* element : *inputObject ) {
236 viewCopy->push_back( originCopy.first->at( element->index() ) );
237 }
238 // Finally, record the view container with the requested name.
239 ANA_CHECK( store.record( viewCopy.release(), outputName ) );
240 // The copy is done.
241 object = viewCopyPtr;
242 return StatusCode::SUCCESS;
243 } else {
244 // If the container was empty, then let's just make a new empty
245 // container, and that's that...
246 auto viewCopy = std::make_unique< T >( SG::VIEW_ELEMENTS );
247 auto viewCopyPtr = viewCopy.get();
248 ANA_CHECK( store.record( viewCopy.release(), outputName ) );
249 // The copy is done.
250 object = viewCopyPtr;
251 return StatusCode::SUCCESS;
252 }
253
254 } else {
255
256 // We can just copy the container as is.
257 auto copy = xAOD::shallowCopyContainer( *inputObject );
258 if (!copy.first || !copy.second)
259 {
260 ANA_MSG_ERROR ("failed to shallow copy object: " << outputName);
261 ANA_MSG_ERROR ("likely shallow copying a view container");
262 return StatusCode::FAILURE;
263 }
264
265 ANA_CHECK (store.record (copy.second, auxName));
266 ANA_CHECK (store.record (copy.first, outputName));
267 object = copy.first;
268 return StatusCode::SUCCESS;
269 }
270 }
271 };
272
273 template<typename T>
274 struct ShallowCopy<T,3>
275 {
277 public:
278 typedef std::decay<decltype(
279 *(std::declval<EL::AnaAlgorithm>().evtStore()))>::type StoreType;
280
281 static StatusCode
282 getCopy (MsgStream& msgStream, StoreType& store,
283 T*& object, const T *inputObject,
284 const std::string& outputName, const std::string& auxName)
285 {
286 // Define the msg(...) function as a lambda.
287 // Suppress thread-checker warning because this provides just a wrapper to MsgStream.
288 const auto msg = [&] ATLAS_NOT_THREAD_SAFE (MSG::Level lvl) -> MsgStream& {
289 msgStream << lvl;
290 return msgStream;
291 };
292
293 // We can just copy the object as is.
294 auto copy = xAOD::shallowCopyObject( *inputObject );
295 if (!copy.first || !copy.second)
296 {
297 ANA_MSG_ERROR ("failed to shallow copy object: " << outputName);
298 ANA_MSG_ERROR ("likely shallow copying a view container");
299 return StatusCode::FAILURE;
300 }
301
302 ANA_CHECK (store.record (copy.second, auxName));
303 ANA_CHECK (store.record (copy.first, outputName));
304 object = copy.first;
305 return StatusCode::SUCCESS;
306 }
307 };
308
309 template<>
311 {
313 public:
314 typedef std::decay<decltype(
315 *(std::declval<EL::AnaAlgorithm>().evtStore()))>::type StoreType;
316 static StatusCode
317 getCopy (MsgStream& msgStream, StoreType& store,
319 const xAOD::IParticleContainer *inputObject,
320 const std::string& outputName, const std::string& auxName);
321 };
322 }
323}
324
325#endif
macros for messaging and checking status codes
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
Define macros for attributes used to control the static checker.
void record(const T *p, const std::string &key)
Definition TestStore.h:81
Manage index tracking and synchronization of auxiliary data.
Class providing the definition of the 4-vector interface.
struct color C
Select isolated Photons, Electrons and Muons.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
STL namespace.
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, const EventContext &ctx)
Function making a shallow copy of a constant container.
bool setOriginalObjectLink(const IParticle &original, IParticle &copy)
This function should be used by CP tools when they make a deep copy of an object in their correctedCo...
std::pair< T *, ShallowAuxInfo * > shallowCopyObject(const T &obj)
Function making a shallow copy of a constant standalone object.
void ClearTransientTrees ATLAS_NOT_THREAD_SAFE()
Function cleaning up the managed memory.
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
check what kind of object/container the argument is
static std::true_type test_container(checker< C, decltype((*(const SG::AuxVectorBase **) nullptr)=((C *) nullptr))> *)
static std::false_type test_iparticle(...)
static std::false_type test_container(...)
static std::true_type test_iparticle(checker< C, decltype((*(const xAOD::IParticle **) nullptr)=((C *) nullptr) ->at(0))> *)
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >().evtStore()))>::type StoreType
the type of the event store we use
static StatusCode getCopy(MsgStream &msgStream, StoreType &store, T *&object, const T *inputObject, const std::string &outputName, const std::string &auxName)
static StatusCode getCopy(MsgStream &msgStream, StoreType &store, T *&object, const T *inputObject, const std::string &outputName, const std::string &auxName)
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >().evtStore()))>::type StoreType
the type of the event store we use
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >().evtStore()))>::type StoreType
the type of the event store we use
static StatusCode getCopy(MsgStream &msgStream, StoreType &store, T *&object, const T *inputObject, const std::string &outputName, const std::string &auxName)
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >().evtStore()))>::type StoreType
the type of the event store we use
static StatusCode getCopy(MsgStream &msgStream, StoreType &store, xAOD::IParticleContainer *&object, const xAOD::IParticleContainer *inputObject, const std::string &outputName, const std::string &auxName)
a helper class to create shallow copies and register them in the event store
MsgStream & msg
Definition testRead.cxx:32