ATLAS Offline Software
Loading...
Searching...
No Matches
TriggerEDMDeserialiserAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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 <string>
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
57public:
58 WritableAuxStore() = default;
59 using SG::AuxStoreInternal::addVector;
60};
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
170 return *( start + TDA::CLIDOffset );
171 }
172
174 constexpr size_t nameLength(TDA::PayloadIterator start) {
175 return *( start + TDA::NameLengthOffset );
176 }
177
179 constexpr size_t dataSize(TDA::PayloadIterator start) {
180 return *( start + TDA::NameOffset + nameLength(start) );
181 }
182
189 return start + (*start); // point ahead by the number of words pointed to by start iterator
190 }
191
193 std::vector<std::string> collectionDescription(TDA::PayloadIterator start) {
195 std::vector<std::string> labels;
196 ss.deserialize( start + TDA::NameOffset, start + TDA::NameOffset + nameLength(start), labels );
197 return labels;
198 }
199
201 void toBuffer(TDA::PayloadIterator start, char* buffer) {
202 // move to the beginning of the buffer memory
203 TDA::PayloadIterator dataStart = start + TDA::NameOffset + nameLength(start) + 1 /*skip size*/;
204 // we rely on continuous memory layout of std::vector ...
205 std::memcpy( buffer, &(*dataStart), dataSize(start) );
206 }
207}
208
209std::unique_ptr<TList> TriggerEDMDeserialiserAlg::s_streamerInfoList{};
211
212TriggerEDMDeserialiserAlg::TriggerEDMDeserialiserAlg(const std::string& name, ISvcLocator* pSvcLocator) :
213 AthReentrantAlgorithm(name, pSvcLocator) {}
214
216 ATH_CHECK( m_resultKey.initialize() );
217 ATH_CHECK( m_clidSvc.retrieve() );
218 ATH_CHECK( m_serializerSvc.retrieve() );
219 ATH_CHECK( m_tpTool.retrieve() );
221 return StatusCode::SUCCESS;
222}
223
224
226 s_streamerInfoList.reset();
227 return StatusCode::SUCCESS;
228}
229
230
231StatusCode TriggerEDMDeserialiserAlg::execute(const EventContext& context) const {
232
233 auto resultHandle = SG::makeHandle( m_resultKey, context );
234 if ( not resultHandle.isValid() ) {
235 ATH_MSG_ERROR("Failed to obtain HLTResultMT with key " << m_resultKey.key());
236 return StatusCode::FAILURE;
237 }
238 ATH_MSG_DEBUG("Obtained HLTResultMT with key " << m_resultKey.key());
239
240 const Payload* dataptr = nullptr;
241 if ( resultHandle->getSerialisedData( m_moduleID, dataptr ).isFailure() ) {
242 if ( m_permitMissingModule ) {
243 ATH_MSG_DEBUG("No payload available with moduleId " << m_moduleID << " in this event, ignored");
244 return StatusCode::SUCCESS;
245 } else {
246 ATH_MSG_ERROR("No payload available with moduleId " << m_moduleID << " in this event");
247 return StatusCode::FAILURE;
248 }
249 }
250 ATH_CHECK( deserialise( dataptr ) );
251 return StatusCode::SUCCESS;
252}
253
254StatusCode TriggerEDMDeserialiserAlg::deserialise( const Payload* dataptr ) const {
255
256 size_t buffSize = m_initialSerialisationBufferSize;
257 std::unique_ptr<char[]> buff = std::make_unique<char[]>(buffSize);
258
259 // returns a char* buffer that is at minimum as large as specified in the argument
260 auto resize = [&buffSize, &buff]( const size_t neededSize ) -> void {
261 if ( neededSize > buffSize ) {
262 buffSize = neededSize;
263 buff = std::make_unique<char[]>(buffSize);
264 }
265 };
266
267 // the pointers defined below need to be used in decoding consecutive fragments of xAOD containers:
268 // 1) xAOD interface, 2) Aux store, 3) decorations
269 // invalid conditions are: invalid interface pointer when decoding Aux store
270 // invalid aux store and interface when decoding the decoration
271 // these pointer should be invalidated when: decoding TP containers, aux store when decoding the xAOD interface
272 std::unique_ptr<WritableAuxStore> currentAuxStoreOwner; // set when decoding Aux
273 WritableAuxStore* currentAuxStore = nullptr; //need to hang on to an observing ptr
274 SG::AuxVectorBase* xAODInterfaceContainer = nullptr; // set when decoding xAOD interface
275
276 size_t fragmentCount = 0;
277 PayloadIterator start = dataptr->begin();
278 std::string previousKey;
279 while ( start != dataptr->end() ) {
281 const CLID clid{ PayloadHelpers::collectionCLID( start ) };
282 std::string transientTypeName, transientTypeInfoName;
283 ATH_CHECK( m_clidSvc->getTypeNameOfID( clid, transientTypeName ) );
284 ATH_CHECK( m_clidSvc->getTypeInfoNameOfID( clid, transientTypeInfoName ) ); // version
285
286 const std::vector<std::string> descr( PayloadHelpers::collectionDescription( start ) );
287 ATH_CHECK( descr.size() == 2 );
288 std::string persistentTypeName{ descr[0] };
289 const std::string key{ descr[1] };
290 const size_t bsize{ PayloadHelpers::dataSize( start ) };
291
292 if( m_skipDuplicates && evtStore()->contains(clid,m_prefix+key) ) {
293 ATH_MSG_DEBUG("Skipping duplicate record " << m_prefix+key);
294 // Advance
295 start = PayloadHelpers::toNextFragment( start );
296 continue;
297 }
298
299 ATH_MSG_DEBUG( "fragment #" << fragmentCount <<
300 " type: "<< transientTypeName << " (" << transientTypeInfoName << ")" <<
301 " persistent type: " << persistentTypeName << " key: " << key << " size: " << bsize );
302 resize( bsize );
303 PayloadHelpers::toBuffer( start, buff.get() );
304
305 // point the start to the next chunk, irrespectively of what happens in deserialisation below
306 start = PayloadHelpers::toNextFragment( start );
307
308 RootType classDesc = RootType::ByNameNoQuiet( persistentTypeName );
309 ATH_CHECK( classDesc.IsComplete() );
310
311 // Many variables in this class were changed from double to float.
312 // However, we wrote data in the past which contained values
313 // that were valid doubles but which were out of range for floats.
314 // So we can get FPEs when we read them.
315 // Disable FPEs when we're reading an instance of this class.
316 CxxUtils::FPControl fpcontrol;
317 if (persistentTypeName == "xAOD::BTaggingTrigAuxContainer_v1") {
318 fpcontrol.holdExceptions();
319 }
320
321 size_t usedBytes{ bsize };
322 void* obj{ nullptr };
323 {
324 // Temporary error handler to debug ATR-25049
325 RootUtils::WithRootErrorHandler hand( handleError(buff.get(), usedBytes, dataptr, &*start) );
326 obj = m_serializerSvc->deserialize( buff.get(), usedBytes, classDesc );
327 }
328
329 ATH_MSG_DEBUG( "Deserialised object of ptr: " << obj << " which used: " << usedBytes <<
330 " bytes from available: " << bsize );
331 if ( obj == nullptr ) {
332 ATH_MSG_ERROR( "Deserialisation of object of CLID " << clid << " and transientTypeName " <<
333 transientTypeName << " # " << key << " failed" );
334 return StatusCode::FAILURE;
335 }
336 const bool isxAODInterfaceContainer = (transientTypeName.starts_with("xAOD") and
337 not transientTypeName.contains("Aux") and
338 not transientTypeName.contains("ElementLink"));
339 const bool isxAODAuxContainer = (transientTypeName.starts_with("xAOD") and
340 transientTypeName.contains("Aux"));
341 const bool isxAODDecoration = transientTypeName.contains("vector");
342 const bool isTPContainer = persistentTypeName.contains("_p");
343 const bool isVersionChange = versionChange(persistentTypeName, transientTypeInfoName);
344
345 ATH_CHECK( checkSanity( transientTypeName, isxAODInterfaceContainer,
346 isxAODAuxContainer, isxAODDecoration, isTPContainer ) );
347
348 if ( isTPContainer or isVersionChange ) {
349 if ( isVersionChange ) ATH_MSG_DEBUG( "Version change detected from " << persistentTypeName << " to "
350 << transientTypeInfoName << ". Will invoke PT converter." );
351
352 std::string decodedTransientName;
353 void * converted = m_tpTool->convertPT( persistentTypeName, obj, decodedTransientName );
354 ATH_CHECK( converted != nullptr );
355 classDesc.Destruct( obj );
356
357 // from now on in case of T/P class we deal with a new class, the transient one
358 classDesc = RootType::ByNameNoQuiet( transientTypeName );
359 ATH_CHECK( classDesc.IsComplete() );
360 obj = converted;
361 }
362
363 if ( isxAODInterfaceContainer or isxAODAuxContainer or isTPContainer ) {
364 BareDataBucket* dataBucket = new BareDataBucket( obj, clid, std::move(classDesc) );
365 const std::string outputName = m_prefix + key;
366 auto proxyPtr = evtStore()->recordObject( SG::DataObjectSharedPtr<BareDataBucket>( dataBucket ),
367 outputName, false, false );
368 if ( proxyPtr == nullptr ) {
369 ATH_MSG_WARNING( "Recording of object of CLID " << clid << " and name " << outputName << " failed" );
370 }
371
372 if ( isxAODInterfaceContainer ) {
373 // If the container of the previous iteration was supposed to have an Aux store (trackIndices)
374 // but we didn't find one, then create at least a DataLink with the correct key name.
375 // The EDMCreatorAlg will take care of creating an empty Aux store with the correct type.
376 if (xAODInterfaceContainer!=nullptr &&
377 xAODInterfaceContainer->trackIndices() && currentAuxStore==nullptr) {
378 ATH_MSG_DEBUG("Container with key " << previousKey << " is missing its Aux store");
379 xAODInterfaceContainer->setStore( DataLink<SG::IConstAuxStore>(previousKey+"Aux.") );
380 }
381 currentAuxStore = nullptr; // the store will be following, setting it to nullptr assure we catch issue with of missing Aux
382 const SG::BaseInfoBase* bib = getBaseInfo(clid);
383 if(!bib){
384 ATH_MSG_WARNING("No BaseInfoBase for CLID "<< clid << " and name " << outputName);
385 }
386 xAODInterfaceContainer =
387 bib ? reinterpret_cast<SG::AuxVectorBase*>(
388 bib->cast(dataBucket->object(),
390 : nullptr;
391 } else if (isxAODAuxContainer) {
392 // key contains exactly one '.' at the end
393 ATH_CHECK( key.find('.') == key.size()-1 );
394 ATH_CHECK( currentAuxStore == nullptr and xAODInterfaceContainer != nullptr );
395 const SG::BaseInfoBase* bib = getBaseInfo(clid);
396 SG::IAuxStore* auxHolder =
397 reinterpret_cast<SG::IAuxStore*>(
398 bib->cast(dataBucket->object(), ClassID_traits<SG::IAuxStore>::ID()));
399 ATH_CHECK(auxHolder != nullptr);
400 //coverity[FORWARD_NULL:FALSE]
401 xAODInterfaceContainer->setStore(auxHolder);
402 currentAuxStoreOwner = std::make_unique<WritableAuxStore>();
403 currentAuxStore = currentAuxStoreOwner.get();
404 auto p = dynamic_cast<SG::IAuxStoreHolder*>(auxHolder);
405 ATH_CHECK(p != nullptr);
406 //coverity[FORWARD_NULL:FALSE]
407 p->setStore( currentAuxStoreOwner.release() ); //IAuxStoreHolder takes ownership
408 } else {
409 currentAuxStore = nullptr;
410 xAODInterfaceContainer = nullptr; // invalidate xAOD related pointers
411 }
412
413 } else if ( isxAODDecoration ) {
414 if(m_skipDuplicates and (currentAuxStore == nullptr || xAODInterfaceContainer == nullptr)) {
415 ATH_MSG_DEBUG("Decoration " << key << " encountered with no active container. Assume this was already handled.");
416 } else {
417 ATH_CHECK( currentAuxStore != nullptr and xAODInterfaceContainer != nullptr );
418 ATH_CHECK( deserialiseDynAux( transientTypeName, persistentTypeName, key, obj,
419 currentAuxStore, xAODInterfaceContainer ) );
420 }
421 }
422 previousKey = key;
423 }
424 return StatusCode::SUCCESS;
425}
426
427
428
429StatusCode TriggerEDMDeserialiserAlg::deserialiseDynAux( const std::string& transientTypeName, const std::string& persistentTypeName, const std::string& decorationName,
430 void* obj, WritableAuxStore* currentAuxStore, SG::AuxVectorBase* interfaceContainer ) const {
431 const bool isPacked = persistentTypeName.contains("SG::PackedContainer");
432
434 SG::auxid_t id = registry.findAuxID ( decorationName );
435 if (id != SG::null_auxid ) {
436 std::string regTypeName = stripStdVec( registry.getVecTypeName(id) );
437 if ( regTypeName != stripStdVec(transientTypeName) and not transientTypeName.contains("ElementLink") )
438 {
439 // Before giving up, also translate any typedefs in the transient name.
440 RootUtils::Type tname (transientTypeName);
441 if ( regTypeName != stripStdVec(tname.getTypeName()) ) {
442 ATH_MSG_INFO( "Schema evolution required for decoration \"" << decorationName << "\" from " << transientTypeName << " to " << registry.getVecTypeName( id ) << " not handled yet");
443 return StatusCode::SUCCESS;
444 }
445 }
446 } else {
447 std::string elementTypeName;
448 const std::type_info* elt_tinfo = getElementType( transientTypeName, elementTypeName );
449 ATH_CHECK( elt_tinfo != nullptr );
450 ATH_MSG_DEBUG( "Dynamic decoration: \"" << decorationName << "\" of type " << transientTypeName << " will create a dynamic ID, stored type" << elementTypeName );
451 id = SG::getDynamicAuxID ( *elt_tinfo, decorationName, elementTypeName, transientTypeName, false, SG::null_auxid );
452 }
453 ATH_MSG_DEBUG( "Unstreaming decoration \"" << decorationName << "\" of type " << transientTypeName << " aux ID " << id << " class " << persistentTypeName << " packed " << isPacked );
454 std::unique_ptr<SG::IAuxTypeVector> vec( registry.makeVectorFromData (id, obj, nullptr, isPacked, true) );
455 ATH_CHECK( vec.get() != nullptr );
456 ATH_MSG_DEBUG("Size for \"" << decorationName << "\" " << vec->size() << " interface " << interfaceContainer->size_v() );
457 ATH_CHECK( vec->size() == interfaceContainer->size_v() );
458 if ( vec->size() != 0 ) {
459 ATH_CHECK( currentAuxStore != nullptr );
460 currentAuxStore->addVector(std::move(vec), false);
461 // trigger loading of the dynamic variables
462 SG::AuxElement::TypelessConstAccessor accessor( decorationName );
463 accessor.getDataArray( *interfaceContainer );
464 }
465 return StatusCode::SUCCESS;
466}
467
468StatusCode TriggerEDMDeserialiserAlg::checkSanity( const std::string& transientTypeName, bool isxAODInterfaceContainer, bool isxAODAuxContainer, bool isDecoration, bool isTPContainer ) const {
469 ATH_MSG_DEBUG( "Recognised type " << transientTypeName <<" as: "
470 << (isxAODInterfaceContainer ? "xAOD Interface Container":"" )
471 << (isxAODAuxContainer ? "xAOD Aux Container ":"" )
472 << ( isDecoration ? "xAOD Decoration" : "")
473 << ( isTPContainer ? "T/P Container " : "") );
474
475 const std::vector<bool> typeOfContainer( { isxAODInterfaceContainer, isxAODAuxContainer, isDecoration, isTPContainer } );
476 const size_t count = std::count( typeOfContainer.begin(), typeOfContainer.end(), true );
477 if ( count == 0 ) {
478 ATH_MSG_ERROR( "Could not recognise the kind of container " << transientTypeName );
479 return StatusCode::FAILURE;
480 }
481 if (count > 1 ) {
482 ATH_MSG_ERROR( "Ambiguous container kind deduced from the transient type name " << transientTypeName );
483 ATH_MSG_ERROR( "Recognised type as: "
484 << (isxAODInterfaceContainer ? "xAOD Interface Context":"" )
485 << (isxAODAuxContainer ? " xAOD Aux Container ":"" )
486 << ( isDecoration ? "xAOD Decoration" : "")
487 << ( isTPContainer ? "T/P Container " : "") );
488 return StatusCode::FAILURE;
489 }
490 return StatusCode::SUCCESS;
491}
492
493
495 std::lock_guard<std::mutex> lock(s_mutex);
496
497 if (s_streamerInfoList) {
498 return;
499 }
500
501 std::string extStreamerInfos = "bs-streamerinfos.root";
502 std::string extFilePath = PathResolver::find_file(extStreamerInfos, "DATAPATH");
503 ATH_MSG_DEBUG( "Using " << extFilePath );
504 TFile extFile(extFilePath.c_str());
505
506 s_streamerInfoList = std::unique_ptr<TList>(extFile.GetStreamerInfoList());
507 for(const auto&& infObj: *s_streamerInfoList) {
508 TString t_name=infObj->GetName();
509 if (t_name.BeginsWith("listOfRules")){
510 ATH_MSG_WARNING( "Could not re-load class " << t_name );
511 continue;
512 }
513
514 TStreamerInfo* inf = static_cast<TStreamerInfo*>(infObj);
515 inf->BuildCheck();
516 TClass *cl = inf->GetClass();
517 if (cl != nullptr) {
518 ATH_MSG_DEBUG( "external TStreamerInfo for " << cl->GetName() <<
519 " checksum: " << std::hex << inf->GetCheckSum() << std::dec );
520 }
521 }
522}
const std::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(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.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
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.
void operator()(T1)
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.
ServiceHandle< StoreGateSvc > & evtStore()
An algorithm that can be simultaneously executed in multiple threads.
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.
Handle mappings between names and auxid_t.
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:51
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
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:116
int count(std::string s, const std::string &regx)
count how many occurances of a regx are in a string
Definition hcg.cxx:148
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:38
Collection of helper functions for raw pointer operations on the bytestream payload.
constexpr TDA::PayloadIterator toNextFragment(TDA::PayloadIterator start)
Returns starting point of the next fragment, can be == end().
constexpr 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
constexpr CLID collectionCLID(TDA::PayloadIterator start)
CLID of the collection stored in the next fragment.
constexpr 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.
AuxStoreInternal(bool standalone=false)
An auxiliary data store that holds data internally.
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