ATLAS Offline Software
Loading...
Searching...
No Matches
python.Util Namespace Reference

Functions

 getTableName (name)
 toCSV (fileName, metadata, HLTTriggers, readL1=False)
 toJson (fileName, metadata, L1Triggers, HLTTriggers)
 toROOT (fileName, triggers)
 getMetadata (inputFile)
 populateTriggers (inputFile, metadata, globalGroupDict, filter)
 slice_dictionary (directory, object_key)
 populateScanTriggers (inputFile, metadata)
 getGlobalGroup (inputFile, filter)
 readDBFromAMI (amiTag)
 exploreTree (inputFile, dumpSummary=False, underflowThreshold=0.1, overflowThreshold=0.1, maxRanges=5, skipRanges=-1)
 getWalltime (inputFile, rootName)
 getAlgorithmTotalTime (inputFile, rootName)
 convert (entry)
 getFileName (tableName, rootName)
 getHistogramPrefix (tableName, rootName)

Variables

 log = logging.getLogger('RatesPostProcessing')

Detailed Description

@file Util.py
@brief Utility functions used by RatesPostProcessing
@file Util.py
@brief Helper functions for CostAnalysisPostProcessing script

Function Documentation

◆ convert()

python.Util.convert ( entry)
@brief Save entry number in scientific notation

Definition at line 142 of file TrigCostAnalysis/python/Util.py.

142def convert(entry):
143 ''' @brief Save entry number in scientific notation'''
144 if type(entry) is float or type(entry) is int:
145 # Avoid scientific notation for small numbers and 0
146 if entry == 0:
147 return 0
148 elif fabs(entry) > 10000 or fabs(entry) < 0.0001:
149 return "{:.4e}".format(entry)
150 elif int(entry) == entry:
151 # Get rid of unnecessary 0
152 return int(entry)
153 else:
154 return "{:.4}".format(entry)
155
156 return entry
157
158

◆ exploreTree()

python.Util.exploreTree ( inputFile,
dumpSummary = False,
underflowThreshold = 0.1,
overflowThreshold = 0.1,
maxRanges = 5,
skipRanges = -1 )
 @brief Explore ROOT Tree to find tables with histograms to be saved in csv

Per each found directory TableConstructor object is created.
Expected directory tree:
    rootDir
        table1Dir
            entry1Dir
                hist1
                hist2
                ...
            entry2Dir
                hist1
                ...
        table2Dir
        ...
        walltimeHist

@param[in] inputFile ROOT.TFile object with histograms

Definition at line 18 of file TrigCostAnalysis/python/Util.py.

