File indexing completed on 2023-03-17 11:28:42
0001
0002 import sys
0003 import os
0004 import ROOT
0005 import argparse
0006
0007
0008
0009
0010 from Validation.RecoTrack.plotting.validation import SimpleValidation, SimpleSample
0011
0012 from Validation.RecoTrack.plotting.plotting import Subtract, FakeDuplicate, CutEfficiency, Transform, AggregateBins, ROC, Plot, PlotEmpty, PlotGroup, PlotOnSideGroup, PlotFolder, Plotter
0013 from Validation.RecoTrack.plotting.html import PlotPurpose
0014
0015 from Validation.RecoParticleFlow.defaults_cfi import ptbins, etabins, response_distribution_name, muLowOffset, muHighOffset, npvLowOffset, npvHighOffset, candidateType, offset_name
0016 from offsetStack import offsetStack
0017
0018 def parse_sample_string(ss):
0019 spl = ss.split(":")
0020 if not (len(spl) >= 3):
0021 raise Exception("Sample must be in the format name:DQMfile1.root:DQMfile2.root:...")
0022
0023 name = spl[0]
0024 files = spl[1:]
0025
0026
0027 for fi in files:
0028 print("Trying to open DQM file {0} for sample {1}".format(fi, name))
0029 if not os.path.isfile(fi):
0030 raise Exception("Could not read DQM file {0}, it does not exist".format(fi))
0031 tf = ROOT.TFile(fi)
0032 if not tf:
0033 raise Exception("Could not read DQM file {0}, it's not a ROOT file".format(fi))
0034
0035 d = tf.Get("DQMData/Run 1/ParticleFlow/Run summary")
0036 if not d:
0037 raise Exception("Could not read DQM file {0}, it's does not seem to be a harvested DQM file".format(fi))
0038 return name, files
0039
0040 def parse_plot_string(ss):
0041 spl = ss.split(":")
0042 if not (len(spl) >= 3):
0043 raise Exception("Plot must be in the format folder:name:hist1:hist2:...")
0044
0045 folder = spl[0]
0046 name = spl[1]
0047 histograms = spl[2:]
0048
0049 return folder, name, histograms
0050
0051 def parse_args():
0052 parser = argparse.ArgumentParser()
0053 parser.add_argument("-s", "--sample", type=str, action='append',
0054 required=True,
0055 help="DQM files to compare for a single sample, in the format 'name:file1.root:file2.root:...:fileN.root'",
0056
0057
0058
0059 )
0060 parser.add_argument("-p", "--plots",
0061 type=str, action='append',
0062 required=False,
0063 help="Plots to put on a single canvas, in the format 'folder:name:plot1:plot2:...:plotN'",
0064 default = [],
0065
0066
0067
0068 )
0069 parser.add_argument("--doResponsePlots",
0070 action='store_true',
0071 required=False,
0072 help="If enabled, do all jet response plots"
0073 )
0074 parser.add_argument("--doOffsetPlots",
0075 action='store_true',
0076 required=False,
0077 help="If enabled, do all offset plots"
0078 )
0079 parser.add_argument("--doMETPlots",
0080 action='store_true',
0081 required=False,
0082 help="If enabled, do all JetMET plots"
0083 )
0084 parser.add_argument("--doPFCandPlots",
0085 action='store_true',
0086 required=False,
0087 help="If enabled, do all PFCandidate plots"
0088 )
0089
0090 parser.add_argument( "--offsetVar", type=str, action='store', default="npv", help="variable to bin offset eT" )
0091 parser.add_argument( "--offsetDR", type=float, action='store', default=0.4, help="offset deltaR value" )
0092 args = parser.parse_args()
0093
0094
0095 samples = []
0096 plots = []
0097
0098 sample_strings = args.sample
0099 for ss in sample_strings:
0100 name, files = parse_sample_string(ss)
0101 samp = SimpleSample(name, name, [(fn, fn.split('/')[-2]) for fn in files])
0102 samples += [samp]
0103
0104 for ss in args.plots:
0105 folder, name, histograms = parse_plot_string(ss)
0106 plots += [(folder, name, histograms)]
0107
0108
0109
0110 if args.doResponsePlots:
0111
0112 JetFolderDirs = ["JetResponse/slimmedJets/JEC", "JetResponse/slimmedJets/noJEC", "JetResponse/slimmedJetsPuppi/JEC", "JetResponse/slimmedJetsPuppi/noJEC"]
0113
0114 for JetFolderDir in JetFolderDirs:
0115 plots += [(JetFolderDir, "reso_pt", ["preso_eta05", "preso_eta13",
0116 "preso_eta21","preso_eta25","preso_eta30","preso_eta50"])]
0117 plots += [(JetFolderDir, "reso_pt_rms", ["preso_eta05_rms",
0118 "preso_eta13_rms","preso_eta21_rms","preso_eta25_rms","preso_eta30_rms",
0119 "preso_eta50_rms"])]
0120 plots += [(JetFolderDir, "response_pt", ["presponse_eta05",
0121 "presponse_eta13", "presponse_eta21", "presponse_eta25", "presponse_eta30",
0122 "presponse_eta50"])]
0123 for iptbin in range(len(ptbins)-1):
0124 pthistograms = []
0125 for ietabin in range(len(etabins)-1):
0126 pthistograms += [response_distribution_name(iptbin, ietabin)]
0127 plots += [(JetFolderDir, "response_{0:.0f}_{1:.0f}".format(ptbins[iptbin], ptbins[iptbin+1]), pthistograms)]
0128
0129 if args.doOffsetPlots:
0130 if args.offsetVar == "npv" :
0131 varHigh, varLow = npvHighOffset, npvLowOffset
0132 else :
0133 varHigh, varLow = muHighOffset, muLowOffset
0134 for ivar in range( varLow, varHigh ) :
0135 offsetHists = []
0136 for itype in candidateType :
0137 offsetHists += [ offset_name( args.offsetVar, ivar, itype ) ]
0138 plots += [("Offset/{0}Plots/{0}{1}".format(args.offsetVar, ivar), "{0}{1}".format(args.offsetVar, ivar), offsetHists)]
0139
0140 if args.doMETPlots:
0141 doMETPlots(files, plots)
0142
0143
0144 if args.doPFCandPlots:
0145 doPFCandPlots(files, plots)
0146
0147 return samples, plots, args.doOffsetPlots, args.offsetVar, args.offsetDR, args.doPFCandPlots
0148
0149
0150 def doMETPlots(files, plots):
0151
0152
0153 METHistograms = []
0154 f = ROOT.TFile(files[0])
0155 d = f.Get("DQMData/Run 1/JetMET/Run summary/METValidation/slimmedMETsPuppi")
0156 for i in d.GetListOfKeys():
0157 METHistograms.append([i.GetName()])
0158
0159 METFolderDirs = ["METValidation/slimmedMETs","METValidation/slimmedMETsPuppi"]
0160 for METFolderDir in METFolderDirs:
0161 for METHistogram in METHistograms:
0162 plots += [(METFolderDir, "", METHistogram)]
0163
0164
0165 JetHistograms = []
0166 d = f.Get("DQMData/Run 1/JetMET/Run summary/JetValidation/slimmedJets")
0167 for i in d.GetListOfKeys():
0168 JetHistograms.append([i.GetName()])
0169 JetValFolderDirs = ["JetValidation/slimmedJets", "JetValidation/slimmedJetsAK8", "JetValidation/slimmedJetsPuppi"]
0170 for JetValFolderDir in JetValFolderDirs:
0171 for JetHistogram in JetHistograms:
0172 plots += [(JetValFolderDir, "", JetHistogram)]
0173
0174
0175 def doPFCandPlots(files, plots):
0176
0177 hist_list = ["Charge", "Eta", "Phi", "Log10Pt", "PtLow","PtMid", "PtHigh"]
0178 f = ROOT.TFile(files[0])
0179 d = f.Get("DQMData/Run 1/ParticleFlow/Run summary/PackedCandidates")
0180
0181 PFFolderNames = []
0182
0183 for i in d.GetListOfKeys():
0184 PFFolderNames.append(i.GetName())
0185
0186 for PFFolderName in PFFolderNames:
0187 for hist in hist_list:
0188 plots += [(PFFolderName, "", [PFFolderName + hist])]
0189
0190
0191 def addPlots(plotter, folder, name, section, histograms, opts, Offset=False):
0192 folders = [folder]
0193
0194
0195 if Offset :
0196 plots = [PlotGroup(name, [Plot(h, **opts) for h in histograms])]
0197 plotter.append("Offset", folders, PlotFolder(*plots, loopSubFolders=False, page="offset", section=section))
0198 elif "JetResponse" in folder :
0199 plots = [PlotGroup(name, [Plot(h, **opts) for h in histograms])]
0200 plotter.append("ParticleFlow/" + section, folders, PlotFolder(*plots, loopSubFolders=False, page="pf", section=section))
0201 for plot in plots:
0202 plot.setProperties(ncols=3)
0203 plot.setProperties(legendDw=-0.68)
0204 plot.setProperties(legendDh=0.005)
0205 plot.setProperties(legendDy=0.24)
0206 plot.setProperties(legendDx=0.05)
0207 elif "JetMET" in folder:
0208 for h in histograms:
0209 plots = [PlotGroup(h, [Plot(h, **opts)])]
0210 for plot in plots:
0211 plot.setProperties(legendDw=-0.5)
0212 plot.setProperties(legendDh=0.01)
0213 plot.setProperties(legendDy=0.24)
0214 plot.setProperties(legendDx=0.05)
0215 plotter.append("JetMET" + section, folders, PlotFolder(*plots, loopSubFolders=False, page="JetMET", section=section))
0216 if "PackedCandidates" in folder:
0217 for h in histograms:
0218 if ("PtMid" in h or "PtHigh" in h):
0219 plots = [PlotGroup(h, [Plot(h, ymin = pow(10,-1), ylog = True)])]
0220 else:
0221 plots = [PlotGroup(h, [Plot(h, **opts)])]
0222 for plot in plots:
0223 plot.setProperties(legendDw=-0.5)
0224 plot.setProperties(legendDh=0.01)
0225 plot.setProperties(legendDy=0.24)
0226 plot.setProperties(legendDx=0.05)
0227 plotter.append("ParticleFlow/PackedCandidates/" + section, folders, PlotFolder(*plots, loopSubFolders=False, page="PackedCandidates", section= section))
0228
0229
0230 def main():
0231
0232
0233
0234 styledict_resolution = {"xlog": True, "xgrid":False, "ygrid":False,
0235 "xtitle":"GenJet pT (GeV)", "ytitle":"Jet pT resolution",
0236 "xtitleoffset":7.7,"ytitleoffset":3.8,"adjustMarginLeft":0.00}
0237
0238 styledict_response = {"xlog": True, "xgrid":False, "ygrid":False,
0239 "xtitle":"GenJet pT (GeV)", "ytitle":"Jet response",
0240 "xtitleoffset":7.7,"ytitleoffset":3.8,"adjustMarginLeft":0.00}
0241 plot_opts = {
0242 "reso_pt": styledict_resolution,
0243 "reso_pt_rms": styledict_resolution,
0244 "response_pt": styledict_response
0245 }
0246 for iptbin in range(len(ptbins)-1):
0247 plot_opts["response_{0:.0f}_{1:.0f}".format(ptbins[iptbin], ptbins[iptbin+1])] = {"stat": True}
0248
0249 samples, plots, doOffsetPlots, offsetVar, offsetDR, doPFCandPlots = parse_args()
0250
0251 plotter = Plotter()
0252
0253
0254 for folder, name, histograms in plots:
0255 opts = plot_opts.get(name, {})
0256
0257
0258
0259 fullJetFolder = "DQMData/Run 1/ParticleFlow/Run summary/{0}".format(folder)
0260 fullMETFolder = "DQMData/Run 1/JetMET/Run summary/{0}".format(folder)
0261 fullPFCandFolder = "DQMData/Run 1/ParticleFlow/Run summary/PackedCandidates/{0}".format(folder)
0262 print("Booking histogram group {0}={1} from folder {2}".format(name, histograms, folder))
0263 if "Offset/" in folder:
0264 opts = {'xtitle':'Default', 'ytitle':'Default'}
0265 addPlots(plotter, fullJetFolder, name, folder, histograms, opts, True)
0266 if "JetResponse" in folder:
0267 addPlots(plotter, fullJetFolder, name, folder, histograms, opts)
0268 if "METValidation" in folder or "JetValidation" in folder:
0269 addPlots(plotter, fullMETFolder, name, folder, histograms, opts)
0270 if doPFCandPlots:
0271 addPlots(plotter, fullPFCandFolder, name, folder, histograms, opts)
0272
0273 outputDir = "plots"
0274 description = "Simple ParticleFlow comparison"
0275
0276 plotterDrawArgs = dict(
0277 separate=False,
0278
0279 )
0280
0281
0282 val = SimpleValidation(samples, outputDir)
0283 report = val.createHtmlReport(validationName=description)
0284 val.doPlots([plotter], plotterDrawArgs=plotterDrawArgs)
0285
0286 report.write()
0287
0288
0289 if doOffsetPlots :
0290 offsetDir = "OffsetStacks"
0291 fullOffsetDir = os.path.join( outputDir, offsetDir )
0292 os.makedirs( fullOffsetDir )
0293
0294 for s in samples :
0295 offFile = open( outputDir + "/" + s.label() + "_offset.html", "r")
0296 lines = offFile.readlines()
0297 offFile.close()
0298 for f in s.files() :
0299 fname = f.split('/')[-2]
0300 outName = offsetStack( [(fname,f)], offsetVar, offsetDR, fullOffsetDir )
0301 outName = outName.replace("plots/", "")
0302 addLine( outName, lines )
0303
0304 for f2 in s.files() :
0305 if f == f2 : continue
0306 fname2 = f2.split('/')[-2]
0307 outName = offsetStack( [(fname,f), (fname2,f2)], offsetVar, offsetDR, fullOffsetDir )
0308 outName = outName.replace("plots/", "")
0309 addLine( outName, lines )
0310
0311 offFile = open( outputDir + "/" + s.label() + "_offset.html", "w")
0312 lines = "".join(lines)
0313 offFile.write(lines)
0314 offFile.close()
0315
0316 def addLine(name, oldLines) :
0317 newLines = [
0318 ' <td><a href="{0}">{0}</a></td>\n'.format(name),
0319 ' <br/>\n',
0320 ' <br/>\n'
0321 ]
0322 oldLines[8:len(newLines)] = newLines
0323
0324 if __name__ == "__main__":
0325 main()