ATLAS Offline Software
Loading...
Searching...
No Matches
hltResultMT.py
Go to the documentation of this file.
1#!/usr/bin/env python
2#
3# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
4#
5
6'''
7Methods to deserialise HLTResultMT using Python bindings of C++ classes
8and reimplementing some logic from TriggerEDMDeserialiserAlg
9'''
10
11from ROOT import StringSerializer
12from AthenaCommon.Logging import logging
13log = logging.getLogger('hltResultMT')
14
15# Global StringSerialiser to avoid constructing per call
16_string_serialiser = StringSerializer()
17
18# Copy of variables defined in TrigOutputHandling/src/TriggerEDMDeserialiserAlg.h
19SizeWord = 0
20CLIDOffset = 1
21NameLengthOffset = 2
22NameOffset = 3
23
24
26 '''A python representation of a serialised EDM collection'''
27
28 def __init__(self, name_vec, size_words, words=None):
29 self.name_persistent = name_vec[0]
30 self.name_key = name_vec[1]
31 self.size_words = size_words
32 self.size_bytes = size_words*4
33 self.words = words
34 self.parent = None
35
36 def __str__(self):
37 return '{:s}, Size: {:d} bytes'.format(self.name(), self.size_bytes)
38
39 def name(self):
40 if not self.parent:
41 return '{:s}#{:s}'.format(self.name_persistent, self.name_key)
42 else:
43 return '{:s}#{:s}{:s}'.format(self.name_persistent, self.parent.name_key, self.name_key)
44
46 return self.name_persistent.startswith('xAOD') and not self.name_key.endswith('Aux.')
47
49 return self.name_persistent.startswith('xAOD') and self.name_key.endswith('Aux.')
50
52 return 'vector' in self.name_persistent and \
53 not self.is_xAOD_interface_container() and \
54 not self.is_xAOD_aux_container()
55
56 def is_TP_container(self):
57 return '_p' in self.name_persistent
58
59 def deserialise(self):
60 if not self.words:
61 log.error('No payload stored, cannot deserialise')
62 return None
63
64 # Lazily import modules needed for deserialisation
65 import cppyy
66 import ROOT
67 import array
68 import struct
69 from ctypes import c_uint
70
71 # Reinterpret words: Python int list -> C unsigned int list -> C char (Python bytes) array
72 cwords = [c_uint(w) for w in self.words]
73 bwords = [struct.pack('@I',cw.value) for cw in cwords]
74 bwords_merged = b''.join(bwords)
75 bwords_array = array.array('b', bwords_merged)
76
77 # ROOT deserialisation
78 cltype = ROOT.RootType.ByNameNoQuiet(self.name_persistent)
79 buffer = ROOT.TBufferFile(ROOT.TBuffer.kRead, len(bwords_array), bwords_array, False)
80 obj_ptr = buffer.ReadObjectAny(cltype.Class())
81 obj = cppyy.bind_object(obj_ptr, self.name_persistent)
82 return obj
83
84
85def get_collection_name(raw_data_words):
86 '''Extract type+name words from the full collection raw data and convert to string'''
87
88 # Use Python bindings of C++ StringSerialiser to deserialise collection type and name.
89 # Doing the tuple-conversion here has a big performance impact. Probably this could be
90 # further improved if the eformat had better support for u32slice iterators.
91
92 nw = raw_data_words[NameLengthOffset]
93 name_words = tuple(raw_data_words[NameOffset:NameOffset+nw])
94 return _string_serialiser.deserialize(name_words)
95
96
97def get_collection_payload(raw_data_words):
98 '''Extract the serialised collection payload from the full collection raw data'''
99
100 name_size = raw_data_words[NameLengthOffset]
101 payload_start = NameOffset + name_size + 1
102 return raw_data_words[payload_start:]
103
104
105def get_collections(rob, skip_payload=False):
106 '''
107 Extract a list of EDMCollection objects from the HLT ROBFragment.
108 If skip_payload=True, only the information about type, name and size
109 are kept but the payload is discarded to improve performance.
110 '''
111
112 start = SizeWord
113 collections = []
114 last_aux_cont = None
115 rod_size = len(rob.rod_data())
116 while start < rod_size:
117 size = rob.rod_data()[start+SizeWord]
118 coll_name = get_collection_name(rob.rod_data()[start:start+size])
119 words = None if skip_payload else get_collection_payload(rob.rod_data()[start:start+size])
120 coll = EDMCollection(coll_name, size, words)
121 if coll.is_xAOD_aux_container():
122 last_aux_cont = coll
123 if coll.is_xAOD_decoration():
124 coll.parent = last_aux_cont
125 collections.append(coll)
126 start += size
127 return collections
Utility class (not a tool or so) to serialize strings into stream of 32bit integers.
__init__(self, name_vec, size_words, words=None)
get_collection_payload(raw_data_words)
get_collection_name(raw_data_words)
get_collections(rob, skip_payload=False)