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