ATLAS Offline Software
Loading...
Searching...
No Matches
TFileChecker.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/TFileChecker.h"
#include "xAODRootAccess/tools/Message.h"
#include "xAODRootAccess/tools/ReturnCheck.h"
#include "xAODRootAccess/TEvent.h"

Go to the source code of this file.

Functions

 ClassImp (xAOD::TFileChecker) namespace xAOD

Function Documentation

◆ ClassImp()

ClassImp ( xAOD::TFileChecker )

Internal cache of dictionaries for auxiliary vector types

Definition at line 28 of file TFileChecker.cxx.

30 {
31
33 static std::map< SG::auxid_t, ::TClass* > s_dictCache =
34 std::map< SG::auxid_t, ::TClass* >();
35
36 TFileChecker::TFileChecker()
37 : ::TObject(), m_stopOnError( kFALSE ), m_ignoredVariables(),
38 m_orpannedContainers() {
39
40 }
41
42 StatusCode TFileChecker::check( TEvent& event ) {
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
130 m_stopOnError = value;
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
148 m_ignoredVariables = value;
149 return;
150 }
151
152 const std::set< std::string >& TFileChecker::ignoredVariables() const {
153
154 return m_ignoredVariables;
155 }
156
157 StatusCode TFileChecker::checkContainer( const SG::AuxVectorBase& vec,
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
std::vector< size_t > vec
#define XAOD_MESSAGE(MESSAGE)
Simple macro for printing error/verbose messages.
#define RETURN_CHECK(CONTEXT, EXP)
Helper macro for checking return codes in a compact form in the code.
Definition ReturnCheck.h:26
Handle mappings between names and auxid_t.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Manage index tracking and synchronization of auxiliary data.
Interface providing I/O for a generic auxiliary store.
Definition IAuxStoreIO.h:44
virtual const void * getIOData(SG::auxid_t auxid) const =0
Return a pointer to the data to be stored for one aux data item.
Interface for const operations on an auxiliary store.
A set of aux data identifiers.
Definition AuxTypes.h:47
double entries
Definition listroot.cxx:49
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition Error.h:16
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
@ Info
Definition ZDCMsg.h:20
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
EventFormat_v1 EventFormat
Definition of the current event format version.
Definition EventFormat.h:16