18def exploreTree(inputFile, dumpSummary=False, underflowThreshold=0.1, overflowThreshold=0.1, maxRanges=5, skipRanges=-1):
19 ''' @brief Explore ROOT Tree to find tables with histograms to be saved in csv
20
21 Per each found directory TableConstructor object is created.
22 Expected directory tree:
23 rootDir
24 table1Dir
25 entry1Dir
26 hist1
27 hist2
28 ...
29 entry2Dir
30 hist1
31 ...
32 table2Dir
33 ...
34 walltimeHist
35
36 @param[in] inputFile ROOT.TFile object with histograms
37 '''
38
39 processingWarnings = []
40 rangeCounter = 0
41 rangesToSkip = skipRanges
42 for timeRange in inputFile.GetListOfKeys():
43 if timeRange.GetName() != "metadata" and rangesToSkip > 0:
44 rangesToSkip-=1
45 log.debug("Skipping range {0}".format(timeRange.GetName()))
46 continue
47
48 if maxRanges > 0 and rangeCounter >= maxRanges:
49 log.info("{0} ranges were processed - exiting the postprocessing".format(rangeCounter))
50 break
51
52 rangeObj = timeRange.ReadObj()
53 if not rangeObj.IsA().InheritsFrom(ROOT.TDirectory.Class()): continue
54
55 walltime = getWalltime(inputFile, timeRange.GetName())
56
57 for table in rangeObj.GetListOfKeys():
58 tableObj = table.ReadObj()
59 if not tableObj.IsA().InheritsFrom(ROOT.TDirectory.Class()): continue
60 log.info("Processing Table %s", table.GetName())
61 # Find and create Table Constructor for specific Table
62 try:
63 className = table.GetName() + "_TableConstructor"
64 exec("from TrigCostAnalysis." + className + " import " + className)
65 t = eval(className + "(tableObj, underflowThreshold, overflowThreshold)")
66
67 if table.GetName() == "Chain_HLT" or table.GetName() == "Chain_Algorithm_HLT":
68 t.totalTime = getAlgorithmTotalTime(inputFile, rangeObj.GetName())
69
70 if table.GetName() == "Global_HLT":
71 t.lbLength = walltime
72
73 if table.GetName() == "Algorithm_HLT":
74 t.dumpSummary = dumpSummary
75
76 fileName = getFileName(table.GetName(), timeRange.GetName())
77 histPrefix = getHistogramPrefix(table.GetName(), timeRange.GetName())
78
79 t.fillTable(histPrefix)
80 t.normalizeColumns(walltime)
81 t.saveToFile(fileName)
82
83 processingWarnings += t.getWarningMsgs()
84
85 except (ValueError):
86 log.error("Processing of table {0} failed!".format(table.GetName()))
87 return []
88 except (NameError, ImportError):
89 log.warning("Class {0} not defined - directory {1} will not be processed"
90 .format(table.GetName()+"_TableConstructor", table.GetName()))
91
92 rangeCounter += 1
93 log.debug("Range {0} was processed".format(timeRange.GetName()))
94
95 # add smmary of most overflown histograms
96 summary = createOverflowSummary(processingWarnings)
97 summary["Summary"] += ["Underflow threshold: {0}".format(underflowThreshold), "Overflow threshold: {0}".format(overflowThreshold)]
98 return processingWarnings + [summary]
99
100

◆ getAlgorithmTotalTime()

python.Util.getAlgorithmTotalTime ( inputFile,
rootName )
 @brief Extract total time [s] of algorithms from histogram

@param[in] inputFile ROOT TFile to look for histogram
@param[in] rootName Name of the root directory to search for tables

@return total execution time [s] value if found else 0

Definition at line 124 of file TrigCostAnalysis/python/Util.py.

124def getAlgorithmTotalTime(inputFile, rootName):
125 ''' @brief Extract total time [s] of algorithms from histogram
126
127 @param[in] inputFile ROOT TFile to look for histogram
128 @param[in] rootName Name of the root directory to search for tables
129
130 @return total execution time [s] value if found else 0
131 '''
132
133 totalTime = 0
134 alg = inputFile.Get(rootName).Get("Global_HLT").Get("Total")
135 hist = alg.Get(rootName + "_Global_HLT_Total_AlgTime_perEvent")
136 for i in range(1, hist.GetXaxis().GetNbins()):
137 totalTime += hist.GetBinContent(i) * hist.GetXaxis().GetBinCenterLog(i)
138
139 return totalTime * 1e-3
140
141
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...

◆ getFileName()

python.Util.getFileName ( tableName,
rootName )
@brief Get name of file to save the table

@param[in] tableName Table name
@param[in] rootName  Name of table's root directory

@return Filename for given table

Definition at line 159 of file TrigCostAnalysis/python/Util.py.

159def getFileName(tableName, rootName):
160 '''@brief Get name of file to save the table
161
162 @param[in] tableName Table name
163 @param[in] rootName Name of table's root directory
164
165 @return Filename for given table
166 '''
167 return "Table_" + tableName + "_" + rootName + ".csv"
168
169

◆ getGlobalGroup()

python.Util.getGlobalGroup ( inputFile,
filter )

Definition at line 245 of file RatesAnalysis/python/Util.py.

