/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Validation/RecoTrack/python/plotting/trackingPlots.py
1 965 строк
92 KB
Brunella DAnzi
Add .711,.713,.714 workflows and show LST seeds for initialStep and HighPtTripletStep
24 июн 2026, 10:01
24 июн 2026, 10:01
4b8392e
Код
Авторство
О чём код?
from builtins import range import os import copy import collections import ROOT ROOT.gROOT.SetBatch(True) ROOT.PyConfig.IgnoreCommandLineOptions = True from .plotting import Subtract, FakeDuplicate, CutEfficiency, Transform, AggregateBins, ROC, Plot, PlotEmpty, PlotGroup, PlotOnSideGroup, PlotFolder, Plotter from .html import PlotPurpose from . import plotting from . import validation from . import html ######################################## # # Per track collection plots # ######################################## _maxEff = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 0.8, 1.025, 1.2, 1.5, 2] _maxFake = [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 0.8, 1.025] #_minMaxResol = [1e-5, 2e-5, 5e-5, 1e-4, 2e-4, 5e-4, 1e-3, 2e-3, 5e-3, 1e-2, 2e-2, 5e-2, 0.1, 0.2, 0.5, 1] _minMaxResol = [1e-5, 4e-5, 1e-4, 4e-4, 1e-3, 4e-3, 1e-2, 4e-2, 0.1, 0.4, 1] _minMaxN = [5e-1, 5, 5e1, 5e2, 5e3, 5e4, 5e5, 5e6, 5e7, 5e8, 5e9] _minHits = [0, 5, 10] _maxHits = [5, 10, 20, 40, 60, 80] _minLayers = [0, 5, 10] _maxLayers = [5, 10, 25] _maxPixelLayers = 8 _min3DLayers = [0, 5, 10] _max3DLayers = [5, 10, 20] _minZ = [-60, -40, -20, -10, -5] _maxZ = [5, 10, 20, 40, 60] _minPU = [0, 10, 20, 50, 100, 150] _maxPU = [20, 50, 65, 80, 100, 150, 200, 250] _minMaxTracks = [0, 200, 500, 1000, 1500, 2000] _minMaxMVA = [-1.025, -0.5, 0, 0.5, 1.025] _maxDRJ = 0.1 def _minMaxResidual(ma): return ([-x for x in ma], ma) (_minResidualPhi, _maxResidualPhi) = _minMaxResidual([1e-4, 2e-4]) # rad (_minResidualCotTheta, _maxResidualCotTheta) = _minMaxResidual([1e-4, 2e-4]) (_minResidualDxy, _maxResidualDxy) = _minMaxResidual([10, 20, 50, 100]) # um (_minResidualDz, _maxResidualDz) = (_minResidualDxy, _maxResidualDxy) (_minResidualPt, _maxResidualPt) = _minMaxResidual([1, 1.5, 2, 5]) # % _legendDy_1row = 0.46 _legendDy_2rows = -0.025 _legendDy_2rows_3cols = -0.17 _legendDy_4rows = 0.09 # Ok, because of the way the "reference release" histograms are # stored, this histogram is not accessible for the summary plots. To # be fixed later with (large) reorganization of how things work. #_trackingNumberOfEventsHistogram = "DQMData/Run 1/Tracking/Run summary/Track/general_trackingParticleRecoAsssociation/tracks" _trackingIterationOrderHistogram = "DQMData/Run 1/Tracking/Run summary/TrackBuilding/num_reco_coll" def _makeEffFakeDupPlots(postfix, quantity, unit="", common={}, effopts={}, fakeopts={}): p = postfix q = quantity xq = q if unit != "": xq += " (" + unit + ")" effargs = dict(xtitle="TP "+xq , ytitle="efficiency vs "+q , ymax=_maxEff) fakeargs = dict(xtitle="track "+xq, ytitle="fake+duplicates rate vs "+q, ymax=_maxFake) effargs.update(common) fakeargs.update(common) effargs.update(effopts) fakeargs.update(fakeopts) return [ Plot("effic_vs_"+p, **effargs), Plot(FakeDuplicate("fakeduprate_vs_"+p, assoc="num_assoc(recoToSim)_"+p, dup="num_duplicate_"+p, reco="num_reco_"+p, title="fake+duplicates vs "+q), **fakeargs) ] def _makeFakeDupPileupPlots(postfix, quantity, unit="", xquantity="", xtitle=None, common={}): p = postfix q = quantity if xtitle is None: if xquantity != "": xq = xquantity else: xq = q if unit != "": xq += " (" + unit + ")" xtitle="track "+xq return [ Plot("fakerate_vs_"+p , xtitle=xtitle, ytitle="fakerate vs "+q , ymax=_maxFake, **common), Plot("duplicatesRate_"+p, xtitle=xtitle, ytitle="duplicates rate vs "+q, ymax=_maxFake, **common), Plot("pileuprate_"+p , xtitle=xtitle, ytitle="pileup rate vs "+q , ymax=_maxFake, **common), ] def _makeFakeDist(postfix): return Subtract("num_fake_"+postfix, "num_reco_"+postfix, "num_assoc(recoToSim)_"+postfix) def _makeDistPlots(postfix, quantity, common={}): p = postfix q = quantity args = dict(xtitle="track "+q, ylog=True, ymin=_minMaxN, ymax=_minMaxN) args.update(common) return [ Plot("num_reco_"+p , ytitle="tracks", **args), Plot("num_assoc(recoToSim)_"+p, ytitle="true tracks", **args), Plot(_makeFakeDist(p), ytitle="fake tracks", **args), Plot("num_duplicate_"+p , ytitle="duplicate tracks", **args), ] def _makeDistSimPlots(postfix, quantity, common={}): p = postfix q = quantity args = dict(xtitle="TP "+q, ylog=True, ymin=_minMaxN, ymax=_minMaxN) args.update(common) return [ Plot("num_simul_"+p , ytitle="TrackingParticles", **args), Plot("num_assoc(simToReco)_"+p, ytitle="Reconstructed TPs", **args), ] def _makeMVAPlots(num, hp=False): pfix = "_hp" if hp else "" pfix2 = "Hp" if hp else "" xtitle = "MVA%d output"%num xtitlecut = "Cut on MVA%d output"%num args = dict(xtitle=xtitle, ylog=True, ymin=_minMaxN, ymax=_minMaxN) argsroc = dict( xtitle="Efficiency (excl. trk eff)", ytitle="Fake rate", xmax=_maxEff, ymax=_maxFake, drawStyle="EP", ) argsroc2 = dict( ztitle="Cut on MVA%d"%num, xtitleoffset=5, ytitleoffset=6.5, ztitleoffset=4, adjustMarginRight=0.12 ) argsroc2.update(argsroc) argsroc2["drawStyle"] = "pcolz" argsprofile = dict(ymin=_minMaxMVA, ymax=_minMaxMVA) true_cuteff = CutEfficiency("trueeff_vs_mva%dcut%s"%(num,pfix), "num_assoc(recoToSim)_mva%dcut%s"%(num,pfix)) fake_cuteff = CutEfficiency("fakeeff_vs_mva%dcut%s"%(num,pfix), Subtract("num_fake_mva%dcut%s"%(num,pfix), "num_reco_mva%dcut%s"%(num,pfix), "num_assoc(recoToSim)_mva%dcut%s"%(num,pfix))) return [ PlotGroup("mva%d%s"%(num,pfix2), [ Plot("num_assoc(recoToSim)_mva%d%s"%(num,pfix), ytitle="true tracks", **args), Plot(Subtract("num_fake_mva%d%s"%(num,pfix), "num_reco_mva%d%s"%(num,pfix), "num_assoc(recoToSim)_mva%d%s"%(num,pfix)), ytitle="fake tracks", **args), Plot("effic_vs_mva%dcut%s"%(num,pfix), xtitle=xtitlecut, ytitle="Efficiency (excl. trk eff)", ymax=_maxEff), # Plot("fakerate_vs_mva%dcut%s"%(num,pfix), xtitle=xtitlecut, ytitle="Fake rate", ymax=_maxFake), Plot(ROC("effic_vs_fake_mva%d%s"%(num,pfix), "effic_vs_mva%dcut%s"%(num,pfix), "fakerate_vs_mva%dcut%s"%(num,pfix)), **argsroc), Plot(ROC("effic_vs_fake_mva%d%s"%(num,pfix), "effic_vs_mva%dcut%s"%(num,pfix), "fakerate_vs_mva%dcut%s"%(num,pfix), zaxis=True), **argsroc2), # Same signal efficiency, background efficiency, and ROC definitions as in TMVA Plot(true_cuteff, xtitle=xtitlecut, ytitle="True track selection efficiency", ymax=_maxEff), Plot(fake_cuteff, xtitle=xtitlecut, ytitle="Fake track selection efficiency", ymax=_maxEff), Plot(ROC("true_eff_vs_fake_rej_mva%d%s"%(num,pfix), true_cuteff, Transform("fake_rej_mva%d%s"%(num,pfix), fake_cuteff, lambda x: 1-x)), xtitle="True track selection efficiency", ytitle="Fake track rejection", xmax=_maxEff, ymax=_maxEff), ], ncols=3, legendDy=_legendDy_1row), PlotGroup("mva%d%sPtEta"%(num,pfix2), [ Plot("mva_assoc(recoToSim)_mva%d%s_pT"%(num,pfix), xtitle="Track p_{T} (GeV)", ytitle=xtitle+" for true tracks", xlog=True, **argsprofile), Plot("mva_fake_mva%d%s_pT"%(num,pfix), xtitle="Track p_{T} (GeV)", ytitle=xtitle+" for fake tracks", xlog=True, **argsprofile), Plot("mva_assoc(recoToSim)_mva%d%s_eta"%(num,pfix), xtitle="Track #eta", ytitle=xtitle+" for true tracks", **argsprofile), Plot("mva_fake_mva%d%s_eta"%(num,pfix), xtitle="Track #eta", ytitle=xtitle+" for fake tracks", **argsprofile), ], legendDy=_legendDy_2rows) ] _effandfakePtEtaPhi = PlotGroup("effandfakePtEtaPhi", [ Plot("efficPt", title="Efficiency vs p_{T}", xtitle="TP p_{T} (GeV)", ytitle="efficiency vs p_{T}", xlog=True, ymax=_maxEff), Plot(FakeDuplicate("fakeduprate_vs_pT", assoc="num_assoc(recoToSim)_pT", dup="num_duplicate_pT", reco="num_reco_pT", title="fake+duplicates vs p_{T}"), xtitle="track p_{T} (GeV)", ytitle="fake+duplicates rate vs p_{T}", ymax=_maxFake, xlog=True), Plot("effic", xtitle="TP #eta", ytitle="efficiency vs #eta", title="", ymax=_maxEff), Plot(FakeDuplicate("fakeduprate_vs_eta", assoc="num_assoc(recoToSim)_eta", dup="num_duplicate_eta", reco="num_reco_eta", title=""), xtitle="track #eta", ytitle="fake+duplicates rate vs #eta", ymax=_maxFake), ] + _makeEffFakeDupPlots("phi", "#phi") ) _effandfakeDxyDzBS = PlotGroup("effandfakeDxyDzBS", _makeEffFakeDupPlots("dxy" , "dxy" , "cm") + _makeEffFakeDupPlots("dz" , "dz" , "cm"), legendDy=_legendDy_2rows ) _effandfakeDxyDzPV = PlotGroup("effandfakeDxyDzPV", _makeEffFakeDupPlots("dxypv" , "dxy(PV)", "cm") + _makeEffFakeDupPlots("dxypv_zoomed", "dxy(PV)", "cm") + _makeEffFakeDupPlots("dzpv" , "dz(PV)" , "cm") + _makeEffFakeDupPlots("dzpv_zoomed" , "dz(PV)" , "cm"), legendDy=_legendDy_4rows ) _effandfakeHitsLayers = PlotGroup("effandfakeHitsLayers", _makeEffFakeDupPlots("hit" , "hits" , common=dict(xmin=_minHits , xmax=_maxHits)) + _makeEffFakeDupPlots("layer" , "layers" , common=dict(xmin=_minLayers , xmax=_maxLayers)) + _makeEffFakeDupPlots("pixellayer", "pixel layers", common=dict( xmax=_maxPixelLayers)) + _makeEffFakeDupPlots("3Dlayer" , "3D layers" , common=dict(xmin=_min3DLayers, xmax=_max3DLayers)), legendDy=_legendDy_4rows ) _common = {"ymin": 0, "ymax": _maxEff} _effandfakePos = PlotGroup("effandfakePos", _makeEffFakeDupPlots("vertpos", "vert r", "cm", fakeopts=dict(xtitle="track ref. point r (cm)", ytitle="fake+duplicates vs. r"), common=dict(xlog=True)) + _makeEffFakeDupPlots("zpos" , "vert z", "cm", fakeopts=dict(xtitle="track ref. point z (cm)", ytitle="fake+duplicates vs. z")) + _makeEffFakeDupPlots("simpvz" , "Sim. PV z", "cm", common=dict(xtitle="Sim. PV z (cm)", xmin=_minZ, xmax=_maxZ)) ) _effandfakeDeltaRPU = PlotGroup("effandfakeDeltaRPU", _makeEffFakeDupPlots("dr" , "#DeltaR", effopts=dict(xtitle="TP min #DeltaR"), fakeopts=dict(xtitle="track min #DeltaR"), common=dict(xlog=True)) + _makeEffFakeDupPlots("drj" , "#DeltaR(track, jet)", effopts=dict(xtitle="#DeltaR(TP, jet)", ytitle="efficiency vs #DeltaR(TP, jet"), fakeopts=dict(xtitle="#DeltaR(track, jet)"), common=dict(xlog=True, xmax=_maxDRJ))+ _makeEffFakeDupPlots("pu" , "PU" , common=dict(xtitle="Pileup", xmin=_minPU, xmax=_maxPU)), legendDy=_legendDy_4rows ) _algos_common = dict(removeEmptyBins=True, xbinlabelsize=10, xbinlabeloption="d") _duplicateAlgo = PlotOnSideGroup("duplicateAlgo", Plot("duplicates_oriAlgo_vs_oriAlgo", drawStyle="COLZ", adjustMarginLeft=0.1, adjustMarginRight=0.1, **_algos_common)) _dupandfakePtEtaPhi = PlotGroup("dupandfakePtEtaPhi", [ Plot("fakeratePt", xtitle="track p_{T} (GeV)", ytitle="fakerate vs p_{T}", xlog=True, ymax=_maxFake), Plot("duplicatesRate_Pt", xtitle="track p_{T} (GeV)", ytitle="duplicates rate vs p_{T}", ymax=_maxFake, xlog=True), Plot("pileuprate_Pt", xtitle="track p_{T} (GeV)", ytitle="pileup rate vs p_{T}", ymax=_maxFake, xlog=True), Plot("fakerate", xtitle="track #eta", ytitle="fakerate vs #eta", title="", ymax=_maxFake), Plot("duplicatesRate", xtitle="track #eta", ytitle="duplicates rate vs #eta", title="", ymax=_maxFake), Plot("pileuprate", xtitle="track #eta", ytitle="pileup rate vs #eta", title="", ymax=_maxFake), ] + _makeFakeDupPileupPlots("phi", "#phi"), ncols=3 ) _dupandfakeDxyDzBS = PlotGroup("dupandfakeDxyDzBS", _makeFakeDupPileupPlots("dxy" , "dxy" , "cm") + _makeFakeDupPileupPlots("dz" , "dz" , "cm"), ncols=3, legendDy=_legendDy_2rows_3cols ) _dupandfakeDxyDzPV = PlotGroup("dupandfakeDxyDzPV", _makeFakeDupPileupPlots("dxypv" , "dxy(PV)", "cm") + _makeFakeDupPileupPlots("dxypv_zoomed", "dxy(PV)", "cm") + _makeFakeDupPileupPlots("dzpv" , "dz(PV)" , "cm") + _makeFakeDupPileupPlots("dzpv_zoomed" , "dz(PV)" , "cm"), ncols=3, legendDy=_legendDy_4rows ) _dupandfakeHitsLayers = PlotGroup("dupandfakeHitsLayers", _makeFakeDupPileupPlots("hit" , "hits" , common=dict(xmin=_minHits , xmax=_maxHits)) + _makeFakeDupPileupPlots("layer" , "layers" , common=dict(xmin=_minLayers , xmax=_maxLayers)) + _makeFakeDupPileupPlots("pixellayer", "pixel layers", common=dict( xmax=_maxPixelLayers)) + _makeFakeDupPileupPlots("3Dlayer" , "3D layers" , common=dict(xmin=_min3DLayers, xmax=_max3DLayers)), ncols=3, legendDy=_legendDy_4rows ) _dupandfakePos = PlotGroup("dupandfakePos", _makeFakeDupPileupPlots("vertpos", "r", "cm", xquantity="ref. point r (cm)", common=dict(xlog=True)) + _makeFakeDupPileupPlots("zpos" , "z", "cm", xquantity="ref. point z (cm)") + _makeFakeDupPileupPlots("simpvz" , "Sim. PV z", xtitle="Sim. PV z (cm)", common=dict(xmin=_minZ, xmax=_maxZ)), ncols=3, ) _dupandfakeDeltaRPU = PlotGroup("dupandfakeDeltaRPU", _makeFakeDupPileupPlots("dr" , "#DeltaR", xquantity="min #DeltaR", common=dict(xlog=True)) + _makeFakeDupPileupPlots("drj" , "#DeltaR(track, jet)", xtitle="#DeltaR(track, jet)", common=dict(xlog=True, xmax=_maxDRJ)) + _makeFakeDupPileupPlots("pu" , "PU" , xtitle="Pileup", common=dict(xmin=_minPU, xmax=_maxPU)), ncols=3 ) _seedingLayerSet_common = dict(removeEmptyBins=True, xbinlabelsize=8, xbinlabeloption="d", adjustMarginRight=0.1) _dupandfakeSeedingPlots = _makeFakeDupPileupPlots("seedingLayerSet", "seeding layers", xtitle="", common=_seedingLayerSet_common) _dupandfakeChi2Seeding = PlotGroup("dupandfakeChi2Seeding", _makeFakeDupPileupPlots("chi2", "#chi^{2}") + _dupandfakeSeedingPlots, ncols=3, legendDy=_legendDy_2rows_3cols ) _common = { "ytitle": "Fake+pileup rate", "ymax": _maxFake, "drawStyle": "EP", } _common2 = {} _common2.update(_common) _common2["drawStyle"] = "pcolz" _common2["ztitleoffset"] = 1.5 _common2["xtitleoffset"] = 7 _common2["ytitleoffset"] = 10 _common2["ztitleoffset"] = 6 _pvassociation1 = PlotGroup("pvassociation1", [ Plot(ROC("effic_vs_fakepileup_dzpvcut", "effic_vs_dzpvcut", FakeDuplicate("fakepileup_vs_dzpvcut", assoc="num_assoc(recoToSim)_dzpvcut", reco="num_reco_dzpvcut", dup="num_pileup_dzpvcut")), xtitle="Efficiency vs. cut on dz(PV)", **_common), Plot(ROC("effic_vs_fakepileup2_dzpvcut", "effic_vs_dzpvcut", FakeDuplicate("fakepileup_vs_dzpvcut", assoc="num_assoc(recoToSim)_dzpvcut", reco="num_reco_dzpvcut", dup="num_pileup_dzpvcut"), zaxis=True), xtitle="Efficiency", ztitle="Cut on dz(PV)", **_common2), # Plot(ROC("effic_vs_fakepileup_dzpvsigcut", "effic_vs_dzpvsigcut", FakeDuplicate("fakepileup_vs_dzpvsigcut", assoc="num_assoc(recoToSim)_dzpvsigcut", reco="num_reco_dzpvsigcut", dup="num_pileup_dzpvsigcut")), xtitle="Efficiency vs. cut on dz(PV)/dzError", **_common), Plot(ROC("effic_vs_fakepileup2_dzpvsigcut", "effic_vs_dzpvsigcut", FakeDuplicate("fakepileup_vs_dzpvsigcut", assoc="num_assoc(recoToSim)_dzpvsigcut", reco="num_reco_dzpvsigcut", dup="num_pileup_dzpvsigcut"), zaxis=True), xtitle="Efficiency", ztitle="Cut on dz(PV)/dzError", **_common2), ], onlyForPileup=True, legendDy=_legendDy_4rows ) _pvassociation2 = PlotGroup("pvassociation2", [ Plot("effic_vs_dzpvcut", xtitle="Cut on dz(PV) (cm)", ytitle="Efficiency vs. cut on dz(PV)", ymax=_maxEff), Plot("effic_vs_dzpvcut2", xtitle="Cut on dz(PV) (cm)", ytitle="Efficiency (excl. trk eff)", ymax=_maxEff), Plot("fakerate_vs_dzpvcut", xtitle="Cut on dz(PV) (cm)", ytitle="Fake rate vs. cut on dz(PV)", ymax=_maxFake), Plot("pileuprate_dzpvcut", xtitle="Cut on dz(PV) (cm)", ytitle="Pileup rate vs. cut on dz(PV)", ymax=_maxFake), # Plot("effic_vs_dzpvsigcut", xtitle="Cut on dz(PV)/dzError", ytitle="Efficiency vs. cut on dz(PV)/dzError", ymax=_maxEff), Plot("effic_vs_dzpvsigcut2", xtitle="Cut on dz(PV)/dzError", ytitle="Efficiency (excl. trk eff)", ymax=_maxEff), Plot("fakerate_vs_dzpvsigcut", xtitle="Cut on dz(PV)/dzError", ytitle="Fake rate vs. cut on dz(PV)/dzError", ymax=_maxFake), Plot("pileuprate_dzpvsigcut", xtitle="Cut on dz(PV)/dzError", ytitle="Pileup rate vs. cut on dz(PV)/dzError", ymax=_maxFake), ], onlyForPileup=True, legendDy=_legendDy_4rows ) # These don't exist in FastSim _common = {"normalizeToUnitArea": True, "stat": True, "drawStyle": "hist"} _dedx = PlotGroup("dedx", [ Plot("h_dedx_estim1", xtitle="dE/dx, harm2", **_common), Plot("h_dedx_estim2", xtitle="dE/dx, trunc40", **_common), Plot("h_dedx_nom1", xtitle="dE/dx number of measurements", title="", **_common), Plot("h_dedx_sat1", xtitle="dE/dx number of measurements with saturation", title="", **_common), ], legendDy=_legendDy_2rows ) _chargemisid = PlotGroup("chargemisid", [ Plot("chargeMisIdRate", xtitle="#eta", ytitle="charge mis-id rate vs #eta", ymax=0.05), Plot("chargeMisIdRate_Pt", xtitle="p_{T}", ytitle="charge mis-id rate vs p_{T}", xmax=300, ymax=0.1, xlog=True), Plot("chargeMisIdRate_hit", xtitle="hits", ytitle="charge mis-id rate vs hits", title=""), Plot("chargeMisIdRate_phi", xtitle="#phi", ytitle="charge mis-id rate vs #phi", title="", ymax=0.01), Plot("chargeMisIdRate_dxy", xtitle="dxy", ytitle="charge mis-id rate vs dxy", ymax=0.1), Plot("chargeMisIdRate_dz", xtitle="dz", ytitle="charge mis-id rate vs dz", ymax=0.1) ]) _common = {"stat": True, "normalizeToUnitArea": True, "ylog": True, "ymin": 1e-6, "drawStyle": "hist"} _hitsAndPt = PlotGroup("hitsAndPt", [ Plot("missing_inner_layers", xmin=_minLayers, xmax=_maxLayers, ymax=1, **_common), Plot("missing_outer_layers", xmin=_minLayers, xmax=_maxLayers, ymax=1, **_common), Plot("hits_eta", xtitle="track #eta", ytitle="<hits> vs #eta", ymin=_minHits, ymax=_maxHits, statyadjust=[0,0,-0.15], fallback={"name": "nhits_vs_eta", "profileX": True}), Plot("hits", stat=True, xtitle="track hits", xmin=_minHits, xmax=_maxHits, ylog=True, ymin=[5e-1, 5, 5e1, 5e2, 5e3], drawStyle="hist"), Plot("num_simul_pT", xtitle="TP p_{T}", xlog=True, ymax=[1e-1, 2e-1, 5e-1, 1], **_common), Plot("num_reco_pT", xtitle="track p_{T}", xlog=True, ymax=[1e-1, 2e-1, 5e-1, 1], **_common) ]) _tuning = PlotGroup("tuning", [ Plot("chi2", stat=True, normalizeToUnitArea=True, ylog=True, ymin=1e-6, ymax=[0.1, 0.2, 0.5, 1.0001], drawStyle="hist", xtitle="#chi^{2}", ratioUncertainty=False), Plot("chi2_prob", stat=True, normalizeToUnitArea=True, drawStyle="hist", xtitle="Prob(#chi^{2})"), Plot("chi2mean", title="", xtitle="#eta", ytitle="< #chi^{2} / ndf >", ymin=[0, 0.5], ymax=[2, 2.5, 3, 5], fallback={"name": "chi2_vs_eta", "profileX": True}), Plot("ptres_vs_eta_Mean", scale=100, title="", xtitle="TP #eta (PCA to beamline)", ytitle="< #delta p_{T} / p_{T} > (%)", ymin=_minResidualPt, ymax=_maxResidualPt), Plot("chi2mean_vs_pt", title="", xtitle="p_{T}", ytitle="< #chi^{2} / ndf >", ymin=[0, 0.5], ymax=[2, 2.5, 3, 5], xlog=True, fallback={"name": "chi2_vs_pt", "profileX": True}), Plot("chi2mean_vs_drj", title="", xtitle="#DeltaR(track, jet)", ytitle="< #chi^{2} / ndf >", ymin=[0, 0.5], ymax=[2, 2.5, 3, 5], xlog=True, xmax=_maxDRJ, fallback={"name": "chi2_vs_drj", "profileX": True}), Plot("ptres_vs_pt_Mean", title="", xtitle="p_{T}", ytitle="< #delta p_{T}/p_{T} > (%)", scale=100, ymin=_minResidualPt, ymax=_maxResidualPt,xlog=True) ], legendDy=_legendDy_4rows ) _common = {"stat": True, "fit": True, "normalizeToUnitArea": True, "drawStyle": "hist", "drawCommand": "", "xmin": -10, "xmax": 10, "ylog": True, "ymin": 5e-5, "ymax": [0.01, 0.05, 0.1, 0.2, 0.5, 0.8, 1.025], "ratioUncertainty": False} _pulls = PlotGroup("pulls", [ Plot("pullPt", **_common), Plot("pullQoverp", **_common), Plot("pullPhi", **_common), Plot("pullTheta", **_common), Plot("pullDxy", **_common), Plot("pullDz", **_common), ], legendDx=0.1, legendDw=-0.1, legendDh=-0.015 ) _common = {"title": "", "ylog": True, "xtitle": "TP #eta (PCA to beamline)", "ymin": _minMaxResol, "ymax": _minMaxResol} _resolutionsEta = PlotGroup("resolutionsEta", [ Plot("phires_vs_eta_Sigma", ytitle="#sigma(#delta #phi) (rad)", **_common), Plot("cotThetares_vs_eta_Sigma", ytitle="#sigma(#delta cot(#theta))", **_common), Plot("dxyres_vs_eta_Sigma", ytitle="#sigma(#delta d_{xy}) (cm)", **_common), Plot("dzres_vs_eta_Sigma", ytitle="#sigma(#delta d_{z}) (cm)", **_common), Plot("ptres_vs_eta_Sigma", ytitle="#sigma(#delta p_{T}/p_{T})", **_common), ]) _common = {"title": "", "ylog": True, "xlog": True, "xtitle": "TP p_{T} (PCA to beamline)", "xmin": 0.1, "xmax": 1000, "ymin": _minMaxResol, "ymax": _minMaxResol} _resolutionsPt = PlotGroup("resolutionsPt", [ Plot("phires_vs_pt_Sigma", ytitle="#sigma(#delta #phi) (rad)", **_common), Plot("cotThetares_vs_pt_Sigma", ytitle="#sigma(#delta cot(#theta))", **_common), Plot("dxyres_vs_pt_Sigma", ytitle="#sigma(#delta d_{xy}) (cm)", **_common), Plot("dzres_vs_pt_Sigma", ytitle="#sigma(#delta d_{z}) (cm)", **_common), Plot("ptres_vs_pt_Sigma", ytitle="#sigma(#delta p_{T}/p_{T})", **_common), ]) _common = {"title": "", "ylog": True, "xtitle": "TP #Phi (PCA to beamline)", "ymin": _minMaxResol, "ymax": _minMaxResol} _resolutionsPhi = PlotGroup("resolutionsPhi", [ Plot("dxyres_vs_phi_Sigma", ytitle="#sigma(#delta d_{xy}) (cm)", **_common), Plot("dzres_vs_phi_Sigma", ytitle="#sigma(#delta d_{z}) (cm)", **_common), Plot("phires_vs_phi_Sigma", ytitle="#sigma(#delta #phi) (rad)", **_common), Plot("ptres_vs_phi_Sigma", ytitle="#sigma(#delta p_{T}/p_{T})", **_common), ]) ## Extended set of plots _extDistPtEtaPhi = PlotGroup("distPtEtaPhi", _makeDistPlots("pT", "p_{T} (GeV)", common=dict(xlog=True)) + _makeDistPlots("eta", "#eta") + _makeDistPlots("phi", "#phi"), ncols=4) _extDistDxyDzBS = PlotGroup("distDxyDzBS", _makeDistPlots("dxy" , "dxy (cm)") + _makeDistPlots("dz" , "dz (cm)"), ncols=4, legendDy=_legendDy_2rows) _extDistDxyDzPV = PlotGroup("distDxyDzPV", _makeDistPlots("dxypv" , "dxy(PV) (cm)") + _makeDistPlots("dxypv_zoomed", "dxy(PV) (cm)") + _makeDistPlots("dzpv" , "dz(PV) (cm)") + _makeDistPlots("dzpv_zoomed" , "dz(PV) (cm)"), ncols=4, legendDy=_legendDy_4rows) _extDistHitsLayers = PlotGroup("distHitsLayers", _makeDistPlots("hit" , "hits" , common=dict(xmin=_minHits , xmax=_maxHits)) + _makeDistPlots("layer" , "layers" , common=dict(xmin=_minLayers , xmax=_maxLayers)) + _makeDistPlots("pixellayer", "pixel layers", common=dict( xmax=_maxPixelLayers)) + _makeDistPlots("3Dlayer" , "3D layers" , common=dict(xmin=_min3DLayers, xmax=_max3DLayers)), ncols=4, legendDy=_legendDy_4rows, ) _extDistPos = PlotGroup("distPos", _makeDistPlots("vertpos", "ref. point r (cm)", common=dict(xlog=True)) + _makeDistPlots("zpos" , "ref. point z (cm)") + _makeDistPlots("simpvz" , "Sim. PV z (cm)", common=dict(xmin=_minZ, xmax=_maxZ)), ncols=3, ) _extDistDeltaR = PlotGroup("distDeltaR", _makeDistPlots("dr" , "min #DeltaR", common=dict(xlog=True)) + _makeDistPlots("drj" , "#DeltaR(track, jet)", common=dict(xlog=True, xmax=_maxDRJ)), ncols=2, legendDy=_legendDy_2rows, ) _extDistSeedingPlots = _makeDistPlots("seedingLayerSet", "seeding layers", common=dict(xtitle="", **_seedingLayerSet_common)) _extDistChi2Seeding = PlotGroup("distChi2Seeding", _makeDistPlots("chi2", "#chi^{2}") + _extDistSeedingPlots, ncols=4, legendDy=_legendDy_2rows_3cols ) _common = dict(title="", xtitle="TP #eta (PCA to beamline)") _extResidualEta = PlotGroup("residualEta", [ Plot("phires_vs_eta_Mean", ytitle="< #delta #phi > (rad)", ymin=_minResidualPhi, ymax=_maxResidualPhi, **_common), Plot("cotThetares_vs_eta_Mean", ytitle="< #delta cot(#theta) >", ymin=_minResidualCotTheta, ymax=_maxResidualCotTheta, **_common), Plot("dxyres_vs_eta_Mean", ytitle="< #delta d_{xy} > (#mum)", scale=10000, ymin=_minResidualDxy, ymax=_maxResidualDxy, **_common), Plot("dzres_vs_eta_Mean", ytitle="< #delta d_{z} > (#mum)", scale=10000, ymin=_minResidualDz, ymax=_maxResidualDz, **_common), Plot("ptres_vs_eta_Mean", ytitle="< #delta p_{T}/p_{T} > (%)", scale=100, ymin=_minResidualPt, ymax=_maxResidualPt, **_common), # same as in tuning, but to be complete ]) _common = dict(title="", xlog=True, xtitle="TP p_{T} (PCA to beamline)", xmin=0.1, xmax=1000) _extResidualPt = PlotGroup("residualPt", [ Plot("phires_vs_pt_Mean", ytitle="< #delta #phi > (rad)", ymin=_minResidualPhi, ymax=_maxResidualPhi, **_common), Plot("cotThetares_vs_pt_Mean", ytitle="< #delta cot(#theta > )", ymin=_minResidualCotTheta, ymax=_maxResidualCotTheta, **_common), Plot("dxyres_vs_pt_Mean", ytitle="< #delta d_{xy} > (#mum)", scale=10000, ymin=_minResidualDxy, ymax=_maxResidualDxy, **_common), Plot("dzres_vs_pt_Mean", ytitle="< #delta d_{z} > (#mum)", scale=10000, ymin=_minResidualDz, ymax=_maxResidualDz, **_common), Plot("ptres_vs_pt_Mean", ytitle="< #delta p_{T}/p_{T} > (%)", scale=100, ymin=_minResidualPt, ymax=_maxResidualPt, **_common), # same as in tuning, but to be complete ]) _common = dict(title="", ytitle="Selected tracks/TrackingParticles", ymax=_maxEff) _extNrecVsNsim = PlotGroup("nrecVsNsim", [ Plot("nrec_vs_nsim", title="", xtitle="TrackingParticles", ytitle="Tracks", profileX=True, xmin=_minMaxTracks, xmax=_minMaxTracks, ymin=_minMaxTracks, ymax=_minMaxTracks), Plot("nrecPerNsim_vs_pu", xtitle="Pileup", xmin=_minPU, xmax=_maxPU, **_common), Plot("nrecPerNsimPt", xtitle="p_{T} (GeV)", xlog=True, **_common), Plot("nrecPerNsim", xtitle="#eta", **_common) ], legendDy=_legendDy_2rows) _extHitsLayers = PlotGroup("hitsLayers", [ Plot("PXLhits_vs_eta", xtitle="#eta", ytitle="<pixel hits>"), Plot("PXLlayersWithMeas_vs_eta", xtitle="#eta", ytitle="<pixel layers>"), Plot("STRIPhits_vs_eta", xtitle="#eta", ytitle="<strip hits>"), Plot("STRIPlayersWithMeas_vs_eta", xtitle="#eta", ytitle="<strip layers>"), ], legendDy=_legendDy_2rows) ## Extended set of plots also for simulation _extDistSimPtEtaPhi = PlotGroup("distsimPtEtaPhi", _makeDistSimPlots("pT", "p_{T} (GeV)", common=dict(xlog=True)) + _makeDistSimPlots("eta", "#eta") + _makeDistSimPlots("phi", "#phi"), ncols=2) _extDistSimDxyDzBS = PlotGroup("distsimDxyDzBS", _makeDistSimPlots("dxy" , "dxy (cm)") + _makeDistSimPlots("dz" , "dz (cm)"), ncols=2, legendDy=_legendDy_2rows) _extDistSimDxyDzPV = PlotGroup("distsimDxyDzPV", _makeDistSimPlots("dxypv" , "dxy(PV) (cm)") + _makeDistSimPlots("dxypv_zoomed", "dxy(PV) (cm)") + _makeDistSimPlots("dzpv" , "dz(PV) (cm)") + _makeDistSimPlots("dzpv_zoomed" , "dz(PV) (cm)"), ncols=2, legendDy=_legendDy_4rows) _extDistSimHitsLayers = PlotGroup("distsimHitsLayers", _makeDistSimPlots("hit" , "hits" , common=dict(xmin=_minHits , xmax=_maxHits)) + _makeDistSimPlots("layer" , "layers" , common=dict(xmin=_minLayers , xmax=_maxLayers)) + _makeDistSimPlots("pixellayer", "pixel layers", common=dict( xmax=_maxPixelLayers)) + _makeDistSimPlots("3Dlayer" , "3D layers" , common=dict(xmin=_min3DLayers, xmax=_max3DLayers)), ncols=2, legendDy=_legendDy_4rows, ) _extDistSimPos = PlotGroup("distsimPos", _makeDistSimPlots("vertpos", "vert r (cm)", common=dict(xlog=True)) + _makeDistSimPlots("zpos" , "vert z (cm)") + _makeDistSimPlots("simpvz" , "Sim. PV z (cm)", common=dict(xmin=_minZ, xmax=_maxZ)), ncols=3, ) _extDistSimDeltaR = PlotGroup("distsimDeltaR", _makeDistSimPlots("dr" , "min #DeltaR", common=dict(xlog=True)) + _makeDistSimPlots("drj" , "#DeltaR(TP, jet)", common=dict(xlog=True, xmax=_maxDRJ)), ncols=2, legendDy=_legendDy_2rows, ) ######################################## # # Summary plots # ######################################## _possibleTrackingNonIterationColls = [ 'ak4PFJets', 'btvLike', ] _possibleTrackingColls = [ 'initialStepPreSplitting', 'initialStep', 'highPtTripletStep', # phase1 'detachedQuadStep', # phase1 'detachedTripletStep', 'lowPtQuadStep', # phase1 'lowPtTripletStep', 'pixelPairStepA', # seeds 'pixelPairStepB', # seeds 'pixelPairStepC', # seeds 'pixelPairStep', 'mixedTripletStepA', # seeds 'mixedTripletStepB', # seeds 'mixedTripletStep', 'pixelLessStep', 'tobTecStepPair', # seeds 'tobTecStepTripl', # seeds 'tobTecStep', 'displacedGeneralStep', 'jetCoreRegionalStep', 'muonSeededStepInOut', 'muonSeededStepOutIn', 'displacedRegionalStepPair', # seeds 'displacedRegionalStepTripl', # seeds 'displacedRegionalStep', 'duplicateMerge', ] + _possibleTrackingNonIterationColls _possibleTrackingCollsOld = { "Zero" : "iter0", "First" : "iter1", "Second": "iter2", "Third" : "iter3", "Fourth": "iter4", "Fifth" : "iter5", "Sixth" : "iter6", "Seventh": "iter7", "Ninth" : "iter9", "Tenth" : "iter10", } def _trackingSubFoldersFallbackSLHC_Phase1PU140(subfolder): ret = subfolder.replace("trackingParticleRecoAsssociation", "AssociatorByHitsRecoDenom") for (old, new) in [("InitialStep", "Zero"), ("HighPtTripletStep", "First"), ("LowPtQuadStep", "Second"), ("LowPtTripletStep", "Third"), ("DetachedQuadStep", "Fourth"), ("PixelPairStep", "Fifth"), ("MuonSeededStepInOut", "Ninth"), ("MuonSeededStepOutIn", "Tenth")]: ret = ret.replace(old, new) if ret == subfolder: return None return ret def _trackingRefFileFallbackSLHC_Phase1PU140(path): for (old, new) in [("initialStep", "iter0"), ("highPtTripletStep", "iter1"), ("lowPtQuadStep", "iter2"), ("lowPtTripletStep", "iter3"), ("detachedQuadStep", "iter4"), ("pixelPairStep", "iter5"), ("muonSeededStepInOut", "iter9"), ("muonSeededStepOutIn", "iter10")]: path = path.replace(old, new) return path def _trackingSubFoldersFallbackFromPV(subfolder): return subfolder.replace("trackingParticleRecoAsssociation", "trackingParticleRecoAsssociationSignal") def _trackingSubFoldersFallbackConversion(subfolder): return subfolder.replace("quickAssociatorByHits", "quickAssociatorByHitsConversion") def _trackingSubFoldersFallbackPreSplitting(subfolder): return subfolder.replace("quickAssociatorByHits", "quickAssociatorByHitsPreSplitting") # Additional "quality" flags than highPurity. In a separate list to # allow customization. _additionalTrackQualities = [ "Pt09", "ByOriginalAlgo", "ByAlgoMask" ] def _mapCollectionToAlgoQuality(collName): if "Hp" in collName: quality = "highPurity" else: quality = "" collNameNoQuality = collName.replace("Hp", "") for qual in _additionalTrackQualities: if qual in collName: quality += qual collNameNoQuality = collNameNoQuality.replace(qual, "") collNameNoQuality = collNameNoQuality.replace("Tracks", "", 1) # make summary naming consistent with iteration folders collNameLow = collNameNoQuality.lower().replace("frompv2", "").replace("frompv", "").replace("frompvalltp", "").replace("alltp", "") if collNameLow.find("seed") == 0: collNameLow = collNameLow[4:] if collNameLow == "initialstepseedspresplitting": collNameLow = "initialsteppresplittingseeds" elif collNameLow == "muonseededseedsinout": collNameLow = "muonseededstepinoutseeds" elif collNameLow == "muonseededseedsoutin": collNameLow = "muonseededstepoutinseeds" i_seeds = collNameLow.index("seeds") quality = collNameLow[i_seeds:]+quality collNameLow = collNameLow[:i_seeds] algo = None prefixes = ["cutsreco", "cutsrecofrompv", "cutsrecofrompv2", "cutsrecofrompvalltp", "cutsrecoetagreater2p7"] if collNameLow in ["general", "generalfrompv", "generaletagreater2p7"]+prefixes: algo = "ootb" elif collNameLow in ["pixel", "pixelfrompv", "pixelfrompvalltp"]: algo = "pixel" else: def testColl(coll): for pfx in prefixes: if coll == collNameLow.replace(pfx, ""): return True return False for coll in _possibleTrackingColls: if testColl(coll.lower()): algo = coll break # next try "old style" if algo is None: for coll, name in _possibleTrackingCollsOld.items(): if testColl(coll.lower()): algo = name break # fallback if algo is None: algo = collNameNoQuality # fix for track collection naming convention if algo == "muonSeededInOut": algo = "muonSeededStepInOut" if algo == "muonSeededOutIn": algo = "muonSeededStepOutIn" return (algo, quality) def _collhelper(name): return (name, [name]) _collLabelMap = collections.OrderedDict(map(_collhelper, ["generalTracks"]+_possibleTrackingColls)) _collLabelMapHp = collections.OrderedDict(map(_collhelper, ["generalTracks"]+[n for n in _possibleTrackingColls if "Step" in n])) def _summaryBinRename(binLabel, highPurity, byOriginalAlgo, byAlgoMask, ptCut, seeds): (algo, quality) = _mapCollectionToAlgoQuality(binLabel) if algo == "ootb": algo = "generalTracks" ret = None if byOriginalAlgo: if algo != "generalTracks" and "ByOriginalAlgo" not in quality: # keep generalTracks bin as well return None quality = quality.replace("ByOriginalAlgo", "") if byAlgoMask: if algo != "generalTracks" and "ByAlgoMask" not in quality: # keep generalTracks bin as well return None quality = quality.replace("ByAlgoMask", "") if ptCut: if "Pt09" not in quality: return None quality = quality.replace("Pt09", "") if highPurity: if quality == "highPurity": ret = algo elif seeds: i_seeds = quality.find("seeds") if i_seeds == 0: ret = algo seedSubColl = quality[i_seeds+5:] if seedSubColl != "": ret += seedSubColl[0].upper() + seedSubColl[1:] else: if quality == "": ret = algo return ret def _constructSummary(mapping=None, highPurity=False, byOriginalAlgo=False, byAlgoMask=False, ptCut=False, seeds=False, midfix=""): _common = {"drawStyle": "EP", "xbinlabelsize": 10, "xbinlabeloption": "d"} _commonN = dict(ylog=True, ymin=_minMaxN, ymax=_minMaxN, normalizeToNumberOfEvents=True, ) _commonN.update(_common) _commonAB = dict(mapping=mapping, renameBin=lambda bl: _summaryBinRename(bl, highPurity, byOriginalAlgo, byAlgoMask, ptCut, seeds), ignoreMissingBins=True, originalOrder=True, ) if byOriginalAlgo or byAlgoMask: _commonAB["minExistingBins"] = 2 prefix = "summary"+midfix h_eff = "effic_vs_coll" h_fakerate = "fakerate_vs_coll" h_duplicaterate = "duplicatesRate_coll" h_pileuprate = "pileuprate_coll" h_reco = "num_reco_coll" h_true = "num_assoc(recoToSim)_coll" h_fake = Subtract("num_fake_coll_orig", "num_reco_coll", "num_assoc(recoToSim)_coll") h_duplicate = "num_duplicate_coll" h_pileup = "num_pileup_coll" if mapping is not None: h_eff = AggregateBins("efficiency", h_eff, **_commonAB) h_fakerate = AggregateBins("fakerate", h_fakerate, **_commonAB) h_duplicaterate = AggregateBins("duplicatesRate", h_duplicaterate, **_commonAB) h_pileuprate = AggregateBins("pileuprate", h_pileuprate, **_commonAB) h_reco = AggregateBins("num_reco_coll", h_reco, **_commonAB) h_true = AggregateBins("num_true_coll", h_true, **_commonAB) h_fake = AggregateBins("num_fake_coll", h_fake, **_commonAB) h_duplicate = AggregateBins("num_duplicate_coll", h_duplicate, **_commonAB) h_pileup = AggregateBins("num_pileup_coll", h_pileup, **_commonAB) summary = PlotGroup(prefix, [ Plot(h_eff, title="Efficiency vs collection", ytitle="Efficiency", ymin=1e-3, ymax=1, ylog=True, **_common), Plot(h_fakerate, title="Fakerate vs collection", ytitle="Fake rate", ymax=_maxFake, **_common), # Plot(h_duplicaterate, title="Duplicates rate vs collection", ytitle="Duplicates rate", ymax=_maxFake, **_common), Plot(h_pileuprate, title="Pileup rate vs collection", ytitle="Pileup rate", ymax=_maxFake, **_common), ], legendDy=_legendDy_2rows ) summaryN = PlotGroup(prefix+"_ntracks", [ # FIXME #Plot(h_reco, ytitle="Tracks/event", title="Number of tracks/event vs collection", **_commonN), #Plot(h_true, ytitle="True tracks/event", title="Number of true tracks/event vs collection", **_commonN), #Plot(h_fake, ytitle="Fake tracks/event", title="Number of fake tracks/event vs collection", **_commonN), #Plot(h_duplicate, ytitle="Duplicate tracks/event", title="Number of duplicate tracks/event vs collection", **_commonN), #Plot(h_pileup, ytitle="Pileup tracks/event", title="Number of pileup tracks/event vs collection", **_commonN), Plot(h_reco, ytitle="Tracks", title="Number of tracks vs collection", **_commonN), Plot(h_true, ytitle="True tracks", title="Number of true tracks vs collection", **_commonN), Plot(h_fake, ytitle="Fake tracks", title="Number of fake tracks vs collection", **_commonN), Plot(h_duplicate, ytitle="Duplicate tracks", title="Number of duplicate tracks vs collection", **_commonN), Plot(h_pileup, ytitle="Pileup tracks", title="Number of pileup tracks vs collection", **_commonN), ]) return (summary, summaryN) (_summaryRaw, _summaryRawN) = _constructSummary(midfix="Raw") (_summary, _summaryN) = _constructSummary(_collLabelMap) (_summaryHp, _summaryNHp) = _constructSummary(_collLabelMapHp, highPurity=True) (_summaryByOriginalAlgo, _summaryByOriginalAlgoN) = _constructSummary(_collLabelMapHp, byOriginalAlgo=True, midfix="ByOriginalAlgo") (_summaryByOriginalAlgoHp, _summaryByOriginalAlgoNHp) = _constructSummary(_collLabelMapHp, byOriginalAlgo=True, midfix="ByOriginalAlgo", highPurity=True) (_summaryByAlgoMask, _summaryByAlgoMaskN) = _constructSummary(_collLabelMapHp, byAlgoMask=True, midfix="ByAlgoMask") (_summaryByAlgoMaskHp, _summaryByAlgoMaskNHp) = _constructSummary(_collLabelMapHp, byAlgoMask=True, midfix="ByAlgoMask", highPurity=True) (_summaryPt09, _summaryPt09N) = _constructSummary(_collLabelMap, ptCut=True, midfix="Pt09") (_summaryPt09Hp, _summaryPt09NHp) = _constructSummary(_collLabelMap, ptCut=True, midfix="Pt09", highPurity=True) (_summarySeeds, _summarySeedsN) = _constructSummary(_collLabelMapHp, seeds=True) ######################################## # # PackedCandidate plots # ######################################## _common = {"normalizeToUnitArea": True, "ylog": True, "ymin": [1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2], "ymax": [1e-2, 1e-1, 1.1]} _commonStatus = {} _commonStatus.update(_common) _commonStatus.update({"xbinlabelsize": 10, "xbinlabeloption": "d", "drawStyle": "hist", "adjustMarginRight": 0.08}) _commonLabelSize = {} _commonLabelSize.update(_common) _commonLabelSize.update({"xlabelsize": 17}) _packedCandidateFlow = PlotGroup("flow", [ Plot("selectionFlow", xbinlabelsize=10, xbinlabeloption="d", adjustMarginRight=0.1, drawStyle="hist", ylog=True, ymin=[0.9, 9, 9e1, 9e2, 9e3, 9e4, 9e5, 9e6, 9e7]), Plot("diffCharge", xtitle="Charge", **_common), Plot("diffIsHighPurity", xtitle="High purity status", **_common), Plot("diffNdof", xtitle="ndof", **_common), Plot("diffNormalizedChi2", xtitle="#chi^{2}/ndof", **_common), ]) _packedCandidateHitsHitPattern = PlotGroup("hitsHitPattern", [ Plot("diffHitPatternNumberOfValidHits", xtitle="Valid hits (via HitPattern)", **_common), Plot("diffHitPatternNumberOfValidPixelHits", xtitle="Valid pixel hits (via HitPattern)", **_common), Plot("diffHitPatternHasValidHitInFirstPixelBarrel", xtitle="Has valid hit in BPix1 layer (via HitPattern)", **_common), Plot("diffHitPatternNumberOfLostPixelHits", xtitle="Lost pixel hits (via HitPattern)", **_common), ], legendDy=_legendDy_2rows ) _packedCandidateHits = PlotGroup("hits", [ Plot("diffNumberOfHits", xtitle="Hits", **_common), Plot("diffNumberOfPixelHits", xtitle="Pixel hits", **_common), Plot("diffLostInnerHits", xtitle="Lost inner hits", **_common), Plot("numberHitsOverMax", xtitle="Number of overflown hits", **_common), Plot("numberPixelHitsOverMax", xtitle="Number of overflown pixel hits", **_common), Plot("numberStripHitsOverMax", xtitle="Number of overflown strip hits", **_common), ], ncols=3, legendDy=_legendDy_2rows_3cols ) _packedCandidateLayers = PlotGroup("layers", [ PlotEmpty(), Plot("diffNumberOfPixelLayers", xtitle="Pixel layers", **_common), Plot("diffNumberOfStripLayers", xtitle="Strip layers", **_common), # Plot("diffHitPatternTrackerLayersWithMeasurement", xtitle="Layers (via HitPattern)", **_common), Plot("diffHitPatternPixelLayersWithMeasurement", xtitle="Pixel layers (via HitPattern)", **_common), Plot("diffHitPatternStripLayersWithMeasurement", xtitle="Strip layers (via HitPattern)", **_common), # Plot("numberLayersOverMax", xtitle="Number of overflown layers", **_common), Plot("numberPixelLayersOverMax", xtitle="Number of overflown pixel layers", **_common), Plot("numberStripLayersOverMax", xtitle="Number of overflown strip layers", **_common), ], ncols=3 ) _packedCandidateImpactParameter1 = PlotGroup("impactParameter1", [ Plot("diffDxyAssocPV", xtitle="dxy(assocPV)", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffDxyAssocPVStatus", **_commonStatus), Plot("diffDxyAssocPVUnderOverFlowSign", xtitle="dxy(assocPV)", **_common), Plot("diffDzAssocPV", xtitle="dz(assocPV)", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffDzAssocPVStatus", **_commonStatus), Plot("diffDzAssocPVUnderOverFlowSign", xtitle="dz(assocPV)", **_common), Plot("diffDxyError", xtitle="dxyError()", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffDszError", xtitle="dszError()", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffDzError", xtitle="dzError()", adjustMarginRight=0.02, **_commonLabelSize), ], ncols=3 ) _packedCandidateImpactParameter2 = PlotGroup("impactParameter2", [ Plot("diffDxyPV", xtitle="dxy(PV) via PC", **_commonLabelSize), Plot("diffDzPV", xtitle="dz(PV) via PC", **_commonLabelSize), Plot("diffTrackDxyAssocPV", xtitle="dxy(PV) via PC::bestTrack()", **_commonLabelSize), Plot("diffTrackDzAssocPV", xtitle="dz(PV) via PC::bestTrack()", **_commonLabelSize), Plot("diffTrackDxyError", xtitle="dxyError() via PC::bestTrack()", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffTrackDzError", xtitle="dzError() via PC::bestTrack()", **_commonLabelSize), ]) _packedCandidateCovarianceMatrix1 = PlotGroup("covarianceMatrix1", [ Plot("diffCovQoverpQoverp", xtitle="cov(qoverp, qoverp)", **_commonLabelSize), Plot("diffCovQoverpQoverpStatus", **_commonStatus), Plot("diffCovQoverpQoverpUnderOverFlowSign", xtitle="cov(qoverp, qoverp)", **_common), Plot("diffCovLambdaLambda", xtitle="cov(lambda, lambda)", **_commonLabelSize), Plot("diffCovLambdaLambdaStatus", **_commonStatus), Plot("diffCovLambdaLambdaUnderOverFlowSign", xtitle="cov(lambda, lambda)", **_common), Plot("diffCovLambdaDsz", xtitle="cov(lambda, dsz)", **_commonLabelSize), Plot("diffCovLambdaDszStatus", **_commonStatus), Plot("diffCovLambdaDszUnderOverFlowSign", xtitle="cov(lambda, dsz)", **_common), Plot("diffCovPhiPhi", xtitle="cov(phi, phi)", **_commonLabelSize), Plot("diffCovPhiPhiStatus", **_commonStatus), Plot("diffCovPhiPhiUnderOverFlowSign", xtitle="cov(phi, phi)", **_common), ], ncols=3, legendDy=_legendDy_4rows ) _packedCandidateCovarianceMatrix2 = PlotGroup("covarianceMatrix2", [ Plot("diffCovPhiDxy", xtitle="cov(phi, dxy)", **_commonLabelSize), Plot("diffCovPhiDxyStatus", **_commonStatus), Plot("diffCovPhiDxyUnderOverFlowSign", xtitle="cov(phi, dxy)", **_common), Plot("diffCovDxyDxy", xtitle="cov(dxy, dxy)", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffCovDxyDxyStatus", **_commonStatus), Plot("diffCovDxyDxyUnderOverFlowSign", xtitle="cov(dxy, dxy)", **_common), Plot("diffCovDxyDsz", xtitle="cov(dxy, dsz)", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffCovDxyDszStatus", **_commonStatus), Plot("diffCovDxyDszUnderOverFlowSign", xtitle="cov(dxy, dsz)", **_common), Plot("diffCovDszDsz", xtitle="cov(dsz, dsz)", adjustMarginRight=0.02, **_commonLabelSize), Plot("diffCovDszDszStatus", **_commonStatus), Plot("diffCovDszDszUnderOverFlowSign", xtitle="cov(dsz, dsz)", **_common), ], ncols=3, legendDy=_legendDy_4rows ) _common["xlabelsize"] = 16 _packedCandidateVertex = PlotGroup("vertex", [ Plot("diffVx", xtitle="Reference point x", **_common), Plot("diffVy", xtitle="Reference point y", **_common), Plot("diffVz", xtitle="Reference point z", **_common), ], legendDy=_legendDy_2rows ) _common["adjustMarginRight"] = 0.05 _packedCandidateKinematics = PlotGroup("kinematics", [ Plot("diffPt", xtitle="p_{T}", **_common), Plot("diffPtError", xtitle="p_{T} error", **_common), Plot("diffEta", xtitle="#eta", **_common), Plot("diffEtaError", xtitle="#eta error", **_common), Plot("diffPhi", xtitle="#phi", **_common), ]) class TrackingPlotFolder(PlotFolder): def __init__(self, *args, **kwargs): self._fallbackRefFiles = kwargs.pop("fallbackRefFiles", []) PlotFolder.__init__(self, *args, **kwargs) def translateSubFolder(self, dqmSubFolderName): spl = dqmSubFolderName.split("_") if len(spl) != 2: return None collName = spl[0] return _mapCollectionToAlgoQuality(collName) def iterSelectionName(self, plotFolderName, translatedDqmSubFolder): (algoOrig, quality) = translatedDqmSubFolder for fallback in [lambda n: n]+self._fallbackRefFiles: algo = fallback(algoOrig) ret = "" if plotFolderName != "": ret += "_"+plotFolderName if quality != "": ret += "_"+quality if not (algo == "ootb" and quality != ""): ret += "_"+algo yield ret def limitSubFolder(self, limitOnlyTo, translatedDqmSubFolder): """Return True if this subfolder should be processed Arguments: limitOnlyTo -- Function '(algo, quality) -> bool' translatedDqmSubFolder -- Return value of translateSubFolder """ (algo, quality) = translatedDqmSubFolder return limitOnlyTo(algo, quality) # track-specific hack def isAlgoIterative(self, algo): return algo not in _possibleTrackingNonIterationColls class TrackingSummaryTable: class GeneralTracks: pass class GeneralTracksPt09: pass class HighPurity: pass class HighPurityPt09: pass class BTVLike: pass class AK4PFJets: pass class Pixel: pass class PixelPt09: pass def __init__(self, section, collection=GeneralTracks): self._collection = collection self._purpose = PlotPurpose.TrackingSummary self._page = "summary" self._section = section def getPurpose(self): return self._purpose def getPage(self): return self._page def getSection(self, dqmSubFolder): return self._section def create(self, tdirectory): def _getAlgoQuality(data, algo, quality): for label, value in data.items(): (a, q) = _mapCollectionToAlgoQuality(label) if a == algo and q == quality: return value[0] # value is (value, uncertainty) tuple return None def _getN(hname): h = tdirectory.Get(hname) if not h: return None data = plotting._th1ToOrderedDict(h) if self._collection == TrackingSummaryTable.GeneralTracks: return _getAlgoQuality(data, "ootb", "") elif self._collection == TrackingSummaryTable.GeneralTracksPt09: return _getAlgoQuality(data, "ootb", "Pt09") elif self._collection == TrackingSummaryTable.HighPurity: return _getAlgoQuality(data, "ootb", "highPurity") elif self._collection == TrackingSummaryTable.HighPurityPt09: return _getAlgoQuality(data, "ootb", "highPurityPt09") elif self._collection == TrackingSummaryTable.BTVLike: return _getAlgoQuality(data, "btvLike", "") elif self._collection == TrackingSummaryTable.AK4PFJets: return _getAlgoQuality(data, "ak4PFJets", "") elif self._collection == TrackingSummaryTable.Pixel: return _getAlgoQuality(data, "pixel", "") elif self._collection == TrackingSummaryTable.PixelPt09: return _getAlgoQuality(data, "pixel", "Pt09") else: raise Exception("Collection not recognized, %s" % str(self._collection)) def _formatOrNone(num, func): if num is None: return None return func(num) n_tps = _formatOrNone(_getN("num_simul_coll"), int) n_m_tps = _formatOrNone(_getN("num_assoc(simToReco)_coll"), int) n_tracks = _formatOrNone(_getN("num_reco_coll"), int) n_true = _formatOrNone(_getN("num_assoc(recoToSim)_coll"), int) if n_tracks is not None and n_true is not None: n_fake = n_tracks-n_true else: n_fake = None n_pileup = _formatOrNone(_getN("num_pileup_coll"), int) n_duplicate = _formatOrNone(_getN("num_duplicate_coll"), int) eff = _formatOrNone(_getN("effic_vs_coll"), lambda n: "%.4f" % n) eff_nopt = _formatOrNone(_getN("effic_vs_coll_allPt"), lambda n: "%.4f" % n) fake = _formatOrNone(_getN("fakerate_vs_coll"), lambda n: "%.4f" % n) duplicate = _formatOrNone(_getN("duplicatesRate_coll"), lambda n: "%.4f" % n) ret = [eff, n_tps, n_m_tps, eff_nopt, fake, duplicate, n_tracks, n_true, n_fake, n_pileup, n_duplicate] if ret.count(None) == len(ret): return None return ret def headers(self): return [ "Efficiency", "Number of TrackingParticles (after cuts)", "Number of matched TrackingParticles", "Efficiency (w/o pT cut)", "Fake rate", "Duplicate rate", "Number of tracks", "Number of true tracks", "Number of fake tracks", "Number of pileup tracks", "Number of duplicate tracks" ] # Provide a "PlotGroup" interface, but provide a html page class TrackingSeedingLayerTable: def __init__(self, fileName, plots, titles, isRate, **kwargs): self._plots = plots self._titles = titles self._fileName = fileName self._format = "%.4g" if isRate else "%d" if len(plots) != len(titles): raise Exception("Number of plots (%d) has to be the same as number of titles (%d)" % (len(plots), len(titles))) def _set(attr, default): setattr(self, "_"+attr, kwargs.get(attr, default)) _set("onlyForPileup", False) def onlyForPileup(self): """Return True if the PlotGroup is intended only for pileup samples""" return self._onlyForPileup def create(self, tdirectoryNEvents, requireAllHistograms=False): # [plot][histo] for plot in self._plots: plot.create(tdirectoryNEvents, requireAllHistograms) def draw(self, legendLabels, prefix=None, directory="", *args, **kwargs): # Do not make the table if it would be empty onlyEmptyPlots = True for plot in self._plots: if not plot.isEmpty(): onlyEmptyPlots = False break if onlyEmptyPlots: return [] haveShortLabels = False legendLabels = legendLabels[:] if max(map(len, legendLabels)) > 20: haveShortLabels = True labels_short = [str(chr(ord('A')+i)) for i in range(len(legendLabels))] for i, ls in enumerate(labels_short): legendLabels[i] = "%s: %s" % (ls, legendLabels[i]) else: labels_short = legendLabels content = [ '<html>', ' <body>', ' <table border="1">', ' <tr>', ] histos_linear = [] histos_index = [] labels = [] for plot, title in zip(self._plots, self._titles): h_tmp = [] l_tmp = [] for h, l in zip(plot._histograms, labels_short): if h is not None: h_tmp.append(len(histos_linear)) histos_linear.append(h) l_tmp.append(l) if len(h_tmp) > 0: histos_index.append(h_tmp) labels.append(l_tmp) content.extend([ ' <td></td>', ' <td colspan="%d">%s</td>' % (len(h_tmp), title), ]) if len(histos_linear) == 0: return [] content.extend([ ' </tr>', ' <tr>', ]) xbinlabels = plotting._mergeBinLabelsX(histos_linear) histos_linear = plotting._th1IncludeOnlyBins(histos_linear, xbinlabels) if len(histos_linear) == 0: return [] (histos_linear_new, xbinlabels) = plotting._th1RemoveEmptyBins(histos_linear, xbinlabels) # in practice either all histograms are returned, or none, but let's add a check anyway if len(histos_linear_new) > 0 and len(histos_linear_new) != len(histos_linear): raise Exception("This should never happen. len(histos_linear_new) %d != len(histos_linear) %d" % (len(histos_linear_new), len(histos_linear))) histos_linear = histos_linear_new if len(histos_linear) == 0: return [] data = [ [h.GetBinContent(i) for i in range(1, h.GetNbinsX()+1)] for h in histos_linear] table = html.Table(["dummy"]*len(histos_linear), xbinlabels, data, None, None, None) data = table.tableAsRowColumn() for labs in labels: content.append(' <td></td>') content.extend([' <td>%s</td>' % lab for lab in labs]) content.extend([ ' </tr>', ]) for irow, row in enumerate(data): content.extend([ ' <tr>', ' <td>%s</td>' % table.rowHeaders()[irow] ]) for hindices in histos_index: for hindex in hindices: item = row[hindex] formatted = self._format%item if item is not None else "" content.append(' <td align="right">%s</td>' % formatted) content.append(' <td></td>') del content[-1] content.append(' </tr>') content.append(' </table>') if haveShortLabels: for lab in legendLabels: content.append(' %s<br/>' % lab) content.extend([ ' </body>', '<html>' ]) name = self._fileName if prefix is not None: name = prefix+name name += ".html" name = os.path.join(directory, name) with open(name, "w") as f: for line in content: f.write(line) f.write("\n") return [name] _dupandfakeSeedingTable = TrackingSeedingLayerTable("dupandfakeSeeding", [p.clone() for p in _dupandfakeSeedingPlots], ["Fake rate", "Duplicate rate", "Pileup rate"], isRate=True) _extDistSeedingTable = TrackingSeedingLayerTable("distSeeding", [p.clone() for p in _extDistSeedingPlots], ["All tracks", "True tracks", "Fake tracks", "Duplicate tracks"], isRate=False) def _trackingFolders(lastDirName="Track"): return [ "DQMData/Run 1/Tracking/Run summary/"+lastDirName, "DQMData/Tracking/"+lastDirName, "DQMData/Run 1/RecoTrackV/Run summary/"+lastDirName, "DQMData/RecoTrackV/"+lastDirName, ] _simBasedPlots = [ _effandfakePtEtaPhi, _effandfakeDxyDzBS, _effandfakeDxyDzPV, _effandfakeHitsLayers, _effandfakePos, _effandfakeDeltaRPU, _duplicateAlgo, ] _recoBasedPlots = [ _dupandfakePtEtaPhi, _dupandfakeDxyDzBS, _dupandfakeDxyDzPV, _dupandfakeHitsLayers, _dupandfakePos, _dupandfakeDeltaRPU, _dupandfakeChi2Seeding, _dupandfakeSeedingTable, _pvassociation1, _pvassociation2, _dedx, # _chargemisid, _hitsAndPt, _pulls, _resolutionsEta, _resolutionsPhi, _resolutionsPt, _tuning, ] _seedingBuildingPlots = _simBasedPlots + [ _dupandfakePtEtaPhi, _dupandfakeDxyDzBS, _dupandfakeDxyDzPV, _dupandfakeHitsLayers, _dupandfakePos, _dupandfakeDeltaRPU, _dupandfakeChi2Seeding, _dupandfakeSeedingTable, _hitsAndPt, ] + _makeMVAPlots(1) \ + _makeMVAPlots(2) \ + _makeMVAPlots(2, hp=True) \ + _makeMVAPlots(3) \ + _makeMVAPlots(3, hp=True) # add more if needed _buildingExtendedPlots = [ _pulls, _resolutionsEta, _resolutionsPhi, _resolutionsPt, _tuning, ] _extendedPlots = [ _extDistPtEtaPhi, _extDistDxyDzBS, _extDistDxyDzPV, _extDistHitsLayers, _extDistPos, _extDistDeltaR, _extDistChi2Seeding, _extDistSeedingTable, _extResidualEta, _extResidualPt, _extNrecVsNsim, _extHitsLayers, _extDistSimPtEtaPhi, _extDistSimDxyDzBS, _extDistSimDxyDzPV, _extDistSimHitsLayers, _extDistSimPos, _extDistSimDeltaR, ] _summaryPlots = [ _summary, _summaryN, _summaryByOriginalAlgo, _summaryByOriginalAlgoN, _summaryByAlgoMask, _summaryByAlgoMaskN, _summaryPt09, _summaryPt09N, ] _summaryPlotsHp = [ _summaryHp, _summaryNHp, _summaryByOriginalAlgoHp, _summaryByOriginalAlgoNHp, _summaryByAlgoMaskHp, _summaryByAlgoMaskNHp, _summaryPt09Hp, _summaryPt09NHp, ] _summaryPlotsSeeds = [ _summarySeeds, _summarySeedsN, ] _packedCandidatePlots = [ _packedCandidateFlow, _packedCandidateKinematics, _packedCandidateVertex, _packedCandidateImpactParameter1, _packedCandidateImpactParameter2, _packedCandidateCovarianceMatrix1, _packedCandidateCovarianceMatrix2, _packedCandidateHits, _packedCandidateHitsHitPattern, _packedCandidateLayers, ] plotter = Plotter() plotterExt = Plotter() def _appendTrackingPlots(lastDirName, name, algoPlots, onlyForPileup=False, onlyForElectron=False, onlyForConversion=False, onlyForBHadron=False, seeding=False, building=False, rawSummary=False, highPuritySummary=True): folders = _trackingFolders(lastDirName) # to keep backward compatibility, this set of plots has empty name limiters = dict(onlyForPileup=onlyForPileup, onlyForElectron=onlyForElectron, onlyForConversion=onlyForConversion, onlyForBHadron=onlyForBHadron) commonForTPF = dict(purpose=PlotPurpose.TrackingIteration, fallbackRefFiles=[ _trackingRefFileFallbackSLHC_Phase1PU140 ], **limiters) common = dict(fallbackDqmSubFolders=[ _trackingSubFoldersFallbackSLHC_Phase1PU140, _trackingSubFoldersFallbackFromPV, _trackingSubFoldersFallbackConversion, _trackingSubFoldersFallbackPreSplitting]) plotter.append(name, folders, TrackingPlotFolder(*algoPlots, **commonForTPF), **common) extendedPlots = [] if building: extendedPlots.extend(_buildingExtendedPlots) extendedPlots.extend(_extendedPlots) plotterExt.append(name, folders, TrackingPlotFolder(*extendedPlots, **commonForTPF), **common) summaryName = "" if name != "": summaryName += name+"_" summaryName += "summary" summaryPlots = [] if rawSummary: summaryPlots.extend([_summaryRaw, _summaryRawN]) summaryPlots.extend(_summaryPlots) common = dict(loopSubFolders=False, purpose=PlotPurpose.TrackingSummary, page="summary", #numberOfEventsHistogram=_trackingNumberOfEventsHistogram, # FIXME **limiters) plotter.append(summaryName, folders, PlotFolder(*summaryPlots, section=name, **common)) if highPuritySummary: plotter.append(summaryName+"_highPurity", folders, PlotFolder(*_summaryPlotsHp, section=name+"_highPurity" if name != "" else "highPurity", **common), fallbackNames=[summaryName]) # backward compatibility for release validation, the HP plots used to be in the same directory with all-track plots if seeding: plotter.append(summaryName+"_seeds", folders, PlotFolder(*_summaryPlotsSeeds, section=name+"_seeds", **common)) plotter.appendTable(summaryName, folders, TrackingSummaryTable(section=name)) plotter.appendTable(summaryName, folders, TrackingSummaryTable(section=name+"Pt09", collection=TrackingSummaryTable.GeneralTracksPt09)) if highPuritySummary: sectionName = name+"_highPurity" if name != "" else "highPurity" plotter.appendTable(summaryName+"_highPurity", folders, TrackingSummaryTable(section=sectionName, collection=TrackingSummaryTable.HighPurity)) plotter.appendTable(summaryName+"_highPurity", folders, TrackingSummaryTable(section=sectionName+"Pt09", collection=TrackingSummaryTable.HighPurityPt09)) if name == "": plotter.appendTable(summaryName, folders, TrackingSummaryTable(section="btvLike", collection=TrackingSummaryTable.BTVLike)) plotter.appendTable(summaryName, folders, TrackingSummaryTable(section="ak4PFJets", collection=TrackingSummaryTable.AK4PFJets)) _appendTrackingPlots("Track", "", _simBasedPlots+_recoBasedPlots) _appendTrackingPlots("TrackTPPtLess09", "tpPtLess09", _simBasedPlots) _appendTrackingPlots("TrackTPEtaGreater2p7", "tpEtaGreater2p7", _simBasedPlots+_recoBasedPlots) _appendTrackingPlots("TrackAllTPEffic", "allTPEffic", _simBasedPlots, onlyForPileup=True) _appendTrackingPlots("TrackFromPV", "fromPV", _simBasedPlots+_recoBasedPlots, onlyForPileup=True) _appendTrackingPlots("TrackFromPVAllTP", "fromPVAllTP", _simBasedPlots+_recoBasedPlots, onlyForPileup=True) _appendTrackingPlots("TrackFromPVAllTP2", "fromPVAllTP2", _simBasedPlots+_recoBasedPlots, onlyForPileup=True) _appendTrackingPlots("TrackSeeding", "seeding", _seedingBuildingPlots, seeding=True) _appendTrackingPlots("TrackBuilding", "building", _seedingBuildingPlots, building=True) _appendTrackingPlots("TrackConversion", "conversion", _simBasedPlots+_recoBasedPlots, onlyForConversion=True, rawSummary=True, highPuritySummary=False) _appendTrackingPlots("TrackGsf", "gsf", _simBasedPlots+_recoBasedPlots, onlyForElectron=True, rawSummary=True, highPuritySummary=False) _appendTrackingPlots("TrackBHadron", "bhadron", _simBasedPlots+_recoBasedPlots, onlyForBHadron=True) _appendTrackingPlots("TrackDisplaced", "displaced", _simBasedPlots+_recoBasedPlots) # Pixel tracks def _appendPixelTrackingPlots(lastDirName, name): _common = dict(purpose=PlotPurpose.Pixel, page="pixel") _folders = _trackingFolders(lastDirName) plotter.append(name, _folders, TrackingPlotFolder(*(_simBasedPlots+_recoBasedPlots), **_common)) plotterExt.append(name, _folders, TrackingPlotFolder(*_extendedPlots, **_common)) plotter.append(name+"_summary", _folders, PlotFolder(_summaryRaw, _summaryRawN, loopSubFolders=False, purpose=PlotPurpose.TrackingSummary, page="summary", section=name)) plotter.append(name+"_summary", _folders, PlotFolder(_summaryRaw, _summaryRawN, loopSubFolders=False, purpose=PlotPurpose.TrackingSummary, page="summary", section=name+"Pt09")) plotter.appendTable(name+"_summary", _folders, TrackingSummaryTable(section=name, collection=TrackingSummaryTable.Pixel)) plotter.appendTable(name+"_summary", _folders, TrackingSummaryTable(section=name+"Pt09", collection=TrackingSummaryTable.PixelPt09)) _appendPixelTrackingPlots("PixelTrack", "pixel") _appendPixelTrackingPlots("PixelTrackFromPV", "pixelFromPV") _appendPixelTrackingPlots("PixelTrackFromPVAllTP", "pixelFromPVAllTP") _appendPixelTrackingPlots("PixelTrackBHadron", "pixelbhadron") _appendPixelTrackingPlots("HIPixelTrack", "hiPixel") # MiniAOD plotter.append("packedCandidate", _trackingFolders("PackedCandidate"), PlotFolder(*_packedCandidatePlots, loopSubFolders=False, purpose=PlotPurpose.MiniAOD, page="miniaod", section="PackedCandidate")) plotter.append("packedCandidateLostTracks", _trackingFolders("PackedCandidate/lostTracks"), PlotFolder(*_packedCandidatePlots, loopSubFolders=False, purpose=PlotPurpose.MiniAOD, page="miniaod", section="PackedCandidate (lostTracks)")) # HLT _hltFolder = [ "DQMData/Run 1/HLT/Run summary/Tracking/ValidationWRTtp", ] plotterHLT = Plotter() plotterHLTExt = Plotter() _common = dict(purpose=PlotPurpose.HLT, page="hlt") plotterHLT.append("hlt", _hltFolder, TrackingPlotFolder(*(_simBasedPlots+_recoBasedPlots), **_common)) plotterHLTExt.append("hlt", _hltFolder, TrackingPlotFolder(*_extendedPlots, **_common)) # Timing class Iteration: def __init__(self, name, clusterMasking=None, seeding=None, building=None, fit=None, selection=None, other=[]): self._name = name def _set(param, name, modules): if param is not None: setattr(self, name, param) else: setattr(self, name, modules) _set(clusterMasking, "_clusterMasking", [self._name+"Clusters"]) # it's fine to include e.g. quadruplets here also for pair # steps, as non-existing modules are just ignored _set(seeding, "_seeding", [self._name+"SeedingLayers", self._name+"TrackingRegions", self._name+"HitDoublets", self._name+"HitTriplets", self._name+"HitQuadruplets", self._name+"Seeds"]) trackCandidates = self._name+"TrackCandidates" _set(building, "_building", [trackCandidates+"MkFitSeeds", trackCandidates+"MkFit", trackCandidates]) _set(fit, "_fit", [self._name+"Tracks"]) _set(selection, "_selection", [self._name]) self._other = other def name(self): return self._name def all(self): return self._clusterMasking+self._seeding+self._building+self._fit+self._selection+self._other def clusterMasking(self): return self._clusterMasking def seeding(self): return self._seeding def building(self): return self._building def fit(self): return self._fit def selection(self): return self._selection def other(self): return self._other def modules(self): return [("Cluster Mask", self.clusterMasking()), ("Seed", self.seeding()), ("Build", self.building()), ("Fit", self.fit()), ("Select", self.selection()), ("Other", self.other())] _iterations = [ Iteration("initialStepPreSplitting", clusterMasking=[], seeding=["initialStepSeedLayersPreSplitting", "initialStepTrackingRegionsPreSplitting", "initialStepHitDoubletsPreSplitting", "initialStepHitTripletsPreSplitting", "initialStepHitQuadrupletsPreSplitting", "initialStepSeedsPreSplitting"], building=["initialStepTrackCandidatesPreSplitting", "initialStepTrackCandidatesMkFitSeedsPreSplitting", "initialStepTrackCandidatesMkFitPreSplitting"], fit=["initialStepTracksPreSplitting"], other=["firstStepPrimaryVerticesPreSplitting", "initialStepTrackRefsForJetsPreSplitting", "caloTowerForTrkPreSplitting", "ak4CaloJetsForTrkPreSplitting", "jetsForCoreTrackingPreSplitting", "siPixelClusters", "siPixelRecHits", "MeasurementTrackerEvent", "siPixelClusterShapeCache", "mkFitSiPixelHitsPreSplitting", "mkFitSiStripHits", "mkFitEventOfHitsPreSplitting"]), Iteration("initialStep", clusterMasking=[], selection=["initialStepClassifier1", "initialStepClassifier2", "initialStepClassifier3", "initialStep", "initialStepSelector"], other=["firstStepPrimaryVerticesUnsorted", "initialStepTrackRefsForJets", "caloTowerForTrk", "ak4CaloJetsForTrk", "firstStepPrimaryVertices", "mkFitSiPixelHits", "mkFitEventOfHits"]), Iteration("highPtTripletStep", seeding=["highPtTripletStepSeedsPixelsWithLST", "highPtTripletStepSeedsPixelsOnly"], selection=["highPtTripletStepClassifier1", "highPtTripletStepClassifier2", "highPtTripletStepClassifier3", "highPtTripletStep", "highPtTripletStepSelector"]), Iteration("detachedQuadStep", selection=["detachedQuadStepClassifier1", "detachedQuadStepClassifier2", "detachedQuadStep", "detachedQuadStepSelector"]), Iteration("detachedTripletStep", selection=["detachedTripletStepClassifier1", "detachedTripletStepClassifier2", "detachedTripletStep", "detachedTripletStepSelector"]), Iteration("lowPtQuadStep", selection=["lowPtQuadStepClassifier1", "lowPtQuadStepClassifier2", "lowPtQuadStep", "lowPtQuadStepSelector"]), Iteration("lowPtTripletStep", selection=["lowPtTripletStepClassifier1", "lowPtTripletStepClassifier2", "lowPtTripletStep", "lowPtTripletStepSelector"]), Iteration("pixelPairStep", seeding=["pixelPairStepSeedLayers", "pixelPairStepSeedLayersB", "pixelPairStepSeedLayersC", "pixelPairStepTrackingRegions", "pixelPairStepTrackingRegionsB", "pixelPairStepTrackingRegionsC", "pixelPairStepTrackingRegionsSeedLayersB", "pixelPairStepHitDoublets", "pixelPairStepHitDoubletsB", "pixelPairStepHitDoubletsC", "pixelPairStepSeedsA", "pixelPairStepSeedsB", "pixelPairStepSeedsC", "pixelPairStepSeeds",], selection=["pixelPairStep", "pixelPairStepSelector"]), Iteration("mixedTripletStep", seeding=["mixedTripletStepSeedLayersA", "mixedTripletStepSeedLayersB", "mixedTripletStepTrackingRegionsA", "mixedTripletStepTrackingRegionsB", "mixedTripletStepHitDoubletsA", "mixedTripletStepHitDoubletsB", "mixedTripletStepHitTripletsA", "mixedTripletStepHitTripletsB", "mixedTripletStepSeedsA", "mixedTripletStepSeedsB", "mixedTripletStepSeeds"], selection=["mixedTripletStepClassifier1", "mixedTripletStepClassifier2", "mixedTripletStep", "mixedTripletStepSelector"]), Iteration("pixelLessStep", selection=["pixelLessStepClassifier1", "pixelLessStepClassifier2", "pixelLessStep", "pixelLessStepSelector"]), Iteration("tobTecStep", seeding=["tobTecStepSeedLayersTripl", "tobTecStepSeedLayersPair", "tobTecStepTrackingRegionsTripl", "tobTecStepTrackingRegionsPair", "tobTecStepHitDoubletsTripl", "tobTecStepHitDoubletsPair", "tobTecStepHitTripletsTripl", "tobTecStepSeedsTripl", "tobTecStepSeedsPair", "tobTecStepSeeds"], selection=["tobTecStepClassifier1", "tobTecStepClassifier2", "tobTecStep", "tobTecStepSelector"]), Iteration("displacedGeneralStep", seeding=["displacedGeneralStepSeedLayers", "displacedGeneralStepTrackingRegions", "displacedGeneralStepHitDoublets", "displacedGeneralStepHitTriplets", "displacedGeneralStepSeeds"], selection=["displacedGeneralStepClassifier1", "displacedGeneralStepClassifier2", "displacedGeneralStep", "displacedGeneralStepSelector"]), Iteration("jetCoreRegionalStep", clusterMasking=[], other=["jetsForCoreTracking", "firstStepGoodPrimaryVertices", ]), Iteration("muonSeededSteps", clusterMasking=[], seeding=["muonSeededSeedsInOut", "muonSeededSeedsOutIn"], building=["muonSeededTrackCandidatesInOut", "muonSeededTrackCandidatesOutIn"], fit=["muonSeededTracksInOut", "muonSeededTracksOutIn"], selection=["muonSeededTracksInOutClassifier", "muonSeededTracksInOutSelector", "muonSeededTracksOutIntClassifier", "muonSeededTracksOutIntSelector"], # other=["earlyMuons"] ), Iteration("displacedRegionalStep", seeding=["displacedRegionalStepSeedLayersTripl", "displacedRegionalStepSeedLayersPair", "displacedRegionalStepTrackingRegionsTripl", "displacedRegionalStepTrackingRegionsPair", "displacedRegionalStepHitDoubletsTripl", "displacedRegionalStepHitDoubletsPair", "displacedRegionalStepHitTripletsTripl", "displacedRegionalStepSeedsTripl", "displacedRegionalStepSeedsPair", "displacedRegionalStepSeeds"], selection=["displacedRegionalStepClassifier1", "displacedRegionalStepClassifier2", "displacedRegionalStep", "displacedRegionalStepSelector"]), Iteration("duplicateMerge", clusterMasking=[], seeding=[], building=["duplicateTrackCandidates"], fit=["mergedDuplicateTracks"], selection=["duplicateTrackClassifier"]), Iteration("generalTracks", clusterMasking=[], seeding=[], building=[], fit=[], selection=[], other=["preDuplicateMergingGeneralTracks", "generalTracks"]), Iteration("ConvStep", clusterMasking=["convClusters"], seeding=["convLayerPairs", "photonConvTrajSeedFromSingleLeg"], building=["convTrackCandidates"], fit=["convStepTracks"], selection=["convStepSelector"]), Iteration("Other", clusterMasking=[], seeding=[], building=[], fit=[], selection=[], other=["trackerClusterCheckPreSplitting", "trackerClusterCheck"]), ] def _iterModuleMap(includeConvStep=True, onlyConvStep=False): iterations = _iterations if not includeConvStep: iterations = [i for i in iterations if i.name() != "ConvStep"] if onlyConvStep: iterations = [i for i in iterations if i.name() == "ConvStep"] return collections.OrderedDict([(i.name(), i.all()) for i in iterations]) def _stepModuleMap(): def getProp(prop): ret = [] for i in _iterations: if i.name() == "ConvStep": continue ret.extend(getattr(i, prop)()) return ret return collections.OrderedDict([ ("Cluster Mask", getProp("clusterMasking")), ("Seed", getProp("seeding")), ("Build", getProp("building")), ("Fit", getProp("fit")), ("Select", getProp("selection")), ("Other", getProp("other")) ]) class TimePerEventPlot: def __init__(self, name, timeHisto): self._name = name self._timeHisto = timeHisto self._eventsHisto = "path time_real" self._cache = {} def __str__(self): return self._name def _create(self, tdirectory): timeTh1 = plotting._getOrCreateObject(tdirectory, self._timeHisto) if timeTh1 is None: return None eventsTh1 = plotting._getOrCreateObject(tdirectory, self._eventsHisto) if eventsTh1 is None: return None nevents = eventsTh1.GetEntries() if nevents == 0: return None ret = timeTh1.Clone(self._name) xaxis = ret.GetXaxis() for i in range(1, ret.GetNbinsX()+1): ret.SetBinContent(i, ret.GetBinContent(i)/nevents) ret.SetBinError(i, ret.GetBinError(i)/nevents) xaxis.SetBinLabel(i, xaxis.GetBinLabel(i).replace(" (unscheduled)", "")) return ret def create(self, tdirectory): path = tdirectory.GetPath() if path not in self._cache: self._cache[path] = self._create(tdirectory) return self._cache[path] class TimePerTrackPlot: def __init__(self, name, timeHisto, selectedTracks=False): self._name = name self._timeHisto = timeHisto self._selectedTracks = selectedTracks def __str__(self): return self._name def _getDirectory(self, tfile): for dirName in _trackingFolders(): tdir = tfile.Get(dirName) if tdir != None: return tdir return None def create(self, tdirectory): timeTh1 = plotting._getOrCreateObject(tdirectory, self._timeHisto) if timeTh1 is None: return None # this is bit of a hack, but as long as it is needed only # here, I won't invest in better solution tfile = tdirectory.GetFile() trkDir = self._getDirectory(tfile) if trkDir is None: return None iterMap = copy.copy(_collLabelMapHp) del iterMap["generalTracks"] del iterMap["jetCoreRegionalStep"] # this is expensive per track on purpose if self._selectedTracks: renameBin = lambda bl: _summaryBinRename(bl, highPurity=True, byOriginalAlgo=False, byAlgoMask=True, ptCut=False, seeds=False) else: renameBin = lambda bl: _summaryBinRename(bl, highPurity=False, byOriginalAlgo=False, byAlgoMask=False, ptCut=False, seeds=False) recoAB = AggregateBins("tmp", "num_reco_coll", mapping=iterMap,ignoreMissingBins=True, renameBin=renameBin) h_reco_per_iter = recoAB.create(trkDir) if h_reco_per_iter is None: return None values = {} for i in range(1, h_reco_per_iter.GetNbinsX()+1): values[h_reco_per_iter.GetXaxis().GetBinLabel(i)] = h_reco_per_iter.GetBinContent(i) result = [] for i in range(1, timeTh1.GetNbinsX()+1): iterName = timeTh1.GetXaxis().GetBinLabel(i) if iterName in values: ntrk = values[iterName] result.append( (iterName, timeTh1.GetBinContent(i)/ntrk if ntrk > 0 else 0, timeTh1.GetBinError(i)/ntrk if ntrk > 0 else 0) ) if len(result) == 0: return None res = ROOT.TH1F(self._name, self._name, len(result), 0, len(result)) for i, (label, value, error) in enumerate(result): res.GetXaxis().SetBinLabel(i+1, label) res.SetBinContent(i+1, value) res.SetBinError(i+1, error) return res class TrackingIterationOrder: def __init__(self): self._cache = {} def _findOrder(self, f): h = f.Get(_trackingIterationOrderHistogram) if not h: return None xaxis = h.GetXaxis() def _edit(s): # remove "Tracks" from the track producer name to get the iteration name # muonSeeded iterations do not have "Step" in the producer name, so add it here return s.replace("Tracks", "").replace("muonSeeded", "muonSeededStep") return [_edit(xaxis.GetBinLabel(i)) for i in range(1, h.GetNbinsX()+1)] def __call__(self, tdirectory, labels): ret = list(range(0, len(labels))) f = tdirectory.GetFile() if not f: return ret if not f.GetName() in self._cache: r = self._findOrder(f) if r is None: return ret self._cache[f.GetName()] = r order = self._cache[f.GetName()] # O(N^2) I know, but we're talking about O(10) elements... orderIndices = [] for l in order: try: orderIndices.append(labels.index(l)) except ValueError: pass ret = [] for i, l in enumerate(labels): if l in order: try: found = orderIndices.index(i) if found == 0: ret.append(i) else: ret.append(orderIndices[0]) except ValueError: ret.append(orderIndices[0]) orderIndices.pop(0) else: ret.append(i) return ret _time_per_event_cpu = TimePerEventPlot("timePerEvent", "module_time_thread_total") _time_per_event_real = TimePerEventPlot("timePerEvent", "module_time_real_total") class TrackingTimingTable: def __init__(self): self._purpose = PlotPurpose.Timing self._page = "timing" self._section = "timing" def getPurpose(self): return self._purpose def getPage(self): return self._page def getSection(self, dqmSubFolder): return self._section def _getValues(self, tdirectory, histo): h = tdirectory.Get(histo._timeHisto) totalReco = None if h: totalReco = "%.1f" % h.Integral() creator = AggregateBins("iteration", histo, _iterModuleMap(includeConvStep=False), ignoreMissingBins=True) h = creator.create(tdirectory) totalTracking = None if h: totalTracking = "%.1f" % h.Integral() creator = AggregateBins("iteration", histo, _iterModuleMap(onlyConvStep=True), ignoreMissingBins=True) h = creator.create(tdirectory) totalConvStep = None if h: totalConvStep = "%.1f" % h.Integral() return [ totalReco, totalTracking, totalConvStep, ] def create(self, tdirectory): cpuValues = self._getValues(tdirectory, _time_per_event_cpu) realValues = self._getValues(tdirectory, _time_per_event_real) return cpuValues + realValues def headers(self): return [ "Average reco CPU time / event (ms)", "Average tracking (w/o convStep) CPU time / event (ms)", "Average convStep CPU time / event (ms)", "Average reco real time / event (ms)", "Average tracking (w/o convStep) real time / event (ms)", "Average convStep real time / event (ms)", ] _common = { "drawStyle": "P", "xbinlabelsize": 10, "xbinlabeloption": "d" } _iteration_reorder = TrackingIterationOrder() _time_per_iter_cpu = AggregateBins("iteration", _time_per_event_cpu, _iterModuleMap(), ignoreMissingBins=True, reorder=_iteration_reorder) _time_per_iter_real = AggregateBins("iteration", _time_per_event_real, _iterModuleMap(), ignoreMissingBins=True, reorder=_iteration_reorder) _timing_common = _common.copy() _timing_common["xbinlabelsize"] = 17 _timing_common["xbinlabeloption"] = "d" _timing_summaryCPU = PlotGroup("summaryCPU", [ Plot(_time_per_iter_cpu, ytitle="Average CPU time (ms)", title="Average CPU time / event", legendDx=-0.4, **_common), Plot(AggregateBins("iteration_fraction", _time_per_event_cpu, _iterModuleMap(), ignoreMissingBins=True, reorder=_iteration_reorder), ytitle="Fraction", title="", normalizeToUnitArea=True, **_common), # Plot(AggregateBins("step", _time_per_event_cpu, _stepModuleMap(), ignoreMissingBins=True), ytitle="Average CPU time (ms)", title="Average CPU time / event", **_timing_common), Plot(AggregateBins("step_fraction", _time_per_event_cpu, _stepModuleMap(), ignoreMissingBins=True), ytitle="Fraction", title="", normalizeToUnitArea=True, **_timing_common), # Plot(TimePerTrackPlot("iteration_track", _time_per_iter_cpu, selectedTracks=False), ytitle="Average CPU time / built track (ms)", title="Average CPU time / built track", **_common), Plot(TimePerTrackPlot("iteration_trackhp", _time_per_iter_cpu, selectedTracks=True), ytitle="Average CPU time / selected track (ms)", title="Average CPU time / selected HP track by algoMask", **_common), ], ) _timing_summaryReal = PlotGroup("summaryReal", [ Plot(_time_per_iter_real, ytitle="Average real time (ms)", title="Average real time / event", legendDx=-0.4, **_common), Plot(AggregateBins("iteration_fraction", _time_per_event_real, _iterModuleMap(), ignoreMissingBins=True, reorder=_iteration_reorder), ytitle="Fraction", title="", normalizeToUnitArea=True, **_common), # Plot(AggregateBins("step", _time_per_event_real, _stepModuleMap(), ignoreMissingBins=True), ytitle="Average real time (ms)", title="Average real time / event", **_timing_common), Plot(AggregateBins("step_fraction", _time_per_event_real, _stepModuleMap(), ignoreMissingBins=True), ytitle="Fraction", title="", normalizeToUnitArea=True, **_timing_common), # Plot(TimePerTrackPlot("iteration_track", _time_per_iter_real, selectedTracks=False), ytitle="Average real time / built track (ms)", title="Average real time / built track", **_common), Plot(TimePerTrackPlot("iteration_trackhp", _time_per_iter_real, selectedTracks=True), ytitle="Average real time / selected track (ms)", title="Average real time / selected HP track by algoMask", **_common), ], ) _timing_iterationsCPU = PlotGroup("iterationsCPU", [ Plot(AggregateBins(i.name(), _time_per_event_cpu, collections.OrderedDict(i.modules()), ignoreMissingBins=True), ytitle="Average CPU time (ms)", title=i.name(), **_timing_common) for i in _iterations ], ncols=4, legend=False ) _timing_iterationsReal = PlotGroup("iterationsReal", [ Plot(AggregateBins(i.name(), _time_per_event_real, collections.OrderedDict(i.modules()), ignoreMissingBins=True), ytitle="Average real time (ms)", title=i.name(), **_timing_common) for i in _iterations ], ncols=4, legend=False ) # TODO: to be updated to new FastTimerService format later #_pixelTiming = PlotGroup("pixelTiming", [ # Plot(AggregateBins("pixel", "reconstruction_step_module_average", {"pixelTracks": ["pixelTracks"]}), ytitle="Average processing time [ms]", title="Average processing time / event", drawStyle="HIST") #]) _timeFolders = [ # "DQMData/Run 1/DQM/Run summary/TimerService/process RECO paths/path reconstruction_step", "DQMData/Run 1/DQM/Run summary/TimerService/process RECO paths/path prevalidation_step", # because of unscheduled, it's actually prevalidation_step that has all the tracking modules? ] timePlotter = Plotter() timePlotter.append("timing", _timeFolders, PlotFolder( _timing_summaryCPU, _timing_iterationsCPU, _timing_summaryReal, _timing_iterationsReal, # _pixelTiming, loopSubFolders=False, purpose=PlotPurpose.Timing, page="timing" )) timePlotter.appendTable("timing", _timeFolders, TrackingTimingTable()) _common = {"stat": True, "normalizeToUnitArea": True, "drawStyle": "hist"} _tplifetime = PlotGroup("tplifetime", [ Plot("TPlip", xtitle="TP lip", **_common), Plot("TPtip", xtitle="TP tip", **_common), ]) tpPlotter = Plotter() tpPlotter.append("tp", [ "DQMData/Run 1/Tracking/Run summary/TrackingMCTruth/TrackingParticle", "DQMData/Tracking/TrackingMCTruth/TrackingParticle", ], PlotFolder( _tplifetime, ))