ATLAS Offline Software
RunTrigCostAnalysis.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
4 #
5 
6 from AthenaConfiguration.ComponentFactory import CompFactory
7 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
8 from AthenaCommon.Logging import logging
9 log = logging.getLogger('RunTrigCostAnalysis.py')
10 
11 
12 # Configure Cost Analysis algorithm
13 def trigCostAnalysisCfg(flags, args, isMC=False):
14  from TrigCostAnalysis.ROSToROB import ROSToROBMap
15 
16  acc = ComponentAccumulator()
17 
18  if len(flags.Input.RunNumbers) > 1:
19  log.error('Multiple run numbers from metadata! Only one expected per cost processing')
20  return acc
21 
22  enhancedBiasWeighter = CompFactory.EnhancedBiasWeighter()
23  enhancedBiasWeighter.RunNumber = flags.Input.RunNumbers[0]
24  enhancedBiasWeighter.UseBunchCrossingData = False
25  enhancedBiasWeighter.IsMC = isMC
26  if isMC:
27  MCpayload = readMCpayload(args)
28  enhancedBiasWeighter.MCCrossSection = MCpayload.get('MCCrossSection')
29  enhancedBiasWeighter.MCFilterEfficiency = MCpayload.get('MCFilterEfficiency')
30  enhancedBiasWeighter.MCKFactor = MCpayload.get('MCKFactor')
31  enhancedBiasWeighter.MCIgnoreGeneratorWeights = MCpayload.get('MCIgnoreGeneratorWeights')
32 
33  trigCostAnalysis = CompFactory.TrigCostAnalysis()
34  trigCostAnalysis.OutputLevel = args.loglevel
35  trigCostAnalysis.BaseEventWeight = args.baseWeight
36  trigCostAnalysis.EnhancedBiasTool = enhancedBiasWeighter
37  trigCostAnalysis.AlgToChainTool = CompFactory.getComp("TrigCompositeUtils::AlgToChainTool")()
38  trigCostAnalysis.UseEBWeights = args.useEBWeights
39  trigCostAnalysis.MaxFullEventDumps = 100
40  trigCostAnalysis.FullEventDumpProbability = 1 # X. Where probability is 1 in X
41  trigCostAnalysis.UseSingleTimeRange = isMC or args.useEBWeights
42  trigCostAnalysis.ROSToROBMap = ROSToROBMap().get_mapping()
43  trigCostAnalysis.DoMonitorChainAlgorithm = args.monitorChainAlgorithm
44 
45  if not isMC:
46  trigCostAnalysis.AdditionalHashList = readHashesFromHLTJO(args.joFile, args.smk, args.dbAlias)
47  else:
48  log.debug("Hashes from the HLTJO won't be retrieved for MC job")
49  trigCostAnalysis.AdditionalHashList = list()
50 
51  acc.addEventAlgo(trigCostAnalysis)
52 
53  return acc
54 
55 # Prepare dictionary with MC parameters read from arguments, or from AMI
56 def readMCpayload(args):
57  payload = {}
58 
59  payload['MCCrossSection'] = args.MCCrossSection
60  payload['MCFilterEfficiency'] = args.MCFilterEfficiency
61  payload['MCKFactor'] = args.MCKFactor
62  payload['MCIgnoreGeneratorWeights'] = args.MCIgnoreGeneratorWeights
63 
64  dset = args.MCDatasetName
65  if payload['MCCrossSection'] == 0: # If the input file is MC then make sure we have the needed info
66  from RatesAnalysis.GetCrossSectionAMITool import GetCrossSectionAMI
67  amiTool = GetCrossSectionAMI()
68  if dset == '': # Can we get the dataset name from the input file path?
69  dset = amiTool.getDatasetNameFromPath(flags.Input.Files[0])
70  amiTool.queryAmi(dset)
71  payload['MCCrossSection'] = amiTool.crossSection
72  payload['MCFilterEfficiency'] = amiTool.filterEfficiency
73 
74  return payload
75 
76 # Read algorithm and class names from HLTJobOptions file
77 def readHashesFromHLTJO(joFileName="", smk=0, dbAlias=""):
78  joData = {}
79  try:
80  if joFileName:
81  log.debug("Reading HLTJobOptions from file {0}".format(joFileName))
82  with open(joFileName, "r") as joFile:
83  import json
84  joData = json.load(joFile)
85  elif smk and dbAlias:
86  log.debug("Reading HLTJobOptions from database {0} {1}".format(smk, dbAlias))
87  from TrigConfIO.HLTTriggerConfigAccess import HLTJobOptionsAccess
88  joData = HLTJobOptionsAccess(dbalias = dbAlias, smkey = smk)
89  else:
90  log.debug("Additional collections' names from HLTJobOptions file are not available")
91  return list()
92  except Exception as err:
93  log.warning("Retrieving additional names fron HLTJO failed: {0}".format(err))
94  return list()
95 
96  namesList = set()
97  for entry in joData["properties"]:
98  namesList.add(entry.split('.')[0])
99 
100  # Read algorithm names with classes
101  entryObj = joData["properties"][entry]
102  if "Members" in entryObj:
103  membersList = entryObj["Members"].strip('][').replace("'", "").split(', ')
104  namesList.update(membersList)
105 
106 
107  log.info("Retrieved {0} additional names from HLT JO file".format(len(namesList)))
108  return list(namesList)
109 
110 
111 # Configure deserialisation
112 def decodingCfg(flags):
113  from AthenaCommon.CFElements import seqAND
114  from TrigEDMConfig import DataScoutingInfo
115 
116  acc = ComponentAccumulator()
117 
118  acc.addSequence(seqAND("Decoding"))
119  acc.addEventAlgo(CompFactory.HLTResultMTByteStreamDecoderAlg(), "Decoding")
120 
121  costDataDeserialiser = CompFactory.TriggerEDMDeserialiserAlg("CostDataTrigDeserialiser")
122  costDataDeserialiser.ModuleID = DataScoutingInfo.getDataScoutingResultID("CostMonDS")
123  acc.addEventAlgo(costDataDeserialiser, "Decoding")
124 
125  return acc
126 
127 
128 # Configure HLTConfigSvc with JSON Menu file
129 def hltConfigSvcCfg(flags, smk, dbAlias):
130  acc = ComponentAccumulator()
131 
132  hltConfigSvc = CompFactory.getComp("TrigConf::HLTConfigSvc")("HLTConfigSvc")
133 
134  menuFile = getHltMenu()
135  # If local file not found - read HLTMenu from database
136  if menuFile:
137  log.debug("Reading HLTMenu from file {0}".format(menuFile))
138 
139  hltConfigSvc.InputType = "FILE"
140  hltConfigSvc.HLTJsonFileName = menuFile
141  elif smk and dbAlias:
142  log.debug("Reading HLTMenu from database {0} {1}".format(smk, dbAlias))
143 
144  hltConfigSvc.InputType = "DB"
145  hltConfigSvc.HLTJsonFileName = ""
146  hltConfigSvc.TriggerDB = dbAlias
147  hltConfigSvc.SMK = smk
148  else:
149  log.error("Cannot read the HLTMenu! Provide file or relevant keys.")
150 
151  acc.addService(hltConfigSvc, False, True)
152 
153  return acc
154 
155 
156 def readConfigFromCool(flags, smk, dbAlias):
157  # Try to read keys from COOL (for P1 data)
158  from TrigConfStorage.TriggerCoolUtil import TriggerCoolUtil
159  dbconn = TriggerCoolUtil.GetConnection("CONDBR2")
160  runNumber = flags.Input.RunNumbers[0]
161  configKeys = TriggerCoolUtil.getHLTConfigKeys(dbconn, [[runNumber, runNumber]])
162 
163  log.debug("Getting keys from COOL for run {0}".format(runNumber))
164  if configKeys and runNumber in configKeys.keys():
165  if not smk:
166  smk = configKeys[runNumber]['SMK']
167 
168  if not dbAlias:
169  dbAlias = configKeys[runNumber]['DB']
170 
171  log.debug("Config keys are SMK: {0} DB alias: {1}".format(smk, dbAlias))
172 
173  else:
174  log.debug("Configuration keys for run {0} not found!".format(runNumber))
175  dbAlias = None if not dbAlias else dbAlias
176  smk = None if not smk else smk
177 
178  return (smk, dbAlias)
179 
180 
181 # Get HLT Menu from json file
183  # Try to find local menu file
184  menuFileName = 'HLTMenu_.*json'
185 
186  import re, os
187  r = re.compile(menuFileName)
188  menuFiles = list(filter(r.match, os.listdir('.')))
189 
190  if len(menuFiles) > 1:
191  log.info("Found more than one menu file! Saving first match %s", menuFiles[0])
192 
193  return menuFiles[0] if len(menuFiles) > 0 else ""
194 
195 
196 if __name__=='__main__':
197  import sys
198  from argparse import ArgumentParser
199  parser = ArgumentParser()
200  parser.add_argument('--outputHist', type=str, default='TrigCostRoot_Results.root', help='Histogram output ROOT file')
201  parser.add_argument('--monitorChainAlgorithm', action='store_true', help='Turn on Chain Algorithm monitoring')
202  parser.add_argument('--baseWeight', type=float, default=1.0, help='Base events weight')
203  parser.add_argument('--useEBWeights', type=bool, default=False, help='Apply Enhanced Bias weights')
204  parser.add_argument('--joFile', type=str, help='Optional HLTJobOptions file to add more hashes')
205 
206  parser.add_argument('--smk', type=int, help='SuperMasterKey to retrieve menu file')
207  parser.add_argument('--dbAlias', type=str, help='Database alias to retrieve menu file')
208 
209  parser.add_argument('--MCDatasetName', default='', type=str, help='For MC input: Name of the dataset, can be used instead of MCCrossSection, MCFilterEfficiency')
210  parser.add_argument('--MCCrossSection', default=0.0, type=float, help='For MC input: Cross section of process in nb')
211  parser.add_argument('--MCFilterEfficiency', default=1.0, type=float, help='For MC input: Filter efficiency of any MC filter (0.0 - 1.0)')
212  parser.add_argument('--MCKFactor', default=1.0, type=float, help='For MC input: Additional multiplicitive fudge-factor to the supplied cross section.')
213  parser.add_argument('--MCIgnoreGeneratorWeights', action='store_true', help='For MC input: Flag to disregard any generator weights.')
214 
215  parser.add_argument('--maxEvents', type=int, help='Maximum number of events to process')
216  parser.add_argument('--skipEvents',type=int, help='Number of events to skip')
217  parser.add_argument('--loglevel', type=int, default=3, help='Verbosity level: 1 - VERBOSE, 2 - DEBUG, 3 - INFO')
218  parser.add_argument('flags', nargs='*', help='Config flag overrides')
219  args = parser.parse_args()
220 
221  log.level = args.loglevel
222 
223  # Set the Athena configuration flags
224  from AthenaConfiguration.AllConfigFlags import initConfigFlags
225  # verbosity defined in Control/AthenaCommon/python/Constants.py
226  flags = initConfigFlags()
227  flags.Exec.OutputLevel = args.loglevel
228  flags.fillFromArgs(args.flags)
229  flags.lock()
230 
231  # Initialize configuration object, add accumulator, merge, and run.
232  from AthenaConfiguration.MainServicesConfig import MainServicesCfg
233  cfg = MainServicesCfg(flags)
234 
235  if flags.Input.isMC:
236  from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
237  cfg.merge(PoolReadCfg(flags))
238  else:
239  from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg
240  cfg.merge(ByteStreamReadCfg(flags))
241  cfg.merge(decodingCfg(flags))
242 
243  histSvc = CompFactory.THistSvc()
244  histSvc.Output += ["COSTSTREAM DATAFILE='" + args.outputHist + "' OPT='RECREATE'"]
245  cfg.addService(histSvc)
246 
247  # Retrieve config from cool database
248  if not flags.Input.isMC and (not args.smk or not args.dbAlias):
249  (args.smk, args.dbAlias) = readConfigFromCool(flags, args.smk, args.dbAlias)
250 
251  cfg.merge(hltConfigSvcCfg(flags, args.smk, args.dbAlias))
252  cfg.merge(trigCostAnalysisCfg(flags, args, flags.Input.isMC))
253 
254  # If you want to turn on more detailed messages ...
255  # exampleMonitorAcc.getEventAlgo('ExampleMonAlg').OutputLevel = 2 # DEBUG
256  cfg.printConfig(withDetails=False) # set True for exhaustive info
257  sc = cfg.run(args.maxEvents)
258  sys.exit(0 if sc.isSuccess() else 1)
RunTrigCostAnalysis.decodingCfg
def decodingCfg(flags)
Definition: RunTrigCostAnalysis.py:112
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
vtune_athena.format
format
Definition: vtune_athena.py:14
RunTrigCostAnalysis.getHltMenu
def getHltMenu()
Definition: RunTrigCostAnalysis.py:182
RunTrigCostAnalysis.hltConfigSvcCfg
def hltConfigSvcCfg(flags, smk, dbAlias)
Definition: RunTrigCostAnalysis.py:129
python.ByteStreamConfig.ByteStreamReadCfg
def ByteStreamReadCfg(flags, type_names=None)
Definition: Event/ByteStreamCnvSvc/python/ByteStreamConfig.py:25
covarianceTool.filter
filter
Definition: covarianceTool.py:514
python.CFElements.seqAND
def seqAND(name, subs=[])
Definition: CFElements.py:25
ROS_HLT_TableConstructor.ROSToROBMap
ROSToROBMap
Definition: ROS_HLT_TableConstructor.py:7
python.MainServicesConfig.MainServicesCfg
def MainServicesCfg(flags, LoopMgr='AthenaEventLoopMgr')
Definition: MainServicesConfig.py:256
RunTrigCostAnalysis.readMCpayload
def readMCpayload(args)
Definition: RunTrigCostAnalysis.py:56
RunTrigCostAnalysis.trigCostAnalysisCfg
def trigCostAnalysisCfg(flags, args, isMC=False)
Definition: RunTrigCostAnalysis.py:13
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:224
Trk::open
@ open
Definition: BinningType.h:40
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
python.PoolReadConfig.PoolReadCfg
def PoolReadCfg(flags)
Definition: PoolReadConfig.py:69
RunTrigCostAnalysis.readHashesFromHLTJO
def readHashesFromHLTJO(joFileName="", smk=0, dbAlias="")
Definition: RunTrigCostAnalysis.py:77
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
RunTrigCostAnalysis.readConfigFromCool
def readConfigFromCool(flags, smk, dbAlias)
Definition: RunTrigCostAnalysis.py:156