245def getGlobalGroup(inputFile, filter):
246 for key in inputFile.GetListOfKeys():
247 if key.GetName() == 'All':
248 for subdirKey in key.ReadObj().GetListOfKeys():
249 if not subdirKey.GetName() == "Rate_Group_HLT" : pass
250 for globalsKey in subdirKey.ReadObj().GetListOfKeys():
251 if filter in globalsKey.GetName():
252 groupsDict = slice_dictionary(globalsKey.ReadObj(), "data")
253 return groupsDict
254
255

◆ getHistogramPrefix()

python.Util.getHistogramPrefix ( tableName,
rootName )
@brief Construct full histogram name

@param[in] tableName Table name
@param[in] rootName  Name of table's root directory

@return Histogram prefix for given table

Definition at line 170 of file TrigCostAnalysis/python/Util.py.

170def getHistogramPrefix(tableName, rootName):
171 '''@brief Construct full histogram name
172
173 @param[in] tableName Table name
174 @param[in] rootName Name of table's root directory
175
176 @return Histogram prefix for given table
177 '''
178
179 return rootName + '_' + tableName + '_'

◆ getMetadata()

python.Util.getMetadata ( inputFile)
Get metadata for rates.json file

Definition at line 131 of file RatesAnalysis/python/Util.py.

131def getMetadata(inputFile):
132 '''Get metadata for rates.json file'''
133 metatree = inputFile.Get("metadata")
134 if metatree is None:
135 return None
136
137 metatree.GetEntry(0)
138 metadata = {}
139
140 metadata['runNumber'] = metatree.runNumber
141
142 metadata['targetMu'] = metatree.targetMu
143 metadata['targetBunches'] = metatree.targetBunches
144 metadata['targetLumi'] = metatree.targetLumi
145
146 metadata['masterKey'] = metatree.masterKey
147 metadata['lvl1PrescaleKey'] = metatree.lvl1PrescaleKey
148 metadata['hltPrescaleKey'] = metatree.hltPrescaleKey
149
150 metadata['AtlasProject'] = str(metatree.AtlasProject)
151 metadata['AtlasVersion'] = str(metatree.AtlasVersion)
152
153 metadata['bunchCrossingRate'] = metatree.bunchCrossingRate
154
155 metadata['multiSliceDiJet'] = metatree.multiSliceDiJet
156
157 prescales = {}
158 lowers = {}
159 express = {}
160 for i in range(0, metatree.triggers.size()):
161 prescale = metatree.prescales.at(i)
162 expressPrescale = metatree.express.at(i)
163 # Handle group prescale values
164 prescales[metatree.triggers.at(i)] = prescale if prescale >= -1 else "Multiple"
165 lowers[metatree.triggers.at(i)] = str(metatree.lowers.at(i))
166 express[metatree.triggers.at(i)] = expressPrescale if expressPrescale >= -1 else "Multiple"
167
168 metadata['prescales'] = prescales
169 metadata['lowers'] = lowers
170 metadata['express'] = express
171
172 chainid = {}
173 chaingroup = {}
174 for i in range(0, metatree.hltChainIDGroup.size()):
175 chainid[metatree.hltChainIDGroup.at(i).at(0)] = metatree.hltChainIDGroup.at(i).at(1)
176 chaingroup[metatree.hltChainIDGroup.at(i).at(0)] = metatree.hltChainIDGroup.at(i).at(2)
177
178 metadata['chainID'] = chainid
179 metadata['chainGroup'] = chaingroup
180
181 itemid = {}
182 for i in range(0, metatree.l1ItemID.size()):
183 itemid[metatree.l1ItemID.at(i).at(0)] = metatree.l1ItemID.at(i).at(1)
184
185 metadata['itemID'] = itemid
186
187 bunchGroups = []
188 for bg in metatree.bunchGroups:
189 bunchGroups.append(bg)
190 metadata['bunchGroups'] = bunchGroups
191
192 return metadata
193
194

◆ getTableName()

python.Util.getTableName ( name)

Definition at line 14 of file RatesAnalysis/python/Util.py.

