ATLAS Offline Software
Loading...
Searching...
No Matches
TriggerEDMDeserialiserAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
10#include "CxxUtils/hexdump.h"
12#include "SGTools/DataProxy.h"
14#include "BareDataBucket.h"
15#include "TBufferFile.h"
16#include "TVirtualCollectionProxy.h"
17#include "TClass.h"
23#include "RootUtils/Type.h"
24
26#include "TriggerEDMCLIDs.h"
27
28#include "TFile.h"
29#include "TStreamerInfo.h"
31
32#include <sys/resource.h>
33#include <cstring>
34#include <regex>
35
36namespace {
37const SG::BaseInfoBase* getBaseInfo(CLID clid) {
39 if (bi){
40 return bi;
41 }
42 // Try to force a dictionary load to get it defined.
43 ServiceHandle<IClassIDSvc> clidsvc("ClassIDSvc", "ProxyProviderSvc");
44 if (!clidsvc.retrieve()){
45 return nullptr;
46 }
47 std::string name;
48 if (!clidsvc->getTypeNameOfID(clid, name).isSuccess()) {
49 return nullptr;
50 }
51 (void)TClass::GetClass(name.c_str());
52 return SG::BaseInfoBase::find(clid);
53}
54} // anonymous namespace
55
61
62
63namespace {
71 const std::type_info* getElementType ( const std::string& tname,
72 std::string& elementTypeName ) {
73 TClass* cls = TClass::GetClass( tname.c_str() );
74 if ( cls == nullptr ) return nullptr;
75 TVirtualCollectionProxy* prox = cls->GetCollectionProxy();
76 if ( prox == nullptr ) return nullptr;
77 if ( prox->GetValueClass() != nullptr ) {
78 elementTypeName = prox->GetValueClass()->GetName();
79 return prox->GetValueClass()->GetTypeInfo();
80 }
81 RootUtils::Type type ( prox->GetType() );
82 elementTypeName = type.getTypeName();
83 return type.getTypeInfo();
84 }
85
89 std::string stripStdVec (const std::string& s_in) {
90 std::string s = s_in;
91 std::string::size_type pos{0};
92 while ((pos = s.find ("std::vector<")) != std::string::npos) {
93 s.erase (pos, 5);
94 }
95 return s;
96 }
97
105 bool versionChange(const std::string& type1, const std::string& type2) {
106 static const std::regex re(".+(_v[0-9]+).*"); // find last _v in string
107 std::smatch m1, m2;
108 return ( std::regex_match(type1, m1, re) and
109 std::regex_match(type2, m2, re) and
110 m1.str(1) != m2.str(1) ); // number 0 is full match
111 }
112
116 struct handleError
117 {
118 using Payload = std::vector<uint32_t>;
119
120 bool operator()(int level, bool /*abort*/, const char* location, const char* /*msg*/) {
121 if ( level >= kError && location && strstr(location, "TBufferFile::ReadClass")) {
122 // Raise soft core dump size limit to hard limit
123 struct rlimit core_limit;
124 getrlimit(RLIMIT_CORE, &core_limit);
125 core_limit.rlim_cur = core_limit.rlim_max;
126 setrlimit(RLIMIT_CORE, &core_limit);
127
128 std::cout << "TriggerEDMDeserialiserAlg: Raising core dump soft size limit to " << core_limit.rlim_cur
129 << " and trying to dump core file..." << std::endl;
130 Athena::DebugAids::coredump(SIGSEGV); // this is non-fatal, job continues
131 }
132
133 if ( level >= kError && location && strstr(location, "TClass::Load")) {
134 std::cout << "TriggerEDMDeserialiserAlg: buff dump; start " << m_start << "\n";
135 CxxUtils::hexdump (std::cout, m_buf, m_bufsize);
136 std::cout << "TriggerEDMDeserialiserAlg: payload dump\n";
137 CxxUtils::hexdump (std::cout, m_payload->data(), m_payload->size() * sizeof(Payload::value_type));
138 }
139
140 return true; // call default handlers
141 }
142
143 handleError (const char* buf, size_t bufsize, const Payload* payload,
144 const void* start)
145 : m_buf (buf), m_bufsize (bufsize), m_payload (payload), m_start(start)
146 {
147 }
148
149 const char* m_buf;
150 size_t m_bufsize;
151 const Payload* m_payload;
152 const void* m_start;
153 };
154
155}
156
165namespace PayloadHelpers {
167
169 #if __cpp_lib_array_constexpr >= 201811L
170 constexpr
171 #endif
173 return *( start + TDA::CLIDOffset );
174 }
175
177 #if __cpp_lib_array_constexpr >= 201811L
178 constexpr
179 #endif
181 return *( start + TDA::NameLengthOffset );
182 }
183
185 #if __cpp_lib_array_constexpr >= 201811L
186 constexpr
187 #endif
189 return *( start + TDA::NameOffset + nameLength(start) );
190 }
191
197 #if __cpp_lib_array_constexpr >= 201811L
198 constexpr
199 #endif
201 return start + (*start); // point ahead by the number of words pointed to by start iterator
202 }
203
205 std::vector<std::string> collectionDescription(TDA::PayloadIterator start) {
207 std::vector<std::string> labels;
208 ss.deserialize( start + TDA::NameOffset, start + TDA::NameOffset + nameLength(start), labels );
209 return labels;
210 }
211
213 void toBuffer(TDA::PayloadIterator start, char* buffer) {
214 // move to the beginning of the buffer memory
215 TDA::PayloadIterator dataStart = start + TDA::NameOffset + nameLength(start) + 1 /*skip size*/;
216 // we rely on continuous memory layout of std::vector ...
217 std::memcpy( buffer, &(*dataStart), dataSize(start) );
218 }
219}
220
221std::unique_ptr<TList> TriggerEDMDeserialiserAlg::s_streamerInfoList{};
223
224TriggerEDMDeserialiserAlg::TriggerEDMDeserialiserAlg(const std::string& name, ISvcLocator* pSvcLocator) :
225 AthReentrantAlgorithm(name, pSvcLocator) {}
226
228 ATH_CHECK( m_resultKey.initialize() );
229 ATH_CHECK( m_clidSvc.retrieve() );
230 ATH_CHECK( m_serializerSvc.retrieve() );
231 ATH_CHECK( m_tpTool.retrieve() );
233 return StatusCode::SUCCESS;
234}
235
236
238 s_streamerInfoList.reset();
239 return StatusCode::SUCCESS;
240}
241
242
243StatusCode TriggerEDMDeserialiserAlg::execute(const EventContext& context) const {
244
245 auto resultHandle = SG::makeHandle( m_resultKey, context );
246 if ( not resultHandle.isValid() ) {
247 ATH_MSG_ERROR("Failed to obtain HLTResultMT with key " << m_resultKey.key());
248 return StatusCode::FAILURE;
249 }
250 ATH_MSG_DEBUG("Obtained HLTResultMT with key " << m_resultKey.key());
251
252 const Payload* dataptr = nullptr;
253 if ( resultHandle->getSerialisedData( m_moduleID, dataptr ).isFailure() ) {
254 if ( m_permitMissingModule ) {
255 ATH_MSG_DEBUG("No payload available with moduleId " << m_moduleID << " in this event, ignored");
256 return StatusCode::SUCCESS;
257 } else {
258 ATH_MSG_ERROR("No payload available with moduleId " << m_moduleID << " in this event");
259 return StatusCode::FAILURE;
260 }
261 }
262 ATH_CHECK( deserialise( dataptr ) );
263 return StatusCode::SUCCESS;
264}
265
266StatusCode TriggerEDMDeserialiserAlg::deserialise( const Payload* dataptr ) const {
267
268 size_t buffSize = m_initialSerialisationBufferSize;
269 std::unique_ptr<char[]> buff = std::make_unique<char[]>(buffSize);
270
271 // returns a char* buffer that is at minimum as large as specified in the argument
272 auto resize = [&buffSize, &buff]( const size_t neededSize ) -> void {
273 if ( neededSize > buffSize ) {
274 buffSize = neededSize;
275 buff = std::make_unique<char[]>(buffSize);
276 }
277 };
278
279 // the pointers defined below need to be used in decoding consecutive fragments of xAOD containers:
280 // 1) xAOD interface, 2) Aux store, 3) decorations
281 // invalid conditions are: invalid interface pointer when decoding Aux store
282 // invalid aux store and interface when decoding the decoration
283 // these pointer should be invalidated when: decoding TP containers, aux store when decoding the xAOD interface
284 WritableAuxStore* currentAuxStore = nullptr; // set when decoding Aux
285 SG::AuxVectorBase* xAODInterfaceContainer = nullptr; // set when decoding xAOD interface
286
287 size_t fragmentCount = 0;
288 PayloadIterator start = dataptr->begin();
289 std::string previousKey;
290 while ( start != dataptr->end() ) {
292 const CLID clid{ PayloadHelpers::collectionCLID( start ) };
293 std::string transientTypeName, transientTypeInfoName;
294 ATH_CHECK( m_clidSvc->getTypeNameOfID( clid, transientTypeName ) );
295 ATH_CHECK( m_clidSvc->getTypeInfoNameOfID( clid, transientTypeInfoName ) ); // version
296
297 const std::vector<std::string> descr( PayloadHelpers::collectionDescription( start ) );
298 ATH_CHECK( descr.size() == 2 );
299 std::string persistentTypeName{ descr[0] };
300 const std::string key{ descr[1] };
301 const size_t bsize{ PayloadHelpers::dataSize( start ) };
302
303 if( m_skipDuplicates && evtStore()->contains(clid,m_prefix+key) ) {
304 ATH_MSG_DEBUG("Skipping duplicate record " << m_prefix+key);
305 // Advance
306 start = PayloadHelpers::toNextFragment( start );
307 continue;
308 }
309
310 ATH_MSG_DEBUG( "fragment #" << fragmentCount <<
311 " type: "<< transientTypeName << " (" << transientTypeInfoName << ")" <<
312 " persistent type: " << persistentTypeName << " key: " << key << " size: " << bsize );
313 resize( bsize );
314 PayloadHelpers::toBuffer( start, buff.get() );
315
316 // point the start to the next chunk, irrespectively of what happens in deserialisation below
317 start = PayloadHelpers::toNextFragment( start );
318
319 RootType classDesc = RootType::ByNameNoQuiet( persistentTypeName );
320 ATH_CHECK( classDesc.IsComplete() );
321
322 // Many variables in this class were changed from double to float.
323 // However, we wrote data in the past which contained values
324 // that were valid doubles but which were out of range for floats.
325 // So we can get FPEs when we read them.
326 // Disable FPEs when we're reading an instance of this class.
327 CxxUtils::FPControl fpcontrol;
328 if (persistentTypeName == "xAOD::BTaggingTrigAuxContainer_v1") {
329 fpcontrol.holdExceptions();
330 }
331
332 size_t usedBytes{ bsize };
333 void* obj{ nullptr };
334 {
335 // Temporary error handler to debug ATR-25049
336 RootUtils::WithRootErrorHandler hand( handleError(buff.get(), usedBytes, dataptr, &*start) );
337 obj = m_serializerSvc->deserialize( buff.get(), usedBytes, classDesc );
338 }
339
340 ATH_MSG_DEBUG( "Deserialised object of ptr: " << obj << " which used: " << usedBytes <<
341 " bytes from available: " << bsize );
342 if ( obj == nullptr ) {
343 ATH_MSG_ERROR( "Deserialisation of object of CLID " << clid << " and transientTypeName " <<
344 transientTypeName << " # " << key << " failed" );
345 return StatusCode::FAILURE;
346 }
347 const bool isxAODInterfaceContainer = (transientTypeName.rfind("xAOD", 0) != std::string::npos and
348 transientTypeName.find("Aux") == std::string::npos and
349 transientTypeName.find("ElementLink") == std::string::npos);
350 const bool isxAODAuxContainer = (transientTypeName.rfind("xAOD", 0) != std::string::npos and
351 transientTypeName.find("Aux") != std::string::npos);
352 const bool isxAODDecoration = transientTypeName.find("vector") != std::string::npos;
353 const bool isTPContainer = persistentTypeName.find("_p") != std::string::npos;
354 const bool isVersionChange = versionChange(persistentTypeName, transientTypeInfoName);
355
356 ATH_CHECK( checkSanity( transientTypeName, isxAODInterfaceContainer,
357 isxAODAuxContainer, isxAODDecoration, isTPContainer ) );
358
359 if ( isTPContainer or isVersionChange ) {
360 if ( isVersionChange ) ATH_MSG_DEBUG( "Version change detected from " << persistentTypeName << " to "
361 << transientTypeInfoName << ". Will invoke PT converter." );
362
363 std::string decodedTransientName;
364 void * converted = m_tpTool->convertPT( persistentTypeName, obj, decodedTransientName );
365 ATH_CHECK( converted != nullptr );
366 classDesc.Destruct( obj );
367
368 // from now on in case of T/P class we deal with a new class, the transient one
369 classDesc = RootType::ByNameNoQuiet( transientTypeName );
370 ATH_CHECK( classDesc.IsComplete() );
371 obj = converted;
372 }
373
374 if ( isxAODInterfaceContainer or isxAODAuxContainer or isTPContainer ) {
375 BareDataBucket* dataBucket = new BareDataBucket( obj, clid, classDesc );
376 const std::string outputName = m_prefix + key;
377 auto proxyPtr = evtStore()->recordObject( SG::DataObjectSharedPtr<BareDataBucket>( dataBucket ),
378 outputName, false, false );
379 if ( proxyPtr == nullptr ) {
380 ATH_MSG_WARNING( "Recording of object of CLID " << clid << " and name " << outputName << " failed" );
381 }
382
383 if ( isxAODInterfaceContainer ) {
384 // If the container of the previous iteration was supposed to have an Aux store (trackIndices)
385 // but we didn't find one, then create at least a DataLink with the correct key name.
386 // The EDMCreatorAlg will take care of creating an empty Aux store with the correct type.
387 if (xAODInterfaceContainer!=nullptr &&
388 xAODInterfaceContainer->trackIndices() && currentAuxStore==nullptr) {
389 ATH_MSG_DEBUG("Container with key " << previousKey << " is missing its Aux store");
390 xAODInterfaceContainer->setStore( DataLink<SG::IConstAuxStore>(previousKey+"Aux.") );
391 }
392 currentAuxStore = nullptr; // the store will be following, setting it to nullptr assure we catch issue with of missing Aux
393 const SG::BaseInfoBase* bib = getBaseInfo(clid);
394 if(!bib){
395 ATH_MSG_WARNING("No BaseInfoBase for CLID "<< clid << " and name " << outputName);
396 }
397 xAODInterfaceContainer =
398 bib ? reinterpret_cast<SG::AuxVectorBase*>(
399 bib->cast(dataBucket->object(),
401 : nullptr;
402 } else if (isxAODAuxContainer) {
403 // key contains exactly one '.' at the end
404 ATH_CHECK( key.find('.') == key.size()-1 );
405 ATH_CHECK( currentAuxStore == nullptr and xAODInterfaceContainer != nullptr );
406 const SG::BaseInfoBase* bib = getBaseInfo(clid);
407 SG::IAuxStore* auxHolder =
408 reinterpret_cast<SG::IAuxStore*>(
409 bib->cast(dataBucket->object(), ClassID_traits<SG::IAuxStore>::ID()));
410 ATH_CHECK(auxHolder != nullptr);
411 xAODInterfaceContainer->setStore(auxHolder);
412 currentAuxStore = new WritableAuxStore();
413 dynamic_cast<SG::IAuxStoreHolder*>(auxHolder)->setStore( currentAuxStore );
414 } else {
415 currentAuxStore = nullptr;
416 xAODInterfaceContainer = nullptr; // invalidate xAOD related pointers
417 }
418
419 } else if ( isxAODDecoration ) {
420 if(m_skipDuplicates and (currentAuxStore == nullptr || xAODInterfaceContainer == nullptr)) {
421 ATH_MSG_DEBUG("Decoration " << key << " encountered with no active container. Assume this was already handled.");
422 } else {
423 ATH_CHECK( currentAuxStore != nullptr and xAODInterfaceContainer != nullptr );
424 ATH_CHECK( deserialiseDynAux( transientTypeName, persistentTypeName, key, obj,
425 currentAuxStore, xAODInterfaceContainer ) );
426 }
427 }
428 previousKey = key;
429 }
430 return StatusCode::SUCCESS;
431}
432
433
434
435StatusCode TriggerEDMDeserialiserAlg::deserialiseDynAux( const std::string& transientTypeName, const std::string& persistentTypeName, const std::string& decorationName,
436 void* obj, WritableAuxStore* currentAuxStore, SG::AuxVectorBase* interfaceContainer ) const {
437 const bool isPacked = persistentTypeName.find("SG::PackedContainer") != std::string::npos;
438
440 SG::auxid_t id = registry.findAuxID ( decorationName );
441 if (id != SG::null_auxid ) {
442 std::string regTypeName = stripStdVec( registry.getVecTypeName(id) );
443 if ( regTypeName != stripStdVec(transientTypeName) and transientTypeName.find("ElementLink") == std::string::npos )
444 {
445 // Before giving up, also translate any typedefs in the transient name.
446 RootUtils::Type tname (transientTypeName);
447 if ( regTypeName != stripStdVec(tname.getTypeName()) ) {
448 ATH_MSG_INFO( "Schema evolution required for decoration \"" << decorationName << "\" from " << transientTypeName << " to " << registry.getVecTypeName( id ) << " not handled yet");
449 return StatusCode::SUCCESS;
450 }
451 }
452 } else {
453 std::string elementTypeName;
454 const std::type_info* elt_tinfo = getElementType( transientTypeName, elementTypeName );
455 ATH_CHECK( elt_tinfo != nullptr );
456 ATH_MSG_DEBUG( "Dynamic decoration: \"" << decorationName << "\" of type " << transientTypeName << " will create a dynamic ID, stored type" << elementTypeName );
457 id = SG::getDynamicAuxID ( *elt_tinfo, decorationName, elementTypeName, transientTypeName, false, SG::null_auxid );
458 }
459 ATH_MSG_DEBUG( "Unstreaming decoration \"" << decorationName << "\" of type " << transientTypeName << " aux ID " << id << " class " << persistentTypeName << " packed " << isPacked );
460 std::unique_ptr<SG::IAuxTypeVector> vec( registry.makeVectorFromData (id, obj, nullptr, isPacked, true) );
461 ATH_CHECK( vec.get() != nullptr );
462 ATH_MSG_DEBUG("Size for \"" << decorationName << "\" " << vec->size() << " interface " << interfaceContainer->size_v() );
463 ATH_CHECK( vec->size() == interfaceContainer->size_v() );
464 if ( vec->size() != 0 ) {
465 ATH_CHECK( currentAuxStore != nullptr );
466 currentAuxStore->addVector(std::move(vec), false);
467 // trigger loading of the dynamic variables
468 SG::AuxElement::TypelessConstAccessor accessor( decorationName );
469 accessor.getDataArray( *interfaceContainer );
470 }
471 return StatusCode::SUCCESS;
472}
473
474StatusCode TriggerEDMDeserialiserAlg::checkSanity( const std::string& transientTypeName, bool isxAODInterfaceContainer, bool isxAODAuxContainer, bool isDecoration, bool isTPContainer ) const {
475 ATH_MSG_DEBUG( "Recognised type " << transientTypeName <<" as: "
476 << (isxAODInterfaceContainer ? "xAOD Interface Container":"" )
477 << (isxAODAuxContainer ? "xAOD Aux Container ":"" )
478 << ( isDecoration ? "xAOD Decoration" : "")
479 << ( isTPContainer ? "T/P Container " : "") );
480
481 const std::vector<bool> typeOfContainer( { isxAODInterfaceContainer, isxAODAuxContainer, isDecoration, isTPContainer } );
482 const size_t count = std::count( typeOfContainer.begin(), typeOfContainer.end(), true );
483 if ( count == 0 ) {
484 ATH_MSG_ERROR( "Could not recognise the kind of container " << transientTypeName );
485 return StatusCode::FAILURE;
486 }
487 if (count > 1 ) {
488 ATH_MSG_ERROR( "Ambiguous container kind deduced from the transient type name " << transientTypeName );
489 ATH_MSG_ERROR( "Recognised type as: "
490 << (isxAODInterfaceContainer ? "xAOD Interface Context":"" )
491 << (isxAODAuxContainer ? " xAOD Aux Container ":"" )
492 << ( isDecoration ? "xAOD Decoration" : "")
493 << ( isTPContainer ? "T/P Container " : "") );
494 return StatusCode::FAILURE;
495 }
496 return StatusCode::SUCCESS;
497}
498
499
501 std::lock_guard<std::mutex> lock(s_mutex);
502
503 if (s_streamerInfoList) {
504 return;
505 }
506
507 std::string extStreamerInfos = "bs-streamerinfos.root";
508 std::string extFilePath = PathResolver::find_file(extStreamerInfos, "DATAPATH");
509 ATH_MSG_DEBUG( "Using " << extFilePath );
510 TFile extFile(extFilePath.c_str());
511
512 s_streamerInfoList = std::unique_ptr<TList>(extFile.GetStreamerInfoList());
513 for(const auto&& infObj: *s_streamerInfoList) {
514 TString t_name=infObj->GetName();
515 if (t_name.BeginsWith("listOfRules")){
516 ATH_MSG_WARNING( "Could not re-load class " << t_name );
517 continue;
518 }
519
520 TStreamerInfo* inf = dynamic_cast<TStreamerInfo*>(infObj);
521 inf->BuildCheck();
522 TClass *cl = inf->GetClass();
523 if (cl != nullptr) {
524 ATH_MSG_DEBUG( "external TStreamerInfo for " << cl->GetName() <<
525 " checksum: " << std::hex << inf->GetCheckSum() << std::dec );
526 }
527 }
528}
const boost::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
An auxiliary data store that holds data internally.
Handle mappings between names and auxid_t.
Basic definitions for auxiliary types.
std::vector< size_t > vec
uint32_t CLID
The Class ID type.
Helper to control FP exceptions.
static Double_t ss
TTypeAdapter RootType
Definition RootType.h:211
This are the SEAL debug aids, adapted to build in Atlas, after the drop of that project.
This is the signal handler from SEAL, adapted to build in Atlas, after the drop of that project.
convert to and from a SG storable
int fragmentCount(uint32_t data, int id)
Wrapper for ROOT types.
Run a MT piece of code with an alternate root error handler.
An algorithm that can be simultaneously executed in multiple threads.
static void coredump(int sig,...)
Drop a core dump and continue.
Allows to insert void* returned from serialisation into the store.
virtual void * object() override
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
Wrapper for ROOT types.
Definition Type.h:40
std::string getTypeName() const
Return the name of this type.
Definition Type.cxx:329
Run a MT piece of code with an alternate root error handler.
ConstAuxElement::TypelessConstAccessor TypelessConstAccessor
Definition AuxElement.h:566
An auxiliary data store that holds data internally.
void addVector(std::unique_ptr< IAuxTypeVector > vec, bool isDecoration)
Explicitly add a vector to the store.
Handle mappings between names and auxid_t.
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
std::unique_ptr< IAuxTypeVector > makeVectorFromData(SG::auxid_t auxid, void *data, IAuxTypeVector *linkedVector, bool isPacked, bool ownFlag) const
Construct an IAuxTypeVector object from a vector.
std::string getVecTypeName(SG::auxid_t auxid) const
Return the type of the STL vector used to hold an aux data item.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Manage index tracking and synchronization of auxiliary data.
void setStore(SG::IAuxStore *store)
Set the store associated with this object.
bool trackIndices() const
Return true if index tracking is enabled for this container.
virtual size_t size_v() const =0
Return the size of the container.
The non-template portion of the BaseInfo implementation.
static const BaseInfoBase * find(CLID clid)
Find the BaseInfoBase instance for clid.
Definition BaseInfo.cxx:570
void * cast(void *p, CLID clid) const
Cast to a base pointer.
Definition BaseInfo.cxx:166
Interface for objects taking part in direct ROOT I/O.
Interface for non-const operations on an auxiliary store.
Definition IAuxStore.h:48
Utility class (not a tool or so) to serialize strings into stream of 32bit integers.
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition RootType.cxx:586
void Destruct(void *place) const
Definition RootType.cxx:677
Bool_t IsComplete() const
Definition RootType.cxx:895
void addVector(std::unique_ptr< IAuxTypeVector > vec, bool isDecoration)
Explicitly add a vector to the store.
from the HLTResultMT Each serialised collection is a chunk of words with the content as described bel...
virtual StatusCode initialize() override
Gaudi::Property< int > m_initialSerialisationBufferSize
Gaudi::Property< bool > m_permitMissingModule
static constexpr size_t CLIDOffset
Payload::const_iterator PayloadIterator
static constexpr size_t NameLengthOffset
static constexpr size_t NameOffset
ServiceHandle< IAthenaSerializeSvc > m_serializerSvc
SG::ReadHandleKey< HLT::HLTResultMT > m_resultKey
virtual StatusCode finalize() override
ToolHandle< TrigSerTPTool > m_tpTool
Gaudi::Property< std::string > m_prefix
StatusCode deserialiseDynAux(const std::string &transientTypeName, const std::string &persistentTypeName, const std::string &decorationName, void *obj, WritableAuxStore *currentAuxStore, SG::AuxVectorBase *interface) const
Handle decoration.
TriggerEDMDeserialiserAlg(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_skipDuplicates
StatusCode checkSanity(const std::string &transientTypeName, bool isxAODInterfaceContainer, bool isxAODAuxContainer, bool isDecoration, bool isTPContainer) const
Checker for data integrity, one and only one of the passed booleans can be true, else FAILURE is retu...
StatusCode deserialise(const Payload *dataptr) const
Performs actual deserialisation loop.
ServiceHandle< IClassIDSvc > m_clidSvc
virtual StatusCode execute(const EventContext &context) const override
Find the auxid for a dynamic branch.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:146
Helpers to make a nice dump of a region of memory.
TStreamerInfo * inf
void hexdump(std::ostream &s, const void *addr, size_t n, size_t offset=0)
Make a hex dump of memory.
Definition hexdump.cxx:37
Collection of helper functions for raw pointer operations on the bytestream payload.
TDA::PayloadIterator toNextFragment(TDA::PayloadIterator start)
Returns starting point of the next fragment, can be == end()
size_t dataSize(TDA::PayloadIterator start)
Size in bytes of the buffer that is needed to decode next fragment data content.
std::vector< std::string > collectionDescription(TDA::PayloadIterator start)
String description of the collection stored in the next fragment, returns persistent type name and th...
TriggerEDMDeserialiserAlg TDA
CLID collectionCLID(TDA::PayloadIterator start)
CLID of the collection stored in the next fragment.
size_t nameLength(TDA::PayloadIterator start)
Length of the serialised name payload.
void toBuffer(TDA::PayloadIterator start, char *buffer)
Copies fragment to the buffer, no size checking, use dataSize to do so.
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
CxxUtils::RefCountedPtr< T > DataObjectSharedPtr
SG::auxid_t getDynamicAuxID(const std::type_info &ti, const std::string &name, const std::string &elementTypeName, const std::string &branch_type_name, bool standalone, SG::auxid_t linked_auxid)
Find the auxid for a dynamic branch.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27