ATLAS Offline Software
Loading...
Searching...
No Matches
list_events.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3# @file PyUtils.scripts.list-events
4# @purpose list event numbers in a given file
5# @author Marcin Nowak
6# @date April 2025
7
8__doc__ = "Print out event numbers of the events in a file. Format: (run#, event#)"
9__author__ = "Marcin Nowak"
10
11
12import PyUtils.acmdlib as acmdlib
13
14
15@acmdlib.command(name='list-events')
16@acmdlib.argument('-f', '--file',
17 help='Athena file to scan')
18@acmdlib.argument('-t', '--tree-name',
19 default='CollectionTree',
20 help='name of the TTree to scan')
21@acmdlib.argument('--entries',
22 default='',
23 help='a list of entries (indices, not event numbers) or an expression (like 0:3) leading to such a list, to inspect')
24@acmdlib.argument('-v', '--verbose',
25 action='store_true',
26 default=False,
27 help="""Enable verbose printout""")
28
29
30def getEventsFromTree(tree, msg):
31
32 eiNames = ['EventInfoAuxDyn.eventNumber',
33 'EventInfoAux.',
34 'Bkg_EventInfoAux.',
35 'xAOD::EventAuxInfo_v3_EventInfoAux.',
36 'xAOD::EventAuxInfo_v2_EventInfoAux.',
37 'xAOD::EventAuxInfo_v1_EventInfoAux.',
38 'xAOD::EventAuxInfo_v3_Bkg_EventInfoAux.',
39 'xAOD::EventAuxInfo_v2_Bkg_EventInfoAux.',
40 'xAOD::EventAuxInfo_v1_Bkg_EventInfoAux.',
41 'McEventInfo',
42 'ByteStreamEventInfo',
43 'EventInfo_p4_McEventInfo',
44 'EventInfo_p4_ByteStreamEventInfo']
45 runName = 'EventInfoAuxDyn.runNumber'
46
47 tree.GetEntry(0)
48 einame = None
49 for n in eiNames:
50 if hasattr(tree, n):
51 einame = n
52 break
53 if einame is None:
54 msg.error('Cannot find event info, aborting.')
55 return []
56 msg.info("Using branch: %s", einame)
57
58 tree.SetBranchStatus ('*', 0)
59 tree.SetBranchStatus (einame, 1)
60 if 'AuxDyn' in einame:
61 tree.SetBranchStatus (runName, 1)
62
63 eventList = []
64 for idx in range(tree.GetEntriesFast()):
65 tree.GetEntry(idx)
66 if einame.endswith('Aux.'):
67 ei = getattr(tree, einame)
68 eventList.append((ei.runNumber, ei.eventNumber))
69 elif einame.endswith('Info'):
70 eid = getattr(tree, einame).m_event_ID
71 eventList.append((eid.m_run_number, eid.m_event_number))
72 elif 'AuxDyn' in einame:
73 eventList.append(( getattr(tree, runName), getattr(tree, einame)))
74
75 tree.SetBranchStatus ('*', 1)
76
77 # Write out the ordered index and event number pairs
78 return eventList
79
80
81def getEventList(file, tree_name="CollectionTree", entries='', verbose=False):
82 """Get list of event+run numbers for given entries in a file/tree"""
83
84 import PyUtils.Logging as L
85 msg = L.logging.getLogger('list-events')
86 if verbose:
87 msg.setLevel(L.logging.VERBOSE)
88 else:
89 msg.setLevel(L.logging.WARNING)
90
91 msg.info('file: [%s]', file)
92 msg.info('tree: [%s]', tree_name)
93 msg.info('entries: %s', entries)
94
95 def get_event_range(entry):
96 smin, smax = 0, None
97 # Parse user input
98 if isinstance(entry, str):
99 # We support three main cases in this format: 5:10 (5th to 10th),
100 # 5: (5th to the end), and :5 (from the start to 5th)
101 if ':' in entry:
102 vals = entry.split(':')
103 smin = int(vals[0]) if len(vals) > 0 and vals[0].isdigit() else 0
104 smax = int(vals[1]) if len(vals) > 1 and vals[1].isdigit() else None
105 # This is the case where the user inputs the total number of events
106 elif entry.isdigit():
107 smin = 0
108 smax = int(entry) if int(entry) > 0 else None
109 # Handle the case where the input is a number (i.e. default)
110 elif isinstance(entry, int):
111 smin = 0
112 smax = entry if entry > 0 else None
113 # If we come across an unhandled case, bail out
114 else:
115 msg.warning(f"Unknown entries argument {entry}, will list all events...")
116 return smin, smax
117
118 import PyUtils.RootUtils as ru
119 ru.import_root() # noqa: F841
120 try:
121 dumper = ru.RootFileDumper(file, tree_name)
122 except AttributeError as e:
123 msg.error( *e.args )
124 return []
125
126 smin, smax = 0, None
127 if entries in (-1,'','-1'):
128 smax = dumper.tree.GetEntries()
129 else:
130 smin, smax = get_event_range(entries)
131 msg.debug(f"Getting Event numbers for entries [{smin},{smax}]")
132
133 return getEventsFromTree(dumper.tree, msg)[smin:smax]
134
135
136def main(args):
137 """Print event numbers of events in a file. Format: (run#, event#)"""
138
139 eventList = getEventList(args.file, args.tree_name, args.entries, args.verbose)
140 # print the output here to get the desired format (event per line)
141 for ent in eventList:
142 print(ent)
143 # return nothing to avoid printing the output again
144 return
145
146
147# example of direct use
148if __name__ == "__main__":
149 import sys
150 if len(sys.argv) < 2:
151 print("no filename given")
152 sys.exit(1)
153 eventList = getEventList(sys.argv[1])
154 for ent in eventList:
155 print(ent)
156
157
158
159
160
void print(char *figname, TCanvas *c1)
getEventList(file, tree_name="CollectionTree", entries='', verbose=False)
getEventsFromTree(tree, msg)
options ----------------------------------------------------------------—