14def getTableName(name):
15 tabName = "Table_Rate_"
16 if name == "HLT" or name == "L1":
17 tabName += "Chain" + name
18 else:
19 tabName += name
20
21 tabName += "_HLT_All.csv"
22
23 return tabName
24
25

◆ getWalltime()

python.Util.getWalltime ( inputFile,
rootName )
 @brief Extract walltime value from histogram

@param[in] inputFile ROOT TFile to look for histogram
@param[in] rootName Name of the root directory to search for tables

@return walltime value if found else 0 and an error

Definition at line 101 of file TrigCostAnalysis/python/Util.py.

101def getWalltime(inputFile, rootName):
102 ''' @brief Extract walltime value from histogram
103
104 @param[in] inputFile ROOT TFile to look for histogram
105 @param[in] rootName Name of the root directory to search for tables
106
107 @return walltime value if found else 0 and an error
108 '''
109
110 dirObj = inputFile.Get(rootName)
111 if not dirObj.IsA().InheritsFrom(ROOT.TDirectory.Class()): return 0
112 for hist in dirObj.GetListOfKeys():
113 if '_walltime' in hist.GetName():
114 histObj = hist.ReadObj()
115 if histObj.IsA().InheritsFrom(ROOT.TProfile.Class()):
116 return histObj.Integral()
117 else:
118 return histObj.GetBinContent(1)
119
120 log.error("Walltime not found")
121 return 0
122
123

◆ populateScanTriggers()

python.Util.populateScanTriggers ( inputFile,
metadata )

Definition at line 231 of file RatesAnalysis/python/Util.py.

231def populateScanTriggers(inputFile, metadata):
232 from .RatesScanTrigger import RatesScanTrigger
233 triggerList = []
234 for key in inputFile.GetListOfKeys():
235 if key.GetName() == 'ScanTriggers':
236 for scanName in key.ReadObj().GetListOfKeys():
237 numerator_dict = slice_dictionary(scanName.ReadObj(), "rateVsThreshold")
238 if len(numerator_dict) == 0:
239 log.error(f"Empty dictionary in populateScanTriggers for scan {scanName}")
240 continue
241 else:
242 triggerList.append(RatesScanTrigger(scanName.GetName(), metadata, numerator_dict))
243 return triggerList
244
Used to calculate a rate scan as a function of some threshold value.

◆ populateTriggers()

python.Util.populateTriggers ( inputFile,
metadata,
globalGroupDict,
filter )

Definition at line 195 of file RatesAnalysis/python/Util.py.

195def populateTriggers(inputFile, metadata, globalGroupDict, filter):
196 # Fix groups' names that are also not GLOBAL
197 def getTriggerName(name, filter):
198 if "Group" in filter and "GLOBAL" not in name:
199 return name.replace('_', ':', 1)
200 else:
201 return name
202
203 from .RatesTrigger import RatesTrigger
204 triggerList = []
205 for key in inputFile.GetListOfKeys():
206 if key.GetName() == 'All':
207 for subdirKey in key.ReadObj().GetListOfKeys():
208 if filter not in subdirKey.GetName(): continue
209 for triggerKey in subdirKey.ReadObj().GetListOfKeys():
210 numeratorDict = slice_dictionary(triggerKey.ReadObj(),"data")
211 for suffix, data in numeratorDict.items():
212 try:
213 triggerList.append(RatesTrigger(getTriggerName(triggerKey.GetName(), filter)+suffix, metadata, data, globalGroupDict[suffix], suffix))
214 except ValueError:
215 log.error("Cannot create a new trigger for {0}".format(triggerKey.GetName()))
216 return []
217 return triggerList
218
219
Used to calculate the rate for a single trigger at L1 or the HLT.

◆ readDBFromAMI()

python.Util.readDBFromAMI ( amiTag)
Read used database based on AMI tag 

Definition at line 256 of file RatesAnalysis/python/Util.py.

