CMS 3D CMS Logo

validation.py
Go to the documentation of this file.
1 import os
2 import re
3 import sys
4 import shutil
5 import subprocess
6 
7 import ROOT
8 ROOT.gROOT.SetBatch(True)
9 ROOT.PyConfig.IgnoreCommandLineOptions = True
10 
11 import plotting
12 import html
13 
14 # Mapping from releases to GlobalTags
15 _globalTags = {
16  "CMSSW_6_2_0": {"default": "PRE_ST62_V8"},
17  "CMSSW_6_2_0_SLHC15": {"UPG2019withGEM": "DES19_62_V8", "UPG2023SHNoTaper": "DES23_62_V1"},
18  "CMSSW_6_2_0_SLHC17": {"UPG2019withGEM": "DES19_62_V8", "UPG2023SHNoTaper": "DES23_62_V1"},
19  "CMSSW_6_2_0_SLHC20": {"UPG2019withGEM": "DES19_62_V8", "UPG2023SHNoTaper": "DES23_62_V1_UPG2023SHNoTaper"},
20  "CMSSW_6_2_0_SLHC22": {"UPG2023SHNoTaper": "PH2_1K_FB_V6_UPG23SHNoTaper",
21  # map 81X GReco and tilted to SHNoTaper
22  "2023GReco": "PH2_1K_FB_V6_UPG23SHNoTaper", "2023GRecoPU35": "", "2023GRecoPU140": "", "2023GRecoPU200": "",
23  "2023tilted": "PH2_1K_FB_V6_UPG23SHNoTaper", "2023tiltedPU35": "", "2023tiltedPU140": "", "2023tiltedPU200": ""},
24  "CMSSW_6_2_0_SLHC26": {"LHCCRefPU140": "DES23_62_V1_LHCCRefPU140", "LHCCRefPU200": "DES23_62_V1_LHCCRefPU200",
25  # map 81X GReco and tilted to LHCCRef
26  "2023GReco": "", "2023GRecoPU35": "", "2023GRecoPU140": "DES23_62_V1_LHCCRefPU140", "2023GRecoPU200": "DES23_62_V1_LHCCRefPU200",
27  "2023tilted": "", "2023tiltedPU35": "", "2023tiltedPU140": "DES23_62_V1_LHCCRefPU140", "2023tiltedPU200": "DES23_62_V1_LHCCRefPU200"},
28  "CMSSW_6_2_0_SLHC27_phase1": {"default": "DES17_62_V8_UPG17"},
29  "CMSSW_7_0_0": {"default": "POSTLS170_V3", "fullsim_50ns": "POSTLS170_V4"},
30  "CMSSW_7_0_0_AlcaCSA14": {"default": "POSTLS170_V5_AlcaCSA14", "fullsim_50ns": "POSTLS170_V6_AlcaCSA14"},
31  "CMSSW_7_0_7_pmx": {"default": "PLS170_V7AN1", "fullsim_50ns": "PLS170_V6AN1"},
32  "CMSSW_7_0_9_patch3": {"default": "PLS170_V7AN2", "fullsim_50ns": "PLS170_V6AN2"},
33  "CMSSW_7_0_9_patch3_Premix": {"default": "PLS170_V7AN2", "fullsim_50ns": "PLS170_V6AN2"},
34  "CMSSW_7_1_0": {"default": "POSTLS171_V15", "fullsim_50ns": "POSTLS171_V16"},
35  "CMSSW_7_1_9": {"default": "POSTLS171_V17", "fullsim_50ns": "POSTLS171_V18"},
36  "CMSSW_7_1_9_patch2": {"default": "POSTLS171_V17", "fullsim_50ns": "POSTLS171_V18"},
37  "CMSSW_7_1_10_patch2": {"default": "MCRUN2_71_V1", "fullsim_50ns": "MCRUN2_71_V0"},
38  "CMSSW_7_2_0_pre5": {"default": "POSTLS172_V3", "fullsim_50ns": "POSTLS172_V4"},
39  "CMSSW_7_2_0_pre7": {"default": "PRE_LS172_V11", "fullsim_50ns": "PRE_LS172_V12"},
40  "CMSSW_7_2_0_pre8": {"default": "PRE_LS172_V15", "fullsim_50ns": "PRE_LS172_V16"},
41  "CMSSW_7_2_0": {"default": "PRE_LS172_V15", "fullsim_50ns": "PRE_LS172_V16"},
42  "CMSSW_7_2_0_PHYS14": {"default": "PHYS14_25_V1_Phys14"},
43  "CMSSW_7_2_2_patch1": {"default": "MCRUN2_72_V1", "fullsim_50ns": "MCRUN2_72_V0"},
44  "CMSSW_7_2_2_patch1_Fall14DR": {"default": "MCRUN2_72_V3_71XGENSIM"},
45 # "CMSSW_7_3_0_pre1": {"default": "PRE_LS172_V15", "fullsim_25ns": "PRE_LS172_V15_OldPU", "fullsim_50ns": "PRE_LS172_V16_OldPU"},
46  "CMSSW_7_3_0_pre1": {"default": "PRE_LS172_V15", "fullsim_50ns": "PRE_LS172_V16"},
47 # "CMSSW_7_3_0_pre2": {"default": "MCRUN2_73_V1_OldPU", "fullsim_50ns": "MCRUN2_73_V0_OldPU"},
48  "CMSSW_7_3_0_pre2": {"default": "MCRUN2_73_V1", "fullsim_50ns": "MCRUN2_73_V0"},
49  "CMSSW_7_3_0_pre3": {"default": "MCRUN2_73_V5", "fullsim_50ns": "MCRUN2_73_V4"},
50  "CMSSW_7_3_0": {"default": "MCRUN2_73_V7", "fullsim_50ns": "MCRUN2_73_V6"},
51  "CMSSW_7_3_0_71XGENSIM": {"default": "MCRUN2_73_V7_71XGENSIM"},
52  "CMSSW_7_3_0_71XGENSIM_FIXGT": {"default": "MCRUN2_73_V9_71XGENSIM_FIXGT"},
53  "CMSSW_7_3_1_patch1": {"default": "MCRUN2_73_V9", "fastsim": "MCRUN2_73_V7"},
54  "CMSSW_7_3_1_patch1_GenSim_7113": {"default": "MCRUN2_73_V9_GenSim_7113"},
55  "CMSSW_7_3_3": {"default": "MCRUN2_73_V11", "fullsim_50ns": "MCRUN2_73_V10", "fastsim": "MCRUN2_73_V13"},
56  "CMSSW_7_4_0_pre1": {"default": "MCRUN2_73_V5", "fullsim_50ns": "MCRUN2_73_V4"},
57  "CMSSW_7_4_0_pre2": {"default": "MCRUN2_73_V7", "fullsim_50ns": "MCRUN2_73_V6"},
58  "CMSSW_7_4_0_pre2_73XGENSIM": {"default": "MCRUN2_73_V7_73XGENSIM_Pythia6", "fullsim_50ns": "MCRUN2_73_V6_73XGENSIM_Pythia6"},
59  "CMSSW_7_4_0_pre5": {"default": "MCRUN2_73_V7", "fullsim_50ns": "MCRUN2_73_V6"},
60  "CMSSW_7_4_0_pre5_BS": {"default": "MCRUN2_73_V9_postLS1beamspot", "fullsim_50ns": "MCRUN2_73_V8_postLS1beamspot"},
61  "CMSSW_7_4_0_pre6": {"default": "MCRUN2_74_V1", "fullsim_50ns": "MCRUN2_74_V0"},
62  "CMSSW_7_4_0_pre8": {"default": "MCRUN2_74_V7", "fullsim_25ns": "MCRUN2_74_V5_AsympMinGT", "fullsim_50ns": "MCRUN2_74_V4_StartupMinGT"},
63  "CMSSW_7_4_0_pre8_minimal": {"default": "MCRUN2_74_V5_MinGT", "fullsim_25ns": "MCRUN2_74_V5_AsympMinGT", "fullsim_50ns": "MCRUN2_74_V4_StartupMinGT"},
64  "CMSSW_7_4_0_pre8_25ns_asymptotic": {"default": "MCRUN2_74_V7"},
65  "CMSSW_7_4_0_pre8_50ns_startup": {"default": "MCRUN2_74_V6"},
66  "CMSSW_7_4_0_pre8_50ns_asympref": {"default": "MCRUN2_74_V5A_AsympMinGT"}, # for reference of 50ns asymptotic
67  "CMSSW_7_4_0_pre8_50ns_asymptotic": {"default": "MCRUN2_74_V7A_AsympGT"},
68  "CMSSW_7_4_0_pre8_ROOT6": {"default": "MCRUN2_74_V7"},
69  "CMSSW_7_4_0_pre8_pmx": {"default": "MCRUN2_74_V7", "fullsim_50ns": "MCRUN2_74_V6"},
70  "CMSSW_7_4_0_pre8_pmx_v2": {"default": "MCRUN2_74_V7_gs_pre7", "fullsim_50ns": "MCRUN2_74_V6_gs_pre7"},
71  "CMSSW_7_4_0_pre8_pmx_v3": {"default": "MCRUN2_74_V7_bis", "fullsim_50ns": "MCRUN2_74_V6_bis"},
72  "CMSSW_7_4_0_pre9": {"default": "MCRUN2_74_V7", "fullsim_50ns": "MCRUN2_74_V6"},
73  "CMSSW_7_4_0_pre9_ROOT6": {"default": "MCRUN2_74_V7", "fullsim_50ns": "MCRUN2_74_V6"},
74  "CMSSW_7_4_0_pre9_extended": {"default": "MCRUN2_74_V7_extended"},
75  "CMSSW_7_4_0": {"default": "MCRUN2_74_V7_gensim_740pre7", "fullsim_50ns": "MCRUN2_74_V6_gensim_740pre7", "fastsim": "MCRUN2_74_V7"},
76  "CMSSW_7_4_0_71XGENSIM": {"default": "MCRUN2_74_V7_GENSIM_7_1_15", "fullsim_50ns": "MCRUN2_74_V6_GENSIM_7_1_15"},
77  "CMSSW_7_4_0_71XGENSIM_PU": {"default": "MCRUN2_74_V7_gs7115_puProd", "fullsim_50ns": "MCRUN2_74_V6_gs7115_puProd"},
78  "CMSSW_7_4_0_71XGENSIM_PXworst": {"default": "MCRUN2_74_V7C_pxWorst_gs7115", "fullsim_50ns": "MCRUN2_74_V6A_pxWorst_gs7115"},
79  "CMSSW_7_4_0_71XGENSIM_PXbest": {"default": "MCRUN2_74_V7D_pxBest_gs7115", "fullsim_50ns": "MCRUN2_74_V6B_pxBest_gs7115"},
80  "CMSSW_7_4_0_pmx": {"default": "MCRUN2_74_V7", "fullsim_50ns": "MCRUN2_74_V6"},
81  "CMSSW_7_4_1": {"default": "MCRUN2_74_V9_gensim_740pre7", "fullsim_50ns": "MCRUN2_74_V8_gensim_740pre7", "fastsim": "MCRUN2_74_V9"},
82  "CMSSW_7_4_1_71XGENSIM": {"default": "MCRUN2_74_V9_gensim71X", "fullsim_50ns": "MCRUN2_74_V8_gensim71X"},
83  "CMSSW_7_4_1_extended": {"default": "MCRUN2_74_V9_extended"},
84  "CMSSW_7_4_3": {"default": "MCRUN2_74_V9", "fullsim_50ns": "MCRUN2_74_V8", "fastsim": "MCRUN2_74_V9", "fastsim_25ns": "MCRUN2_74_V9_fixMem"},
85  "CMSSW_7_4_3_extended": {"default": "MCRUN2_74_V9_ext","fastsim": "MCRUN2_74_V9_fixMem"},
86  "CMSSW_7_4_3_pmx": {"default": "MCRUN2_74_V9_ext", "fullsim_50ns": "MCRUN2_74_V8", "fastsim": "MCRUN2_74_V9_fixMem"},
87  "CMSSW_7_4_3_patch1_unsch": {"default": "MCRUN2_74_V9_unsch", "fullsim_50ns": "MCRUN2_74_V8_unsch"},
88  "CMSSW_7_4_4": {"default": "MCRUN2_74_V9_38Tbis", "fullsim_50ns": "MCRUN2_74_V8_38Tbis"},
89  "CMSSW_7_4_4_0T": {"default": "MCRUN2_740TV1_0Tv2", "fullsim_50ns": "MCRUN2_740TV0_0TV2", "fullsim_25ns": "MCRUN2_740TV1_0TV2"},
90  "CMSSW_7_4_6_patch6": {"default": "MCRUN2_74_V9_scheduled", "fullsim_50ns": "MCRUN2_74_V8_scheduled"},
91  "CMSSW_7_4_6_patch6_unsch": {"default": "MCRUN2_74_V9", "fullsim_50ns": "MCRUN2_74_V8"},
92  "CMSSW_7_4_6_patch6_noCCC": {"default": "MCRUN2_74_V9_unsch_noCCC", "fullsim_50ns": "MCRUN2_74_V8_unsch_noCCC"},
93  "CMSSW_7_4_6_patch6_noCCC_v3": {"default": "MCRUN2_74_V9_unsch_noCCC_v3", "fullsim_50ns": "MCRUN2_74_V8_unsch_noCCC_v3"},
94  "CMSSW_7_4_6_patch6_BS": {"default": "74X_mcRun2_asymptotic_realisticBS_v0_2015Jul24", "fullsim_50ns": "74X_mcRun2_startup_realisticBS_v0_2015Jul24PU", "fullsim_25ns": "74X_mcRun2_asymptotic_realisticBS_v0_2015Jul24PU"},
95  "CMSSW_7_4_8_patch1_MT": {"default": "MCRUN2_74_V11_mulTrh", "fullsim_50ns": "MCRUN2_74_V10_mulTrh",},
96  "CMSSW_7_4_12": {"default": "74X_mcRun2_asymptotic_v2", "fullsim_25ns": "74X_mcRun2_asymptotic_v2_v2", "fullsim_50ns": "74X_mcRun2_startup_v2_v2"},
97  "CMSSW_7_5_0_pre1": {"default": "MCRUN2_74_V7", "fullsim_50ns": "MCRUN2_74_V6"},
98  "CMSSW_7_5_0_pre2": {"default": "MCRUN2_74_V7", "fullsim_50ns": "MCRUN2_74_V6"},
99  "CMSSW_7_5_0_pre3": {"default": "MCRUN2_74_V7", "fullsim_50ns": "MCRUN2_74_V6"},
100  "CMSSW_7_5_0_pre4": {"default": "MCRUN2_75_V1", "fullsim_50ns": "MCRUN2_75_V0"},
101  "CMSSW_7_5_0_pre5": {"default": "MCRUN2_75_V5", "fullsim_50ns": "MCRUN2_75_V4"},
102  "CMSSW_7_5_0_pre6": {"default": "75X_mcRun2_asymptotic_v1", "fullsim_50ns": "75X_mcRun2_startup_v1"},
103  "CMSSW_7_5_0": {"default": "75X_mcRun2_asymptotic_v1", "fullsim_50ns": "75X_mcRun2_startup_v1"},
104  "CMSSW_7_5_0_71XGENSIM": {"default": "75X_mcRun2_asymptotic_v1_gs7115", "fullsim_50ns": "75X_mcRun2_startup_v1_gs7115"},
105  "CMSSW_7_5_1": {"default": "75X_mcRun2_asymptotic_v3", "fullsim_50ns": "75X_mcRun2_startup_v3"},
106  "CMSSW_7_5_1_71XGENSIM": {"default": "75X_mcRun2_asymptotic_v3_gs7118", "fullsim_50ns": "75X_mcRun2_startup_v3_gs7118"},
107  "CMSSW_7_5_2": {"default": "75X_mcRun2_asymptotic_v5", "fullsim_50ns": "75X_mcRun2_startup_v4"},
108  "CMSSW_7_6_0_pre1": {"default": "75X_mcRun2_asymptotic_v1", "fullsim_50ns": "75X_mcRun2_startup_v1"},
109  "CMSSW_7_6_0_pre2": {"default": "75X_mcRun2_asymptotic_v2", "fullsim_50ns": "75X_mcRun2_startup_v2"},
110  "CMSSW_7_6_0_pre3": {"default": "75X_mcRun2_asymptotic_v2", "fullsim_50ns": "75X_mcRun2_startup_v2"},
111  "CMSSW_7_6_0_pre4": {"default": "76X_mcRun2_asymptotic_v1", "fullsim_50ns": "76X_mcRun2_startup_v1"},
112  "CMSSW_7_6_0_pre5": {"default": "76X_mcRun2_asymptotic_v1", "fullsim_50ns": "76X_mcRun2_startup_v1"},
113  "CMSSW_7_6_0_pre6": {"default": "76X_mcRun2_asymptotic_v4", "fullsim_50ns": "76X_mcRun2_startup_v4"},
114  "CMSSW_7_6_0_pre7": {"default": "76X_mcRun2_asymptotic_v5", "fullsim_50ns": "76X_mcRun2_startup_v5", "fastsim": "76X_mcRun2_asymptotic_v5_resub"},
115  "CMSSW_7_6_0": {"default": "76X_mcRun2_asymptotic_v11", "fullsim_50ns": "76X_mcRun2_startup_v11"},
116  "CMSSW_7_6_0_71XGENSIM": {"default": "76X_mcRun2_asymptotic_v11_gs7120p2rlBS", "fullsim_50ns": "76X_mcRun2_startup_v11_gs7120p2rlBS"},
117  "CMSSW_7_6_2": {"default": "76X_mcRun2_asymptotic_v12", "fullsim_50ns": "76X_mcRun2_startup_v11"},
118  "CMSSW_7_6_3_patch2_0T": {"default": "76X_mcRun2_0T_v1_0Tv1GT"},
119  "CMSSW_8_0_0_pre1": {"default": "76X_mcRun2_asymptotic_v11", "fullsim_50ns": "76X_mcRun2_startup_v11"},
120  "CMSSW_8_0_0_pre2": {"default": "76X_mcRun2_asymptotic_v12", "fullsim_50ns": "76X_mcRun2_startup_v11"},
121  "CMSSW_8_0_0_pre2_phase1": {"default": "76X_upgrade2017_design_v7"},
122  "CMSSW_8_0_0_pre2_phase1_rereco": {"default": "76X_upgrade2017_design_v7_rereco"},
123  "CMSSW_8_0_0_pre3_phase1": {"default": "76X_upgrade2017_design_v8"},
124  "CMSSW_8_0_0_pre3_phase1_pythia8": {"default": "76X_upgrade2017_design_v8_pythia8"},
125  "CMSSW_8_0_0_pre4": {"default": "76X_mcRun2_asymptotic_v13", "fullsim_50ns": "76X_mcRun2_startup_v12"},
126  "CMSSW_8_0_0_pre4_phase1": {"default": "76X_upgrade2017_design_v8_UPG17"},
127  "CMSSW_8_0_0_pre4_phase1_13TeV": {"default": "76X_upgrade2017_design_v8_UPG17"},
128  "CMSSW_8_0_0_pre4_ecal15fb": {"default": "80X_mcRun2_asymptotic_2016EcalTune_15fb_v0_ecal15fbm1"},
129  "CMSSW_8_0_0_pre4_ecal30fb": {"default": "80X_mcRun2_asymptotic_2016EcalTune_30fb_v0_ecal30fbm1"},
130  "CMSSW_8_0_0_pre5": {"default": "80X_mcRun2_asymptotic_v1", "fullsim_50ns": "80X_mcRun2_startup_v1"},
131  "CMSSW_8_0_0_pre5_phase1": {"default": "80X_upgrade2017_design_v1_UPG17"},
132  "CMSSW_8_0_0_pre6": {"default": "80X_mcRun2_asymptotic_v4"},
133  "CMSSW_8_0_0_pre6_phase1": {"default": "80X_upgrade2017_design_v3_UPG17"},
134  "CMSSW_8_0_0_pre6_MT": {"default": "80X_mcRun2_asymptotic_v4_multiCoreResub"},
135  "CMSSW_8_0_0": {"default": "80X_mcRun2_asymptotic_v4"},
136  "CMSSW_8_0_0_patch1_phase1": {"default": "80X_upgrade2017_design_v4_UPG17"},
137  "CMSSW_8_0_0_patch1_phase1_rereco": {"default": "80X_upgrade2017_design_v4_UPG17_rereco"},
138  "CMSSW_8_0_0_patch2": {"default": "80X_mcRun2_asymptotic_v5_refGT"},
139  "CMSSW_8_0_0_patch2_pixDynIneff": {"default": "80X_mcRun2_asymptotic_v5_2016PixDynIneff_targetGT"},
140 # "CMSSW_8_0_0_patch2": {"default": "80X_mcRun2_asymptotic_v5_refGT"},
141 # "CMSSW_8_0_0_patch2_pixDynIneff": {"default": "80X_mcRun2_asymptotic_v5_2016PixDynIneff_targetGT"},
142  "CMSSW_8_0_0_patch2": {"default": "80X_mcRun2_asymptotic_v5_refGT_resub"},
143  "CMSSW_8_0_0_patch2_pixDynIneff": {"default": "80X_mcRun2_asymptotic_v5_2016PixDynIneff_targetGT_resub"},
144  "CMSSW_8_0_1": {"default": "80X_mcRun2_asymptotic_v6"},
145  "CMSSW_8_0_1_71XGENSIM": {"default": "80X_mcRun2_asymptotic_v6_gs7120p2"},
146  "CMSSW_8_0_1_gcc530": {"default": "80X_mcRun2_asymptotic_v6_gcc530"},
147  "CMSSW_8_0_3_71XGENSIM": {"default": "80X_mcRun2_asymptotic_2016_v3_gs7120p2NewGTv3"},
148  "CMSSW_8_0_3_71XGENSIM_hcal": {"default": "80X_mcRun2_asymptotic_2016_v3_gs71xNewGtHcalCust"},
149  "CMSSW_8_0_3_71XGENSIM_tec": {"default": "80X_mcRun2_asymptotic_SiStripBad_TEC_CL62_for2016_v1_mc_gs7120p2TrkCoolLoop"},
150  "CMSSW_8_0_5": {"default": "80X_mcRun2_asymptotic_v12_gs7120p2", "fastsim": "80X_mcRun2_asymptotic_v12"},
151  "CMSSW_8_0_5_pmx": {"default": "80X_mcRun2_asymptotic_v12_gs7120p2_resub", "fastsim": "80X_mcRun2_asymptotic_v12"},
152  "CMSSW_8_0_10": {"default": "80X_mcRun2_asymptotic_v14"},
153  "CMSSW_8_0_10_patch1_BS": {"default": "80X_mcRun2_asymptotic_RealisticBS_25ns_13TeV2016_v1_mc_realisticBS2016"},
154  "CMSSW_8_0_11": {"default": "80X_mcRun2_asymptotic_v14"},
155  "CMSSW_8_0_15": {"default": "80X_mcRun2_asymptotic_v16_gs7120p2", "fastsim": "80X_mcRun2_asymptotic_v16"},
156  "CMSSW_8_0_16": {"default": "80X_mcRun2_asymptotic_v16_gs7120p2", "fastsim": "80X_mcRun2_asymptotic_v16"},
157  "CMSSW_8_0_16_Tranche4GT": {"default": "80X_mcRun2_asymptotic_2016_TrancheIV_v0_gs7120p2_Tranch4GT",
158  "fastsim": {"default": "80X_mcRun2_asymptotic_2016_TrancheIV_v0_Tranch4GT", "RelValTTbar": "80X_mcRun2_asymptotic_2016_TrancheIV_v0_Tr4GT_resub"}, "fastsim_25ns": "80X_mcRun2_asymptotic_2016_TrancheIV_v0_Tranch4GT"},
159  "CMSSW_8_0_16_Tranche4GT_v2": {"default": "80X_mcRun2_asymptotic_2016_TrancheIV_v2_Tr4GT_v2"},
160  "CMSSW_8_0_16_Tranche4GT_pmx": {"default": "80X_mcRun2_asymptotic_2016_TrancheIV_v0_gs7120p2_Tranch4GT", "fastsim": "80X_mcRun2_asymptotic_2016_TrancheIV_v0_resub"},
161  "CMSSW_8_0_19_Tranche4GT_v2": {"default": "80X_mcRun2_asymptotic_2016_TrancheIV_v2_Tr4GT_v2"},
162  "CMSSW_8_0_20_Tranche4GT": {"default": "80X_mcRun2_asymptotic_2016_TrancheIV_v4_Tr4GT_v4"},
163  "CMSSW_8_0_21_Tranche4GT": {"default": "80X_mcRun2_asymptotic_2016_TrancheIV_v6_Tr4GT_v6"},
164  "CMSSW_8_1_0_pre1": {"default": "80X_mcRun2_asymptotic_v6"},
165  "CMSSW_8_1_0_pre1_phase1": {"default": "80X_upgrade2017_design_v4_UPG17", "fullsim_25ns": "80X_upgrade2017_design_v4_UPG17PU35"},
166  "CMSSW_8_1_0_pre2": {"default": "80X_mcRun2_asymptotic_v10_gs810pre2", "fastsim": "80X_mcRun2_asymptotic_v10"},
167  "CMSSW_8_1_0_pre2_phase1": {"default": "80X_upgrade2017_design_v9_UPG17designGT", "fullsim_25ns": "80X_upgrade2017_design_v9_UPG17PU35designGT"},
168  "CMSSW_8_1_0_pre2_phase1_realGT": {"default": "80X_upgrade2017_realistic_v1_UPG17realGT", "fullsim_25ns": "80X_upgrade2017_realistic_v1_UPG17PU35realGT"},
169  "CMSSW_8_1_0_pre3": {"default": "80X_mcRun2_asymptotic_v12"},
170  "CMSSW_8_1_0_pre3_phase1": {"default": "80X_upgrade2017_realistic_v3_UPG17", "fullsim_25ns": "80X_upgrade2017_realistic_v3_UPG17PU35"},
171  "CMSSW_8_1_0_pre4": {"default": "80X_mcRun2_asymptotic_v13"},
172  "CMSSW_8_1_0_pre4_phase1": {"default": "80X_upgrade2017_realistic_v4_UPG17", "fullsim_25ns": "80X_upgrade2017_realistic_v4_UPG17PU35"},
173  "CMSSW_8_1_0_pre5": {"default": "80X_mcRun2_asymptotic_v13"},
174  "CMSSW_8_1_0_pre5_phase1": {"default": "80X_upgrade2017_realistic_v4_resubUPG17", "fullsim_25ns": "80X_upgrade2017_realistic_v4_resubUPG17PU35"},
175  "CMSSW_8_1_0_pre6": {"default": "80X_mcRun2_asymptotic_v14"},
176  "CMSSW_8_1_0_pre6_phase1": {"default": "81X_upgrade2017_realistic_v0_UPG17", "fullsim_25ns": "81X_upgrade2017_realistic_v0_UPG17PU35"},
177  "CMSSW_8_1_0_pre7": {"default": "81X_mcRun2_asymptotic_v0"},
178  "CMSSW_8_1_0_pre7_phase1": {"default": "81X_upgrade2017_realistic_v2_UPG17", "fullsim_25ns": "81X_upgrade2017_realistic_v2_UPG17PU35"},
179  "CMSSW_8_1_0_pre7_phase1_newGT": {"default": "81X_upgrade2017_realistic_v3_UPG17newGT", "fullsim_25ns": "81X_upgrade2017_realistic_v3_UPG17PU35newGTresub"},
180  "CMSSW_8_1_0_pre7_phase2": {"2023GReco": "81X_mcRun2_asymptotic_v0_2023GReco", "2023GRecoPU35": "", "2023GRecoPU140": "81X_mcRun2_asymptotic_v0_2023GRecoPU140resubmit2", "2023GRecoPU200": "81X_mcRun2_asymptotic_v0_2023GRecoPU200resubmit2",
181  "2023tilted": "81X_mcRun2_asymptotic_v0_2023tilted", "2023tiltedPU35": "", "2023tiltedPU140": "81X_mcRun2_asymptotic_v0_2023tiltedPU140resubmit2", "2023tiltedPU200": "81X_mcRun2_asymptotic_v0_2023tiltedPU200resubmit2"},
182  "CMSSW_8_1_0_pre8": {"default": "81X_mcRun2_asymptotic_v1"},
183  "CMSSW_8_1_0_pre8_phase1": {"default": "81X_upgrade2017_realistic_v3_UPG17", "fullsim_25ns": "81X_upgrade2017_realistic_v3_UPG17PU35"},
184  "CMSSW_8_1_0_pre8_phase1_newGT": {"default": "81X_upgrade2017_realistic_v4_UPG17newGT", "fullsim_25ns": "81X_upgrade2017_realistic_v4_UPG17PU35newGT"},
185  "CMSSW_8_1_0_pre8_phase1_newGT2": {"default": "81X_upgrade2017_realistic_v5_UPG17newGTset2", "fullsim_25ns": "81X_upgrade2017_realistic_v5_UPG17PU35newGTset2"},
186  "CMSSW_8_1_0_pre8_phase2": {"2023GReco": "81X_mcRun2_asymptotic_v1_resub2023GReco", "2023GRecoPU35": "81X_mcRun2_asymptotic_v1_resub2023GRecoPU35", "2023GRecoPU140": "81X_mcRun2_asymptotic_v1_resub2023GRecoPU140", "2023GRecoPU200": "81X_mcRun2_asymptotic_v1_resub2023GRecoPU200",
187  "2023tilted": "81X_mcRun2_asymptotic_v1_2023tilted", "2023tiltedPU35": "81X_mcRun2_asymptotic_v1_2023tiltedPU", "2023tiltedPU140": "81X_mcRun2_asymptotic_v1_2023tiltedPU140", "2023tiltedPU200": "81X_mcRun2_asymptotic_v1_2023tiltedPU200"},
188  "CMSSW_8_1_0_pre9": {"default": "81X_mcRun2_asymptotic_v2"},
189  "CMSSW_8_1_0_pre9_Geant4102": {"default": "81X_mcRun2_asymptotic_v2"},
190  "CMSSW_8_1_0_pre9_phase1": {"default": "81X_upgrade2017_realistic_v5_UPG17", "fullsim_25ns": "81X_upgrade2017_realistic_v5_UPG17PU35"},
191  "CMSSW_8_1_0_pre9_phase1_newGT": {"default": "81X_upgrade2017_realistic_v6_UPG17newGT", "fullsim_25ns": "81X_upgrade2017_realistic_v6_UPG17PU35newGT"},
192  "CMSSW_8_1_0_pre10": {"default": "81X_mcRun2_asymptotic_v5_recycle", "fullsim_25ns": "81X_mcRun2_asymptotic_v5_resub", "fastsim": "81X_mcRun2_asymptotic_v5"},
193  "CMSSW_8_1_0_pre10_pmx": {"default": "81X_mcRun2_asymptotic_v5"},
194  "CMSSW_8_1_0_pre10_phase1": {"default": "81X_upgrade2017_realistic_v9_UPG17resub", "fullsim_25ns": "81X_upgrade2017_realistic_v9_UPG17PU35resub"},
195  "CMSSW_8_1_0_pre11": {"default": "81X_mcRun2_asymptotic_Candidate_2016_08_30_11_31_55", "fullsim_25ns": "81X_mcRun2_asymptotic_Candidate_2016_08_30_11_31_55_resub", "fastsim_25ns": "81X_mcRun2_asymptotic_Candidate_2016_08_30_11_31_55_resub2"},
196  "CMSSW_8_1_0_pre11_pmx": {"default": "81X_mcRun2_asymptotic_Candidate_2016_08_30_11_31_55"},
197  "CMSSW_8_1_0_pre11_phase1": {"default": "81X_upgrade2017_realistic_v9_UPG17", "fullsim_25ns": "81X_upgrade2017_realistic_v9_UPG17PU35"},
198  "CMSSW_8_1_0_pre12": {"default": "81X_mcRun2_asymptotic_v8", "fullsim_25ns": "81X_mcRun2_asymptotic_v8_resub", "fastsim": "81X_mcRun2_asymptotic_v8_resub", "fastsim_25ns": "81X_mcRun2_asymptotic_v8"},
199  "CMSSW_8_1_0_pre12_pmx": {"default": "81X_mcRun2_asymptotic_v8_resub", "fastsim_25ns": "81X_mcRun2_asymptotic_v8_rsub"},
200  "CMSSW_8_1_0_pre12_phase1": {"default": "81X_upgrade2017_realistic_v13"},
201  "CMSSW_8_1_0_pre12_phase1_newBPix": {"default": "81X_upgrade2017_realistic_newBPix_wAlign_v1_BpixGeom"},
202  "CMSSW_8_1_0_pre12_phase1_newBPixFPix": {"default": "81X_upgrade2017_realistic_v13_BpixFpixGeom"},
203  "CMSSW_8_1_0_pre12_phase1_newBPixFPixHCAL": {"default": "81X_upgrade2017_HCALdev_v2_BpixFpixHcalGeom"},
204  "CMSSW_8_1_0_pre12_phase1_newHCAL": {"default": "81X_upgrade2017_HCALdev_v2_HcalGeom"},
205  "CMSSW_8_1_0_pre12_phase1_newBPixHCAL": {"default": "81X_upgrade2017_HCALdev_v2_NewBPix_BpixHcalGeom"},
206  "CMSSW_8_1_0_pre15": {"default": "81X_mcRun2_asymptotic_v11"},
207  "CMSSW_8_1_0_pre15_HIP": {"default": "81X_mcRun2_asymptotic_v11_hip"},
208  "CMSSW_8_1_0_pre15_PU": {"default": "81X_mcRun2_asymptotic_v11_M17"},
209  "CMSSW_8_1_0_pre15_PU_HIP": {"default": "81X_mcRun2_asymptotic_v11_hipM17"},
210  "CMSSW_8_1_0_pre15_phase1": {"default": "81X_upgrade2017_realistic_v17_BpixFpixHcalGeom",
211  "Design": "81X_upgrade2017_design_IdealBS_v1_2017design", "Design_fullsim_25ns": "81X_upgrade2017_design_IdealBS_v1_design"},
212  "CMSSW_8_1_0_pre16": {"default": "81X_mcRun2_asymptotic_v11"},
213  "CMSSW_8_1_0_pre16_phase1": {"default": "81X_upgrade2017_realistic_v22", "Design": "81X_upgrade2017_design_IdealBS_v6"},
214  "CMSSW_8_1_0": {"default": "81X_mcRun2_asymptotic_v12"},
215  "CMSSW_8_1_0_phase1": {"default": "81X_upgrade2017_realistic_v26_HLT2017"},
216  "CMSSW_9_0_0_pre1": {"default": "90X_mcRun2_asymptotic_v0"},
217  "CMSSW_9_0_0_pre1_phase1": {"default": "90X_upgrade2017_realistic_v0",
218  "Design": "90X_upgrade2017_design_IdealBS_v0", "Design_fullsim_25ns": "90X_upgrade2017_design_IdealBS_v0_resub"},
219  "CMSSW_9_0_0_pre2": {"default": "90X_mcRun2_asymptotic_v0"},
220  "CMSSW_9_0_0_pre2_ROOT6": {"default": "90X_mcRun2_asymptotic_v0"},
221  "CMSSW_9_0_0_pre2_phase1": {"default": "90X_upgrade2017_realistic_v0",
222  "Design": "90X_upgrade2017_design_IdealBS_v0", "Design_fullsim_25ns": "90X_upgrade2017_design_IdealBS_v0_resub"},
223  "CMSSW_9_0_0_pre4": {"default": "90X_mcRun2_asymptotic_v1", "fullsim_25ns": "90X_mcRun2_asymptotic_v1_resub"},
224  "CMSSW_9_0_0_pre4_phase1": {"default": "90X_upgrade2017_realistic_v6", "fullsim_25ns_PU50": "Nonexistent",
225  "Design": "90X_upgrade2017_design_IdealBS_v6"},
226  "CMSSW_9_0_0_pre4_GS": {"default": "90X_mcRun2_asymptotic_v1_GSval", "fullsim_25ns": "90X_mcRun2_asymptotic_v1_GSval"},
227  "CMSSW_9_0_0_pre4_phase1_ecalsrb5": {"default": "90X_upgrade2017_realistic_v6_B5"},
228  "CMSSW_9_0_0_pre4_phase1_ecalsrc1": {"default": "90X_upgrade2017_realistic_v6_C1"},
229  "CMSSW_9_0_0_pre4_phase1_ecalsrd7": {"default": "90X_upgrade2017_realistic_v6_D7"},
230  "CMSSW_9_0_0_pre5": {"default": "90X_mcRun2_asymptotic_v4"},
231  "CMSSW_9_0_0_pre5_pmx": {"default": "90X_mcRun2_asymptotic_v4", "fastsim_25ns": "90X_mcRun2_asymptotic_v4_resub"},
232  "CMSSW_9_0_0_pre5_phase1": {"default": "90X_upgrade2017_realistic_v15",
233  "fullsim_25ns_PU35": "90X_upgrade2017_realistic_v15_resub", "fullsim_25ns_PU50": "90X_upgrade2017_realistic_v15_PU50",
234  "Design": "90X_upgrade2017_design_IdealBS_v15"},
235  "CMSSW_9_0_0_pre6": {"default": "90X_mcRun2_asymptotic_v4"},
236  "CMSSW_9_0_0_pre6_phase1": {"default": "90X_upgrade2017_realistic_v15",
237  "fullsim_25ns_PU50": "90X_upgrade2017_realistic_v15_PU50",
238  "Design": "90X_upgrade2017_design_IdealBS_v15"},
239  "CMSSW_9_0_0": {"default": "90X_mcRun2_asymptotic_v5"},
240  "CMSSW_9_0_0_phase1": {"default": "90X_upgrade2017_realistic_v20_resub",
241  "fullsim_25ns_PU50": "90X_upgrade2017_realistic_v20_PU50_resub",
242  "Design": "90X_upgrade2017_design_IdealBS_v19_resub"},
243  "CMSSW_9_0_0_gcc630": {"default": "90X_mcRun2_asymptotic_v5_gcc630"},
244  "CMSSW_9_0_0_phase1_gcc630": {"default": "90X_upgrade2017_realistic_v20_gcc630"},
245  "CMSSW_9_0_0_cc7": {"default": "90X_mcRun2_asymptotic_v5_cc7"},
246  "CMSSW_9_0_0_phase1_cc7": {"default": "90X_upgrade2017_realistic_v20_cc7_rsb"},
247  "CMSSW_9_0_2_phase1": {"default": "90X_upgrade2017_realistic_v20",
248  "fullsim_25ns_PU50": "90X_upgrade2017_realistic_v20_PU50",
249  "Design": "90X_upgrade2017_design_IdealBS_v19"},
250  "CMSSW_9_1_0_pre1": {"default": "90X_mcRun2_asymptotic_v5"},
251  "CMSSW_9_1_0_pre1_phase1": {"default": "90X_upgrade2017_realistic_v20",
252  "fullsim_25ns_PU50": "90X_upgrade2017_realistic_v20_PU50",
253  "Design": "90X_upgrade2017_design_IdealBS_v19_resub"},
254  "CMSSW_9_1_0_pre2": {"default": "90X_mcRun2_asymptotic_v5"},
255  "CMSSW_9_1_0_pre2_phase1": {"default": "90X_upgrade2017_realistic_v20",
256  "fullsim_25ns_PU50": "90X_upgrade2017_realistic_v20_PU50",
257  "Design": "90X_upgrade2017_design_IdealBS_v19"},
258  "CMSSW_9_1_0_pre3": {"default": "91X_mcRun2_asymptotic_v2"},
259  "CMSSW_9_1_0_pre3_phase1": {"default": "91X_upgrade2017_realistic_v3",
260  "fullsim_25ns_PU50": "91X_upgrade2017_realistic_v3_PU50_resub",
261  "Design": "91X_upgrade2017_design_IdealBS_v3"},
262  "CMSSW_9_2_0": {"default": "91X_mcRun2_asymptotic_v3"},
263  "CMSSW_9_2_0_phase1": {"default": "91X_upgrade2017_realistic_v5",
264  "fullsim_25ns_PU50": "91X_upgrade2017_realistic_v5_PU50",
265  "Design": "91X_upgrade2017_design_IdealBS_v5"},
266  "CMSSW_9_2_0_phase1_PXmap": {"default": "91X_upgrade2017_realistic_v5_pixel_ideal_PXgeom"},
267  "CMSSW_9_2_1_phase1": {"default": "92X_upgrade2017_realistic_v1",
268  "fullsim_25ns_PU50": "92X_upgrade2017_realistic_v1_PU50",
269  "Design": "92X_upgrade2017_design_IdealBS_v1"},
270  "CMSSW_9_2_2": {"default": "91X_mcRun2_asymptotic_v3"},
271  "CMSSW_9_2_2_phase1": {"default": "92X_upgrade2017_realistic_v1",
272  "fullsim_25ns_PU50": "92X_upgrade2017_realistic_v1_highPU_AVE50",
273  "Design": "92X_upgrade2017_design_IdealBS_v1"},
274  "CMSSW_9_2_4_run1": {"default": "91X_mcRun1_realistic_v2"},
275  "CMSSW_9_2_4": {"default": "91X_mcRun2_asymptotic_v3"},
276  "CMSSW_9_2_7_phase1": {"default": "92X_upgrade2017_realistic_v7"},
277  "CMSSW_9_3_0_pre1": {"default": "92X_mcRun2_asymptotic_v2"},
278  "CMSSW_9_3_0_pre1_phase1": {"default": "92X_upgrade2017_realistic_v7",
279  "fullsim_25ns_PU50": "92X_upgrade2017_realistic_v7_highPU_AVE50",
280  "Design": "92X_upgrade2017_design_IdealBS_v7"},
281  "CMSSW_9_3_0_pre1_run1": {"default": "92X_mcRun1_realistic_v2"},
282  "CMSSW_9_3_0_pre2": {"default": "92X_mcRun2_asymptotic_v2"},
283  "CMSSW_9_3_0_pre2_phase1": {"default": "92X_upgrade2017_realistic_v7",
284  "fullsim_25ns_PU50": "92X_upgrade2017_realistic_v7_highPU_AVE50_resub",
285  "Design": "92X_upgrade2017_design_IdealBS_v7"},
286 }
287 
288 _releasePostfixes = ["_AlcaCSA14", "_PHYS14", "_TEST", "_v2", "_v3", "_pmx", "_Fall14DR", "_FIXGT", "_PU", "_PXbest", "_PXworst", "_hcal", "_tec", "_71XGENSIM", "_73XGENSIM", "_BS", "_GenSim_7113", "_extended",
289  "_25ns_asymptotic", "_50ns_startup", "_50ns_asympref", "_50ns_asymptotic", "_minimal", "_0T", "_unsch", "_noCCC", "_MT", "_GS", "_rereco", "_pythia8", "_13TeV", "_realGT", "_newGT2", "_newGT", "_phase1", "_phase2", "_ecal15fb", "_ecal30fb", "_ecalsrb5", "_ecalsrc1", "_ecalsrd7", "_pixDynIneff", "_PXmap", "_gcc530", "_gcc630", "_cc7", "_Tranche4GT", "_newBPixFPixHCAL", "_newBPixFPix", "_newBPixHCAL", "_newBPix", "_newHCAL", "_HIP", "_run1"]
290 def _stripRelease(release):
291  for pf in _releasePostfixes:
292  if pf in release:
293  return _stripRelease(release.replace(pf, ""))
294  return release
295 
296 
297 def _getGlobalTag(sample, release):
298  """Get a GlobalTag.
299 
300  Arguments:
301  sample -- Sample object
302  release -- CMSSW release string
303  """
304  if not release in _globalTags:
305  print "Release %s not found from globaltag map in validation.py" % release
306  sys.exit(1)
307  gtmap = _globalTags[release]
308  selectedGT = None
309  if sample.hasOverrideGlobalTag():
310  ogt = sample.overrideGlobalTag()
311  if release in ogt:
312  gtmap = _globalTags[ogt[release]]
313  scenario = ""
314  if sample.hasScenario():
315  scenario = sample.scenario()
316  sims = []
317  if sample.fullsim():
318  if sample.pileupEnabled():
319  sim = "fullsim_"+sample.pileupType()
320  sims.extend([
321  sim+"_PU%d"%sample.pileupNumber(),
322  sim
323  ])
324  elif sample.fastsim():
325  sim = "fastsim"
326  if sample.pileupEnabled():
327  sim += "_"+sample.pileupType()
328  sims.append(sim+"_PU%d"%sample.pileupNumber())
329  sims.append(sim)
330 
331  selectedGT = None
332  # First try with scenario+simulation
333  if scenario != "":
334  for sim in sims:
335  selectedGT = gtmap.get(scenario+"_"+sim, None)
336  if selectedGT is not None:
337  break
338  # Then with scenario (but only if sample specifies a scenario)
339  if selectedGT is None:
340  selectedGT = gtmap.get(scenario, None)
341  # Then with simulation
342  if selectedGT is None:
343  for sim in sims:
344  selectedGT = gtmap.get(sim, None)
345  if selectedGT is not None:
346  break
347  # Finally default
348  if selectedGT is None:
349  selectedGT = gtmap["default"]
350 
351  if isinstance(selectedGT, dict):
352  return selectedGT.get(sample.name(), selectedGT["default"])
353  else:
354  return selectedGT
355 
356 # Mapping from release series to RelVal download URLs
357 _relvalUrls = {
358  "6_2_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_6_2_x/",
359  "7_0_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_0_x/",
360  "7_1_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_1_x/",
361  "7_2_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_2_x/",
362  "7_3_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_3_x/",
363  "7_4_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_4_x/",
364  "7_5_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_5_x/",
365  "7_6_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_6_x/",
366  "8_0_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_8_0_x/",
367  "8_1_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_8_1_x/",
368  "9_0_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_0_x/",
369  "9_1_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_1_x/",
370  "9_2_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_2_x/",
371  "9_3_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_3_x/",
372 }
373 
374 _doElectronSamples = [
375  "RelValTTbar",
376  "RelValSingleElectronPt35",
377  "RelValSingleElectronPt10",
378 ]
379 _doConversionSamples = [
380  "RelValTTbar",
381  "RelValH125GGgluonfusion",
382 ]
383 _doBHadronSamples = [
384  "RelValTTbar"
385 ]
386 
387 def _getRelValUrl(release):
388  """Get RelVal download URL for a given release."""
389  version_re = re.compile("CMSSW_(?P<X>\d+)_(?P<Y>\d+)")
390  m = version_re.search(release)
391  if not m:
392  raise Exception("Regex %s does not match to release version %s" % (version_re.pattern, release))
393  version = "%s_%s_X" % (m.group("X"), m.group("Y"))
394  if not version in _relvalUrls:
395  print "No RelVal URL for version %s, please update _relvalUrls" % version
396  sys.exit(1)
397  return _relvalUrls[version]
398 
399 def _processPlotsForSample(plotterFolder, sample):
400  if plotterFolder.onlyForPileup() and not sample.pileupEnabled():
401  return False
402  if plotterFolder.onlyForElectron() and not sample.doElectron():
403  return False
404  if plotterFolder.onlyForConversion() and not sample.doConversion():
405  return False
406  if plotterFolder.onlyForBHadron() and not sample.doBHadron():
407  return False
408  return True
409 
410 class Sample:
411  """Represents a RelVal sample."""
412  def __init__(self, sample, append=None, midfix=None, putype=None, punum=0,
413  fastsim=False, fastsimCorrespondingFullsimPileup=None,
414  doElectron=None, doConversion=None, doBHadron=None,
415  version="v1", dqmVersion="0001", scenario=None, overrideGlobalTag=None, appendGlobalTag=""):
416  """Constructor.
417 
418  Arguments:
419  sample -- String for name of the sample
420 
421  Keyword arguments
422  append -- String for a variable name within the DWM file names, to be directly appended to sample name (e.g. "HS"; default None)
423  midfix -- String for a variable name within the DQM file names, to be appended after underscore to "sample name+append" (e.g. "13", "UP15"; default None)
424  putype -- String for pileup type (e.g. "25ns"/"50ns" for FullSim, "AVE20" for FastSim; default None)
425  punum -- String for amount of pileup (default None)
426  fastsim -- Bool indicating the FastSim status (default False)
427  fastsimCorrespondingFullSimPileup -- String indicating what is the FullSim pileup sample corresponding this FastSim sample. Must be set if fastsim=True and putype!=None (default None)
428  doElectron -- Bool specifying if electron-specific plots should be produced (default depends on sample)
429  doConversion -- Bool specifying if conversion-specific plots should be produced (default depends on sample)
430  doBHadron -- Bool specifying if B-hadron-specific plots should be produced (default depends on sample)
431  version -- String for dataset/DQM file version (default "v1")
432  scenario -- Geometry scenario for upgrade samples (default None)
433  overrideGlobalTag -- GlobalTag obtained from release information (in the form of {"release": "actualRelease"}; default None)
434  appendGlobalTag -- String to append to GlobalTag (intended for one-time hacks; default "")
435  """
436  self._sample = sample
437  self._append = append
438  self._midfix = midfix
439  self._putype = putype
440  self._punum = punum
441  self._fastsim = fastsim
442  self._fastsimCorrespondingFullsimPileup = fastsimCorrespondingFullsimPileup
443  self._version = version
444  self._dqmVersion = dqmVersion
445  self._scenario = scenario
446  self._overrideGlobalTag = overrideGlobalTag
447  self._appendGlobalTag = appendGlobalTag
448 
449  if doElectron is not None:
450  self._doElectron = doElectron
451  else:
452  self._doElectron = (sample in _doElectronSamples)
453  if doConversion is not None:
454  self._doConversion = doConversion
455  else:
456  self._doConversion = (sample in _doConversionSamples)
457  if doBHadron is not None:
458  self._doBHadron = doBHadron
459  else:
460  self._doBHadron = (sample in _doBHadronSamples)
461 
462  if self._fastsim and self.hasPileup() and self._fastsimCorrespondingFullsimPileup is None:
464 
465  def digest(self):
466  """Return a tuple uniquely identifying the sample, to be used e.g. as a key to dict"""
467  return (self.name(), self.pileupNumber(), self.pileupType(), self.scenario(), self.fastsim())
468 
469  def sample(self):
470  """Get the sample name"""
471  return self._sample
472 
473  def name(self):
474  """Get the sample name"""
475  return self._sample
476 
477  def label(self):
478  return self._sample
479 
480  def hasPileup(self):
481  """Return True if sample has pileup (for HTML generation)"""
482  return self._putype is not None
483 
484  def pileupEnabled(self):
485  """Return True if pileup plots are enabled (for plot generation)"""
486  return self.hasPileup()
487 
488  def pileup(self):
489  """Return "PU"/"noPU" corresponding the pileup status"""
490  if self.hasPileup():
491  return "PU"
492  else:
493  return "noPU"
494 
495  def pileupType(self, release=None):
496  """Return the pileup type"""
497  if isinstance(self._putype, dict):
498  return self._putype.get(release, self._putype["default"])
499  else:
500  return self._putype
501 
502  def pileupNumber(self):
503  return self._punum
504 
505  def doElectron(self):
506  return self._doElectron
507 
508  def doConversion(self):
509  return self._doConversion
510 
511  def doBHadron(self):
512  return self._doBHadron
513 
514  def version(self, release=None):
515  if isinstance(self._version, dict):
516  return self._version.get(release, self._version["default"])
517  else:
518  return self._version
519 
520  def hasScenario(self):
521  return self._scenario is not None
522 
523  def scenario(self):
524  return self._scenario
525 
527  return self._overrideGlobalTag is not None
528 
529  def overrideGlobalTag(self):
530  return self._overrideGlobalTag
531 
532  def fastsim(self):
533  """Return True for FastSim sample"""
534  return self._fastsim
535 
536  def fullsim(self):
537  """Return True for FullSim sample"""
538  return not self._fastsim
539 
542 
543  def dirname(self, newRepository, newRelease, newSelection):
544  """Return the output directory name
545 
546  Arguments:
547  newRepository -- String for base directory for output files
548  newRelease -- String for CMSSW release
549  newSelection -- String for histogram selection
550  """
551  pileup = ""
552  if self.hasPileup() and not self._fastsim:
553  pileup = "_"+self._putype
554  return "{newRepository}/{newRelease}/{newSelection}{pileup}/{sample}".format(
555  newRepository=newRepository, newRelease=newRelease, newSelection=newSelection,
556  pileup=pileup, sample=sample)
557 
558  def filename(self, newRelease):
559  """Return the DQM file name
560 
561  Arguments:
562  newRelease -- String for CMSSW release
563  """
564  pileup = ""
565  fastsim = ""
566  midfix = ""
567  sample = self._sample
568  if self._append is not None:
569  midfix += self._append
570  if self._midfix is not None:
571  midfix += "_"+self._midfix
572  if self.hasPileup():
573  if self._fastsim:
574  #sample = sample.replace("RelVal", "RelValFS_")
575  # old style
576  #pileup = "PU_"
577  #midfix += "_"+self.pileupType(newRelease)
578  # new style
579  pileup = "PU"+self.pileupType(newRelease)+"_"
580  else:
581  pileup = "PU"+self.pileupType(newRelease)+"_"
582  if self._fastsim:
583  fastsim = "_FastSim"
584 
585  globalTag = _getGlobalTag(self, newRelease)
586 
587  fname = 'DQM_V{dqmVersion}_R000000001__{sample}{midfix}__{newrelease}-{pileup}{globaltag}{appendGlobalTag}{fastsim}-{version}__DQMIO.root'.format(
588  sample=sample, midfix=midfix, newrelease=_stripRelease(newRelease),
589  pileup=pileup, globaltag=globalTag, appendGlobalTag=self._appendGlobalTag, fastsim=fastsim,
590  version=self.version(newRelease), dqmVersion=self._dqmVersion
591  )
592 
593  return fname
594 
595  def datasetpattern(self, newRelease):
596  """Return the dataset pattern
597 
598  Arguments:
599  newRelease -- String for CMSSW release
600  """
601  pileup = ""
602  fastsim = ""
603  digi = ""
604  if self.hasPileup():
605  pileup = "-PU_"
606  if self._fastsim:
607  fastsim = "_FastSim-"
608  digi = "DIGI-"
609  else:
610  fastsim = "*"
611  globalTag = _getGlobalTag(self, newRelease)
612  return "{sample}/{newrelease}-{pileup}{globaltag}{fastsim}{version}/GEN-SIM-{digi}RECO".format(
613  sample=self._sample, newrelease=newRelease,
614  pileup=pileup, globaltag=globalTag, fastsim=fastsim, digi=digi,
615  version=self.version(newRelease)
616  )
617 
619  """Base class for Tracking/Vertex validation."""
620  def __init__(self, fullsimSamples, fastsimSamples, refRelease, refRepository, newRelease, newRepository, newFileModifier=None, selectionName=""):
621  """Constructor.
622 
623  Arguments:
624  fullsimSamples -- List of Sample objects for FullSim samples (may be empty)
625  fastsimSamples -- List of Sample objects for FastSim samples (may be empty)
626  refRelease -- String for reference CMSSW release (can be None for no reference release)
627  newRepository -- String for directory whete to put new files
628  newRelease -- CMSSW release to be validated
629  refRepository -- String for directory where reference root files are
630  newFileModifier -- If given, a function to modify the names of the new files (function takes a string and returns a string)
631  selectionName -- If given, use this string as the selection name (appended to GlobalTag for directory names)
632  """
633  try:
634  self._newRelease = os.environ["CMSSW_VERSION"]
635  except KeyError:
636  print >>sys.stderr, 'Error: CMSSW environment variables are not available.'
637  print >>sys.stderr, ' Please run cmsenv'
638  sys.exit()
639 
640  self._fullsimSamples = fullsimSamples
641  self._fastsimSamples = fastsimSamples
642  self._refRelease = refRelease
643  self._refRepository = refRepository
644  self._newRelease = newRelease
645  self._newBaseDir = os.path.join(newRepository, self._newRelease)
646  self._newFileModifier = newFileModifier
647  self._selectionName = selectionName
648 
649  def _getDirectoryName(self, *args, **kwargs):
650  return None
651 
652  def _getSelectionName(self, *args, **kwargs):
653  return self._selectionName
654 
655  def download(self):
656  """Download DQM files. Requires grid certificate and asks your password for it."""
657  filenames = [s.filename(self._newRelease) for s in self._fullsimSamples+self._fastsimSamples]
658  if self._newFileModifier is not None:
659  filenames = map(self._newFileModifier, filenames)
660  filenames = filter(lambda f: not os.path.exists(f), filenames)
661  if len(filenames) == 0:
662  print "All files already downloaded"
663  return
664 
665  relvalUrl = _getRelValUrl(self._newRelease)
666  urls = [relvalUrl+f for f in filenames]
667  certfile = os.path.join(os.environ["HOME"], ".globus", "usercert.pem")
668  if not os.path.exists(certfile):
669  print "Certificate file {certfile} does not exist, unable to download RelVal files from {url}".format(certfile=certfile, url=relvalUrl)
670  sys.exit(1)
671  keyfile = os.path.join(os.environ["HOME"], ".globus", "userkey.pem")
672  if not os.path.exists(certfile):
673  print "Private key file {keyfile} does not exist, unable to download RelVal files from {url}".format(keyfile=keyfile, url=relvalUrl)
674  sys.exit(1)
675 
676  # curl --cert-type PEM --cert $HOME/.globus/usercert.pem --key $HOME/.globus/userkye.pem -k -O <url> -O <url>
677  cmd = ["curl", "--cert-type", "PEM", "--cert", certfile, "--key", keyfile, "-k"]
678  for u in urls:
679  cmd.extend(["-O", u])
680  print "Downloading %d files from RelVal URL %s:" % (len(filenames), relvalUrl)
681  print " "+"\n ".join(filenames)
682  print "Please provide your private key pass phrase when curl asks it"
683  ret = subprocess.call(cmd)
684  if ret != 0:
685  print "Downloading failed with exit code %d" % ret
686  sys.exit(1)
687 
688  # verify
689  allFine = True
690  for f in filenames:
691  p = subprocess.Popen(["file", f], stdout=subprocess.PIPE)
692  stdout = p.communicate()[0]
693  if p.returncode != 0:
694  print "file command failed with exit code %d" % p.returncode
695  sys.exit(1)
696  if not "ROOT" in stdout:
697  print "File {f} is not ROOT, please check the correct version, GlobalTag etc. from {url}".format(f=f, url=relvalUrl)
698  allFine = False
699  if os.path.exists(f):
700  os.remove(f)
701  if not allFine:
702  sys.exit(1)
703 
704  def createHtmlReport(self):
705  return html.HtmlReport(self._newRelease, self._newBaseDir)
706 
707  def doPlots(self, plotter, plotterDrawArgs={}, limitSubFoldersOnlyTo=None, htmlReport=html.HtmlReportDummy(), doFastVsFull=True, doPhase2PU=False):
708  """Create validation plots.
709 
710  Arguments:
711  plotter -- plotting.Plotter object that does the plotting
712 
713  Keyword arguments:
714  plotterDrawArgs -- Dictionary for additional arguments to Plotter.draw() (default: {})
715  limitSubFoldersOnlyTo -- If not None, should be a dictionary from string to an object. The string is the name of a PlotFolder, and the object is PlotFolder-type specific to limit the subfolders to be processed. In general case the object is a list of strings, but e.g. for track iteration plots it is a function taking the algo and quality as parameters.
716  htmlReport -- Object returned by createHtmlReport(), in case HTML report generation is desired
717  doFastVsFull -- Do FastSim vs. FullSim comparison? (default: True)
718  doPhase2PU -- Do Phase2 PU 200 vs. 140 comparison (default: False)
719  """
720  self._plotter = plotter
721  self._plotterDrawArgs = plotterDrawArgs
722 
723  # New vs. Ref
724  for sample in self._fullsimSamples+self._fastsimSamples:
725  # Check that the new DQM file exists
726  harvestedFile = sample.filename(self._newRelease)
727  if not os.path.exists(harvestedFile):
728  print "Harvested file %s does not exist!" % harvestedFile
729  sys.exit(1)
730 
731  plotterInstance = plotter.readDirs(harvestedFile)
732  htmlReport.beginSample(sample)
733  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
734  if not _processPlotsForSample(plotterFolder, sample):
735  continue
736  plotFiles = self._doPlots(sample, harvestedFile, plotterFolder, dqmSubFolder, htmlReport)
737  htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
738 
739  # Fast vs. Full
740  if doFastVsFull:
741  self._doFastsimFastVsFullPlots(limitSubFoldersOnlyTo, htmlReport)
742 
743  # Phase2 PU200 vs. PU 140
744  if doPhase2PU:
745  self._doPhase2PileupPlots(limitSubFoldersOnlyTo, htmlReport)
746 
747  def _doFastsimFastVsFullPlots(self, limitSubFoldersOnlyTo, htmlReport):
748  for fast in self._fastsimSamples:
749  correspondingFull = None
750  for full in self._fullsimSamples:
751  if fast.name() != full.name():
752  continue
753  if fast.pileupEnabled():
754  if not full.pileupEnabled():
755  continue
756  if fast.fastsimCorrespondingFullsimPileup() != full.pileupType():
757  continue
758  else:
759  if full.pileupEnabled():
760  continue
761 
762  if correspondingFull is None:
763  correspondingFull = full
764  else:
765  raise Exception("Got multiple compatible FullSim samples for FastSim sample %s %s" % (fast.name(), fast.pileup()))
766  if correspondingFull is None:
767  print "WARNING: Did not find compatible FullSim sample for FastSim sample %s %s, omitting FastSim vs. FullSim comparison" % (fast.name(), fast.pileup())
768  continue
769 
770  # If we reach here, the harvestedFile must exist
771  harvestedFile = fast.filename(self._newRelease)
772  plotterInstance = self._plotter.readDirs(harvestedFile)
773  htmlReport.beginSample(fast, fastVsFull=True)
774  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
775  if not _processPlotsForSample(plotterFolder, fast):
776  continue
777  plotFiles = self._doPlotsFastFull(fast, correspondingFull, plotterFolder, dqmSubFolder, htmlReport)
778  htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
779 
780  def _doPhase2PileupPlots(self, limitSubFoldersOnlyTo, htmlReport):
781  def _stripScenario(name):
782  puindex = name.find("PU")
783  if puindex < 0:
784  return name
785  return name[:puindex]
786 
787  pu140samples = {}
788  for sample in self._fullsimSamples:
789  if sample.pileupNumber() == 140:
790  key = (sample.name(), _stripScenario(sample.scenario()))
791  if key in pu140samples:
792  raise Exception("Duplicate entry for sample %s in scenario %s" % (sample.name(), sample.scenar()))
793  pu140samples[key] = sample
794 
795  for sample in self._fullsimSamples:
796  if sample.pileupNumber() != 200:
797  continue
798  key = (sample.name(), _stripScenario(sample.scenario()))
799  if not key in pu140samples:
800  continue
801 
802  sample_pu140 = pu140samples[key]
803 
804  # If we reach here, the harvestedFile must exist
805  harvestedFile = sample.filename(self._newRelease)
806  plotterInstance = self._plotter.readDirs(harvestedFile)
807  htmlReport.beginSample(sample, pileupComparison="vs. PU140")
808  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
809  if not _processPlotsForSample(plotterFolder, sample):
810  continue
811  plotFiles = self._doPlotsPileup(sample_pu140, sample, plotterFolder, dqmSubFolder, htmlReport)
812  htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
813 
814 
815  def _getRefFileAndSelection(self, sample, plotterFolder, dqmSubFolder, selectionNameBase, valname):
816  if self._refRelease is None:
817  return (None, "")
818 
819  refGlobalTag = _getGlobalTag(sample, self._refRelease)
820  def _createRefSelection(selectionName):
821  sel = refGlobalTag+selectionNameBase+selectionName
822  if sample.pileupEnabled():
823  refPu = sample.pileupType(self._refRelease)
824  if refPu != "":
825  sel += "_"+refPu
826  return sel
827  refSelection = _createRefSelection(plotterFolder.getSelectionName(dqmSubFolder))
828 
829  # Construct reference directory name, and open reference file it it exists
830  refValFile = None
831  triedRefValFiles = []
832  tmp = [self._refRepository, self._refRelease]
833  if sample.fastsim():
834  tmp.extend(["fastsim", self._refRelease])
835  for selName in plotterFolder.getSelectionNameIterator(dqmSubFolder):
836  refSel = _createRefSelection(selName)
837  refdir = os.path.join(*(tmp+[refSel, sample.name()]))
838 
839  # Open reference file if it exists
840  refValFilePath = os.path.join(refdir, valname)
841  if os.path.exists(refValFilePath):
842  refSelection = refSel
843  refValFile = ROOT.TFile.Open(refValFilePath)
844  break
845  else:
846  triedRefValFiles.append(refValFilePath)
847  if refValFile is None:
848  if len(triedRefValFiles) == 1:
849  if plotting.verbose:
850  print "Reference file %s not found" % triedRefValFiles[0]
851  else:
852  if plotting.verbose:
853  print "None of the possible reference files %s not found" % ",".join(triedRefValFiles)
854 
855  return (refValFile, refSelection)
856 
857  def _doPlots(self, sample, harvestedFile, plotterFolder, dqmSubFolder, htmlReport):
858  """Do the real plotting work for a given sample and DQM subfolder"""
859  # Get GlobalTags
860  newGlobalTag = _getGlobalTag(sample, self._newRelease)
861 
862  # Construct selection string
863  selectionNameBase = "_"+sample.pileup()
864  newSelection = newGlobalTag+selectionNameBase+plotterFolder.getSelectionName(dqmSubFolder)
865  if sample.pileupEnabled():
866  newPu = sample.pileupType(self._newRelease)
867  if newPu != "":
868  newSelection += "_"+newPu
869 
870  valname = "val.{sample}.root".format(sample=sample.name())
871 
872  # Construct reference file and selection string
873  (refValFile, refSelection) = self._getRefFileAndSelection(sample, plotterFolder, dqmSubFolder, selectionNameBase, valname)
874 
875  # Construct new directory name
876  tmp = []
877  if sample.fastsim():
878  tmp.extend(["fastsim", self._newRelease])
879  tmp.extend([newSelection, sample.name()])
880  newsubdir = os.path.join(*tmp)
881  newdir = os.path.join(self._newBaseDir, newsubdir)
882  if not os.path.exists(newdir):
883  os.makedirs(newdir)
884  valnameFullPath = os.path.join(newdir, valname)
885 
886  # Copy the relevant histograms to a new validation root file
887  # TODO: treat the case where dqmSubFolder is empty
888  newValFile = _copySubDir(harvestedFile, valnameFullPath, plotterFolder.getPossibleDQMFolders(), dqmSubFolder.subfolder if dqmSubFolder is not None else None)
889  fileList = []
890 
891  # Do the plots
892  if plotting.verbose:
893  print "Comparing ref and new {sim} {sample} {translatedFolder}".format(
894  sim="FullSim" if not sample.fastsim() else "FastSim",
895  sample=sample.name(), translatedFolder=str(dqmSubFolder.translated) if dqmSubFolder is not None else "")
896  rootFiles = [refValFile, newValFile]
897  legendLabels = [
898  "%s, %s %s" % (sample.name(), _stripRelease(self._refRelease), refSelection) if self._refRelease is not None else "dummy",
899  "%s, %s %s" % (sample.name(), _stripRelease(self._newRelease), newSelection)
900  ]
901  plotterFolder.create(rootFiles, legendLabels, dqmSubFolder, isPileupSample=sample.pileupEnabled())
902  fileList.extend(plotterFolder.draw(directory=newdir, **self._plotterDrawArgs))
903  # Copy val file only if there were plots
904  if len(fileList) > 0:
905  fileList.append(valnameFullPath)
906 
907  # For tables we just try them all, and see which ones succeed
908  for tableCreator in plotterFolder.getTableCreators():
909  htmlReport.addTable(tableCreator.create(rootFiles, legendLabels, dqmSubFolder))
910 
911  newValFile.Close()
912  if refValFile is not None:
913  refValFile.Close()
914 
915  if len(fileList) == 0:
916  return []
917 
918  dups = _findDuplicates(fileList)
919  if len(dups) > 0:
920  print "Plotter produced multiple files with names", ", ".join(dups)
921  print "Typically this is a naming problem in the plotter configuration"
922  sys.exit(1)
923 
924  # Move plots to new directory
925  print "Created plots and %s in %s" % (valname, newdir)
926  return map(lambda n: n.replace(newdir, newsubdir), fileList)
927 
928  def _doPlotsFastFull(self, fastSample, fullSample, plotterFolder, dqmSubFolder, htmlReport):
929  """Do the real plotting work for FastSim vs. FullSim for a given algorithm, quality flag, and sample."""
930  # Get GlobalTags
931  fastGlobalTag = _getGlobalTag(fastSample, self._newRelease)
932  fullGlobalTag = _getGlobalTag(fullSample, self._newRelease)
933 
934  # Construct selection string
935  tmp = plotterFolder.getSelectionName(dqmSubFolder)
936  fastSelection = fastGlobalTag+"_"+fastSample.pileup()+tmp
937  fullSelection = fullGlobalTag+"_"+fullSample.pileup()+tmp
938  if fullSample.pileupEnabled():
939  fullSelection += "_"+fullSample.pileupType(self._newRelease)
940  fastSelection += "_"+fastSample.pileupType(self._newRelease)
941 
942  # Construct directories for FastSim, FullSim, and for the results
943  fastdir = os.path.join(self._newBaseDir, "fastsim", self._newRelease, fastSelection, fastSample.name())
944  fulldir = os.path.join(self._newBaseDir, fullSelection, fullSample.name())
945  newsubdir = os.path.join("fastfull", self._newRelease, fastSelection, fastSample.name())
946  newdir = os.path.join(self._newBaseDir, newsubdir)
947  if not os.path.exists(newdir):
948  os.makedirs(newdir)
949 
950  # Open input root files
951  valname = "val.{sample}.root".format(sample=fastSample.name())
952  fastValFilePath = os.path.join(fastdir, valname)
953  if not os.path.exists(fastValFilePath) and plotting.verbose:
954  print "FastSim file %s not found" % fastValFilePath
955  fullValFilePath = os.path.join(fulldir, valname)
956  if not os.path.exists(fullValFilePath) and plotting.verbose:
957  print "FullSim file %s not found" % fullValFilePath
958 
959  fastValFile = ROOT.TFile.Open(fastValFilePath)
960  fullValFile = ROOT.TFile.Open(fullValFilePath)
961 
962  # Do plots
963  if plotting.verbose:
964  print "Comparing FullSim and FastSim {sample} {translatedFolder}".format(
965  sample=fastSample.name(), translatedFolder=str(dqmSubFolder.translated) if dqmSubFolder is not None else "")
966  rootFiles = [fullValFile, fastValFile]
967  legendLabels = [
968  "FullSim %s, %s %s" % (fullSample.name(), _stripRelease(self._newRelease), fullSelection),
969  "FastSim %s, %s %s" % (fastSample.name(), _stripRelease(self._newRelease), fastSelection),
970  ]
971  plotterFolder.create(rootFiles, legendLabels, dqmSubFolder, isPileupSample=fastSample.pileupEnabled(), requireAllHistograms=True)
972  fileList = plotterFolder.draw(directory=newdir, **self._plotterDrawArgs)
973 
974  # For tables we just try them all, and see which ones succeed
975  for tableCreator in plotterFolder.getTableCreators():
976  htmlReport.addTable(tableCreator.create(rootFiles, legendLabels, dqmSubFolder))
977 
978  fullValFile.Close()
979  fastValFile.Close()
980 
981  if len(fileList) == 0:
982  return []
983 
984  dups = _findDuplicates(fileList)
985  if len(dups) > 0:
986  print "Plotter produced multiple files with names", ", ".join(dups)
987  print "Typically this is a naming problem in the plotter configuration"
988  sys.exit(1)
989 
990  # Move plots to new directory
991  print "Created plots in %s" % (newdir)
992  return map(lambda n: n.replace(newdir, newsubdir), fileList)
993 
994  def _doPlotsPileup(self, pu140Sample, pu200Sample, plotterFolder, dqmSubFolder, htmlReport):
995  """Do the real plotting work for two pileup scenarios for a given algorithm, quality flag, and sample."""
996  # Get GlobalTags
997  pu140GlobalTag = _getGlobalTag(pu140Sample, self._newRelease)
998  pu200GlobalTag = _getGlobalTag(pu200Sample, self._newRelease)
999 
1000  # Construct selection string
1001  tmp = plotterFolder.getSelectionName(dqmSubFolder)
1002  pu140Selection = pu140GlobalTag+"_"+pu140Sample.pileup()+tmp+"_"+pu140Sample.pileupType(self._newRelease)
1003  pu200Selection = pu200GlobalTag+"_"+pu200Sample.pileup()+tmp+"_"+pu200Sample.pileupType(self._newRelease)
1004 
1005  # Construct directories for
1006  pu140dir = os.path.join(self._newBaseDir, pu140Selection, pu140Sample.name())
1007  pu200dir = os.path.join(self._newBaseDir, pu200Selection, pu200Sample.name())
1008  newsubdir = os.path.join("pileup", self._newRelease, pu200Selection, pu200Sample.name())
1009  newdir = os.path.join(self._newBaseDir, newsubdir)
1010  if not os.path.exists(newdir):
1011  os.makedirs(newdir)
1012 
1013  # Open input root files
1014  valname = "val.{sample}.root".format(sample=pu140Sample.name())
1015  pu140ValFilePath = os.path.join(pu140dir, valname)
1016  if not os.path.exists(pu140ValFilePath):
1017  if plotting.verbose:
1018  print "PU140 file %s not found" % pu140ValFilePath
1019  return []
1020  pu200ValFilePath = os.path.join(pu200dir, valname)
1021  if not os.path.exists(pu200ValFilePath):
1022  if plotting.verbose:
1023  print "PU200 file %s not found" % pu200ValFilePath
1024  return []
1025 
1026  pu140ValFile = ROOT.TFile.Open(pu140ValFilePath)
1027  pu200ValFile = ROOT.TFile.Open(pu200ValFilePath)
1028 
1029  # Do plots
1030  if plotting.verbose:
1031  print "Comparing PU140 and PU200 {sample} {translatedFolder}".format(
1032  sample=pu200Sample.name(), translatedFolder=str(dqmSubFolder.translated) if dqmSubFolder is not None else "")
1033  rootFiles = [pu140ValFile, pu200ValFile]
1034  legendLabels = [
1035  "%s, %s %s" % (pu140Sample.name(), _stripRelease(self._newRelease), pu140Selection),
1036  "%s, %s %s" % (pu200Sample.name(), _stripRelease(self._newRelease), pu200Selection),
1037  ]
1038  plotterFolder.create(rootFiles, legendLabels, dqmSubFolder, isPileupSample=pu140Sample.pileupEnabled(), requireAllHistograms=True)
1039  fileList = plotterFolder.draw(directory=newdir, **self._plotterDrawArgs)
1040 
1041  # For tables we just try them all, and see which ones succeed
1042  for tableCreator in plotterFolder.getTableCreators():
1043  htmlReport.addTable(tableCreator.create(rootFiles, legendLabels, dqmSubFolder))
1044 
1045  pu200ValFile.Close()
1046  pu140ValFile.Close()
1047 
1048  if len(fileList) == 0:
1049  return []
1050 
1051  dups = _findDuplicates(fileList)
1052  if len(dups) > 0:
1053  print "Plotter produced multiple files with names", ", ".join(dups)
1054  print "Typically this is a naming problem in the plotter configuration"
1055  sys.exit(1)
1056 
1057  # Move plots to new directory
1058  print "Created plots in %s" % (newdir)
1059  return map(lambda n: n.replace(newdir, newsubdir), fileList)
1060 
1061 
1062 def _copySubDir(oldfile, newfile, basenames, dirname):
1063  """Copy a subdirectory from oldfile to newfile.
1064 
1065  Arguments:
1066  oldfile -- String for source TFile
1067  newfile -- String for destination TFile
1068  basenames -- List of strings for base directories, first existing one is picked
1069  dirname -- String for directory name under the base directory
1070  """
1071  oldf = ROOT.TFile.Open(oldfile)
1072 
1073  dirold = None
1074  for basename in basenames:
1075  dirold = oldf.GetDirectory(basename)
1076  if dirold:
1077  break
1078  if not dirold:
1079  raise Exception("Did not find any of %s directories from file %s" % (",".join(basenames), oldfile))
1080  if dirname:
1081  d = dirold.Get(dirname)
1082  if not d:
1083  raise Exception("Did not find directory %s under %s" % (dirname, dirold.GetPath()))
1084  dirold = d
1085 
1086  newf = ROOT.TFile.Open(newfile, "RECREATE")
1087  dirnew = newf
1088  for d in basenames[0].split("/"):
1089  dirnew = dirnew.mkdir(d)
1090  if dirname:
1091  dirnew = dirnew.mkdir(dirname)
1092  _copyDir(dirold, dirnew)
1093 
1094  oldf.Close()
1095  return newf
1096 
1097 def _copyDir(src, dst):
1098  """Copy non-TTree objects from src TDirectory to dst TDirectory."""
1099  keys = src.GetListOfKeys()
1100  for key in keys:
1101  classname = key.GetClassName()
1102  cl = ROOT.TClass.GetClass(classname)
1103  if not cl:
1104  continue
1105  if not (cl.InheritsFrom("TTree") and cl.InheritsFrom("TDirectory")):
1106  dst.cd()
1107  obj = key.ReadObj()
1108  obj.Write()
1109  obj.Delete()
1110 
1112  found = set()
1113  found2 = set()
1114  for x in lst:
1115  if x in found:
1116  found2.add(x)
1117  else:
1118  found.add(x)
1119  return list(found2)
1120 
1122  def __init__(self, label, name, fileLegends, pileup=True, customPileupLabel=""):
1123  self._label = label
1124  self._name = name
1125  self._fileLegends = fileLegends
1126  self._pileup = pileup
1127  self._customPileupLabel = customPileupLabel
1128 
1129  def digest(self):
1130  # Label should be unique among the plotting run, so it serves also as the digest
1131  return self._label
1132 
1133  def label(self):
1134  return self._label
1135 
1136  def name(self):
1137  return self._name
1138 
1139  def files(self):
1140  return [t[0] for t in self._fileLegends]
1141 
1142  def legendLabels(self):
1143  return [t[1] for t in self._fileLegends]
1144 
1145  def fastsim(self):
1146  # No need to emulate the release validation fastsim behaviour here
1147  return False
1148 
1149  def pileupEnabled(self):
1150  return self._pileup
1151 
1153  return self._customPileupLabel
1154 
1155  def doElectron(self):
1156  return True
1157 
1158  def doConversion(self):
1159  return True
1160 
1161  def doBHadron(self):
1162  return True
1163 
1165  def __init__(self, samples, newdir):
1166  self._samples = samples
1167  self._newdir = newdir
1168  if not os.path.exists(newdir):
1169  os.makedirs(newdir)
1170 
1172 
1173  def createHtmlReport(self, validationName=""):
1174  if hasattr(self._htmlReport, "write"):
1175  raise Exception("HTML report object already created. There is probably some logic error in the calling code.")
1176  self._htmlReport = html.HtmlReport(validationName, self._newdir)
1177  return self._htmlReport
1178 
1179  def doPlots(self, plotters, plotterDrawArgs={}, **kwargs):
1180  self._plotterDrawArgs = plotterDrawArgs
1181 
1182  for sample in self._samples:
1183  self._subdirprefix = sample.label()
1184  self._labels = sample.legendLabels()
1185  self._htmlReport.beginSample(sample)
1186 
1187  self._openFiles = []
1188  for f in sample.files():
1189  if os.path.exists(f):
1190  self._openFiles.append(ROOT.TFile.Open(f))
1191  else:
1192  print "File %s not found (from sample %s), ignoring it" % (f, sample.name())
1193  self._openFiles.append(None)
1194 
1195  for plotter in plotters:
1196  self._doPlotsForPlotter(plotter, sample, **kwargs)
1197 
1198  for tf in self._openFiles:
1199  if tf is not None:
1200  tf.Close()
1201  self._openFiles = []
1202 
1203  def _doPlotsForPlotter(self, plotter, sample, limitSubFoldersOnlyTo=None):
1204  plotterInstance = plotter.readDirs(*self._openFiles)
1205  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
1206  if sample is not None and not _processPlotsForSample(plotterFolder, sample):
1207  continue
1208  plotFiles = self._doPlots(plotterFolder, dqmSubFolder)
1209  if len(plotFiles) > 0:
1210  self._htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
1211 
1212  def _doPlots(self, plotterFolder, dqmSubFolder):
1213  plotterFolder.create(self._openFiles, self._labels, dqmSubFolder)
1214  newsubdir = self._subdirprefix+plotterFolder.getSelectionName(dqmSubFolder)
1215  newdir = os.path.join(self._newdir, newsubdir)
1216  if not os.path.exists(newdir):
1217  os.makedirs(newdir)
1218  fileList = plotterFolder.draw(directory=newdir, **self._plotterDrawArgs)
1219 
1220  for tableCreator in plotterFolder.getTableCreators():
1221  self._htmlReport.addTable(tableCreator.create(self._openFiles, self._labels, dqmSubFolder))
1222 
1223 
1224  if len(fileList) == 0:
1225  return fileList
1226 
1227  dups = _findDuplicates(fileList)
1228  if len(dups) > 0:
1229  print "Plotter produced multiple files with names", ", ".join(dups)
1230  print "Typically this is a naming problem in the plotter configuration"
1231  sys.exit(1)
1232 
1233  print "Created plots in %s" % newdir
1234  return map(lambda n: n.replace(newdir, newsubdir), fileList)
def name(self)
Definition: validation.py:473
def sample(self)
Definition: validation.py:469
_fastsimCorrespondingFullsimPileup
Definition: validation.py:442
def _getGlobalTag(sample, release)
Definition: validation.py:297
def _doPlotsPileup(self, pu140Sample, pu200Sample, plotterFolder, dqmSubFolder, htmlReport)
Definition: validation.py:994
def createHtmlReport(self, validationName="")
Definition: validation.py:1173
def _getSelectionName(self, args, kwargs)
Definition: validation.py:652
def hasPileup(self)
Definition: validation.py:480
def dirname(self, newRepository, newRelease, newSelection)
Definition: validation.py:543
def fullsim(self)
Definition: validation.py:536
def filename(self, newRelease)
Definition: validation.py:558
def _getDirectoryName(self, args, kwargs)
Definition: validation.py:649
def __init__(self, label, name, fileLegends, pileup=True, customPileupLabel="")
Definition: validation.py:1122
def doBHadron(self)
Definition: validation.py:511
def datasetpattern(self, newRelease)
Definition: validation.py:595
def label(self)
Definition: validation.py:477
def _doPlots(self, plotterFolder, dqmSubFolder)
Definition: validation.py:1212
def hasScenario(self)
Definition: validation.py:520
def doConversion(self)
Definition: validation.py:508
def pileupType(self, release=None)
Definition: validation.py:495
def pileupNumber(self)
Definition: validation.py:502
def _doFastsimFastVsFullPlots(self, limitSubFoldersOnlyTo, htmlReport)
Definition: validation.py:747
def _getRelValUrl(release)
Definition: validation.py:387
def _stripRelease(release)
Definition: validation.py:290
def _processPlotsForSample(plotterFolder, sample)
Definition: validation.py:399
def hasOverrideGlobalTag(self)
Definition: validation.py:526
def _doPlotsFastFull(self, fastSample, fullSample, plotterFolder, dqmSubFolder, htmlReport)
Definition: validation.py:928
def doElectron(self)
Definition: validation.py:505
def digest(self)
Definition: validation.py:465
def version(self, release=None)
Definition: validation.py:514
def doPlots(self, plotters, plotterDrawArgs={}, kwargs)
Definition: validation.py:1179
def __init__(self, fullsimSamples, fastsimSamples, refRelease, refRepository, newRelease, newRepository, newFileModifier=None, selectionName="")
Definition: validation.py:620
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def _copyDir(src, dst)
Definition: validation.py:1097
def pileupEnabled(self)
Definition: validation.py:484
def _findDuplicates(lst)
Definition: validation.py:1111
def _copySubDir(oldfile, newfile, basenames, dirname)
Definition: validation.py:1062
def _doPhase2PileupPlots(self, limitSubFoldersOnlyTo, htmlReport)
Definition: validation.py:780
def scenario(self)
Definition: validation.py:523
def doPlots(self, plotter, plotterDrawArgs={}, limitSubFoldersOnlyTo=None, htmlReport=html.HtmlReportDummy(), doFastVsFull=True, doPhase2PU=False)
Definition: validation.py:707
def __init__(self, sample, append=None, midfix=None, putype=None, punum=0, fastsim=False, fastsimCorrespondingFullsimPileup=None, doElectron=None, doConversion=None, doBHadron=None, version="v1", dqmVersion="0001", scenario=None, overrideGlobalTag=None, appendGlobalTag="")
Definition: validation.py:415
def pileup(self)
Definition: validation.py:488
def fastsimCorrespondingFullsimPileup(self)
Definition: validation.py:540
def fastsim(self)
Definition: validation.py:532
def createHtmlReport(self)
Definition: validation.py:704
def _doPlotsForPlotter(self, plotter, sample, limitSubFoldersOnlyTo=None)
Definition: validation.py:1203
def __init__(self, samples, newdir)
Definition: validation.py:1165
double split
Definition: MVATrainer.cc:139
def _getRefFileAndSelection(self, sample, plotterFolder, dqmSubFolder, selectionNameBase, valname)
Definition: validation.py:815
def _doPlots(self, sample, harvestedFile, plotterFolder, dqmSubFolder, htmlReport)
Definition: validation.py:857
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
def overrideGlobalTag(self)
Definition: validation.py:529