ATLAS Offline Software
TrigCostAnalysis/python/Util.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
4 #
5 
6 '''
7 @file Util.py
8 @brief Helper functions for CostAnalysisPostProcessing script
9 '''
10 
11 import ROOT
12 from math import fabs
13 from TrigCostAnalysis.CostMetadataUtil import createOverflowSummary
14 from AthenaCommon.Logging import logging
15 log = logging.getLogger('CostAnalysisPostProcessing')
16 
17 
18 def 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 
101 def 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 
124 def 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 
142 def 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 
159 def 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 
170 def 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 + '_'
vtune_athena.format
format
Definition: vtune_athena.py:14
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.Util.convert
def convert(entry)
Definition: TrigCostAnalysis/python/Util.py:142
python.Util.exploreTree
def exploreTree(inputFile, dumpSummary=False, underflowThreshold=0.1, overflowThreshold=0.1, maxRanges=5, skipRanges=-1)
Definition: TrigCostAnalysis/python/Util.py:18
python.Util.getFileName
def getFileName(tableName, rootName)
Definition: TrigCostAnalysis/python/Util.py:159
python.Util.getAlgorithmTotalTime
def getAlgorithmTotalTime(inputFile, rootName)
Definition: TrigCostAnalysis/python/Util.py:124
Get
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,...
Definition: comparitor.cxx:179
python.Util.getHistogramPrefix
def getHistogramPrefix(tableName, rootName)
Definition: TrigCostAnalysis/python/Util.py:170
LArG4FSStartPointFilter.exec
exec
Definition: LArG4FSStartPointFilter.py:103
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
python.CostMetadataUtil.createOverflowSummary
def createOverflowSummary(warnings)
Definition: CostMetadataUtil.py:97
python.Util.getWalltime
def getWalltime(inputFile, rootName)
Definition: TrigCostAnalysis/python/Util.py:101