ATLAS Offline Software
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 
17 #include <xAODCore/ShallowCopy.h>
18 
19 #include <memory>
20 
21 namespace 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 
60  struct ShallowCopy
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,
318  xAOD::IParticleContainer*& object,
319  const xAOD::IParticleContainer *inputObject,
320  const std::string& outputName, const std::string& auxName);
321  };
322  }
323 }
324 
325 #endif
ShallowCopy.h
SGTest::store
TestStore store
Definition: TestStore.cxx:23
CP::detail::ContainerType::test_iparticle
static std::true_type test_iparticle(checker< C, decltype((*(const xAOD::IParticle **) nullptr)=((C *) nullptr) ->at(0))> *)
ATLAS_NOT_THREAD_SAFE
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
Definition: checker_macros.h:212
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
DMTest::C
C_v1 C
Definition: C.h:26
ANA_MSG_ERROR
#define ANA_MSG_ERROR(xmsg)
Macro printing error messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:294
athena.value
value
Definition: athena.py:124
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
detail
Definition: extract_histogram_tag.cxx:14
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
CP::detail::ContainerType::test_iparticle
static std::false_type test_iparticle(...)
CP
Select isolated Photons, Electrons and Muons.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:48
SG::AuxVectorBase
Manage index tracking and synchronization of auxiliary data.
Definition: AuxVectorBase.h:98
CP::detail::ShallowCopy
a helper class to create shallow copies and register them in the event store
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:61
CP::detail::ShallowCopy< T, 2 >::StoreType
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >).evtStore()))>::type StoreType
the type of the event store we use
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:182
CP::detail::ShallowCopy< T, 2 >::getCopy
static StatusCode getCopy(MsgStream &msgStream, StoreType &store, T *&object, const T *inputObject, const std::string &outputName, const std::string &auxName)
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:185
AnaAlgorithm.h
CP::detail::ShallowCopy< xAOD::IParticleContainer >::StoreType
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >).evtStore()))>::type StoreType
the type of the event store we use
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:315
CP::detail::ShallowCopy< T, 1 >::StoreType
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >).evtStore()))>::type StoreType
the type of the event store we use
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:72
TrigConf::MSGTC::Level
Level
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:21
lumiFormat.i
int i
Definition: lumiFormat.py:85
xAOD::shallowCopyObject
std::pair< T *, ShallowAuxInfo * > shallowCopyObject(const T &obj)
Function making a shallow copy of a constant standalone object.
Definition: ShallowCopy.h:163
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
IParticleContainer.h
MessageCheck.h
macros for messaging and checking status codes
CP::detail::ShallowCopy< T, 3 >::StoreType
std::decay< decltype(*(std::declval< EL::AnaAlgorithm >).evtStore()))>::type StoreType
the type of the event store we use
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:279
CP::detail::ContainerType::test_container
static std::false_type test_container(...)
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
StatusCode.h
CP::detail::ContainerType::test_container
static std::true_type test_container(checker< C, decltype((*(const SG::AuxVectorBase **) nullptr)=((C *) nullptr))> *)
CP::detail::ShallowCopy< T, 1 >::getCopy
static StatusCode getCopy(MsgStream &msgStream, StoreType &store, T *&object, const T *inputObject, const std::string &outputName, const std::string &auxName)
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:75
CP::detail::ShallowCopy< T, 3 >::getCopy
static StatusCode getCopy(MsgStream &msgStream, StoreType &store, T *&object, const T *inputObject, const std::string &outputName, const std::string &auxName)
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:282
SGTest::TestStore::record
void record(const T *p, const std::string &key)
Definition: TestStore.h:81
lumiFormat.outputName
string outputName
Definition: lumiFormat.py:65
xAOD::shallowCopyContainer
std::pair< std::unique_ptr< T >, std::unique_ptr< ShallowAuxContainer > > shallowCopyContainer(const T &cont, [[maybe_unused]] const EventContext &ctx)
Function making a shallow copy of a constant container.
Definition: ShallowCopy.h:110
xAOD::setOriginalObjectLink
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...
Definition: IParticleHelpers.cxx:30
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
CP::detail::ContainerType::checker
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:29
IParticleHelpers.h
calibdata.copy
bool copy
Definition: calibdata.py:27
CP::detail::ContainerType
check what kind of object/container the argument is
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:28
checker_macros.h
Define macros for attributes used to control the static checker.
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
CP::detail::ContainerType::value
static const int value
Value evaluating to:
Definition: SystematicsHandles/SystematicsHandles/CopyHelpers.h:47
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35