256def readDBFromAMI(amiTag):
257 ''' Read used database based on AMI tag '''
258 try:
259 import pyAMI.client
260 import pyAMI.atlas.api as AtlasAPI
261 except ModuleNotFoundError:
262 log.warning("Unable to import AMIClient from pyAMI. Maybe you didn't do localSetupPyAMI?")
263 return ""
264
265 amiclient = pyAMI.client.Client('atlas')
266 AtlasAPI.init()
267
268 command = [ 'AMIGetAMITagInfo', '-amiTag="%s"' % amiTag, '-cached' ]
269 amiTagInfo = amiclient.execute(command, format = 'dict_object').get_rows('amiTagInfo')[0]
270
271 return amiTagInfo['DBserver'] if "DBserver" in amiTagInfo else None

◆ slice_dictionary()

python.Util.slice_dictionary ( directory,
object_key )

Definition at line 220 of file RatesAnalysis/python/Util.py.

220def slice_dictionary(directory, object_key):
221 slices_dict = {}
222 for hist in directory.GetListOfKeys():
223 if str(hist.GetName()).startswith(object_key):
224 try:
225 slice_index = "_"+str(hist.GetName()).split("_")[1]
226 except IndexError:
227 slice_index = ""
228 slices_dict[slice_index] = hist.ReadObj()
229 return slices_dict
230
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179

◆ toCSV()

python.Util.toCSV ( fileName,
metadata,
HLTTriggers,
readL1 = False )

Definition at line 26 of file RatesAnalysis/python/Util.py.

