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