64 assert len(words) % num_sets == 0
65 n_words_per_set = len(words) // num_sets
67 for iset
in range(num_sets):
68 words_in_set = words[iset*n_words_per_set:(iset+1)*n_words_per_set]
70 for iw
in range(len(words_in_set)):
71 bit_indices.extend([base*iw+i
for i
in range(base)
if words_in_set[iw] & (1 << i)])
72 result.append(bit_indices)
90def decode_status(fragment):
91 '''Return event/ROB fragment status and string representation'''
93 if not fragment.status():
96 info_str = '[' + ', '.join('0x%x' % s for s in fragment.status()) + ']'
99 status = eformat.helper.Status(fragment.status()[0])
100 info_str += ''.join(f' {item.name}' for code, item in eformat.helper.GenericStatus.values.items()
101 if status.generic() & code)
103 # The specific bits of the first word are only relevant for the full event:
104 if isinstance(fragment, eformat.FullEventFragment):
105 info_str += ''.join(f' {item.name}' for code, item in eformat.helper.FullEventStatus.values.items()
106 if status.specific() & code)
108 # HLT-specific event status:
109 if len(fragment.status())>1:
111 cppyy.gbl.HLT.OnlineErrorCode # trigger auto-loading via enum
112 info_str += ' '+ cppyy.gbl.HLT.OnlineErrorCodeToString(fragment.status()[1]).data()
117def ctp_rob(event, module_id=1):
118 '''Return a string with information from the CTP ROB'''
120 ctp_robs = [rob for rob in event \
121 if rob.source_id().subdetector_id() == eformat.helper.SubDetector.TDAQ_CTP \
122 and rob.source_id().module_id()==module_id]
125 log.warning('No CTP ROB found')
128 assert len(ctp_robs)==1
131 from TrigByteStreamTools import CTPfragment
132 x = CTPfragment.getExtraPayloadObject(rob)
133 info_str = (f'ROB 0x{rob.source_id().code():x}, '
134 f'L1ID {event.lvl1_id():10d}, '
135 f'LB {event.lumi_block():4d}, '
136 f'Version {CTPfragment.ctpFormatVersion(rob)}, '
137 f'Bunch {CTPfragment.lvl1AcceptBunch(rob)}, '
138 f'HLT counter: {CTPfragment.hltCounter(rob):3d}, '
139 f'Payload #{CTPfragment.numberHltExtraPayloadWords(rob)} '
140 f'{CTPfragment.hltExtraPayloadWords(rob)} '
141 f'L1PSK {x.getL1PSK()} BGK {x.getBGK()}')
142 folderUpdates = CTPfragment.getFolderUpdates(x)
143 if len(folderUpdates)>0:
144 info_str += ' COOLUPD '+''.join([f'[{f.second.folderIndex}, {f.second.lumiBlock}]' for f in folderUpdates])
149 '''Return a string with information about LVL1 bits (IDs of items passed at TBP, TAP, TAV)'''
151 info = event.lvl1_trigger_info()
152 lvl1_bits = decodeTriggerBits(info, 3) # TBP, TAP, TAV
153 info_str = 'L1 CTP IDs - TBP: {:s}\n'.format(str(lvl1_bits[0]))
154 info_str += 'L1 CTP IDs - TAP: {:s}\n'.format(str(lvl1_bits[1]))
155 info_str += 'L1 CTP IDs - TAV: {:s}'.format(str(lvl1_bits[2]))
159def hlt_bits(event, version=(1,1)):
160 '''Return a string with information about passed chain IDs at HLT'''
162 # Version 1.0 has {passed, prescaled, rerun}, 1.1 and later only {passed, prescaled}
163 num_sets = 3 if version[0] < 1 or version==(1,0) else 2
165 info = event.event_filter_info()
166 hlt_bits = decodeTriggerBits(info, num_sets)
167 info_str = 'HLT passed chain IDs: {:s}'.format(str(hlt_bits[0]))
168 info_str += '\nHLT prescaled chain IDs: {:s}'.format(str(hlt_bits[1]))
170 info_str += '\nHLT rerun chain IDs: {:s}'.format(str(hlt_bits[2]))
174def stream_tags(event):
176 return '[' + ', '.join([hex(num) for num in nums]) + ']'
177 info_str = 'Stream Tags:'
178 for st in event.stream_tag():
179 info_str += '\n-- {}_{}'.format(st.type, st.name)
182 if len(robs) == 0 and len(dets) == 0:
183 info_str += ' - Full Event Building'
185 info_str += ' - Partial Event Building, robs={}, dets={}'.format(hex_list(robs), hex_list(dets))
189def hlt_rod_minor_version(rob):
190 version = rob.rod_version()
191 minor_version = version.minor_version()
192 minor_version_M = (minor_version & 0xff00) >> 8
193 minor_version_L = minor_version & 0xff
194 return (minor_version_M, minor_version_L)
203def hlt_result(event, print_sizes=False, deserialize=False, conf_keys=False, runtime_metadata=False):
206 for rob in event.children():
207 if rob.source_id().subdetector_id() != eformat.helper.SubDetector.TDAQ_HLT:
210 version = hlt_rod_minor_version(rob)
211 info_str += '\n-- {:s} SourceID: {:s}, Version: {:s}, Size: {:d} bytes, Status: {:s}'.format(
212 rob.__class__.__name__,
213 rob.source_id().human(),
214 f'{version[0]:d}.{version[1]:d}',
215 rob.fragment_size_word()*4,
218 if print_sizes or deserialize or conf_keys or runtime_metadata:
220 raise RuntimeError('Cannot decode data from before Run 3, HLT ROD minor version needs to be >= 1.0')
221 skip_payload = not conf_keys and not runtime_metadata and not deserialize
222 collections = hltResultMT.get_collections(rob, skip_payload=skip_payload)
224 conf_list = [c for c in collections if 'xAOD::TrigConfKeys_v' in c.name_persistent]
225 conf_available = False
226 for conf in conf_list:
227 conf_obj = conf.deserialise()
230 conf_available = True
231 info_str += '\n---- {:s}#{:s} SMK: {:d}, L1PSK: {:d}, HLTPSK: {:d}'.format(
232 conf.name_persistent, conf.name_key,
233 conf_obj.smk(), conf_obj.l1psk(), conf_obj.hltpsk())
234 if not conf_available:
235 info_str += '\n---- TrigConfKeys unavailable in this ROB'
237 decorations = ['hostname']
238 meta_list = [c for c in collections if any([f'RuntimeMetadataAux.{decor}' in c.name() for decor in decorations])]
239 meta_available = False
240 for meta in meta_list:
241 meta_obj = meta.deserialise()
244 meta_available = True
245 info_str += '\n---- RuntimeMetadata {:s}: {:s}'.format(
246 meta.name_key, meta_obj.at(0))
247 if not meta_available:
248 info_str += '\n---- RuntimeMetadata unavailable in this ROB'
249 if print_sizes or deserialize:
250 for coll in collections:
251 indent = 4 if not coll.is_xAOD_decoration() else 6
252 info_str += '\n{:s} {:s}'.format('-'*indent, str(coll))
253 if deserialize and (coll_obj := coll.deserialise()) is not None:
255 length = coll_obj.size() # all collections should have this method
258 if length is not None:
259 info_str += f' ({length} element' + ('s)' if length!=1 else ')')
260 info_str += '\n{:s} {:s}'.format(' '*indent, str(coll_obj))
263 info_str = 'Found {:d} HLT ROBs'.format(num_hlt_robs) + info_str
267def size_summary(events):
269 # Format of the data dictionary:
280 for rob in event.children():
281 if rob.source_id().subdetector_id() != eformat.helper.SubDetector.TDAQ_HLT:
283 version = hlt_rod_minor_version(rob)
285 raise RuntimeError('Cannot decode data from before Run 3, HLT ROD minor version needs to be >= 1.0')
286 module = rob.source_id().module_id()
287 if module not in data.keys():
288 data[module] = {'total': 0}
289 data[module]['total'] += rob.fragment_size_word()*4
290 if 'collections' not in data[module].keys():
291 data[module]['collections'] = {}
292 for coll in hltResultMT.get_collections(rob, skip_payload=True):
293 coll_name = coll.name()
294 if coll_name in data[module]['collections'].keys():
295 data[module]['collections'][coll_name] += coll.size_bytes
297 data[module]['collections'][coll_name] = coll.size_bytes
298 info_str = '='*20 + '\nSize summary:\n' + '='*20
299 for module in data.keys():
300 module_size = data[module]['total']
301 module_size_per_evt = module_size / float(len(events))
302 info_str += '\n-- TDAQ_HLT module {:d} total size {:d} bytes, {:.3f} bytes/event'.format(
303 module, module_size, module_size_per_evt)
304 sorted_colls = sorted(data[module]['collections'].items(),
305 key=lambda kv: kv[1],
307 max_name_len = len(max(data[module]['collections'].keys(), key=len))
308 max_name_len = min(120, max_name_len) # Make a reasonable limit to avoid line breaks
309 for coll_name, coll_size in sorted_colls:
310 coll_size_per_evt = coll_size / float(len(events))
311 info_str += '\n---- {:{width}} {:12d} B {:12.3f} B/ev'.format(
312 coll_name, coll_size, coll_size_per_evt, width=max_name_len)
315def dump_info(bsfile, args):
316 log.info('Opening %s', bsfile)
317 input = eformat.istream(bsfile)
318 offset = args.skip if args.skip else 0
319 max_events = min(args.events, len(input)) if args.events else len(input)
327 if event_count <= offset:
329 if event_count > offset+max_events:
334 version = hlt_rod_minor_version_from_event(event)
337 print('{sep:s} Event: {:{width}d}, {:s} {sep:s}'.format(
338 event_count, header_info(event),
339 sep='===', width=len(str(max_events))))
342 if args.ctp is not False:
343 print(ctp_rob(event, 1))
345 # Print L1/L2/HLT bits
347 print(lvl1_bits(event))
348 if args.ef and version is not None:
349 print(hlt_bits(event, version))
353 print(stream_tags(event))
356 if args.efres or args.sizes or args.deserialize or args.confKeys or args.runtimeMetadata:
357 print(hlt_result(event, args.sizes, args.deserialize, args.confKeys, args.runtimeMetadata))
359 # Size summary (after the loop over events)
361 print(size_summary(events))
decodeTriggerBits(words, num_sets, base=32)