ATLAS Offline Software
REvent.icc
Go to the documentation of this file.
1 // Dear emacs, this is -*- c++ -*-
2 //
3 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4 //
5 #ifndef XAODROOTACCESS_REVENT_ICC
6 #define XAODROOTACCESS_REVENT_ICC
7 
8 // ROOT include(s):
9 #include <TError.h>
10 
11 // EDM include(s):
12 #include "AthContainers/normalizedTypeinfoName.h"
13 
14 namespace xAOD {
15 
16  namespace Experimental {
17 
18  /// This function works pretty much like StoreGateSvc::contains. It can be
19  /// used to check if an object with a given type having a given key can be
20  /// retrieved from the event.
21  ///
22  /// @param key The key (branch name) of the object
23  /// @returns <code>kTRUE</code> if the object is available,
24  /// <code>kFALSE</code> otherwise
25  ///
26  template< typename T >
27  ::Bool_t REvent::contains( const std::string& key ) {
28 
29  return contains( key, typeid( T ), kFALSE );
30  }
31 
32  /// This function works pretty much like StoreGateSvc::transientContains.
33  /// It doesn't try to do any I/O operations, it just checks if an object
34  /// of a given type, with a given key, is already in memory.
35  ///
36  /// @param key The key (branch name) of the object
37  /// @returns <code>kTRUE</code> if the object is already in memory,
38  /// <code>kFALSE</code> otherwise
39  ///
40  template< typename T >
41  ::Bool_t REvent::transientContains( const std::string& key ) const {
42 
43  // Simply forward the call:
44  return transientContains( key, typeid( T ), kFALSE );
45  }
46 
47  /// This function needs to be used when retrieving an object either from
48  /// the input or the output object list. The returned object can not be
49  /// modified.
50  ///
51  /// @param obj The pointer that will be set to the object requested
52  /// @param key The key (branch name) of the object
53  /// @returns <code>kTRUE</code> if the operation was successful,
54  /// <code>kFALSE</code> if it wasn't
55  ///
56  template< typename T >
57  StatusCode REvent::retrieve( const T*& obj, const std::string& key ) {
58 
59  // Look among the output objects first:
60  const void* result = getOutputObject( key, typeid( T ) );
61  // Check if it succeeded:
62  if( ! result ) {
63  // Try the input then:
64  result = getInputObject( key, typeid( T ) );
65  if( ! result ) {
66  ::Warning( "xAOD::REvent::retrieve",
67  "Couldn't (const) retrieve \"%s/%s\"",
68  SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
69  key.c_str() );
70  return StatusCode::RECOVERABLE;
71  }
72  } else {
73  // Even if there is an output object with this key, it may
74  // be an input object that was copied to the output. So let's
75  // try to silently retrieve an input object as well. This makes
76  // sure that the input/output object is updated for the current
77  // event.
78  getInputObject( key, typeid( T ), kTRUE );
79  }
80 
81  // If we were successful:
82  obj = reinterpret_cast< const T* >( result );
83  return StatusCode::SUCCESS;
84  }
85 
86  /// This function can be used to retrieve an object from the output list.
87  /// Since only output objects are considered, the function returns a
88  /// non-const object, allowing downstream code to modify an object that
89  /// was put into the event somewhere upstream.
90  ///
91  /// @param obj The pointer that will be set to the object requested
92  /// @param key The key (branch name) of the object
93  /// @returns <code>kTRUE</code> if the operation was successful,
94  /// <code>kFALSE</code> if it wasn't
95  ///
96  template< typename T >
97  StatusCode REvent::retrieve( T*& obj, const std::string& key ) {
98 
99  // Only look among the output objects in this case:
100  void* result = getOutputObject( key, typeid( T ) );
101  // Check if we found the object:
102  if( ! result ) {
103  ::Warning( "xAOD::REvent::retrieve",
104  "Couldn't (non-const) retrieve \"%s/%s\"",
105  SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
106  key.c_str() );
107  return StatusCode::RECOVERABLE;
108  }
109 
110  // If we were successful:
111  obj = reinterpret_cast< T* >( result );
112  return StatusCode::SUCCESS;
113  }
114 
115  // /// This function can be used to add an object to the output. The function
116  // /// takes posession of the object, so the user code must not delete an
117  // /// object that was added to an event.
118  // ///
119  // /// @param obj Pointer to the object to be added to the event
120  // /// @param key The key (branch name) to give the object
121  // /// @param basketSize Basket size for the branch created from the object
122  // /// @param splitLevel The split level of the branch to create
123  // /// @returns <code>kTRUE</code> if the operation was successful,
124  // /// <code>kFALSE</code> if it wasn't
125  // ///
126  // template< typename T >
127  // StatusCode REvent::record( T* obj, const std::string& key,
128  // ::Int_t basketSize, ::Int_t splitLevel ) {
129 
130  // // Just call the non-templated implementation:
131  // return record( obj, SG::normalizedTypeinfoName( typeid( T ) ), key,
132  // basketSize, splitLevel );
133  // }
134 
135  // /// This function is used to add an object to the output. As the interface
136  // /// clearly states, the function takes posession of the object given to it.
137  // /// Since the user must give up ownership of the object in order to call this
138  // /// function, it doesn't even need to be said that the user must not delete
139  // /// the object by hand after calling this function.
140  // ///
141  // /// @param obj Smart pointer to the object to tbe added to the event
142  // /// @param key The key (branch name) to give the object
143  // /// @param basketSize Basket size for the branch created from the object
144  // /// @param splitLevel The split level of the branch to create
145  // /// @returns <code>kTRUE</code> if the operation was successful,
146  // /// <code>kFALSE</code> if it wasn't
147  // ///
148  // template< typename T >
149  // StatusCode REvent::record( std::unique_ptr< T > obj, const std::string& key,
150  // ::Int_t basketSize, ::Int_t splitLevel ) {
151 
152  // // Just call the non-templated implementation:
153  // const StatusCode rc =
154  // record( obj.get(), SG::normalizedTypeinfoName( typeid( T ) ), key,
155  // basketSize, splitLevel );
156  // if( ! rc.isSuccess() ) {
157  // return rc;
158  // }
159 
160  // // If the record was successful, let's release the object from the unique
161  // // pointer:
162  // (void)obj.release();
163  // return StatusCode::SUCCESS;
164  // }
165 
166  /// This function works pretty much like StoreGateSvc::contains for metadata
167  /// objects. It can be used to check containsMetaif a metadata object with a given type
168  /// having a given key can be (const) retrieved.
169  ///
170  /// @param key The key (branch name) of the metadata object
171  /// @returns <code>kTRUE</code> if the object is available,
172  /// <code>kFALSE</code> otherwise
173  ///
174  template< typename T >
175  ::Bool_t REvent::containsMeta( const std::string& key ) {
176 
177  return contains( key, typeid( T ), kTRUE );
178  }
179 
180  /// This function works pretty much like StoreGateSvc::transientContains for
181  /// metadata objects. It doesn't try to do any I/O operations, it just checks
182  /// if an object of a given type, with a given key, can be retrieved in
183  /// non-const mode.
184  ///
185  /// @param key The key (branch name) of the metadata object
186  /// @returns <code>kTRUE</code> if the object is available for modifications,
187  /// <code>kFALSE</code> otherwise
188  ///
189  template< typename T >
190  ::Bool_t REvent::transientContainsMeta( const std::string& key ) const {
191 
192  // Simply forward the call:
193  return transientContains( key, typeid( T ), kTRUE );
194  }
195 
196  /// This function can be used to retrieve an object from the input metadata
197  /// list.
198  ///
199  /// @param obj The pointer that will be set to the object requested
200  /// @param key The key (branch name) of the object
201  /// @returns The usual StatusCode values
202  ///
203  template< typename T >
204  StatusCode REvent::retrieveMetaInput( const T*& obj,
205  const std::string& key ) {
206 
207  // Only look among the output objects in this case:
208  const void* result = getInputObject( key, typeid( T ), kFALSE, kTRUE );
209  // Check if we found the object:
210  if( ! result ) {
211  ::Warning( "xAOD::REvent::retrieveMetaInput",
212  "Couldn't (const) retrieve \"%s/%s\"",
213  SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
214  key.c_str() );
215  return StatusCode::RECOVERABLE;
216  }
217 
218  // If we were successful:
219  obj = reinterpret_cast< const T* >( result );
220  return StatusCode::SUCCESS;
221  }
222 
223  /// This function can be used to retrieve an object from the output metadata
224  /// list.
225  ///
226  /// @param obj The pointer that will be set to the object requested
227  /// @param key The key (branch name) of the object
228  /// @returns The usual StatusCode values
229  ///
230  template< typename T >
231  StatusCode REvent::retrieveMetaOutput( const T*& obj,
232  const std::string& key ) {
233 
234  // Only look among the output objects in this case:
235  const void* result = getOutputObject( key, typeid( T ), kTRUE );
236  // Check if we found the object:
237  if( ! result ) {
238  ::Warning( "xAOD::REvent::retrieveMetaOutput",
239  "Couldn't (const) retrieve \"%s/%s\"",
240  SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
241  key.c_str() );
242  return StatusCode::RECOVERABLE;
243  }
244 
245  // If we were successful:
246  obj = reinterpret_cast< const T* >( result );
247  return StatusCode::SUCCESS;
248  }
249 
250  // /// This function can be used to retrieve an object from the output metadata
251  // /// list.
252  // ///
253  // /// @param obj The pointer that will be set to the object requested
254  // /// @param key The key (branch name) of the object
255  // /// @returns The usual StatusCode values
256  // ///
257  // template< typename T >
258  // StatusCode REvent::retrieveMetaOutput( T*& obj, const std::string& key ) {
259 
260  // // Only look among the output objects in this case:
261  // void* result = getOutputObject( key, typeid( T ), kTRUE );
262  // // Check if we found the object:
263  // if( ! result ) {
264  // ::Warning( "xAOD::REvent::retrieveMetaOutput",
265  // "Couldn't (non-const) retrieve \"%s/%s\"",
266  // SG::normalizedTypeinfoName( typeid( T ) ).c_str(),
267  // key.c_str() );
268  // return StatusCode::RECOVERABLE;
269  // }
270 
271  // // If we were successful:
272  // obj = reinterpret_cast< T* >( result );
273  // return StatusCode::SUCCESS;
274  // }
275 
276  /// This function can be used to add a metadata object to the output.
277  /// The function takes posession of the object, so the user code must not
278  /// delete an object that was added to the output.
279  ///
280  /// @param obj Pointer to the object to be added to the output metadata
281  /// @param key The key (branch name) to give the object
282  /// @param basketSize Basket size for the branch created from the object
283  /// @param splitLevel The split level of the branch to create
284  /// @returns <code>kTRUE</code> if the operation was successful,
285  /// <code>kFALSE</code> if it wasn't
286  ///
287  template< typename T >
288  StatusCode REvent::recordMeta( T* obj, const std::string& key,
289  ::Int_t basketSize, ::Int_t splitLevel ) {
290 
291  // Just call the non-templated implementation:
292  return record( obj, SG::normalizedTypeinfoName( typeid( T ) ), key,
293  basketSize, splitLevel, kFALSE, kTRUE );
294  }
295 
296  /// This function can be used to add a metadata object to the output. As the
297  /// interface clearly states, the function takes posession of the object
298  /// given to it. So it's not even worth mentioning that the user must not
299  /// delete the object after giving it to this function.
300  ///
301  /// @param obj Smart pointer to the object to be added to the output metadata
302  /// @param key The key (branch name) to give the object
303  /// @param basketSize Basket size for the branch created from the object
304  /// @param splitLevel The split level of the branch to create
305  /// @returns <code>kTRUE</code> if the operation was successful,
306  /// <code>kFALSE</code> if it wasn't
307  ///
308  template< typename T >
309  StatusCode REvent::recordMeta( std::unique_ptr< T > obj,
310  const std::string& key,
311  ::Int_t basketSize, ::Int_t splitLevel ) {
312 
313  // Just call the non-templated implementation:
314  const StatusCode rc =
315  record( obj.get(), SG::normalizedTypeinfoName( typeid( T ) ), key,
316  basketSize, splitLevel, kFALSE, kTRUE );
317  if( ! rc.isSuccess() ) {
318  return rc;
319  }
320 
321  // If the record was successful, let's release the object from the unique
322  // pointer:
323  (void)obj.release();
324  return StatusCode::SUCCESS;
325  }
326 
327  } // namespace Experimental
328 
329 } // namespace xAOD
330 
331 #endif // XAODROOTACCESS_REVENT_ICC