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