ATLAS Offline Software
Functions
RFileChecker.cxx File Reference
#include <set>
#include <string>
#include <map>
#include <TClass.h>
#include <TVirtualCollectionProxy.h>
#include "AthContainersInterfaces/IConstAuxStore.h"
#include "AthContainersInterfaces/IAuxStoreIO.h"
#include "AthContainers/AuxVectorBase.h"
#include "AthContainers/AuxTypeRegistry.h"
#include "xAODRootAccess/tools/RFileChecker.h"
#include "xAODRootAccess/tools/Message.h"
#include "xAODRootAccess/tools/ReturnCheck.h"
#include "xAODRootAccess/REvent.h"

Go to the source code of this file.

Functions

 ClassImp (xAOD::Experimental::RFileChecker) namespace xAOD
 

Function Documentation

◆ ClassImp()

Internal cache of dictionaries for auxiliary vector types

Definition at line 28 of file RFileChecker.cxx.

30  {
31 
32  namespace Experimental {
33 
35  static std::map< SG::auxid_t, ::TClass* > s_dictCache =
36  std::map< SG::auxid_t, ::TClass* >();
37 
38  RFileChecker::RFileChecker()
39  : ::TObject(), m_stopOnError( kFALSE ), m_ignoredVariables(),
40  m_orpannedContainers() {
41 
42  }
43 
45 
46  // ::Info( "RFileChecker::check", XAOD_MESSAGE( "entering"));
47 
48  // Reset the internal cache(es):
49  m_orpannedContainers.clear();
50 
51  // Bail right away if there are no events in the file:
52  if( ! event.getEntries() ) {
53  return StatusCode::SUCCESS;
54  }
55  // Load the first event:
56  if( event.getEntry( 0 ) < 0 ) {
57  Error( "check",
58  XAOD_MESSAGE( "Couldn't load event 0 from the input" ) );
59  return StatusCode::FAILURE;
60  }
61 
62  // Get the list of containers in the file:
63  std::set< std::string > containerNames;
64  const EventFormat* ef = event.inputEventFormat();
65  EventFormat::const_iterator ef_itr = ef->begin();
66  EventFormat::const_iterator ef_end = ef->end();
67 
68  // int icont = 0;
69 
70  for( ; ef_itr != ef_end; ++ef_itr ) {
71 
72  // Skip the auxiliary objects:
73  if( ef_itr->first.find( "Aux." ) == ( ef_itr->first.size() - 4 ) ) {
74  continue;
75  }
76  if( ef_itr->second.parentName() != "" ) {
77  continue;
78  }
79 
80  // Check whether it's available, and a container type:
81  if( ! event.contains< SG::AuxVectorBase >( ef_itr->first ) ) {
82  continue;
83  }
84 
85  // This seems to be a valid vector type to check:
86  containerNames.insert( ef_itr->first );
87  }
88 
89  // Loop over the events:
90  const ::Long64_t entries = event.getEntries();
91  for( ::Long64_t entry = 0; entry < entries; ++entry ) {
92 
93  // Load the event:
94  if( event.getEntry( entry ) < 0 ) {
95  Error( "check",
96  XAOD_MESSAGE( "Failed to load event %i from the input" ),
97  static_cast< int >( entry ) );
98  return StatusCode::FAILURE;
99  }
100 
101  // Print a progress message:
102  if( ! ( entry % 100 ) ) {
103  Info( "check", "Now validating entry %i / %i",
104  static_cast< int >( entry ), static_cast< int >( entries ) );
105  }
106 
107  // Check all containers:
108  for( const std::string& cname : containerNames ) {
109 
110  // Retrieve the container:
111  const SG::AuxVectorBase* vec = 0;
112  RETURN_CHECK( "xAOD::RFileChecker::check",
113  event.retrieve( vec, cname ) );
114 
115  // Check it:
116  if( m_stopOnError ) {
117  RETURN_CHECK( "xAOD::RFileChecker::check",
118  checkContainer( *vec, cname ) );
119  } else {
120  if( checkContainer( *vec, cname ).isFailure() ) {
121  Error( "check",
122  XAOD_MESSAGE( "Error found with container \"%s\" in "
123  "event %i" ),
124  cname.c_str(), static_cast< int >( entry ) );
125  }
126  }
127  }
128  }
129 
130  // Return gracefully:
131  return StatusCode::SUCCESS;
132  }
133 
134  void RFileChecker::setStopOnError( ::Bool_t value ) {
135 
136  m_stopOnError = value;
137  return;
138  }
139 
140  ::Bool_t RFileChecker::stopOnError() const {
141 
142  return m_stopOnError;
143  }
144 
145  void RFileChecker::addIgnoredVariable( const std::string& name ) {
146 
147  m_ignoredVariables.insert( name );
148  return;
149  }
150 
151  void
152  RFileChecker::setIgnoredVariables( const std::set< std::string >& value ) {
153 
154  m_ignoredVariables = value;
155  return;
156  }
157 
158  const std::set< std::string >& RFileChecker::ignoredVariables() const {
159 
160  return m_ignoredVariables;
161  }
162 
163  StatusCode RFileChecker::checkContainer( const SG::AuxVectorBase& vec,
164  const std::string& name ) {
165 
166  // Access the auxiliary store of the container:
167  const SG::IConstAuxStore* cStore = vec.getConstStore();
168  const SG::IAuxStoreIO* ioStore =
169  dynamic_cast< const SG::IAuxStoreIO* >( cStore );
170  if( ! ioStore ) {
171  if( ! cStore ) {
172  // No auxiliary store is found for the container at all. That's a
173  // problem.
174  if( m_orpannedContainers.find( name ) ==
175  m_orpannedContainers.end() ) {
176  Error( "checkContainer",
177  XAOD_MESSAGE( "Couldn't get I/O store for "
178  "container: %s" ),
179  name.c_str() );
180  m_orpannedContainers.insert( name );
181  return StatusCode::FAILURE;
182  }
183  return StatusCode::SUCCESS;
184  } else {
185  // This can happen when the auxiliary store doesn't implement the
186  // I/O interface. This is the case for types inheriting from
187  // xAOD::ByteStreamAuxContainer for instance. Since all issues that
188  // we check for in here are tied to the I/O happening through this
189  // interface, let's not bother with such objects.
190  return StatusCode::SUCCESS;
191  }
192  }
193 
194  // Get the size of the interface container:
195  const size_t size = vec.size_v();
196 
197  // Loop over all of its auxiliary variables:
198  const SG::auxid_set_t auxids = vec.getAuxIDs();
199  for( SG::auxid_t auxid : auxids ) {
200 
201  // The auxiliary type registry:
203 
204  // Get a pointer to the underlying std::vector variable. This should
205  // trigger the loading of the necessary dictionaries for this type.
206  const void* vecPtr = ioStore->getIOData( auxid );
207  if( ! vecPtr ) {
208  Error( "checkContainer",
209  XAOD_MESSAGE( "Couldn't load variable %s.%s" ),
210  name.c_str(), reg.getName( auxid ).c_str() );
211  return StatusCode::FAILURE;
212  }
213 
214  // Find a dictionary for this type:
215  ::TClass* cl = 0;
216  auto itr = s_dictCache.find( auxid );
217  if( itr != s_dictCache.end() ) {
218  cl = itr->second;
219  } else {
220  const std::type_info* typeId = reg.getVecType( auxid );
221  if( ! typeId ) {
222  Error( "checkContainer",
223  XAOD_MESSAGE( "Couldn't get std::type_info for "
224  "variable %s" ),
225  reg.getName( auxid ).c_str() );
226  return StatusCode::FAILURE;
227  }
228  cl = ::TClass::GetClass( *typeId );
229  s_dictCache[ auxid ] = cl;
230  }
231  if( ! cl ) {
232  Error( "checkContainer",
233  XAOD_MESSAGE( "Couldn't get dictionary for variable %s" ),
234  reg.getName( auxid ).c_str() );
235  return StatusCode::FAILURE;
236  }
237 
238  // Make sure that the type has a collection proxy:
239  ::TVirtualCollectionProxy* proxy = cl->GetCollectionProxy();
240  if( ! proxy ) {
241  Error( "checkContainer",
242  XAOD_MESSAGE( "Couldn't get collection proxy for "
243  "variable %s" ),
244  reg.getName( auxid ).c_str() );
245  return StatusCode::FAILURE;
246  }
247 
248  // Get the size of the vector using the collection proxy:
249  proxy->PushProxy( ( void* ) vecPtr );
250  const size_t varSize = static_cast< size_t >( proxy->Size() );
251  proxy->PopProxy();
252 
253  // Check that the size is as it should be:
254  if( ( size != varSize ) &&
255  ( m_ignoredVariables.find( reg.getName( auxid ) ) ==
256  m_ignoredVariables.end() ) ) {
257  Error( "checkContainer",
258  XAOD_MESSAGE( "%s.size() (%i) != %sAux.%s.size() (%i)" ),
259  name.c_str(), static_cast< int >( size ),
260  name.c_str(), reg.getName( auxid ).c_str(),
261  static_cast< int >( varSize ) );
262  return StatusCode::FAILURE;
263  }
264  }
265 
266  // Return gracefully:
267  return StatusCode::SUCCESS;
268  }
269 
270  } // namespace Experimental
271 
272 } // namespace xAOD
RETURN_CHECK
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Definition: ReturnCheck.h:26
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:407
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
gridSubmitIDTPM.check
check
Definition: gridSubmitIDTPM.py:45
SG::AuxTypeRegistry::getName
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
Definition: AuxTypeRegistry.cxx:881
athena.value
value
Definition: athena.py:124
XAOD_MESSAGE
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
Definition: Control/xAODRootAccess/xAODRootAccess/tools/Message.h:19
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:9
ZDCMsg::Info
@ Info
Definition: ZDCMsg.h:20
SG::AuxVectorBase
Manage index tracking and synchronization of auxiliary data.
Definition: AuxVectorBase.h:98
SG::IAuxStoreIO
Interface providing I/O for a generic auxiliary store.
Definition: IAuxStoreIO.h:44
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
POOL::TEvent::contains
PyObject * contains(PyObject *tp, PyObject *pykey)
Definition: PhysicsAnalysis/POOLRootAccess/src/TEvent.cxx:212
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
POOL::TEvent::getEntry
int getEntry(long entry)
Definition: PhysicsAnalysis/POOLRootAccess/src/TEvent.cxx:185
POOL::TEvent::getEntries
long getEntries()
Definition: PhysicsAnalysis/POOLRootAccess/src/TEvent.cxx:124
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SG::AuxTypeRegistry::getVecType
const std::type_info * getVecType(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
Definition: AuxTypeRegistry.cxx:936
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
SG::IAuxStoreIO::getIOData
virtual const void * getIOData(SG::auxid_t auxid) const =0
Return a pointer to the data to be stored for one aux data item.
POOL::TEvent::retrieve
StatusCode retrieve(const T *&obj)
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:74
xAOD::EventFormat
EventFormat_v1 EventFormat
Definition of the current event format version.
Definition: EventFormat.h:16
entries
double entries
Definition: listroot.cxx:49
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
L1Topo::Error
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition: Error.h:16
SG::IConstAuxStore
Interface for const operations on an auxiliary store.
Definition: IConstAuxStore.h:64
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:25
LheEventFiller_Common.ef
ef
Definition: SFGen_i/share/common/LheEventFiller_Common.py:7