ATLAS Offline Software
PrintTrkAnaSummary.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 
4 import sys, os, argparse, ROOT
5 import pandas as pd
6 import math
7 from uncertainties import ufloat as rd
8 
9 # Parsing arguments
10 commandName = os.path.basename( sys.argv[0] )
11 summaryDirDefault="InDetTrackPerfMonPlots/&TrkAnaName&/Offline/Tracks/"
12 parser = argparse.ArgumentParser( description = commandName+" options:" )
13 parser.add_argument( "-t", "--testFile", help="Path to input TEST file" )
14 parser.add_argument( "-r", "--refFile", default="", help="Path to input REFERENCE file" )
15 parser.add_argument( "-T", "--testLabel", default="TEST", help="Label for TEST" )
16 parser.add_argument( "-R", "--refLabel", default="REF", help="Label for REFERENCE" )
17 parser.add_argument( "-d", "--dirName", default=summaryDirDefault, help="Name of the TDirectory path with plots" )
18 parser.add_argument( "-a", "--analyses", default="TrkAnaEF", help="Comma-separeted list of track analyses to process" )
19 parser.add_argument( "-o", "--outName", default="TrkAnaSummary_&TrkAnaName&.html", help="Name of the output html files" )
20 MyArgs = parser.parse_args()
21 anaList = MyArgs.analyses.strip().split(',')
22 
23 if not MyArgs.testFile:
24  print( "ERROR: input test file not provided" )
25  sys.exit(1)
26 
27 def fround( c, e ):
28  e = math.fabs( e )
29  res = str( rd( c, e ) )
30  return res.replace( '+/-', ' \u00b1 ' ).replace( '(', '( ' ).replace( ')', ' )' )
31 
32 def processFile( inFileName, dirName, label, data, dataDict, index, updateIndex=True, printMultiplicity=True ):
33  if updateIndex: index.clear()
34  sList = []
35  sDict = {}
36  inFile = ROOT.TFile.Open( inFileName, "READ" )
37 
38 
39  if printMultiplicity:
40  hs = inFile.Get( dirName+"Multiplicities/summary" )
41  for i in range( 1, 8 ) :
42  if hs:
43  if updateIndex : index.append( hs.GetXaxis().GetBinLabel(i) )
44  c = hs.GetBinContent(i)
45  e = hs.GetBinError(i)
46  sList.append( f"{c:.0f} \u00b1 {e:.0f}" )
47  sDict.update( { "mult_"+str(i) : [ c, e ] } )
48  else:
49  if updateIndex : index.append(" ")
50  sList.append( "-" )
51 
52  # efficiencies
53  he = inFile.Get( dirName+"Efficiencies/eff_vs_truth_inclusive" )
54  if updateIndex : index.append( " " )
55  sList.append( " " )
56  if updateIndex : index.append( "Eff_vs_truth" )
57  if he:
58  c = 100*he.GetEfficiency(1)
59  eu = 100*he.GetEfficiencyErrorUp(1)
60  el = 100*he.GetEfficiencyErrorLow(1)
61  e = max( [ eu, el ] )
62  sList.append( f"{fround( c, e )} %" )
63  sDict.update( { "eff" : [ c, e ] } )
64  else : sList.append( "-" )
65 
66 
67  het = inFile.Get( dirName+"Efficiencies/Technical/eff_vs_truth_inclusive" )
68  if updateIndex : index.append( "Tech_eff_vs_truth" )
69  if het:
70  c = 100*het.GetEfficiency(1)
71  eu = 100*het.GetEfficiencyErrorUp(1)
72  el = 100*het.GetEfficiencyErrorLow(1)
73  e = max( [ eu, el ] )
74  sList.append( f"{fround( c, e )} %" )
75  sDict.update( { "tech_eff" : [ c, e ] } )
76  else : sList.append( "-" )
77 
78 
79 
80  hrpt = inFile.Get( dirName+"Resolutions/resolution_pt_vs_truth_inclusive" )
81  if updateIndex : index.append( " " )
82  sList.append( " " )
83  if updateIndex : index.append( "Resolution_pT_vs_truth" )
84  if hrpt:
85  c = hrpt.GetBinContent(1)
86  e = hrpt.GetBinError(1)
87  sList.append( f"{fround( c, e )} GeV" )
88  sDict.update( { "res_pt" : [ c, e ] } )
89  else : sList.append( "-" )
90 
91 
92 
93  hrd0 = inFile.Get( dirName+"Resolutions/resolution_d0_vs_truth_inclusive" )
94  if updateIndex : index.append( "Resolution_d0_vs_truth" )
95  if hrd0:
96  c = hrd0.GetBinContent(1)
97  e = hrd0.GetBinError(1)
98  sList.append( f"{fround( c, e )} \u03BCm" )
99  sDict.update( { "res_d0" : [ c, e ] } )
100  else : sList.append( "-" )
101 
102 
103 
104  hrz0 = inFile.Get( dirName+"Resolutions/resolution_z0_vs_truth_inclusive" )
105  if updateIndex : index.append( "Resolution_z0_vs_truth" )
106  if hrz0:
107  c = hrz0.GetBinContent(1)
108  e = hrz0.GetBinError(1)
109  sList.append( f"{fround( c, e )} \u03BCm" )
110  sDict.update( { "res_z0" : [ c, e ] } )
111  else : sList.append( "-" )
112 
113 
114 
115  hf = inFile.Get( dirName+"FakeRates/fakerate_vs_offl_inclusive" )
116  if updateIndex : index.append( " " )
117  sList.append( " " )
118  if updateIndex : index.append( "FakeRate_vs_reco" )
119  if hf:
120  c = 100*hf.GetEfficiency(1)
121  eu = 100*hf.GetEfficiencyErrorUp(1)
122  el = 100*hf.GetEfficiencyErrorLow(1)
123  e = max( [ eu, el ] )
124  sList.append( f"{fround( c, e )} %" )
125  sDict.update( { "fake" : [ c, e ] } )
126  else : sList.append( "-" )
127 
128 
129 
130  hd = inFile.Get( dirName+"Duplicates/duplrate_vs_truth_inclusive" )
131  if updateIndex : index.append( "DuplicateRate_vs_truth" )
132  if hd:
133  c = 100*hd.GetEfficiency(1)
134  eu = 100*hd.GetEfficiencyErrorUp(1)
135  el = 100*hd.GetEfficiencyErrorLow(1)
136  e = max( [ eu, el ] )
137  sList.append( f"{fround( c, e )} %" )
138  sDict.update( { "dupl" : [ c, e ] } )
139  else : sList.append( "-" )
140 
141 
142 
143  data.update( { label : sList } )
144  dataDict.update( { label : sDict } )
145  inFile.Close()
146 
147 def getRatio( a, ae, b, be ):
148  if b==0 :
149  return ( 0., 0. )
150 
151  c = a / b
152  ce = math.sqrt( ( ae / b )**2 + ( a * be / b**2 )**2 )
153  return ( c, ce )
154 
155 def computeRatios( ltest, lref, data, dataDict, printMultiplicity=True ):
156  sList = []
157 
158 
159  if printMultiplicity:
160  for i in range( 1, 8 ) :
161  if "mult_"+str(i) in dataDict[ltest] and "mult_"+str(i) in dataDict[lref] :
162  c, e = getRatio( dataDict[ltest]["mult_"+str(i)][0],
163  dataDict[ltest]["mult_"+str(i)][1],
164  dataDict[lref]["mult_"+str(i)][0],
165  dataDict[lref]["mult_"+str(i)][1] )
166  sList.append( f"{fround( c, e )}" )
167  else:
168  sList.append( "-" )
169 
170  # efficiencies
171  sList.append( " " )
172  if "eff" in dataDict[ltest] and "eff" in dataDict[lref] :
173  c, e = getRatio( dataDict[ltest]["eff"][0],
174  dataDict[ltest]["eff"][1],
175  dataDict[lref]["eff"][0],
176  dataDict[lref]["eff"][1] )
177  c = 100*c
178  e = 100*e
179  sList.append( f"{fround( c, e )} %" )
180  else : sList.append( "-" )
181 
182 
183  if "tech_eff" in dataDict[ltest] and "tech_eff" in dataDict[lref] :
184  c, e = getRatio( dataDict[ltest]["tech_eff"][0],
185  dataDict[ltest]["tech_eff"][1],
186  dataDict[lref]["tech_eff"][0],
187  dataDict[lref]["tech_eff"][1] )
188  c = 100*c
189  e = 100*e
190  sList.append( f"{fround( c, e )} %" )
191  else : sList.append( "-" )
192 
193 
194 
195  sList.append( " " )
196  if "res_pt" in dataDict[ltest] and "res_pt" in dataDict[lref] :
197  c, e = getRatio( dataDict[ltest]["res_pt"][0],
198  dataDict[ltest]["res_pt"][1],
199  dataDict[lref]["res_pt"][0],
200  dataDict[lref]["res_pt"][1] )
201  sList.append( f"{fround( c, e )}" )
202  else : sList.append( "-" )
203 
204 
205 
206  if "res_d0" in dataDict[ltest] and "res_d0" in dataDict[lref] :
207  c, e = getRatio( dataDict[ltest]["res_d0"][0],
208  dataDict[ltest]["res_d0"][1],
209  dataDict[lref]["res_d0"][0],
210  dataDict[lref]["res_d0"][1] )
211  sList.append( f"{fround( c, e )}" )
212  else : sList.append( "-" )
213 
214 
215 
216  if "res_z0" in dataDict[ltest] and "res_z0" in dataDict[lref] :
217  c, e = getRatio( dataDict[ltest]["res_z0"][0],
218  dataDict[ltest]["res_z0"][1],
219  dataDict[lref]["res_z0"][0],
220  dataDict[lref]["res_z0"][1] )
221  sList.append( f"{fround( c, e )}" )
222  else : sList.append( "-" )
223 
224 
225 
226  sList.append( " " )
227  if "fake" in dataDict[ltest] and "fake" in dataDict[lref] :
228  c, e = getRatio( dataDict[ltest]["fake"][0],
229  dataDict[ltest]["fake"][1],
230  dataDict[lref]["fake"][0],
231  dataDict[lref]["fake"][1] )
232  sList.append( f"{fround( c, e )}" )
233  else : sList.append( "-" )
234 
235 
236 
237  if "dupl" in dataDict[ltest] and "dupl" in dataDict[lref] :
238  c, e = getRatio( dataDict[ltest]["dupl"][0],
239  dataDict[ltest]["dupl"][1],
240  dataDict[lref]["dupl"][0],
241  dataDict[lref]["dupl"][1] )
242  sList.append( f"{fround( c, e )}" )
243  else : sList.append( "-" )
244 
245 
246 
247  data.update( { ltest + " / " + lref : sList } )
248 
249 
250 outFile = MyArgs.outName.replace( "_&TrkAnaName&", "" )
251 if os.path.isfile( outFile ) :
252  os.remove( outFile )
253 
254 
255 for anaName in anaList :
256 
257  data = {}
258  dataDict = {}
259  index = []
260  anaDirName = MyArgs.dirName.replace( "&TrkAnaName&", anaName )
261  anaOutName = MyArgs.outName.replace( "&TrkAnaName&", anaName )
262 
263  testFile = ROOT.TFile.Open( MyArgs.testFile, "READ" )
264  testMultiplicity = testFile.Get( anaDirName+"Multiplicities/summary" )
265  testFile.Close()
266 
267  refFile = ROOT.TFile.Open( MyArgs.refFile, "READ" )
268  refMultiplicity = refFile.Get( anaDirName+"Multiplicities/summary" )
269  refFile.Close()
270 
271  printMultiplicity = refMultiplicity or testMultiplicity
272 
273  processFile(
274  inFileName = MyArgs.testFile,
275  dirName = anaDirName,
276  label = MyArgs.testLabel,
277  data = data,
278  dataDict = dataDict,
279  index = index,
280  printMultiplicity = printMultiplicity
281  )
282 
283 
284  if MyArgs.refFile :
285  processFile(
286  inFileName = MyArgs.refFile,
287  dirName = anaDirName,
288  label = MyArgs.refLabel,
289  data = data,
290  dataDict = dataDict,
291  index = index,
292  updateIndex = not testMultiplicity,
293  printMultiplicity = printMultiplicity
294  )
295 
296 
297  if MyArgs.refFile :
299  ltest = MyArgs.testLabel,
300  lref = MyArgs.refLabel,
301  data = data,
302  dataDict = dataDict,
303  printMultiplicity = printMultiplicity
304  )
305 
306 
307  df = pd.DataFrame( data, index=index )
308  titleStr = f"Summary for TrackAnalysis = {anaName}:"
309  print( f"\n\n---------------\n{titleStr}" )
310  print( df )
311 
312 
313  with open( anaOutName, 'w' ) as f :
314  print( df.to_html(), file=f )
315 
316 
317  os.system( f"echo \"<br><b>{titleStr}</b><br>\" >> {outFile}" )
318  os.system( f"cat {anaOutName} >> {outFile}" )
319  os.remove( f"{anaOutName}" )
320 
321 sys.exit(0)
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
PrintTrkAnaSummary.computeRatios
def computeRatios(ltest, lref, data, dataDict, printMultiplicity=True)
Definition: PrintTrkAnaSummary.py:155
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
PrintTrkAnaSummary.fround
def fround(c, e)
Definition: PrintTrkAnaSummary.py:27
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
PrintTrkAnaSummary.getRatio
def getRatio(a, ae, b, be)
Definition: PrintTrkAnaSummary.py:147
PrintTrkAnaSummary.processFile
def processFile(inFileName, dirName, label, data, dataDict, index, updateIndex=True, printMultiplicity=True)
Definition: PrintTrkAnaSummary.py:32
Trk::open
@ open
Definition: BinningType.h:40
str
Definition: BTagTrackIpAccessor.cxx:11
Trk::split
@ split
Definition: LayerMaterialProperties.h:38