ATLAS Offline Software
Loading...
Searching...
No Matches
list_events.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3'''
4@author ATLAS Computing Activity
5@file PyUtils.python.scripts.list_events.py
6'''
7__doc__ = "output run number, event number of events in POOL/BS file(s)"
8
9import PyUtils.acmdlib as acmdlib
10
11@acmdlib.command(
12 name='list-events'
13 )
14@acmdlib.argument(
15 'files',
16 nargs='+',
17 help='input (POOL/BS) file(s)'
18 )
19@acmdlib.argument(
20 '-o', '--output',
21 default='-',
22 help='output text file containing <run number> <event number> record(s) (one per line);'
23 ' if is -, write output on standard output'
24 )
25@acmdlib.argument(
26 '--prefix',
27 default='',
28 help='prefix to print in front of each line of output'
29 )
30def main(args):
31 """Output run number (mc channel number in case of Monte Carlo), event number of events in input (POOL/BS) file(s).
32 """
33
34 import sys
35 if args.output == "-":
36 output = sys.stdout
37 opened = False
38 else:
39 output = open(args.output, 'w', encoding="utf-8")
40 opened = True
41
42 # Setup configuration logging
43 from AthenaCommon.Logging import logging
44 log = logging.getLogger('list-events')
45
46 from os.path import expandvars, expanduser
47 args.files = [expandvars(expanduser(fn)) for fn in args.files]
48
49 log.info(f"input files: {" ".join(repr(fn) for fn in args.files)}")
50 log.info(f"output file: {args.output!r}")
51 log.info(f"prefix: {args.prefix!r}")
52
53 from PyUtils.MetaReader import read_metadata
54 logging.getLogger('MetaReader').setLevel(logging.WARNING)
55 metadata = read_metadata(args.files[0], mode='tiny')[args.files[0]]
56
57 if metadata['file_type'] == 'BS':
58 # run directly AtlListBSEvents
59 import subprocess
60 cmd = ["AtlListBSEvents", "-l"]
61 cmd.extend(args.files)
62 try:
63 log.info("running")
64 log.debug(f"... {cmd=}")
65 log.info(" ...")
66 proc = subprocess.run(cmd, capture_output=True, text=True, check=True)
67 except OSError as err:
68 log.error(err)
69 return err.errno
70 except subprocess.CalledProcessError as err:
71 log.error(f"{err}\nstderr={err.stderr!r}\nstdout={err.stdout!r}")
72 return err.returncode
73 else:
74 from collections import defaultdict
75 info = defaultdict(list)
76
77 indexprefix = "Index="
78 runprefix = "Run="
79 runoff = len(runprefix)
80 eventprefix = "Event="
81 eventoff = len(eventprefix)
82 for line in proc.stdout.splitlines():
83 match line.split():
84 case [Index, Run, Event, _, _, *_] if Index.startswith(indexprefix):
85 if Run.startswith(runprefix) and Event.startswith(eventprefix):
86 try:
87 run = int(Run[runoff:])
88 event = int(Event[eventoff:])
89 except ValueError:
90 log.warning(f"could not parse {line=}")
91 else:
92 log.debug(f"parsed {run=} {event=}")
93 info['run_number'].append(run)
94 info['event_number'].append(event)
95 else:
96 log.warning(f"could not parse {line=}")
97
98 for run, event in zip(info['run_number'], info['event_number'], strict=True):
99 # Changed in version 3.10: Added the strict argument.
100 print(f"{args.prefix}{run:d} {event:d}",
101 file=output)
102 finally:
103 if opened: output.close()
104
105 return 0
106
107 log.info('== Listing <run number> <event number> for events from POOL files (the CA Configuration)')
108
109 # Set the configuration flags
110 log.info('== Setting ConfigFlags')
111 from AthenaConfiguration.AllConfigFlags import initConfigFlags
112 flags = initConfigFlags()
113 flags.Input.Files = args.files
114
115 import AthenaCommon.Constants as Lvl
116 flags.Exec.OutputLevel=Lvl.WARNING
117
118 # Lock and dump the configuration flags
119 flags.lock()
120 log.info('== ConfigFlags Locked')
121
122 # Setup the main services
123 log.info('== Configuring Main Services')
124 from AthenaConfiguration.MainServicesConfig import MainServicesCfg
125 cfg = MainServicesCfg(flags)
126
127 # Setup the input reading
128 log.info('== Configuring Input Reading')
129 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
130 cfg.merge(PoolReadCfg(flags))
131
132 # add event listing algorithm
133 cfg.addEventAlgo(PyEventInfo('EventInfoAlg',
134 # the store-gate key
135 evt_info='EventInfo',
136 is_mc=flags.Input.isMC,
137 output=output,
138 prefix=args.prefix,
139 OutputLevel=Lvl.WARNING),
140 sequenceName='AthAlgSeq')
141
142 for item in flags.Input.TypedCollections:
143 ctype, cname = item.split('#')
144 if ctype.startswith(('Trk', 'InDet')):
145 from TrkEventCnvTools.TrkEventCnvToolsConfig import TrkEventCnvSuperToolCfg
146 cfg.merge(TrkEventCnvSuperToolCfg(flags))
147 if ctype.startswith(('Calo', 'LAr')):
148 from LArGeoAlgsNV.LArGMConfig import LArGMCfg
149 cfg.merge(LArGMCfg(flags))
150 if ctype.startswith(('Calo', 'Tile')):
151 from TileGeoModel.TileGMConfig import TileGMCfg
152 cfg.merge(TileGMCfg(flags))
153 if ctype.startswith('Muon'):
154 from MuonConfig.MuonGeometryConfig import MuonGeoModelCfg
155 cfg.merge(MuonGeoModelCfg(flags))
156
157 # Now run the job
158 log.info('== Running...')
159 sc = cfg.run()
160
161 if opened: output.close()
162
163 # Exit accordingly
164 return sc.isFailure()
165
166
167from AthenaPython.PyAthena import Alg, py_svc, StatusCode
168
169class PyEventInfo(Alg):
170
171 # Constructor
172 def __init__(self, name='PyEventInfo', **kwargs):
173 kwargs['name'] = name
174 super().__init__(**kwargs)
175 # location of EventInfo
176 self.evt_info = kwargs.get('evt_info', None)
177 self.is_mc = kwargs.get('is_mc', False) # default value
178 self.output = kwargs.get('output')
179 self.prefix = kwargs.get('prefix', '')
180
181 # Initialize the algorithm
182 def initialize(self):
183 _info = self.msg.info
184 _error = self.msg.error
185 _info('==> initialize...')
186
187 _info ('EventInfo name: %s',
188 self.evt_info
189 if self.evt_info else '<any>')
190
191 self.sg = py_svc('StoreGateSvc')
192 # if self.sg is None:
193 if not self.sg:
194 _error ('could not retrieve event store')
195 return StatusCode.Failure
196 _info (f'retrieved {self.sg=} service')
197
198 from collections import defaultdict
199 self.info = defaultdict(list)
200 return StatusCode.Success
201
202 # Execute the algorithm
203 def execute(self):
204 _info = self.msg.info
205 _error= self.msg.error
206
207 for evtinfocls in ('xAOD::EventInfo', 'EventInfo'):
208 try:
209 evtinfo = self.sg.retrieve (evtinfocls, self.evt_info)
210 except Exception as e:
211 _info ('could not retrieve %r at [%s]\n caught exception:\n%r', evtinfocls, self.evt_info, e)
212 else:
213 if evtinfo is None:
214 _info ('retrieved \'None\' for %r at [%s]', evtinfocls, self.evt_info)
215 continue
216 break
217 else:
218 _error ("could not retrieve 'EventInfo' or 'xAOD::EventInfo' at [%s]", self.evt_info)
219 return StatusCode.Failure
220
221 if evtinfocls == 'EventInfo':
222 evtid = evtinfo.event_ID()
223 runnbr = evtid.run_number()
224 evtnbr = evtid.event_number()
225 elif evtinfocls == 'xAOD::EventInfo':
226 if not self.is_mc:
227 runnbr = evtinfo.runNumber()
228 else:
229 runnbr = evtinfo.mcChannelNumber()
230 evtnbr = evtinfo.eventNumber()
231
232 self.info['run_number'].append(runnbr)
233 self.info['event_number'].append(evtnbr)
234
235 return StatusCode.Success
236
237 # Finalize the algorithm
238 def finalize(self):
239 for run, event in zip(self.info['run_number'], self.info['event_number'], strict=True):
240 # Changed in version 3.10: Added the strict argument.
241 print(f"{self.prefix}{run:d} {event:d}",
242 file=self.output)
243 return StatusCode.Success
244
void print(char *figname, TCanvas *c1)
__init__(self, name='PyEventInfo', **kwargs)
void initialize()