ATLAS Offline Software
Loading...
Searching...
No Matches
L1CaloPhase1Monitoring.py
Go to the documentation of this file.
1#!/usr/bin/env athena
2# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3
4
10
11from AthenaCommon.Logging import logging
12from AthenaCommon.Logging import log as topLog
13topLog.setLevel(logging.WARNING) # default to suppressing all info logging except our own
14log = logging.getLogger('l1calo-ath-mon')
15log.setLevel(logging.INFO)
16
17from TrigT1CaloMonitoring.LVL1CaloMonitoringConfig import L1CaloMonitorCfgHelper
18L1CaloMonitorCfgHelper.embargoed = ["Expert/Efficiency/gFEX/MuonReferenceTrigger/SRpt_L1_gJ400p0ETA25"]#,"Expert/Sim/L1TopoAlgoMismatchRateVsLB","Expert/Sim/L1TopoMultiplicityMismatchRateVsLumi"]
19
20
21
22from AthenaConfiguration.ComponentFactory import CompFactory
23from AthenaConfiguration.AllConfigFlags import initConfigFlags
24from AthenaConfiguration.Enums import LHCPeriod,Format
25from AthenaCommon import Constants
26import os
27import ispy
28import re
29partition = ispy.IPCPartition(os.getenv("TDAQ_PARTITION","ATLAS"))
30
31flags = initConfigFlags()
32# remove unused flag categories. Note Calo and Tile are only needed if running on CaloCells
33neededCats = ["GeoModel","DQ","Trigger","PerfMon","Detector","Muon","Overlay","LAr","Reco","Calo","Tile"]
34for cat in list(flags._dynaflags.keys()):
35 if cat not in neededCats: del flags._dynaflags[cat]
36flags.Input.Files = [] # so that when no files given we can detect that
37
38# Note: The order in which all these flag defaults get set is very fragile
39# so don't reorder the setup of this flags stuff
40
41
42flags.Exec.OutputLevel = Constants.WARNING # by default make everything output at WARNING level
43flags.Exec.InfoMessageComponents = ["AthenaEventLoopMgr","AthenaHiveEventLoopMgr","THistSvc","PerfMonMTSvc","ApplicationMgr","AvalancheSchedulerSvc"] # Re-enable some info messaging though
44flags.Exec.PrintAlgsSequence = True # print the alg sequence at the start of the job (helpful to see what is scheduled)
45# flags.Exec.FPE = -2 # disable FPE auditing ... set to 0 to re-enable
46
47
48flags.GeoModel.Run = LHCPeriod.Run3 # needed for LArGMConfig - or can infer from above
49flags.Common.useOnlineLumi = True # needed for lumi-scaled monitoring, only have lumi in online DB at this time
50flags.DQ.doMonitoring = True # use this flag to turn on/off monitoring in this application
51flags.DQ.enableLumiAccess = False # in fact, we don't need lumi access for now ... this turns it all off
52flags.DQ.FileKey = "" if partition.isValid() else "EXPERT" # histsvc file "name" to record to - Rafal asked it to be blank @ P1 ... means monitoring.root will be empty
53flags.Output.HISTFileName = os.getenv("L1CALO_ATHENA_JOB_NAME","") + "monitoring.root" # control names of monitoring root file - ensure each online monitoring job gets a different filename to avoid collision between processes
54flags.DQ.useTrigger = False # don't do TrigDecisionTool in MonitorCfg helper methods
55flags.Trigger.L1.doCaloInputs = partition.isValid() # flag for saying if inputs should be decoded or not
56flags.Trigger.enableL1CaloPhase1 = True # used by this script to turn on/off the simulation
57# flags for rerunning simulation - on by default only in online environment
58flags.Trigger.L1.doCalo = partition.isValid()
59flags.Trigger.L1.doeFex = partition.isValid()
60flags.Trigger.L1.dojFex = partition.isValid()
61flags.Trigger.L1.dogFex = partition.isValid()
62flags.Trigger.L1.doTopo = partition.isValid()
63# if running online, override these with autoconfig values
64# will set things like the GlobalTag automatically
65if partition.isValid():
66 # must ensure doLVL1 and doHLT are False, otherwise will get ByteStreamCnvSvc conflicts (TrigByteStreamCnvSvc is setup, but EMon setup provides ByteStreamCnvSvc)
67 # see TriggerByteStreamConfig.py
68 flags.Trigger.doLVL1 = False
69 flags.Trigger.doHLT = False
70 from AthenaConfiguration.AutoConfigOnlineRecoFlags import autoConfigOnlineRecoFlags
71 autoConfigOnlineRecoFlags(flags, partition.name()) # sets things like projectName etc which would otherwise be inferred from input file
72else:
73 flags.Trigger.doLVL1 = True # set this just so that IOBDb.GlobalTag is autoconfigured based on release setup if running on RAW (autoconfig will take it from POOL file if running on that)
74#flags.IOVDb.GlobalTag = lambda s: "OFLCOND-MC23-SDR-RUN3-02" if s.Input.isMC else "CONDBR2-ES1PA-2022-07" #"CONDBR2-HLTP-2022-02"
75
76# now parse
77
78parser = flags.getArgumentParser(epilog="""
79Extra flags are specified after a " -- " and the following are most relevant flags for this script:
80
81 Trigger.enableL1CaloPhase1 : turn on/off the offline simulation [default: True]
82 DQ.doMonitoring : turn on/off the monitoring [default: True]
83 Trigger.L1.doCaloInputs : controls input readout decoding and monitoring [default: False*]
84 Trigger.L1.doCalo : controls trex (legacy syst) monitoring [default: False]
85 Trigger.L1.doeFex : controls efex simulation and monitoring [default: False*]
86 Trigger.L1.dojFex : controls jfex simulation and monitoring [default: False*]
87 Trigger.L1.dogFex : controls gfex simulation and monitoring [default: False*]
88 Trigger.L1.doTopo : controls topo simulation and monitoring [default: False*] (from 2023 Onwards)
89 Trigger.L1.doGlobal : controls global simulation and monitoring [default: False]
90 DQ.useTrigger : controls if JetEfficiency monitoring alg is run or not [default: False]
91 PerfMon.doFullMonMT : print info about execution time of algorithms and memory use etc [default: False]
92 Trigger.triggerConfig : if you specifying this as "FILE:<filename>" the script will use that L1 json menu. [default: "DB" (takes menu from DB for data)]
93
94Note: If you do not specify any flags, then all the flags that are marked with a * will automatically become True
95
96E.g. to run just the jFex monitoring, without offline simulation, you can do:
97
98athena TrigT1CaloMonitoring/L1CalPhase1Monitoring.py .... -- Trigger.enableL1CaloPhase1=False Trigger.L1.doCaloInputs=False Trigger.L1.doeFex=False Trigger.L1.dogFex=False
99
100Further notes: Run with "--evtMax 0" to print flags and ca config, and generate a hanConfig file.
101 Run with "--evtMax 1" to dump StoreGate contents after the first event
102
103""")
104import argparse
105#class combinedFormatter(parser.formatter_class,argparse.RawDescriptionHelpFormatter): pass
106parser.formatter_class = argparse.RawDescriptionHelpFormatter
107parser.add_argument('--runNumber',default=None,help="specify to select a run number")
108parser.add_argument('--lumiBlock',default=None,help="specify to select a lumiBlock")
109parser.add_argument('--evtNumber',default=None,nargs="+",type=int,help="specify to select an evtNumber")
110parser.add_argument('--stream',default="*",help="stream to lookup files in")
111parser.add_argument('--fexReadoutFilter',action='store_true',help="If specified, will skip events without fexReadout")
112parser.add_argument('--dbOverrides',default=None,nargs="+",type=str,help="specify overrides of COOL database folders in form <folder>=<dbPath> or <folder>:<tag>[=<dbPath>] to override a tag, example: /TRIGGER/L1Calo/V1/Calibration/EfexEnergyCalib=mytest.db ")
113parser.add_argument('--postConfig',default=[],nargs="+",type=str,help="specify component properties to apply at the end of the config. Can also specify in the flags section if start with 'cfg.' Use '--postHelp' option to explore the configurables and their properties")
114parser.add_argument('--postInclude',default=[],nargs="+",type=str,help="specify python files to call before configuration completes")
115parser.add_argument('--postHelp',default=None,nargs="*",help="Displays configurables and their properties")
116args,unknown_args = flags.fillFromArgs(parser=parser,return_unknown=True)
117args.postConfig += [x[4:] for x in unknown_args if x.startswith("cfg.")]
118if any([not x.startswith("cfg.") for x in unknown_args]):
119 raise KeyError("Unknown flags: " + " ".join([x for x in unknown_args if not x.startswith("cfg.")]))
120if not any([flags.Trigger.L1.doCalo,flags.Trigger.L1.doCaloInputs,flags.Trigger.L1.doeFex,flags.Trigger.L1.dojFex,flags.Trigger.L1.dogFex,flags.Trigger.L1.doTopo,flags.DQ.useTrigger]):
121 log.info("No steering flags specified, turning on all phase 1 systems (trex,efex,jfex,gfex,topo)")
122 flags.Trigger.L1.doCaloInputs = True # flag for saying if inputs should be decoded or not
123 flags.Trigger.L1.doCalo = True
124 flags.Trigger.L1.doeFex = True
125 flags.Trigger.L1.dojFex = True
126 flags.Trigger.L1.dogFex = True
127 flags.Trigger.L1.doTopo = True
128
129# check input files
130if len(flags.Input.Files)>0:
131 # check input files list for alias to default test files ... substituting them
132 from AthenaConfiguration.TestDefaults import defaultTestFiles
133 flags.Input.Files = [getattr(defaultTestFiles,f,f) for f in flags.Input.Files]
134 flags.Input.Files = [item for x in flags.Input.Files for item in (x if isinstance(x,list) else [x])] # flatten mix of str and list
135 # now also check for non-existent input files before continuing
136 for f in flags.Input.Files:
137 if not os.path.exists(f):
138 log.fatal(f"file '{f}' does not exist")
139 exit(-1)
140
141if args.runNumber is not None:
142 # todo: if an exact event number is provided, we can in theory use the event index and rucio to obtain a filename:
143 # e.g: event-lookup -D RAW "477048 3459682284"
144 # use GUID result to do:
145 # ~/getRucioLFNbyGUID.sh 264A4214-E922-EF11-AB28-B8CEF6444828
146 # gives a filename (last part): data24_13p6TeV.00477048.physics_Main.daq.RAW._lb0975._SFO-13._0001.data
147 from glob import glob
148 if args.lumiBlock is None: args.lumiBlock="*"
149 log.info(" ".join(("Looking up files in atlastier0 for run",args.runNumber,"lb =",args.lumiBlock)))
150 flags.Input.Files = []
151 for lb in args.lumiBlock.split(","):
152 if lb=="*":
153 tryStr = f"/eos/atlas/atlastier0/rucio/data*/{args.stream}/*{args.runNumber}/*RAW/*lb*.*"
154 else:
155 tryStr = f"/eos/atlas/atlastier0/rucio/data*/{args.stream}/*{args.runNumber}/*RAW/*lb{int(lb):04}.*"
156 log.info(" ".join(("Trying",tryStr)))
157 flags.Input.Files += glob(tryStr)
158 log.info(" ".join(("Found",str(len(flags.Input.Files)),"files")))
159
160customMenuFile = ""
161if type(flags.Trigger.triggerConfig)==str and flags.Trigger.triggerConfig.startswith("FILE:"):
162 customMenuFile = flags.Trigger.triggerConfig.split(":",1)[-1]
163 flags.Trigger.triggerConfig="FILE"
164
165standalone = False
166# require at least 1 input file if running offline, unless running config-generating mode ....
167if not flags.Common.isOnline and len(flags.Input.Files)==0:
168 if flags.Exec.MaxEvents==0:
169 # this test file is used for generating the han config file
170 flags.Input.Files = ["/eos/atlas/atlascerngroupdisk/det-l1calo/OfflineSoftware/TestFiles/data24_13p6TeV/data24_13p6TeV.00477048.physics_Main.daq.RAW._lb0821._SFO-20._0001.data"]
171 else:
172 log.fatal("Running in offline mode but no input files provided. Please specify with: --filesInput <file>")
173 from AthenaConfiguration.TestDefaults import defaultTestFiles
174 log.fatal("You can specify one of the default test files:" + ",".join([f for f in dir(defaultTestFiles) if f[0].isupper()]))
175 exit(-1)
176elif flags.Common.isOnline:
177 log.info("Running Online with Partition: "+partition.name())
178 # if the partition name is not set in the flags, run the autoconfig again
179 # this occurs when running the online monitoring config in offline environment for testing
180 if flags.Trigger.Online.partitionName == '':
181 # must ensure doLVL1 and doHLT are False, otherwise will get ByteStreamCnvSvc conflicts (TrigByteStreamCnvSvc is setup, but EMon setup provides ByteStreamCnvSvc)
182 # see TriggerByteStreamConfig.py
183 flags.Trigger.doLVL1 = False
184 flags.Trigger.doHLT = False
185 from AthenaConfiguration.AutoConfigOnlineRecoFlags import autoConfigOnlineRecoFlags
186 autoConfigOnlineRecoFlags(flags, partition.name())
187 standalone = (partition.name()!="ATLAS")
188 if standalone : log.info("Using local menu because partition is not ATLAS")
189 elif len(flags.Input.Files)==0 and partition.isValid():
190 # wait here for 2 minutes, to give LAr time to put fw info in the database
191 import time
192 log.info("Waiting 2 minutes for LATOME to get their databases in order")
193 time.sleep(120)
194
195# if running on an input file, change the DQ environment, which will allow debug tree creation from monitoring algs
196if len(flags.Input.Files)>0:
197 flags.DQ.Environment = "user"
198 # triggerConfig should default to DB which is appropriate if running on data
199 # standalone if project tag is data_test of dataXX_calib
200 standalone = ((flags.Input.ProjectName == "data_test") or (re.match(r"data\d\d_calib", flags.Input.ProjectName)))
201 if standalone : print("Using local menu because project_name=",flags.Input.ProjectName)
202 if flags.Input.isMC : flags.Trigger.triggerConfig='FILE' # uses the generated L1Menu (see below)
203 elif flags.Trigger.triggerConfig=='INFILE':
204 # this happens with AOD data files, but this is incompatible with the setup of the LVL1ConfigSvc
205 flags.Trigger.triggerConfig="DB" # so force onto DB usage
206 # legacy monitoring doesn't work with MC, so disable that if running on mc
207 if flags.Input.isMC and flags.Trigger.L1.doCalo:
208 log.info("Disabling legacy monitoring because it doesn't work with MC")
209 flags.Trigger.L1.doCalo=False
210
211if standalone :
212 flags.Trigger.triggerConfig='FILE' #Uses generated L1Menu In online on input files
213
214
215if flags.Exec.MaxEvents == 0:
216 # in this mode, ensure all monitoring activated, so that generated han config is complete
217 flags.DQ.doMonitoring=True
218 flags.Trigger.L1.doCalo=True
219 flags.Trigger.L1.doCaloInputs=True
220 flags.Trigger.L1.doeFex=True
221 flags.Trigger.L1.dojFex=True
222 flags.Trigger.L1.dogFex=True
223 flags.Trigger.L1.doTopo=True
224 flags.DQ.useTrigger=True # enables JetEfficiency algorithms
225 flags.Exec.OutputLevel = Constants.INFO
226
227# due to https://gitlab.cern.ch/atlas/athena/-/merge_requests/65253 must now specify geomodel explicitly if cant take from input file, but can autoconfigure it based on LHCPeriod set above
228if flags.GeoModel.AtlasVersion is None:
229 from AthenaConfiguration.TestDefaults import defaultGeometryTags
230 flags.GeoModel.AtlasVersion = defaultGeometryTags.autoconfigure(flags)
231
232if flags.Trigger.triggerConfig=="FILE" and flags.Trigger.L1.doCalo:
233 # HLTConfgSvc fails to load if using a json file for the menu
234 # so disable the legacy monitoring which triggers that svc
235 log.warning("Cannot run Legacy sim/mon when using json l1 menu. Disabling")
236 flags.Trigger.L1.doCalo=False
237
238if (flags.Input.Format == Format.POOL): flags.Trigger.L1.doTopo = False #Deactivating L1Topo if Format is POOL
239if not flags.Trigger.L1.doTopo: flags.Trigger.L1.doMuon = False # don't do muons if not doing topo
240
241if flags.Trigger.enableL1CaloPhase1:
242 # add detector conditions flags required for rerunning simulation
243 # needs input files declared if offline, hence doing after parsing
244 from AthenaConfiguration.DetectorConfigFlags import setupDetectorsFromList
245 setupDetectorsFromList(flags,['LAr','Tile','MBTS'] + (['RPC','TGC','MDT'] if flags.Trigger.L1.doMuon else []),True)
246
247from AthenaConfiguration.MainServicesConfig import MainServicesCfg
248cfg = MainServicesCfg(flags)
249
250log.setLevel(logging.INFO)
251
252flags.lock()
253if flags.Exec.MaxEvents == 0: flags.dump(evaluate=True)
254
255# if nothing enabled, exit out here
256if not any([flags.Trigger.L1.doCaloInputs,flags.Trigger.L1.doCalo,flags.Trigger.L1.doeFex,flags.Trigger.L1.dojFex,flags.Trigger.L1.dogFex,flags.Trigger.L1.doTopo]):
257 log.fatal("You did not set any flags to specify what to run. ")
258 log.fatal("Please set at least one of the flags in Trigger.L1.(doCaloInputs, doCalo, doeFex, dojFex, dogFex, doTopo) ")
259 log.fatal("or use '--all' option to turn on everything (but that is slow)")
260 log.fatal("See --help for more info about the flags")
261 exit(1)
262
263if flags.Common.isOnline and len(flags.Input.Files)==0:
264 flags.dump(evaluate=True)
265 from ByteStreamEmonSvc.EmonByteStreamConfig import EmonByteStreamCfg
266 cfg.merge(EmonByteStreamCfg(flags)) # setup EmonSvc
267 bsSvc = cfg.getService("ByteStreamInputSvc")
268 bsSvc.Partition = partition.name()
269 bsSvc.Key = os.environ.get("L1CALO_PTIO_KEY", "REB" if partition.name()=="L1CaloStandalone" else "dcm") # set the Sampler Key Type name (default is SFI)
270 if partition.name()=="L1CaloSTF": bsSvc.Key = "SWROD"
271 bsSvc.KeyCount = int(os.environ.get("L1CALO_PTIO_KEY_COUNT","25"))
272 bsSvc.ISServer = "Histogramming" # IS server on which to create this provider
273 bsSvc.BufferSize = 10 # event buffer size for each sampler
274 bsSvc.UpdatePeriod = 30 # time in seconds between updating plots
275 bsSvc.Timeout = 240000 # timeout (not sure what this does)
276 bsSvc.PublishName = os.getenv("L1CALO_ATHENA_JOB_NAME","testing") # set name of this publisher as it will appear in IS (default is "l1calo-athenaHLT"; change to something sensible for testing)
277 bsSvc.StreamType = os.getenv("L1CALO_PTIO_STREAM_TYPE","physics") # name of the stream type (physics,express, etc.)
278 bsSvc.ExitOnPartitionShutdown = False
279 bsSvc.ClearHistograms = True # clear hists at start of new run
280 bsSvc.GroupName = "RecExOnline"
281 # name of the stream (Egamma,JetTauEtmiss,MinBias,Standby, etc.), this can be a colon(:) separated list of streams that use the 'streamLogic' to combine stream for 2016 HI run
282 bsSvc.StreamNames = os.getenv("L1CALO_PTIO_STREAM_NAME","L1Calo:Main:MinBias:MinBiasOverlay:UPC:EnhancedBias:ZeroBias:HardProbes:Standby:ALFACalib").split(":")
283 bsSvc.StreamLogic = os.getenv("L1CALO_PTIO_STREAM_LOGIC","Or") if partition.name() != "L1CaloStandalone" else "Ignore"
284 bsSvc.LVL1Names = [] # name of L1 items to select
285 bsSvc.LVL1Logic = "Ignore" # one of: Ignore, Or, And
286elif flags.Input.Format == Format.POOL:
287 log.info(f"Running Offline on {len(flags.Input.Files)} POOL files: {flags.Input.Files[0]} ...")
288 from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
289 cfg.merge(PoolReadCfg(flags))
290else:
291 log.info(f"Running Offline on {len(flags.Input.Files)} bytestream files: {flags.Input.Files[0]} ...")
292 #from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
293 #TODO: Figure out why the above line causes CA conflict @ P1 if try to run on a RAW file there
294 from TriggerJobOpts.TriggerByteStreamConfig import ByteStreamReadCfg
295 cfg.merge(ByteStreamReadCfg(flags)) # configure reading bytestream
296
297# ensure histsvc is set up
298from AthenaMonitoring.AthMonitorCfgHelper import getDQTHistSvc
299cfg.merge(getDQTHistSvc(flags))
300
301# Create run3 L1 menu (needed for L1Calo EDMs)
302from TrigConfigSvc.TrigConfigSvcCfg import L1ConfigSvcCfg,generateL1Menu, createL1PrescalesFileFromMenu,getL1MenuFileName
303if flags.Trigger.triggerConfig=="FILE":
304 # for MC we set the TriggerConfig to "FILE" above, so must generate a menu for it to load (will be the release's menu)
305 menuFilename = getL1MenuFileName(flags)
306 if customMenuFile == "":
307 if os.path.exists(menuFilename): os.remove(menuFilename)
308 generateL1Menu(flags)
309 else:
310 # create a symlink to the custom file
311 import os,errno
312 try:
313 os.symlink(customMenuFile, menuFilename)
314 except OSError as e:
315 if e.errno == errno.EEXIST:
316 os.remove(menuFilename)
317 os.symlink(customMenuFile, menuFilename)
318 else:
319 raise e
320 menuFilename = customMenuFile
321 if os.path.exists(menuFilename):
322 log.info(f"Using L1Menu: {menuFilename}")
323 else:
324 log.fatal(f"L1Menu file does not exist: {menuFilename}")
325 exit(1)
326 createL1PrescalesFileFromMenu(flags)
327cfg.merge(L1ConfigSvcCfg(flags))
328
329# -------- CHANGES GO BELOW ------------
330# setup the L1Calo software we want to monitor
331
332decoderTools = []
333
334if flags.Common.isOnline or (flags.Input.Format != Format.POOL and not flags.Input.isMC):
335 from L1CaloFEXByteStream.L1CaloFEXByteStreamConfig import eFexByteStreamToolCfg, jFexRoiByteStreamToolCfg, jFexInputByteStreamToolCfg, gFexByteStreamToolCfg, gFexInputByteStreamToolCfg
336 if flags.Trigger.L1.doeFex: decoderTools += [cfg.popToolsAndMerge(eFexByteStreamToolCfg(flags=flags,name='eFexBSDecoderTool',TOBs=flags.Trigger.L1.doeFex,xTOBs=flags.Trigger.L1.doeFex,decodeInputs=flags.Trigger.L1.doCaloInputs,multiSlice=True))]
337 if flags.Trigger.L1.dojFex: decoderTools += [cfg.popToolsAndMerge(jFexRoiByteStreamToolCfg(flags=flags,name="jFexBSDecoderTool",writeBS=False))]
338 if flags.Trigger.L1.dogFex: decoderTools += [cfg.popToolsAndMerge(gFexByteStreamToolCfg(flags=flags,name="gFexBSDecoderTool",writeBS=False))]
339 if flags.Trigger.L1.doTopo:
340 from L1TopoByteStream.L1TopoByteStreamConfig import L1TopoPhase1ByteStreamToolCfg
341 decoderTools += [cfg.popToolsAndMerge(L1TopoPhase1ByteStreamToolCfg(flags=flags,name="L1TopoBSDecoderTool",writeBS=False))]
342
343 if flags.Trigger.L1.doMuon:
344 from MuonConfig.MuonBytestreamDecodeConfig import RpcBytestreamDecodeCfg,TgcBytestreamDecodeCfg
345 cfg.merge(RpcBytestreamDecodeCfg(flags))
346 cfg.merge(TgcBytestreamDecodeCfg(flags))
347 from TrigT1ResultByteStream.TrigT1ResultByteStreamConfig import MuonRoIByteStreamToolCfg
348 decoderTools += [cfg.popToolsAndMerge(MuonRoIByteStreamToolCfg(flags, name="L1MuonBSDecoderTool", writeBS=False))]
349
350
351 if flags.Trigger.L1.doCaloInputs:
352 if flags.Trigger.L1.dojFex: decoderTools += [cfg.popToolsAndMerge(jFexInputByteStreamToolCfg(flags=flags,name='jFexInputBSDecoderTool',writeBS=False))]
353 if flags.Trigger.L1.dogFex: decoderTools += [cfg.popToolsAndMerge(gFexInputByteStreamToolCfg(flags=flags,name='gFexInputBSDecoderTool',writeBS=False))]
354
355 if len(decoderTools) > 0:
356 from TrigT1ResultByteStream.TrigT1ResultByteStreamMonitoringConfig import L1TriggerByteStreamDecoderMonitoringCfg
357 cfg.addEventAlgo(CompFactory.L1TriggerByteStreamDecoderAlg(
358 name="L1TriggerByteStreamDecoder",
359 OutputLevel=Constants.ERROR, # hides warnings about non-zero status codes in fragments ... will show up in hists
360 DecoderTools=decoderTools,
361 ByteStreamMetadataRHKey = '', # seems necessary @ P1 if trying to run on a raw file
362 MaybeMissingROBs= [id for tool in decoderTools for id in tool.ROBIDs ] if partition.name()!="ATLAS" or not flags.Common.isOnline else [], # allow missing ROBs away from online ATLAS partition
363 MonTool= cfg.popToolsAndMerge(L1TriggerByteStreamDecoderMonitoringCfg(flags,"L1TriggerByteStreamDecoder", decoderTools))
364 ),sequenceName='AthAlgSeq'
365 )
366
367# rerun sim if required
368if flags.Trigger.enableL1CaloPhase1:
369 from L1CaloFEXSim.L1CaloFEXSimCfg import L1CaloFEXSimCfg
370 # create a subsequence for the sim to live in; primarily keeps the config tidy
371 cfg.addSequence(CompFactory.AthSequencer("L1Sim",StopOverride=True),parentName="AthAlgSeq") # this matches the sequence name the helpers will create
372
373 # note to self ... could look into input key remapping to avoid conflict with sim from input:
374 # from SGComps.AddressRemappingConfig import InputRenameCfg
375 # acc.merge(InputRenameCfg('xAOD::TriggerTowerContainer', 'xAODTriggerTowers_rerun', 'xAODTriggerTowers'))
376 cfg.merge(L1CaloFEXSimCfg(flags,outputSuffix="_ReSim" if flags.Input.Format == Format.POOL else ""),sequenceName="L1Sim")
377 # scheduling simulation of topo
378 if flags.Trigger.L1.doTopo:
379 from L1TopoSimulation.L1TopoSimulationConfig import L1TopoSimulationCfg
380 cfg.merge(L1TopoSimulationCfg(flags,readMuCTPI=True,doMonitoring=False),sequenceName="L1Sim") # monitoring scheduled separately below
381
382 # Phase II Global simulation...
383 if "doGlobal" in flags.Trigger.L1 and flags.Trigger.L1.doGlobal:
384 # we will create a subsequence just for globalsim too
385 cfg.addSequence(CompFactory.AthSequencer("L1GlobalSim",StopOverride=True),parentName="AthAlgSeq")
386 from GlobalSimulation.GlobalSimulationConfig import GlobalSimulationCfg
387 cfg.merge(GlobalSimulationCfg(flags),sequenceName="L1GlobalSim")
388
389 if flags.Trigger.L1.doeFex:
390 # print the algoVersions of the eFex from menu:
391 from TrigConfigSvc.TriggerConfigAccess import getL1MenuAccess
392 L1_menu = getL1MenuAccess(flags)
393 L1_menu.printSummary()
394 em_algoVersion = L1_menu.thresholdExtraInfo("eEM").get("algoVersion", 0)
395 tau_algoVersion = L1_menu.thresholdExtraInfo("eTAU").get("algoVersion", 0)
396 log.info(f"algoVersions: eEM: {em_algoVersion}, eTAU: {tau_algoVersion}")
397
398
399
400 # do otf masking:
401 # from IOVDbSvc.IOVDbSvcConfig import addFolders,addOverride
402 # #cfg.merge(addFolders(flags,"<db>sqlite://;schema=/afs/cern.ch/user/w/will/new_maskedSCs_run457976.db;dbname=CONDBR2</db> /LAR/BadChannels/NoisyChannelsSC",className="CondAttrListCollection")) # dmCorr from DB!
403 # cfg.merge(addFolders(flags,"/LAR/BadChannels/MaskedSC","LAR_ONL",tag="LARBadChannelsMaskedSC-RUN3-UPD1-00",className="CondAttrListCollection",extensible=False)) # when run online, need folder to be extensible to force reload each event
404 # cfg.addCondAlgo(CompFactory.LArBadChannelCondAlg(name="MaskedSCCondAlg",ReadKey="/LAR/BadChannels/MaskedSC",isSC=True,CablingKey="LArOnOffIdMapSC",WriteKey="LArMaskedSC"))
405 # # note to self, if need to flag extensible after loaded elsewhere, look at property: cfg.getService("IOVDbSvc").Folders ... extend relevant entry with "<extensible/>"
406 # print(cfg.getService("MessageSvc"))
407 # cfg.getService("MessageSvc").errorLimit = 0
408 #
409 # cfg.getEventAlgo("L1_eFexEmulatedTowers").LArBadChannelKey = "LArMaskedSC"
410
411
412
413if flags.DQ.doMonitoring:
414 # create a subsequence for the sim to live in; primarily keeps the config tidy
415 cfg.addSequence(CompFactory.AthSequencer("L1Mon",StopOverride=True),parentName="AthAlgSeq") # this matches the sequence name the helpers will create
416 if flags.Trigger.L1.doCalo:
417 from TrigT1CaloMonitoring.PprMonitorAlgorithm import PprMonitoringConfig
418 cfg.merge(PprMonitoringConfig(flags),sequenceName="L1Mon")
419 from TrigT1CaloMonitoring.PPMSimBSMonitorAlgorithm import PPMSimBSMonitoringConfig
420 cfg.merge(PPMSimBSMonitoringConfig(flags),sequenceName="L1Mon")
421 from TrigT1CaloMonitoring.OverviewMonitorAlgorithm import OverviewMonitoringConfig
422 cfg.merge(OverviewMonitoringConfig(flags),sequenceName="L1Mon")
423 # CPM was disabled for run 480893 onwards, so stop monitoring that part
424 # could have used detectorMask to determine if CPM is disabled, but will just assume it here
425 OverviewMonAlg = cfg.getEventAlgo("OverviewMonAlg")
426 OverviewMonAlg.CPMErrorLocation = ""
427 OverviewMonAlg.CPMMismatchLocation = ""
428
429 if flags.Trigger.L1.doeFex:
430 from TrigT1CaloMonitoring.EfexMonitorAlgorithm import EfexMonitoringConfig
431 cfg.merge(EfexMonitoringConfig(flags),sequenceName="L1Mon")
432 EfexMonAlg = cfg.getEventAlgo('EfexMonAlg')
433 # do we need next lines??
434 EfexMonAlg.eFexEMTobKeyList = ['L1_eEMRoI', 'L1_eEMxRoI'] # default is just L1_eEMRoI
435 EfexMonAlg.eFexTauTobKeyList = ['L1_eTauRoI', 'L1_eTauxRoI']
436 # Adjust eFEX containers to be monitored to also monitor the sim RoI unless running on raw without simulation
437 if flags.Input.Format == Format.POOL or flags.Trigger.enableL1CaloPhase1:
438 for l in [EfexMonAlg.eFexEMTobKeyList,EfexMonAlg.eFexTauTobKeyList]: l += [x + ("_ReSim" if flags.Input.Format == Format.POOL and flags.Trigger.enableL1CaloPhase1 else "Sim") for x in l ]
439 # monitoring of simulation vs hardware
440 if not flags.Input.isMC and flags.Trigger.enableL1CaloPhase1:
441 from TrigT1CaloMonitoring.EfexSimMonitorAlgorithm import EfexSimMonitoringConfig
442 cfg.merge(EfexSimMonitoringConfig(flags),sequenceName="L1Mon")
443 # EfexSimMonitorAlgorithm = cfg.getEventAlgo('EfexSimMonAlg')
444 # and now book the histograms that depend on the containers
445 from TrigT1CaloMonitoring.EfexMonitorAlgorithm import EfexMonitoringHistConfig
446 cfg.merge(EfexMonitoringHistConfig(flags,EfexMonAlg),sequenceName="L1Mon")
447
448 if flags.Trigger.L1.dojFex:
449 from TrigT1CaloMonitoring.JfexMonitorAlgorithm import JfexMonitoringConfig
450 cfg.merge(JfexMonitoringConfig(flags),sequenceName="L1Mon")
451 if not flags.Input.isMC and flags.Trigger.enableL1CaloPhase1:
452 from TrigT1CaloMonitoring.JfexSimMonitorAlgorithm import JfexSimMonitoringConfig
453 cfg.merge(JfexSimMonitoringConfig(flags),sequenceName="L1Mon")
454 if flags.Trigger.L1.dogFex:
455 from TrigT1CaloMonitoring.GfexMonitorAlgorithm import GfexMonitoringConfig
456 cfg.merge(GfexMonitoringConfig(flags),sequenceName="L1Mon")
457 if not flags.Input.isMC and flags.Trigger.enableL1CaloPhase1:
458 from TrigT1CaloMonitoring.GfexSimMonitorAlgorithm import GfexSimMonitoringConfig
459 cfg.merge(GfexSimMonitoringConfig(flags),sequenceName="L1Mon")
460 # generally can't include efficiency monitoring because requires too many things we don't have
461 # but b.c. alg requires TrigDecisionTool, we activate it if DQ.useTrigger explicitly set
462 if flags.DQ.useTrigger:
463 from TrigT1CaloMonitoring.JetEfficiencyMonitorAlgorithm import JetEfficiencyMonitoringConfig
464 cfg.merge(JetEfficiencyMonitoringConfig(flags),sequenceName="L1Mon")
465
466 if flags.Trigger.L1.doTopo:
467 from L1TopoOnlineMonitoring.L1TopoOnlineMonitoringConfig import Phase1TopoMonitoringCfg
468 cfg.merge(Phase1TopoMonitoringCfg(flags))
469
470 # input data monitoring
471 if flags.Trigger.L1.doCaloInputs and not flags.Input.isMC:
472 from TrigT1CaloMonitoring.EfexInputMonitorAlgorithm import EfexInputMonitoringConfig
473 if flags.Trigger.L1.doeFex: cfg.merge(EfexInputMonitoringConfig(flags),sequenceName="L1Mon")
474 from TrigT1CaloMonitoring.JfexInputMonitorAlgorithm import JfexInputMonitoringConfig
475 if flags.Trigger.L1.dojFex: cfg.merge(JfexInputMonitoringConfig(flags),sequenceName="L1Mon")
476 from TrigT1CaloMonitoring.GfexInputMonitorAlgorithm import GfexInputMonitoringConfig
477 if flags.Trigger.L1.dogFex: cfg.merge(GfexInputMonitoringConfig(flags),sequenceName="L1Mon")
478
479mainSeq = "AthAllAlgSeq"
480if args.fexReadoutFilter:
481 # want to take existing AthAllSeqSeq and move it inside a new sequence
482 topSeq = cfg.getSequence("AthAlgEvtSeq")
483 algSeq = cfg.getSequence(mainSeq)
484 mainSeq = "New" + mainSeq
485 # topSeq has three sub-sequencers ... preserve first and last
486 topSeq.Members = [topSeq.Members[0],CompFactory.AthSequencer(mainSeq),topSeq.Members[-1]]
487 cfg.addEventAlgo(CompFactory.L1IDFilterAlgorithm(),sequenceName=mainSeq)
488 cfg.getSequence(mainSeq).Members += [algSeq]
489
490if args.evtNumber is not None:
491 print("filtering events",args.evtNumber)
492 # similar adjustment with an event filter
493 topSeq = cfg.getSequence("AthAlgEvtSeq")
494 algSeq = cfg.getSequence(mainSeq)
495 mainSeq = "New" + mainSeq
496 # topSeq has three sub-sequencers ... preserve first and last
497 topSeq.Members = [topSeq.Members[0],CompFactory.AthSequencer(mainSeq),topSeq.Members[-1]]
498 cfg.addEventAlgo(CompFactory.EventNumberFilterAlgorithm("EvtNumberFilter",EventNumbers=args.evtNumber),sequenceName=mainSeq)
499 cfg.getSequence(mainSeq).Members += [algSeq]
500
501from PerfMonComps.PerfMonCompsConfig import PerfMonMTSvcCfg
502cfg.merge( PerfMonMTSvcCfg(flags) )
503
504from AthenaConfiguration.Utils import setupLoggingLevels
505setupLoggingLevels(flags,cfg)
506
507if any([s.name=="AthenaEventLoopMgr" for s in cfg.getServices()]): cfg.getService("AthenaEventLoopMgr").IntervalInSeconds = 30
508if any([s.name=="AthenaHiveEventLoopMgr" for s in cfg.getServices()]): cfg.getService("AthenaHiveEventLoopMgr").EventPrintoutInterval = 100
509if any([s.name=="AvalancheSchedulerSvc" for s in cfg.getServices()]): cfg.getService("AvalancheSchedulerSvc").ShowDataDependencies=True
510
511# need to override a folder tag for LAr while testing v6 firmware...
512if not flags.Input.isMC:
513 from LArConditionsCommon.LArRunFormat import getLArDTInfoForRun
514 runinfo = getLArDTInfoForRun(flags.Input.RunNumbers[0], connstring="COOLONL_LAR/CONDBR2")
515 if runinfo.FWversion()==6:
516 # need a dbOverride ... add it
517 if args.dbOverrides is None: args.dbOverrides = []
518 args.dbOverrides += ["/LAR/Identifier/LatomeMapping:LARIdentifierLatomeMapping-fw6"]
519
520
521
522if type(args.dbOverrides)==list:
523 from IOVDbSvc.IOVDbSvcConfig import addOverride
524 #examples:
525 #cfg.merge( addOverride(flags, folder="/TRIGGER/L1Calo/V1/Calibration/EfexEnergyCalib", db="sqlite://;schema=mytest.db;dbname=CONDBR2",tag="" ) )
526 #cfg.merge( addOverride(flags, folder="/TRIGGER/L1Calo/V1/Calibration/EfexNoiseCuts", db="sqlite://;schema=/afs/cern.ch/user/w/will/calib.sqlite;dbname=L1CALO",tag="" ) )
527 for override in args.dbOverrides:
528 folderName,dbPath = override.split("=",1) if "=" in override else (override,"")
529 if folderName == "": raise ValueError("Cannot parse dbOverride: " + override)
530 db = ""
531 if dbPath != "":
532 if ";dbname=" not in dbPath: dbPath += ";dbname=CONDBR2"
533 dbPath,dbInst = dbPath.split(";dbname=")
534 if not os.path.exists(dbPath): raise ValueError("dbOverride file doesn't exist: " + dbPath)
535 db = f"sqlite://;schema={dbPath};dbname={dbInst}"
536 tag = ""
537 if ":" in folderName:
538 folderName,tag = folderName.split(":",1)
539 if folderName[0] != "/": folderName = "/TRIGGER/L1Calo/V1/Calibration/" + folderName
540 log.info(" ".join(("Overriding COOL folder=",folderName,"db=",db,"tag=",tag)))
541 if db=="":
542 cfg.merge( addOverride(flags,folder=folderName,tag=tag))
543 else:
544 cfg.merge( addOverride(flags,folder=folderName,db=db,tag=tag))
545
546
547# configure output AOD if requested
548if flags.Output.AODFileName != "":
549 def addEDM(edmType, edmName):
550 if edmName.endswith("Sim") and flags.Input.Format == Format.POOL: edmName = edmName.replace("Sim","_ReSim")
551 auxType = edmType.replace('Container','AuxContainer')
552 return [f'{edmType}#{edmName}', f'{auxType}#{edmName}Aux.']
553
554 outputEDM = []
555
556 if flags.Trigger.L1.doeFex:
557 outputEDM += addEDM('xAOD::eFexEMRoIContainer' , "L1_eEMRoI")
558 outputEDM += addEDM('xAOD::eFexEMRoIContainer' , "L1_eEMRoISim")
559 outputEDM += addEDM('xAOD::eFexEMRoIContainer' , "L1_eEMxRoI")
560 outputEDM += addEDM('xAOD::eFexEMRoIContainer' , "L1_eEMxRoISim")
561
562 outputEDM += addEDM('xAOD::eFexTauRoIContainer' , "L1_eTauRoI")
563 outputEDM += addEDM('xAOD::eFexTauRoIContainer' , "L1_eTauRoISim")
564 outputEDM += addEDM('xAOD::eFexTauRoIContainer' , "L1_eTauxRoI")
565 outputEDM += addEDM('xAOD::eFexTauRoIContainer' , "L1_eTauxRoISim")
566
567 if flags.Trigger.L1.dojFex:
568 outputEDM += addEDM('xAOD::jFexTowerContainer' , "L1_jFexDataTowers")
569 outputEDM += addEDM('xAOD::jFexTowerContainer' , "L1_jFexEmulatedTowers")
570 outputEDM += addEDM('xAOD::jFexSRJetRoIContainer', 'L1_jFexSRJetRoISim')
571 outputEDM += addEDM('xAOD::jFexLRJetRoIContainer', 'L1_jFexLRJetRoISim')
572 outputEDM += addEDM('xAOD::jFexTauRoIContainer' , 'L1_jFexTauRoISim' )
573 outputEDM += addEDM('xAOD::jFexFwdElRoIContainer', 'L1_jFexFwdElRoISim')
574 outputEDM += addEDM('xAOD::jFexSumETRoIContainer', 'L1_jFexSumETRoISim')
575 outputEDM += addEDM('xAOD::jFexMETRoIContainer' , 'L1_jFexMETRoISim' )
576 outputEDM += addEDM('xAOD::jFexSRJetRoIContainer', 'L1_jFexSRJetRoI')
577 outputEDM += addEDM('xAOD::jFexLRJetRoIContainer', 'L1_jFexLRJetRoI')
578 outputEDM += addEDM('xAOD::jFexTauRoIContainer' , 'L1_jFexTauRoI' )
579 outputEDM += addEDM('xAOD::jFexFwdElRoIContainer', 'L1_jFexFwdElRoI')
580 outputEDM += addEDM('xAOD::jFexSumETRoIContainer', 'L1_jFexSumETRoI')
581 outputEDM += addEDM('xAOD::jFexMETRoIContainer' , 'L1_jFexMETRoI' )
582
583 outputEDM += addEDM('xAOD::jFexSRJetRoIContainer', 'L1_jFexSRJetxRoI')
584 outputEDM += addEDM('xAOD::jFexLRJetRoIContainer', 'L1_jFexLRJetxRoI')
585 outputEDM += addEDM('xAOD::jFexTauRoIContainer' , 'L1_jFexTauxRoI' )
586 outputEDM += addEDM('xAOD::jFexFwdElRoIContainer', 'L1_jFexFwdElxRoI')
587 outputEDM += addEDM('xAOD::jFexSumETRoIContainer', 'L1_jFexSumETxRoI')
588 outputEDM += addEDM('xAOD::jFexMETRoIContainer' , 'L1_jFexMETxRoI' )
589
590 if flags.Trigger.L1.dogFex:
591 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gMETComponentsJwoj')
592 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gMETComponentsJwojSim')
593 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gMHTComponentsJwoj')
594 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gMHTComponentsJwojSim')
595 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gMSTComponentsJwoj')
596 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gMSTComponentsJwojSim')
597 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gScalarEJwoj')
598 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gScalarEJwojSim')
599 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gScalarENoiseCutSim')
600 outputEDM += addEDM('xAOD::gFexGlobalRoIContainer','L1_gScalarERmsSim')
601
602 outputEDM += addEDM('xAOD::gFexJetRoIContainer','L1_gFexLRJetRoI')
603 outputEDM += addEDM('xAOD::gFexJetRoIContainer','L1_gFexLRJetRoISim')
604 outputEDM += addEDM('xAOD::gFexJetRoIContainer','L1_gFexSRJetRoI')
605 outputEDM += addEDM('xAOD::gFexJetRoIContainer','L1_gFexSRJetRoISim')
606 outputEDM += addEDM('xAOD::gFexJetRoIContainer','L1_gFexRhoRoI')
607 outputEDM += addEDM('xAOD::gFexJetRoIContainer','L1_gFexRhoRoISim')
608
609
610
611 from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
612 cfg.merge(OutputStreamCfg(flags, 'AOD', ItemList=outputEDM, takeItemsFromInput=True))
613 from xAODMetaDataCnv.InfileMetaDataConfig import SetupMetaDataForStreamCfg
614 cfg.merge(SetupMetaDataForStreamCfg(flags, 'AOD'))
615
616# configure RAW output if requested
617if flags.Output.BSFileName != "":
618 from TrigT1ResultByteStream.TrigT1ResultByteStreamConfig import L1TriggerByteStreamEncoderCfg
619 cfg.merge(L1TriggerByteStreamEncoderCfg(flags))
620
621 # create A TrigCompositeContainer with the things we want to write out
622 algo = CompFactory.L1TriggerResultMaker("OutputBSTCCMaker",
623 MuRoIKeys=[],
624 eFexEMRoIKeys=[], eFexTauRoIKeys=[],
625 jFexFwdElRoIKeys=[], jFexTauRoIKeys = [],
626 jFexSRJetRoIKeys = [], jFexLRJetRoIKeys = [],
627 gFexSRJetRoIKeys = [], gFexLRJetRoIKeys = [],
628 cTauRoIKey = "", cjTauLinkKey = "", ThresholdPatternTools= [],
629 L1TriggerResultWHKey = "OutputBSTCC")
630 if flags.Trigger.L1.doeFex:
631 algo.eFexEMRoIKeys = ["L1_eEMRoI","L1_eEMxRoI"] # will write these containers
632 algo.eFexTauRoIKeys = ["L1_eTauRoI","L1_eTauxRoI"]
633
634 cfg.addEventAlgo(algo)
635 from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamWriteCfg
636 write = ByteStreamWriteCfg(flags, ["xAOD::TrigCompositeContainer#OutputBSTCC"])
637 cfg.merge(write)
638
639if "MuonAlignmentCondAlg" in [a.name for a in cfg.getCondAlgos()]: cfg.getCondAlgo("MuonAlignmentCondAlg").OutputLevel=Constants.ERROR # this alg produces warnings every time, silence it!
640
641
642if flags.Trigger.L1.doeFex and (args.evtNumber is not None):
643 # when debugging individual events, add the eFex event dumper to the job
644 cfg.addEventAlgo(CompFactory.LVL1.eFexEventDumper(TowersKey="L1_eFexDataTowers",EMRoIKey="L1_eEMRoI",TauRoIKey="L1_eTauRoI"))
645
646# example of adding user algorithm
647# cfg.addEventAlgo(CompFactory.AnotherPackageAlg(),sequenceName="AthAlgSeq")
648
649from AthenaCommon.Include import include
650from AthenaCommon.Configurable import ConfigurableCABehavior
651with ConfigurableCABehavior():
652 for inc in args.postInclude: include(inc)
653
654for conf in args.postConfig:
655 compName,propNameAndVal=conf.split(".",1)
656 propName,propVal=propNameAndVal.split("=",1)
657 applied = False
658 from collections import defaultdict
659 availableComps = defaultdict(list)
660 for comp in [c for c in cfg._allComponents()]+cfg.getServices():
661 availableComps[comp.getType()] += [comp.getName()]
662 if comp.getName()==compName or comp.getType()==compName or comp.toStringProperty()==compName:
663 applied = True
664 try:
665 log.info("Setting "+compName+" property: "+propNameAndVal)
666 exec(f"comp.{propNameAndVal}")
667 except AttributeError as e:
668 log.fatal("Unknown property of " + compName +" : " + propNameAndVal)
669 log.fatal("See next line for available properties:")
670 print(comp)
671 raise e
672 break
673 if not applied:
674 print("Available comps:")
675 for k,v in availableComps.items():
676 print(k,":",*v,sep="\n\t")
677 raise ValueError(f"postConfig {conf} had no effect ... typo? See list above of available components")
678
679if args.postHelp is not None:
680 from collections import defaultdict
681 availableComps = defaultdict(list)
682 for comp in [c for c in cfg._allComponents()]+cfg.getServices():
683 availableComps[comp.getType()] += [comp.getName()]
684 print("Available comps:")
685 for k,v in availableComps.items():
686 print("",k,":",", ".join(v))
687 exit(0)
688
689# -------- CHANGES GO ABOVE ------------
690
691if flags.Exec.MaxEvents==0: cfg.printConfig(withDetails = True, summariseProps = True, printDefaults = True)
692log.info( " ".join(("Configured Services:",*[svc.name for svc in cfg.getServices()])) )
693#print("Configured EventAlgos:",*[alg.name for alg in cfg.getEventAlgos()])
694#print("Configured CondAlgos:",*[alg.name for alg in cfg.getCondAlgos()])
695
696if flags.Exec.MaxEvents==1:
697 # special debugging mode
698 cfg.getService("StoreGateSvc").Dump=True
699 cfg.getService("DetectorStore").Dump=True
700
701# ensure printout level is low enough if dumping
702if cfg.getService("StoreGateSvc").Dump:
703 cfg.getService("StoreGateSvc").OutputLevel=3
704if cfg.getService("DetectorStore").Dump:
705 cfg.getService("DetectorStore").OutputLevel=3
706
707if args.interactive:
708 from AthenaConfiguration.ComponentAccumulator import startInteractive
709 oldLevel = int(cfg._msg.getEffectiveLevel()) # need effectivelevel to account for inheriting
710 cfg._msg.setLevel(logging.INFO) # reverting to info level to ease interactive
711 print("\n\nEntering interactive configuration mode. You can explore and edit the cfg object. Ctrl+D to configure application and move to pre-initialize step")
712 startInteractive(locals()|{"self":cfg})
713 cfg._msg.setLevel(oldLevel)
714 # force writing the history file so that if job fails we still get our history
715 import readline, os
716 readline.write_history_file(os.path.expanduser( '~/.athena.history' ))
717
718if flags.Exec.MaxEvents==0:
719 # create a han config file if running in config-only mode
720 # command used to generate official config:
721 # athena TrigT1CaloMonitoring/L1CaloPhase1Monitoring.py --evtMax 0
722 from TrigT1CaloMonitoring.LVL1CaloMonitoringConfig import L1CaloMonitorCfgHelper
723 L1CaloMonitorCfgHelper.printHanConfig()
724 cfg._wasMerged = True # prevents spurious error message showing up about cfg that wasn't used
725 exit(0)
726
727if cfg.run().isFailure():
728 exit(1)
void print(char *figname, TCanvas *c1)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179