ATLAS Offline Software
Loading...
Searching...
No Matches
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
44 StatusCode RFileChecker::check( REvent& event ) {
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
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