ATLAS Offline Software
Loading...
Searching...
No Matches
TrigIDR4MonConfig.py
Go to the documentation of this file.
1#!/bin/env python
2#
3# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
4#
5# create all the histograms for each analysis - this will get called once for each
6# configured chain - we can set the HistPath either already here, or from the c++
7# code
8
9
10# actual code to configure al;l the different algorithm instances for
11# the different slices
12
13import os
14import sys
15import glob
16
17from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
18from TrigInDetAnalysisExample.chainString import chainString
19
20from TrigIDR4Monitoring.TrigIDR4MonFlags import TrigIDR4MonFlags
21from TrigIDR4Monitoring.NodeUtils import decodeFlags
22from TrigIDR4Monitoring.NodeUtils import updateFlags
23
24
25
26# wrapper function for the central monitoring configuration
27
28def TrigIDR4MonConfig( flags, monlevels=None ):
29 return TrigIDR4MonitoringCA( flags, monlevels )
30
31
32
33# component accumulator wrapper around the overall
34# monitoring functiom
35
36def TrigIDR4MonitoringCA( iflags, monlevels=None ):
37
38 flags = decodeFlags( iflags )
39
40 from AthenaMonitoring import AthMonitorCfgHelper
41 monConfig = AthMonitorCfgHelper( flags, "TrigIDR4Mon" )
42
43 ca = ComponentAccumulator()
44
45 # print( "monlevel: ", monlevels )
46
47 if flags.Input.isMC:
48 # this turns on the centra athena decoration algorithm
49 if flags.IDTPM2.useDecorations:
50 from TrigIDR4Monitoring.TruthSelectBase import TruthPerigeeDecoratorCfg
51 ca.merge( TruthPerigeeDecoratorCfg( flags ) )
52
53 # maybe this is too soom to specialise to IDTPM2, but hey ...
54
55 algs = TrigIDR4Monitoring( flags.IDTPM2, "Tier0", monlevel="idMon:t0:shifter", kak=ca )
56
57 # if flags.Input.isMC:
58 # algs += TrigIDR4Monitoring( flags.IDTPM2, name="PhysVal", monlevel="idMon:t0" , kak=ca )
59 # algs += TrigIDR4Monitoring( flags.IDTPM2, name="PhysValShifter", monlevel="idMon:shifter", kak=ca )
60
61 for a in algs : monConfig.addAlgorithm(a)
62
63 ca.merge(monConfig.result())
64 return ca
65
66
67# As these debug ssettings will make things very slow, we don't want these
68# but it is useful to leave this here to facilitate easy debugging
69# ComponentAccumulator.debugMode = "trackCA trackEventAlgo trackPublicTool trackPrivateTool"
70
71def TrigIDR4Monitoring( flags, name=None, monlevel=None, kak=None ) :
72
73 tools = []
74
75 from AthenaCommon.Logging import logging
76 log = logging.getLogger("TrigIDR4Monitoring")
77
78 log.info( f"Creating monitoring: {name}" )
79
80 # had key for a reason in the past - I wonder why it is
81 # not being used now ??
82 # key = "All"
83 toolkey = "All"
84
85 if monlevel is not None:
86 log.info( "TIDA monitoring not None: monlevel: " + monlevel )
87 if "t0" in monlevel:
88 # key = "Expert"
89 toolkey = "Expert"
90 elif "shifter" in monlevel:
91 # key = "Shifter"
92 toolkey = "Shifter"
93
94 for node in flags.nodes(): log.info( f"Configuring analysis : {node.name()}" )
95
96 for node in flags.nodes():
97 TrigIDR4MonSignature( node, node.name(), toolkey, tools, monlevel, kak )
98
99 return tools
100
101
102
103def TrigIDR4MonSignature( flags, key, toolkey, tools, monlevel, kak ) :
104
105 tida = TrigIDR4Mon_builder( flags, name = f"ID{key}_{toolkey}Tool" )
106
107 tida.SliceTag = flags.SliceTag
108
109 from TrigInDetMonitoring.TIDAChains import getchains
110
111 hltchains = False
112
113 for pattern in flags.Chains :
114 if chainString(pattern).head:
115 hltchains = True
116 break
117
118 if hltchains : chains = getchains( flags, flags.Chains, monlevel )
119 else: chains = flags.Chains
120
121 if len(chains)==0 : raise RuntimeError(f"No matched chains for Signature: {flags.name()}")
122
123 if len(chains)>0 :
124
125 tida.MonTools = createTATools( flags, flags.SliceTag, chains )
126
127 tools += [ tida ]
128
129 # just because I don't like hanging indentations at ends of functions
130 return
131
132
133
134# create the actual algorithm
135def TrigIDR4Mon_builder( flags=None, name="NoName" ):
136 from AthenaConfiguration.ComponentFactory import CompFactory
137 alg = CompFactory.TrigIDR4Mon( name=name )
138 return alg
139
140
141
142# create a separate specific monTool for each analysis chain
143# - simplifies the overall analysis configuration
144
145def createTATools( flags, label, chains, excludeTagChains=True, kak=None ):
146 tools = []
147
148 from TrigIDR4Monitoring.TrackAnalysisConfig import createTrackAnalysis
149
150 for chain in chains :
151 cs = chainString(chain)
152 if excludeTagChains and "tag" in cs.extra: continue
153 # if it's a probe chain, find the correspondiong tag chain
154 # and pass the pair to track analysis
155 tpchains = getTagnProbe( chain, chains, cs )
156 tatool = createTrackAnalysis( flags, chain, tpchains, label, kak )
157 tools += [ tatool ]
158 return tools
159
160
161def chomp(s, suffix):
162 if s.endswith(suffix) : return s[:-len(suffix)]
163 else : return s
164
165
166def getTagnProbe( probe, chains, cs_probe=None ) :
167
168 if cs_probe is None: cs_probe = chainString(probe)
169
170 if "probe" not in cs_probe.extra : return [ probe ]
171
172 prefix_probe = chomp( cs_probe.extra, "_probe" )
173
174 # so this is a probe chain ...
175
176 # print( "searching for tag for ", probe )
177
178 for tag in chains :
179
180 # print( "\ttag: ", tag )
181
182 if tag==probe : continue
183
184 cstag = chainString(tag)
185
186 # in principle, should be able to use any chain as a tag, and
187 # any chain as a probe, but then each extra=xxx_probe would
188 # need to be unique, which would prevent using wildcared
189 # tag and probe chain pairs
190
191 if cs_probe.head!=cstag.head : continue
192
193 # actually, for the tag and probe analysis, you don't
194 # really care about the tag trigger information, only the
195 # reference selection to reconstruct the tnp selection
196 # criterion
197
198 # if cs_probe.tail!=cstag.tail : continue
199
200 if "tag" not in cstag.extra : continue
201
202 prefix_tag = chomp( cstag.extra, "_tag" )
203
204 if prefix_probe != prefix_tag : continue
205
206 # print( " Fount Tnp: tag: ", tag )
207 # print( " Fount Tnp: probe: ", probe )
208
209 return [ probe, tag ]
210
211 return [ probe ]
212
213
214
215
216def histsvc( flags ):
217
218 from AthenaCommon.Logging import log
219
220 if flags.Output.HISTFileName:
221 log.info( "histsvc: Create THistSvc with file name: "+flags.Output.HISTFileName )
222
223 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
224 ca = ComponentAccumulator()
225
226 from AthenaConfiguration.ComponentFactory import CompFactory
227 THistSvc = CompFactory.THistSvc
228
229 histsvc = THistSvc()
230 if flags.Output.HISTFileName:
231 histsvc.Output += ["%s DATAFILE='%s' OPT='RECREATE'" % (flags.DQ.FileKey, flags.Output.HISTFileName)]
232 log.info( "histsvc: "+histsvc.Output[-1] )
233
234 ca.addService(histsvc)
235
236 return ca
237
238
239
240def file_exists( files ):
241 if isinstance( files, str ): files = [ files ]
242 for f in files:
243 print( f"check file: {f}" )
244 # don't check xrootd files ...
245 if f.startswith(("root://","http://")): continue
246 if not os.path.isfile(f):
247 print(f"ERROR: Input file '{f}' does not exist, cwd: "+os.getcwd())
248 sys.exit(1)
249
250
251def is_mc( filename ):
252 from PyUtils.MetaReader import read_metadata
253 if filename.startswith(("root://","http://")): return None
254 metadata = read_metadata(filename)
255 return 'IS_SIMULATION' in metadata[filename].get('eventTypes', [])
256
257
258def clean_args( values, args, cmdoption ):
259 if not args : return
260 for arg in args:
261 if arg.startswith(cmdoption) :
262 idx = args.index(arg)
263 del args[idx]
264
265 for arg in values:
266 if arg in args:
267 idx = args.index(arg)
268 del args[idx]
269
270
271def parse_signatures( signatures, args=None ) :
272 if not signatures: return None
273 sigs = []
274 for sig in signatures:
275 if sig.endswith(".py") or "=" in sig: continue
276 sigs.append( sig )
277
278 if args: clean_args( sigs, args, "--signatures" )
279
280 return sigs
281
282
283def parse_files( files, args=None ) :
284
285 if files is None :
286 print( "no input files" )
287 return []
288
289 if isinstance(files,str): files = [ files ]
290
291 _out = []
292
293 for file in files:
294 if file.endswith(".py") or "=" in file: continue
295 _out += file.split(",")
296
297 out = []
298
299 for f in _out :
300 if f.startswith(("root://","http://")): out.append(f)
301 else: out += glob.glob(f)
302
303 if not out :
304 print( "no matching files", _out )
305
306 if args: clean_args( _out, args, "--filesInput" )
307
308 return out
309
310
311
312if __name__=='__main__':
313
314 # Setup logs
315 from AthenaCommon.Logging import log
316 log.info( "test running" )
317
318 # Set the Athena configuration flags
319 from AthenaConfiguration.AllConfigFlags import initConfigFlags
320
321 flags = initConfigFlags()
322
323 # Input files
324 # AOD file to be run w/ MT access and Mon Groups implemented
325 file = 'AOD.pool.root'
326
327 flags.Input.Files = [file]
328
329 file_exists( flags.Input.Files )
330
331 flags.Input.isMC = is_mc( flags.Input.Files[0] )
332
333 flags.Output.HISTFileName = 'duff.root'
334
335 # in case we are looking at an express stream file ...
336 flags.Common.doExpressProcessing=True
337
338 # run using 10 threads and 5 events at a time, so 2 threads per events
339 # really these should be settable parameters
340 # flags.Concurrency.NumThreads = 20
341 # flags.Concurrency.NumConcurrentEvents = 10
342 # flags.Concurrency.NumThreads = 10
343 # flags.Concurrency.NumConcurrentEvents = 5
344 # flags.Concurrency.NumThreads = 0
345 # flags.Concurrency.NumConcurrentEvents = 0
346
347
348 flags.Input.AODFixesDone = {"egammaAODFixesCfg"}
349
350 tflags = decodeFlags( flags )
351
352 TrigIDR4MonFlags( tflags )
353
354 updateFlags(flags,tflags)
355
356 tflags.lock()
357 flags.lock()
358
359
360 # Initialize configuration object, add accumulator, merge, and run.
361 from AthenaConfiguration.MainServicesConfig import MainServicesCfg
362 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
363 cfg = MainServicesCfg(tflags)
364
365 cfg.merge( PoolReadCfg(tflags) )
366
367 cfg.merge( histsvc(tflags) )
368
369 cfg.merge( TrigIDR4MonConfig( tflags ) )
370
371 # If you want to turn on more detailed messages ...
372 cfg.printConfig(withDetails=False) # set True for exhaustive info
373
374 Nevents = 25000
375 cfg.run(Nevents)
376
377
378
void print(char *figname, TCanvas *c1)
void name(const std::string &n)
Definition node.h:40
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
TrigIDR4Mon_builder(flags=None, name="NoName")
parse_signatures(signatures, args=None)
TrigIDR4MonSignature(flags, key, toolkey, tools, monlevel, kak)
parse_files(files, args=None)
clean_args(values, args, cmdoption)
createTATools(flags, label, chains, excludeTagChains=True, kak=None)
getTagnProbe(probe, chains, cs_probe=None)
TrigIDR4Monitoring(flags, name=None, monlevel=None, kak=None)
TrigIDR4MonitoringCA(iflags, monlevels=None)