ATLAS Offline Software
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 
12 import 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 
30 def 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 
81 def 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 
136 def 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
148 if __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 
python.scripts.list_events.getEventList
def getEventList(file, tree_name="CollectionTree", entries='', verbose=False)
Definition: list_events.py:81
python.scripts.list_events.main
def main(args)
Definition: list_events.py:136
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
python.scripts.list_events.getEventsFromTree
def getEventsFromTree(tree, msg)
functions --------------------------------------------------------------—
Definition: list_events.py:30
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45