ATLAS Offline Software
TFileChecker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // $Id: TFileChecker.cxx 673572 2015-06-09 08:40:47Z krasznaa $
6 
7 // System include(s):
8 #include <set>
9 #include <string>
10 #include <map>
11 
12 // ROOT include(s):
13 #include <TClass.h>
14 #include <TVirtualCollectionProxy.h>
15 
16 // EDM include(s):
21 
22 // Local include(s):
26 #include "xAODRootAccess/TEvent.h"
27 
29 
30 namespace xAOD {
31 
33  static std::map< SG::auxid_t, ::TClass* > s_dictCache =
34  std::map< SG::auxid_t, ::TClass* >();
35 
37  : ::TObject(), m_stopOnError( kFALSE ), m_ignoredVariables(),
38  m_orpannedContainers() {
39 
40  }
41 
43 
44  // Reset the internal cache(es):
45  m_orpannedContainers.clear();
46 
47  // Bail right away if there are no events in the file:
48  if( ! event.getEntries() ) {
49  return StatusCode::SUCCESS;
50  }
51 
52  // Load the first event:
53  if( event.getEntry( 0 ) < 0 ) {
54  Error( "check",
55  XAOD_MESSAGE( "Couldn't load event 0 from the input" ) );
56  return StatusCode::FAILURE;
57  }
58 
59  // Get the list of containers in the file:
60  std::set< std::string > containerNames;
61  const EventFormat* ef = event.inputEventFormat();
62  EventFormat::const_iterator ef_itr = ef->begin();
63  EventFormat::const_iterator ef_end = ef->end();
64  for( ; ef_itr != ef_end; ++ef_itr ) {
65 
66  // Skip the auxiliary objects:
67  if( ef_itr->first.find( "Aux." ) == ( ef_itr->first.size() - 4 ) ) {
68  continue;
69  }
70  if( ef_itr->second.parentName() != "" ) {
71  continue;
72  }
73 
74  // Check whether it's available, and a container type:
75  if( ! event.contains< SG::AuxVectorBase >( ef_itr->first ) ) {
76  continue;
77  }
78 
79  // This seems to be a valid vector type to check:
80  containerNames.insert( ef_itr->first );
81  }
82 
83  // Loop over the events:
84  const ::Long64_t entries = event.getEntries();
85  for( ::Long64_t entry = 0; entry < entries; ++entry ) {
86 
87  // Load the event:
88  if( event.getEntry( entry ) < 0 ) {
89  Error( "check",
90  XAOD_MESSAGE( "Failed to load event %i from the input" ),
91  static_cast< int >( entry ) );
92  return StatusCode::FAILURE;
93  }
94 
95  // Print a progress message:
96  if( ! ( entry % 100 ) ) {
97  Info( "check", "Now validating entry %i / %i",
98  static_cast< int >( entry ), static_cast< int >( entries ) );
99  }
100 
101  // Check all containers:
102  for( const std::string& cname : containerNames ) {
103 
104  // Retrieve the container:
105  const SG::AuxVectorBase* vec = 0;
106  RETURN_CHECK( "xAOD::TFileChecker::check",
107  event.retrieve( vec, cname ) );
108 
109  // Check it:
110  if( m_stopOnError ) {
111  RETURN_CHECK( "xAOD::TFileChecker::check",
112  checkContainer( *vec, cname ) );
113  } else {
114  if( checkContainer( *vec, cname ).isFailure() ) {
115  Error( "check",
116  XAOD_MESSAGE( "Error found with container \"%s\" in "
117  "event %i" ),
118  cname.c_str(), static_cast< int >( entry ) );
119  }
120  }
121  }
122  }
123 
124  // Return gracefully:
125  return StatusCode::SUCCESS;
126  }
127 
128  void TFileChecker::setStopOnError( ::Bool_t value ) {
129 
131  return;
132  }
133 
134  ::Bool_t TFileChecker::stopOnError() const {
135 
136  return m_stopOnError;
137  }
138 
139  void TFileChecker::addIgnoredVariable( const std::string& name ) {
140 
141  m_ignoredVariables.insert( name );
142  return;
143  }
144 
145  void
146  TFileChecker::setIgnoredVariables( const std::set< std::string >& value ) {
147 
149  return;
150  }
151 
152  const std::set< std::string >& TFileChecker::ignoredVariables() const {
153 
154  return m_ignoredVariables;
155  }
156 
158  const std::string& name ) {
159 
160  // Access the auxiliary store of the container:
161  const SG::IConstAuxStore* cStore = vec.getConstStore();
162  const SG::IAuxStoreIO* ioStore =
163  dynamic_cast< const SG::IAuxStoreIO* >( cStore );
164  if( ! ioStore ) {
165  if( ! cStore ) {
166  // No auxiliary store is found for the container at all. That's a
167  // problem.
168  if( m_orpannedContainers.find( name ) ==
169  m_orpannedContainers.end() ) {
170  Error( "checkContainer",
171  XAOD_MESSAGE( "Couldn't get I/O store for "
172  "container: %s" ),
173  name.c_str() );
174  m_orpannedContainers.insert( name );
175  return StatusCode::FAILURE;
176  }
177  return StatusCode::SUCCESS;
178  } else {
179  // This can happen when the auxiliary store doesn't implement the
180  // I/O interface. This is the case for types inheriting from
181  // xAOD::ByteStreamAuxContainer for instance. Since all issues that
182  // we check for in here are tied to the I/O happening through this
183  // interface, let's not bother with such objects.
184  return StatusCode::SUCCESS;
185  }
186  }
187 
188  // Get the size of the interface container:
189  const size_t size = vec.size_v();
190 
191  // Loop over all of its auxiliary variables:
192  const SG::auxid_set_t auxids = vec.getAuxIDs();
193  for( SG::auxid_t auxid : auxids ) {
194 
195  // The auxiliary type registry:
197 
198  // Get a pointer to the underlying std::vector variable. This should
199  // trigger the loading of the necessary dictionaries for this type.
200  const void* vecPtr = ioStore->getIOData( auxid );
201  if( ! vecPtr ) {
202  Error( "checkContainer",
203  XAOD_MESSAGE( "Couldn't load variable %s.%s" ),
204  name.c_str(), reg.getName( auxid ).c_str() );
205  return StatusCode::FAILURE;
206  }
207 
208  // Find a dictionary for this type:
209  ::TClass* cl = 0;
210  auto itr = s_dictCache.find( auxid );
211  if( itr != s_dictCache.end() ) {
212  cl = itr->second;
213  } else {
214  const std::type_info* typeId = reg.getVecType( auxid );
215  if( ! typeId ) {
216  Error( "checkContainer",
217  XAOD_MESSAGE( "Couldn't get std::type_info for "
218  "variable %s" ),
219  reg.getName( auxid ).c_str() );
220  return StatusCode::FAILURE;
221  }
222  cl = ::TClass::GetClass( *typeId );
223  s_dictCache[ auxid ] = cl;
224  }
225  if( ! cl ) {
226  Error( "checkContainer",
227  XAOD_MESSAGE( "Couldn't get dictionary for variable %s" ),
228  reg.getName( auxid ).c_str() );
229  return StatusCode::FAILURE;
230  }
231 
232  // Make sure that the type has a collection proxy:
233  ::TVirtualCollectionProxy* proxy = cl->GetCollectionProxy();
234  if( ! proxy ) {
235  Error( "checkContainer",
236  XAOD_MESSAGE( "Couldn't get collection proxy for "
237  "variable %s" ),
238  reg.getName( auxid ).c_str() );
239  return StatusCode::FAILURE;
240  }
241 
242  // Get the size of the vector using the collection proxy:
243  proxy->PushProxy( ( void* ) vecPtr );
244  const size_t varSize = static_cast< size_t >( proxy->Size() );
245  proxy->PopProxy();
246 
247  // Check that the size is as it should be:
248  if( ( size != varSize ) &&
249  ( m_ignoredVariables.find( reg.getName( auxid ) ) ==
250  m_ignoredVariables.end() ) ) {
251  Error( "checkContainer",
252  XAOD_MESSAGE( "%s.size() (%i) != %sAux.%s.size() (%i)" ),
253  name.c_str(), static_cast< int >( size ),
254  name.c_str(), reg.getName( auxid ).c_str(),
255  static_cast< int >( varSize ) );
256  return StatusCode::FAILURE;
257  }
258  }
259 
260  // Return gracefully:
261  return StatusCode::SUCCESS;
262  }
263 
264 } // 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
xAOD::name
name
Definition: TriggerMenuJson_v1.cxx:29
StateLessPT_NewConfig.proxy
proxy
Definition: StateLessPT_NewConfig.py:392
xAOD::TFileChecker::setIgnoredVariables
void setIgnoredVariables(const std::set< std::string > &value)
Set the list of variables to be ignored in the test.
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:639
xAOD::TFileChecker::stopOnError
::Bool_t stopOnError() const
Check whether the validation will stop when an error is found.
SG::AuxTypeRegistry::getName
std::string getName(SG::auxid_t auxid) const
Return the name of an aux data item.
Definition: AuxTypeRegistry.cxx:881
xAOD::TFileChecker::m_orpannedContainers
std::set< std::string > m_orpannedContainers
List of containers without an auxiliary store.
Definition: TFileChecker.h:71
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
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:12
xAOD::TFileChecker::ignoredVariables
const std::set< std::string > & ignoredVariables() const
Get the list of variables which are ignored in the test.
ReturnCheck.h
AuxVectorBase.h
Manage index tracking and synchronization of auxiliary data.
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
ClassImp
ClassImp(xAOD::TFileChecker) namespace xAOD
Definition: TFileChecker.cxx:28
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
IAuxStoreIO.h
Interface providing I/O for a generic auxiliary store.
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Message.h
TEvent.h
xAOD::TFileChecker
Tool for running sanity checks on xAOD files.
Definition: TFileChecker.h:39
xAOD::TFileChecker::TFileChecker
TFileChecker()
Default constructor.
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
xAOD::TFileChecker::setStopOnError
void setStopOnError(::Bool_t value)
Set whether the validation should stop when an error is found.
xAOD::TFileChecker::addIgnoredVariable
void addIgnoredVariable(const std::string &name)
Add a variable to be ignored in the test.
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
xAOD::TFileChecker::checkContainer
StatusCode checkContainer(const SG::AuxVectorBase &vec, const std::string &name)
Check the health of a container.
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.
xAOD::TFileChecker::m_ignoredVariables
std::set< std::string > m_ignoredVariables
List of variables to ignore in the test.
Definition: TFileChecker.h:68
POOL::TEvent::retrieve
StatusCode retrieve(const T *&obj)
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:74
xAOD::TFileChecker::m_stopOnError
::Bool_t m_stopOnError
Stop the validation when an issue is found?
Definition: TFileChecker.h:66
xAOD::EventFormat
EventFormat_v1 EventFormat
Definition of the current event format version.
Definition: EventFormat.h:16
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
entries
double entries
Definition: listroot.cxx:49
SG::auxid_set_t
A set of aux data identifiers.
Definition: AuxTypes.h:47
xAOD::EventFormat_v1::const_iterator
KeyedData_t::const_iterator const_iterator
Iterator for looping over the elements of the object.
Definition: EventFormat_v1.h:67
IConstAuxStore.h
Interface for const operations on an auxiliary store.
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:26
LheEventFiller_Common.ef
ef
Definition: SFGen_i/share/common/LheEventFiller_Common.py:7
TFileChecker.h
xAOD::TFileChecker::check
StatusCode check(TEvent &event)
Execute all sanity checks on a given file.