26def toCSV(fileName, metadata, HLTTriggers, readL1=False):
27 import csv
28
29 with open(fileName, mode='w') as outputCSV_file:
30 rates_csv_writer = csv.writer(outputCSV_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
31
32 rates_csv_writer.writerow(['Name','Active Time [s]','Group','Weighted PS Rate [Hz]','Weighted PS Rate Err [Hz]', \
33 'Unique Rate [Hz]','Unique Rate Err [Hz]','Express Rate [Hz]','Express Rate Err [Hz]','Prescale','Express Prescale','ID', \
34 'Raw Active Events','Raw Pass Events','Active Events','Input Rate [Hz]','Pass Fraction after PS [%]','Pass Weighted PS'])
35 rates_csv_writer.writerow(['Trigger name','Integrated length of all lumi blocks which contributed events to this rates prediction.','The group this chain belongs to.','Rate after applying all prescale(s) as weights.','Error on rate after applying all prescale(s) as weights','Total rate without this chain rate','Error on unique rate','Express stream rate','Error on express rate','The prescale of this chain. Only displayed for simple combinations.','The prescale of the chain including express prescale','The CPTID or HLT Chain ID','Raw underlying statistics on the number events processed for this chain.','Raw underlying statistics on the number events passed by this chain.','Number of events in which the chain - or at least one chain in the combination - was executed.','Input rate to this chain or combination of chains. At L1 this will be the collision frequency for the bunch pattern.','Fraction of events which pass this trigger after prescale.','Number of events this chain or combination passed after applying prescales as weighting factors.'])
36
37 for trig in HLTTriggers:
38
39 group_name = chain_id = ""
40 if "ChainL1" in fileName:
41 group_name = "None"
42 chain_id = metadata["itemID"].get(trig.name)
43 elif "ChainHLT" in fileName:
44 group_name = metadata["chainGroup"].get(trig.name)
45 chain_id = metadata["chainID"].get(trig.name)
46 elif "Group" in fileName:
47 chain_id = 0
48 group_name = "All" if "GLOBAL" in trig.name else group_name
49
50 if float(trig.rateDenominator)==0:
51 print("float(trig.rateDenominator) is ZERO! This shouldn't happen")
52 if float(trig.activeWeighted)==0:
53 passFrac_afterPS=0
54 else:
55 passFrac_afterPS=100*float(trig.passWeighted)/float(trig.activeWeighted)
56
57 isL1 = trig.name.startswith("L1_")
58 rates_csv_writer.writerow([trig.name,"%.4f" % trig.rateDenominator,group_name,"%.4f" % trig.rate,"%.4f" % trig.rateErr, \
59 "%.4f" % trig.rateUnique,"%.4f" % trig.rateUniqueErr, ("%.4f" % trig.rateExpress if not isL1 else "-"), ("%.4f" % trig.rateExpressErr if not isL1 else "-"), \
60 trig.prescale, (trig.expressPrescale if not isL1 else "-"), chain_id, "%.0f" % trig.activeRaw,"%.0f" % trig.passRaw,"%.4f" % trig.activeWeighted, \
61 "%.4f" % (float(trig.activeWeighted)/float(trig.rateDenominator)),"%.4f" % passFrac_afterPS,"%.4f" % trig.passWeighted])
62
63
64
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

◆ toJson()

python.Util.toJson ( fileName,
metadata,
L1Triggers,
HLTTriggers )

Definition at line 65 of file RatesAnalysis/python/Util.py.

65def toJson(fileName, metadata, L1Triggers, HLTTriggers):
66 import json
67 l1 = {}
68 for trig in L1Triggers:
69 trig.export(l1)
70 hlt = {}
71 for trig in HLTTriggers:
72 trig.export(hlt)
73
74 level = {}
75 level['L1'] = l1
76 level['HLT'] = hlt
77
78 jsonDict = {}
79 jsonDict['PredictionLumi'] = metadata['targetLumi']
80 for k,v in metadata.items():
81 if k.startswith("n_evts"):
82 jsonDict[k] = v
83 jsonDict['AtlasProject'] = metadata['AtlasProject']
84 jsonDict['AtlasVersion'] = metadata['AtlasVersion']
85 jsonDict['triggerMenuSetup'] = metadata['masterKey']
86 jsonDict['L1PrescaleSet'] = metadata['lvl1PrescaleKey']
87 jsonDict['HLTPrescaleSet'] = metadata['hltPrescaleKey']
88 jsonDict['bunchgroup'] = metadata['bunchGroups']
89 jsonDict['level'] = level
90
91 with open(fileName, 'w') as outFile:
92 json.dump(obj=jsonDict, fp=outFile, indent=2, sort_keys=True)
93
94
95 metajsonData = [
96 {'PredictionLumi' : metadata['targetLumi']},
97 {'TargetMu' : metadata['targetMu']},
98 {'RunNumber' : metadata['runNumber']},
99 {'Details' : metadata['details']},
100 {'JIRA' : metadata['JIRA']},
101 {'AMITag' : metadata['amiTag']},
102 {'SMK' : metadata['masterKey']},
103 {'DB' : readDBFromAMI(metadata['amiTag']) if metadata['amiTag'] else None},
104 {'LVL1PSK' : metadata['lvl1PrescaleKey']},
105 {'HLTPSK' : metadata['hltPrescaleKey']},
106 {'AtlasProject' : metadata['AtlasProject']},
107 {'AtlasVersion' : metadata['AtlasVersion']}
108 ]
109 for k,v in metadata.items():
110 if k.startswith("n_evts"):
111 metajsonData.append({k: v})
112
113 metajsonDict = {}
114 metajsonDict['text'] = 'metadata'
115 metajsonDict['children'] = metajsonData
116
117 with open('metadata.json', 'w') as outMetaFile:
118 json.dump(obj=metajsonDict, fp=outMetaFile, indent=2, sort_keys=True)
119
120

◆ toROOT()

python.Util.toROOT ( fileName,
triggers )

Definition at line 121 of file RatesAnalysis/python/Util.py.

121def toROOT(fileName, triggers):
122 mydict = {}
123 for trigger in triggers:
124 trigger.export(mydict)
125 from ROOT import TFile
126 with TFile.Open(fileName, 'RECREATE') as fout:
127 for key, scanDict in mydict.items():
128 fout.WriteObject(scanDict['rate'], f"{key}_rate")
129
130

Variable Documentation

◆ log

python.Util.log = logging.getLogger('RatesPostProcessing')

Definition at line 12 of file RatesAnalysis/python/Util.py.