ATLAS Offline Software
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 '''
7 Methods to deserialise HLTResultMT using Python bindings of C++ classes
8 and reimplementing some logic from TriggerEDMDeserialiserAlg
9 '''
10 
11 from ROOT import StringSerializer
12 from AthenaCommon.Logging import logging
13 log = 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
19 SizeWord = 0
20 CLIDOffset = 1
21 NameLengthOffset = 2
22 NameOffset = 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 
51  def is_xAOD_decoration(self):
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 
85 def 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 
97 def 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 
105 def 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
python.hltResultMT.EDMCollection.name
def name(self)
Definition: hltResultMT.py:39
vtune_athena.format
format
Definition: vtune_athena.py:14
python.hltResultMT.get_collections
def get_collections(rob, skip_payload=False)
Definition: hltResultMT.py:105
python.hltResultMT.EDMCollection.__init__
def __init__(self, name_vec, size_words, words=None)
Definition: hltResultMT.py:28
python.hltResultMT.EDMCollection.is_xAOD_decoration
def is_xAOD_decoration(self)
Definition: hltResultMT.py:51
python.hltResultMT.EDMCollection.name_key
name_key
Definition: hltResultMT.py:30
python.hltResultMT.EDMCollection.deserialise
def deserialise(self)
Definition: hltResultMT.py:59
python.hltResultMT.EDMCollection
Definition: hltResultMT.py:25
python.hltResultMT.EDMCollection.parent
parent
Definition: hltResultMT.py:34
python.hltResultMT.EDMCollection.size_words
size_words
Definition: hltResultMT.py:31
python.hltResultMT.EDMCollection.name_persistent
name_persistent
Definition: hltResultMT.py:29
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.hltResultMT.get_collection_name
def get_collection_name(raw_data_words)
Definition: hltResultMT.py:85
python.hltResultMT.EDMCollection.is_TP_container
def is_TP_container(self)
Definition: hltResultMT.py:56
python.hltResultMT.EDMCollection.is_xAOD_interface_container
def is_xAOD_interface_container(self)
Definition: hltResultMT.py:45
python.hltResultMT.EDMCollection.words
words
Definition: hltResultMT.py:33
python.hltResultMT.get_collection_payload
def get_collection_payload(raw_data_words)
Definition: hltResultMT.py:97
python.hltResultMT.EDMCollection.is_xAOD_aux_container
def is_xAOD_aux_container(self)
Definition: hltResultMT.py:48
python.hltResultMT.EDMCollection.size_bytes
size_bytes
Definition: hltResultMT.py:32
python.hltResultMT.EDMCollection.__str__
def __str__(self)
Definition: hltResultMT.py:36