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