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  "CMSSW_9_3_0_pre3": {"default": "92X_mcRun2_asymptotic_v2"},
287  "CMSSW_9_3_0_pre3_phase1": {"default": "92X_upgrade2017_realistic_v10_resub",
288  "fullsim_25ns_PU50": "92X_upgrade2017_realistic_v10_highPU_AVE50_resub",
289  "Design": "92X_upgrade2017_design_IdealBS_v10_resub"},
290  "CMSSW_9_3_0_pre3_phase1_pmx": {"default": "92X_upgrade2017_realistic_v10_resub2"},
291  "CMSSW_9_3_0_pre4": {"default": "93X_mcRun2_asymptotic_v0"},
292  "CMSSW_9_3_0_pre4_phase1": {"default": "93X_mc2017_realistic_v1",
293  "fullsim_25ns_PU50": "93X_mc2017_realistic_v1_highPU_AVE50",
294  "Design": "93X_mc2017_design_IdealBS_v1"},
295  "CMSSW_9_3_0_pre5": {"default": "93X_mcRun2_asymptotic_v0"},
296  "CMSSW_9_3_0_pre5_phase1": {"default": "93X_mc2017_realistic_v2",
297  "fullsim_25ns_PU50": "93X_mc2017_realistic_v2_highPU_AVE50",
298  "Design": "93X_mc2017_design_IdealBS_v2"},
299  "CMSSW_9_4_0_pre1": {"default": "93X_mcRun2_asymptotic_v1"},
300  "CMSSW_9_4_0_pre1_phase1": {"default": "93X_mc2017_realistic_v3",
301  "fullsim_25ns_PU50": "93X_mc2017_realistic_v3_highPU_AVE50",
302  "Design": "93X_mc2017_design_IdealBS_v3"},
303  "CMSSW_9_4_0_pre2": {"default": "93X_mcRun2_asymptotic_v2"},
304  "CMSSW_9_4_0_pre2_phase1": {"default": "94X_mc2017_realistic_v1",
305  "fullsim_25ns_PU50": "94X_mc2017_realistic_v1_highPU_AVE50",
306  "Design": "94X_mc2017_design_IdealBS_v0"},
307  "CMSSW_9_4_0_pre3": {"default": "94X_mcRun2_asymptotic_v0"},
308  "CMSSW_9_4_0_pre3_phase1": {"default": "94X_mc2017_realistic_v4",
309  "fullsim_25ns_PU50": "94X_mc2017_realistic_v4_highPU_AVE50",
310  "Design": "94X_mc2017_design_IdealBS_v4"},
311  "CMSSW_9_4_0": {"default": "94X_mcRun2_asymptotic_v0"},
312  "CMSSW_9_4_0_phase1": {"default": "94X_mc2017_realistic_v10",
313  "fullsim_25ns_PU50": "94X_mc2017_realistic_v10_highPU_AVE50",
314  "Design": "94X_mc2017_design_IdealBS_v5"},
315 }
316 
317 _releasePostfixes = ["_AlcaCSA14", "_PHYS14", "_TEST", "_v2", "_v3", "_pmx", "_Fall14DR", "_FIXGT", "_PU", "_PXbest", "_PXworst", "_hcal", "_tec", "_71XGENSIM", "_73XGENSIM", "_BS", "_GenSim_7113", "_extended",
318  "_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"]
319 def _stripRelease(release):
320  for pf in _releasePostfixes:
321  if pf in release:
322  return _stripRelease(release.replace(pf, ""))
323  return release
324 
325 
326 def _getGlobalTag(sample, release):
327  """Get a GlobalTag.
328 
329  Arguments:
330  sample -- Sample object
331  release -- CMSSW release string
332  """
333  if not release in _globalTags:
334  print "Release %s not found from globaltag map in validation.py" % release
335  sys.exit(1)
336  gtmap = _globalTags[release]
337  selectedGT = None
338  if sample.hasOverrideGlobalTag():
339  ogt = sample.overrideGlobalTag()
340  if release in ogt:
341  gtmap = _globalTags[ogt[release]]
342  scenario = ""
343  if sample.hasScenario():
344  scenario = sample.scenario()
345  sims = []
346  if sample.fullsim():
347  if sample.pileupEnabled():
348  sim = "fullsim_"+sample.pileupType()
349  sims.extend([
350  sim+"_PU%d"%sample.pileupNumber(),
351  sim
352  ])
353  elif sample.fastsim():
354  sim = "fastsim"
355  if sample.pileupEnabled():
356  sim += "_"+sample.pileupType()
357  sims.append(sim+"_PU%d"%sample.pileupNumber())
358  sims.append(sim)
359 
360  selectedGT = None
361  # First try with scenario+simulation
362  if scenario != "":
363  for sim in sims:
364  selectedGT = gtmap.get(scenario+"_"+sim, None)
365  if selectedGT is not None:
366  break
367  # Then with scenario (but only if sample specifies a scenario)
368  if selectedGT is None:
369  selectedGT = gtmap.get(scenario, None)
370  # Then with simulation
371  if selectedGT is None:
372  for sim in sims:
373  selectedGT = gtmap.get(sim, None)
374  if selectedGT is not None:
375  break
376  # Finally default
377  if selectedGT is None:
378  selectedGT = gtmap["default"]
379 
380  if isinstance(selectedGT, dict):
381  return selectedGT.get(sample.name(), selectedGT["default"])
382  else:
383  return selectedGT
384 
385 # Mapping from release series to RelVal download URLs
386 _relvalUrls = {
387  "6_2_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_6_2_x/",
388  "7_0_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_0_x/",
389  "7_1_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_1_x/",
390  "7_2_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_2_x/",
391  "7_3_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_3_x/",
392  "7_4_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_4_x/",
393  "7_5_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_5_x/",
394  "7_6_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_7_6_x/",
395  "8_0_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_8_0_x/",
396  "8_1_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_8_1_x/",
397  "9_0_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_0_x/",
398  "9_1_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_1_x/",
399  "9_2_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_2_x/",
400  "9_3_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_3_x/",
401  "9_4_X": "https://cmsweb.cern.ch/dqm/relval/data/browse/ROOT/RelVal/CMSSW_9_4_x/",
402 }
403 
404 _doElectronSamples = [
405  "RelValTTbar",
406  "RelValSingleElectronPt35",
407  "RelValSingleElectronPt10",
408 ]
409 _doConversionSamples = [
410  "RelValTTbar",
411  "RelValH125GGgluonfusion",
412 ]
413 _doBHadronSamples = [
414  "RelValTTbar"
415 ]
416 
417 def _getRelValUrl(release):
418  """Get RelVal download URL for a given release."""
419  version_re = re.compile("CMSSW_(?P<X>\d+)_(?P<Y>\d+)")
420  m = version_re.search(release)
421  if not m:
422  raise Exception("Regex %s does not match to release version %s" % (version_re.pattern, release))
423  version = "%s_%s_X" % (m.group("X"), m.group("Y"))
424  if not version in _relvalUrls:
425  print "No RelVal URL for version %s, please update _relvalUrls" % version
426  sys.exit(1)
427  return _relvalUrls[version]
428 
429 def _processPlotsForSample(plotterFolder, sample):
430  if plotterFolder.onlyForPileup() and not sample.pileupEnabled():
431  return False
432  if plotterFolder.onlyForElectron() and not sample.doElectron():
433  return False
434  if plotterFolder.onlyForConversion() and not sample.doConversion():
435  return False
436  if plotterFolder.onlyForBHadron() and not sample.doBHadron():
437  return False
438  return True
439 
440 class Sample:
441  """Represents a RelVal sample."""
442  def __init__(self, sample, append=None, midfix=None, putype=None, punum=0,
443  fastsim=False, fastsimCorrespondingFullsimPileup=None,
444  doElectron=None, doConversion=None, doBHadron=None,
445  version="v1", dqmVersion="0001", scenario=None, overrideGlobalTag=None, appendGlobalTag=""):
446  """Constructor.
447 
448  Arguments:
449  sample -- String for name of the sample
450 
451  Keyword arguments
452  append -- String for a variable name within the DWM file names, to be directly appended to sample name (e.g. "HS"; default None)
453  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)
454  putype -- String for pileup type (e.g. "25ns"/"50ns" for FullSim, "AVE20" for FastSim; default None)
455  punum -- String for amount of pileup (default None)
456  fastsim -- Bool indicating the FastSim status (default False)
457  fastsimCorrespondingFullSimPileup -- String indicating what is the FullSim pileup sample corresponding this FastSim sample. Must be set if fastsim=True and putype!=None (default None)
458  doElectron -- Bool specifying if electron-specific plots should be produced (default depends on sample)
459  doConversion -- Bool specifying if conversion-specific plots should be produced (default depends on sample)
460  doBHadron -- Bool specifying if B-hadron-specific plots should be produced (default depends on sample)
461  version -- String for dataset/DQM file version (default "v1")
462  scenario -- Geometry scenario for upgrade samples (default None)
463  overrideGlobalTag -- GlobalTag obtained from release information (in the form of {"release": "actualRelease"}; default None)
464  appendGlobalTag -- String to append to GlobalTag (intended for one-time hacks; default "")
465  """
466  self._sample = sample
467  self._append = append
468  self._midfix = midfix
469  self._putype = putype
470  self._punum = punum
471  self._fastsim = fastsim
472  self._fastsimCorrespondingFullsimPileup = fastsimCorrespondingFullsimPileup
473  self._version = version
474  self._dqmVersion = dqmVersion
475  self._scenario = scenario
476  self._overrideGlobalTag = overrideGlobalTag
477  self._appendGlobalTag = appendGlobalTag
478 
479  if doElectron is not None:
480  self._doElectron = doElectron
481  else:
482  self._doElectron = (sample in _doElectronSamples)
483  if doConversion is not None:
484  self._doConversion = doConversion
485  else:
486  self._doConversion = (sample in _doConversionSamples)
487  if doBHadron is not None:
488  self._doBHadron = doBHadron
489  else:
490  self._doBHadron = (sample in _doBHadronSamples)
491 
492  if self._fastsim and self.hasPileup() and self._fastsimCorrespondingFullsimPileup is None:
494 
495  def digest(self):
496  """Return a tuple uniquely identifying the sample, to be used e.g. as a key to dict"""
497  return (self.name(), self.pileupNumber(), self.pileupType(), self.scenario(), self.fastsim())
498 
499  def sample(self):
500  """Get the sample name"""
501  return self._sample
502 
503  def name(self):
504  """Get the sample name"""
505  return self._sample
506 
507  def label(self):
508  return self._sample
509 
510  def hasPileup(self):
511  """Return True if sample has pileup (for HTML generation)"""
512  return self._putype is not None
513 
514  def pileupEnabled(self):
515  """Return True if pileup plots are enabled (for plot generation)"""
516  return self.hasPileup()
517 
518  def pileup(self):
519  """Return "PU"/"noPU" corresponding the pileup status"""
520  if self.hasPileup():
521  return "PU"
522  else:
523  return "noPU"
524 
525  def pileupType(self, release=None):
526  """Return the pileup type"""
527  if isinstance(self._putype, dict):
528  return self._putype.get(release, self._putype["default"])
529  else:
530  return self._putype
531 
532  def pileupNumber(self):
533  return self._punum
534 
535  def doElectron(self):
536  return self._doElectron
537 
538  def doConversion(self):
539  return self._doConversion
540 
541  def doBHadron(self):
542  return self._doBHadron
543 
544  def version(self, release=None):
545  if isinstance(self._version, dict):
546  return self._version.get(release, self._version["default"])
547  else:
548  return self._version
549 
550  def hasScenario(self):
551  return self._scenario is not None
552 
553  def scenario(self):
554  return self._scenario
555 
557  return self._overrideGlobalTag is not None
558 
559  def overrideGlobalTag(self):
560  return self._overrideGlobalTag
561 
562  def fastsim(self):
563  """Return True for FastSim sample"""
564  return self._fastsim
565 
566  def fullsim(self):
567  """Return True for FullSim sample"""
568  return not self._fastsim
569 
572 
573  def dirname(self, newRepository, newRelease, newSelection):
574  """Return the output directory name
575 
576  Arguments:
577  newRepository -- String for base directory for output files
578  newRelease -- String for CMSSW release
579  newSelection -- String for histogram selection
580  """
581  pileup = ""
582  if self.hasPileup() and not self._fastsim:
583  pileup = "_"+self._putype
584  return "{newRepository}/{newRelease}/{newSelection}{pileup}/{sample}".format(
585  newRepository=newRepository, newRelease=newRelease, newSelection=newSelection,
586  pileup=pileup, sample=sample)
587 
588  def filename(self, newRelease):
589  """Return the DQM file name
590 
591  Arguments:
592  newRelease -- String for CMSSW release
593  """
594  pileup = ""
595  fastsim = ""
596  midfix = ""
597  sample = self._sample
598  if self._append is not None:
599  midfix += self._append
600  if self._midfix is not None:
601  midfix += "_"+self._midfix
602  if self.hasPileup():
603  if self._fastsim:
604  #sample = sample.replace("RelVal", "RelValFS_")
605  # old style
606  #pileup = "PU_"
607  #midfix += "_"+self.pileupType(newRelease)
608  # new style
609  pileup = "PU"+self.pileupType(newRelease)+"_"
610  else:
611  pileup = "PU"+self.pileupType(newRelease)+"_"
612  if self._fastsim:
613  fastsim = "_FastSim"
614 
615  globalTag = _getGlobalTag(self, newRelease)
616 
617  fname = 'DQM_V{dqmVersion}_R000000001__{sample}{midfix}__{newrelease}-{pileup}{globaltag}{appendGlobalTag}{fastsim}-{version}__DQMIO.root'.format(
618  sample=sample, midfix=midfix, newrelease=_stripRelease(newRelease),
619  pileup=pileup, globaltag=globalTag, appendGlobalTag=self._appendGlobalTag, fastsim=fastsim,
620  version=self.version(newRelease), dqmVersion=self._dqmVersion
621  )
622 
623  return fname
624 
625  def datasetpattern(self, newRelease):
626  """Return the dataset pattern
627 
628  Arguments:
629  newRelease -- String for CMSSW release
630  """
631  pileup = ""
632  fastsim = ""
633  digi = ""
634  if self.hasPileup():
635  pileup = "-PU_"
636  if self._fastsim:
637  fastsim = "_FastSim-"
638  digi = "DIGI-"
639  else:
640  fastsim = "*"
641  globalTag = _getGlobalTag(self, newRelease)
642  return "{sample}/{newrelease}-{pileup}{globaltag}{fastsim}{version}/GEN-SIM-{digi}RECO".format(
643  sample=self._sample, newrelease=newRelease,
644  pileup=pileup, globaltag=globalTag, fastsim=fastsim, digi=digi,
645  version=self.version(newRelease)
646  )
647 
649  """Base class for Tracking/Vertex validation."""
650  def __init__(self, fullsimSamples, fastsimSamples, refRelease, refRepository, newRelease, newRepository, newFileModifier=None, selectionName=""):
651  """Constructor.
652 
653  Arguments:
654  fullsimSamples -- List of Sample objects for FullSim samples (may be empty)
655  fastsimSamples -- List of Sample objects for FastSim samples (may be empty)
656  refRelease -- String for reference CMSSW release (can be None for no reference release)
657  newRepository -- String for directory whete to put new files
658  newRelease -- CMSSW release to be validated
659  refRepository -- String for directory where reference root files are
660  newFileModifier -- If given, a function to modify the names of the new files (function takes a string and returns a string)
661  selectionName -- If given, use this string as the selection name (appended to GlobalTag for directory names)
662  """
663  try:
664  self._newRelease = os.environ["CMSSW_VERSION"]
665  except KeyError:
666  print >>sys.stderr, 'Error: CMSSW environment variables are not available.'
667  print >>sys.stderr, ' Please run cmsenv'
668  sys.exit()
669 
670  self._fullsimSamples = fullsimSamples
671  self._fastsimSamples = fastsimSamples
672  self._refRelease = refRelease
673  self._refRepository = refRepository
674  self._newRelease = newRelease
675  self._newBaseDir = os.path.join(newRepository, self._newRelease)
676  self._newFileModifier = newFileModifier
677  self._selectionName = selectionName
678 
679  def _getDirectoryName(self, *args, **kwargs):
680  return None
681 
682  def _getSelectionName(self, *args, **kwargs):
683  return self._selectionName
684 
685  def download(self):
686  """Download DQM files. Requires grid certificate and asks your password for it."""
687  filenames = [s.filename(self._newRelease) for s in self._fullsimSamples+self._fastsimSamples]
688  if self._newFileModifier is not None:
689  filenames = map(self._newFileModifier, filenames)
690  filenames = filter(lambda f: not os.path.exists(f), filenames)
691  if len(filenames) == 0:
692  print "All files already downloaded"
693  return
694 
695  relvalUrl = _getRelValUrl(self._newRelease)
696  urls = [relvalUrl+f for f in filenames]
697  certfile = os.path.join(os.environ["HOME"], ".globus", "usercert.pem")
698  if not os.path.exists(certfile):
699  print "Certificate file {certfile} does not exist, unable to download RelVal files from {url}".format(certfile=certfile, url=relvalUrl)
700  sys.exit(1)
701  keyfile = os.path.join(os.environ["HOME"], ".globus", "userkey.pem")
702  if not os.path.exists(certfile):
703  print "Private key file {keyfile} does not exist, unable to download RelVal files from {url}".format(keyfile=keyfile, url=relvalUrl)
704  sys.exit(1)
705 
706  # curl --cert-type PEM --cert $HOME/.globus/usercert.pem --key $HOME/.globus/userkye.pem -k -O <url> -O <url>
707  cmd = ["curl", "--cert-type", "PEM", "--cert", certfile, "--key", keyfile, "-k"]
708  for u in urls:
709  cmd.extend(["-O", u])
710  print "Downloading %d files from RelVal URL %s:" % (len(filenames), relvalUrl)
711  print " "+"\n ".join(filenames)
712  print "Please provide your private key pass phrase when curl asks it"
713  ret = subprocess.call(cmd)
714  if ret != 0:
715  print "Downloading failed with exit code %d" % ret
716  sys.exit(1)
717 
718  # verify
719  allFine = True
720  for f in filenames:
721  p = subprocess.Popen(["file", f], stdout=subprocess.PIPE)
722  stdout = p.communicate()[0]
723  if p.returncode != 0:
724  print "file command failed with exit code %d" % p.returncode
725  sys.exit(1)
726  if not "ROOT" in stdout:
727  print "File {f} is not ROOT, please check the correct version, GlobalTag etc. from {url}".format(f=f, url=relvalUrl)
728  allFine = False
729  if os.path.exists(f):
730  os.remove(f)
731  if not allFine:
732  sys.exit(1)
733 
734  def createHtmlReport(self):
735  return html.HtmlReport(self._newRelease, self._newBaseDir)
736 
737  def doPlots(self, plotter, plotterDrawArgs={}, limitSubFoldersOnlyTo=None, htmlReport=html.HtmlReportDummy(), doFastVsFull=True, doPhase2PU=False):
738  """Create validation plots.
739 
740  Arguments:
741  plotter -- plotting.Plotter object that does the plotting
742 
743  Keyword arguments:
744  plotterDrawArgs -- Dictionary for additional arguments to Plotter.draw() (default: {})
745  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.
746  htmlReport -- Object returned by createHtmlReport(), in case HTML report generation is desired
747  doFastVsFull -- Do FastSim vs. FullSim comparison? (default: True)
748  doPhase2PU -- Do Phase2 PU 200 vs. 140 comparison (default: False)
749  """
750  self._plotter = plotter
751  self._plotterDrawArgs = plotterDrawArgs
752 
753  # New vs. Ref
754  for sample in self._fullsimSamples+self._fastsimSamples:
755  # Check that the new DQM file exists
756  harvestedFile = sample.filename(self._newRelease)
757  if not os.path.exists(harvestedFile):
758  print "Harvested file %s does not exist!" % harvestedFile
759  sys.exit(1)
760 
761  plotterInstance = plotter.readDirs(harvestedFile)
762  htmlReport.beginSample(sample)
763  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
764  if not _processPlotsForSample(plotterFolder, sample):
765  continue
766  plotFiles = self._doPlots(sample, harvestedFile, plotterFolder, dqmSubFolder, htmlReport)
767  htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
768 
769  # Fast vs. Full
770  if doFastVsFull:
771  self._doFastsimFastVsFullPlots(limitSubFoldersOnlyTo, htmlReport)
772 
773  # Phase2 PU200 vs. PU 140
774  if doPhase2PU:
775  self._doPhase2PileupPlots(limitSubFoldersOnlyTo, htmlReport)
776 
777  def _doFastsimFastVsFullPlots(self, limitSubFoldersOnlyTo, htmlReport):
778  for fast in self._fastsimSamples:
779  correspondingFull = None
780  for full in self._fullsimSamples:
781  if fast.name() != full.name():
782  continue
783  if fast.pileupEnabled():
784  if not full.pileupEnabled():
785  continue
786  if fast.fastsimCorrespondingFullsimPileup() != full.pileupType():
787  continue
788  else:
789  if full.pileupEnabled():
790  continue
791 
792  if correspondingFull is None:
793  correspondingFull = full
794  else:
795  raise Exception("Got multiple compatible FullSim samples for FastSim sample %s %s" % (fast.name(), fast.pileup()))
796  if correspondingFull is None:
797  print "WARNING: Did not find compatible FullSim sample for FastSim sample %s %s, omitting FastSim vs. FullSim comparison" % (fast.name(), fast.pileup())
798  continue
799 
800  # If we reach here, the harvestedFile must exist
801  harvestedFile = fast.filename(self._newRelease)
802  plotterInstance = self._plotter.readDirs(harvestedFile)
803  htmlReport.beginSample(fast, fastVsFull=True)
804  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
805  if not _processPlotsForSample(plotterFolder, fast):
806  continue
807  plotFiles = self._doPlotsFastFull(fast, correspondingFull, plotterFolder, dqmSubFolder, htmlReport)
808  htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
809 
810  def _doPhase2PileupPlots(self, limitSubFoldersOnlyTo, htmlReport):
811  def _stripScenario(name):
812  puindex = name.find("PU")
813  if puindex < 0:
814  return name
815  return name[:puindex]
816 
817  pu140samples = {}
818  for sample in self._fullsimSamples:
819  if sample.pileupNumber() == 140:
820  key = (sample.name(), _stripScenario(sample.scenario()))
821  if key in pu140samples:
822  raise Exception("Duplicate entry for sample %s in scenario %s" % (sample.name(), sample.scenar()))
823  pu140samples[key] = sample
824 
825  for sample in self._fullsimSamples:
826  if sample.pileupNumber() != 200:
827  continue
828  key = (sample.name(), _stripScenario(sample.scenario()))
829  if not key in pu140samples:
830  continue
831 
832  sample_pu140 = pu140samples[key]
833 
834  # If we reach here, the harvestedFile must exist
835  harvestedFile = sample.filename(self._newRelease)
836  plotterInstance = self._plotter.readDirs(harvestedFile)
837  htmlReport.beginSample(sample, pileupComparison="vs. PU140")
838  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
839  if not _processPlotsForSample(plotterFolder, sample):
840  continue
841  plotFiles = self._doPlotsPileup(sample_pu140, sample, plotterFolder, dqmSubFolder, htmlReport)
842  htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
843 
844 
845  def _getRefFileAndSelection(self, sample, plotterFolder, dqmSubFolder, selectionNameBase, valname):
846  if self._refRelease is None:
847  return (None, "")
848 
849  refGlobalTag = _getGlobalTag(sample, self._refRelease)
850  def _createRefSelection(selectionName):
851  sel = refGlobalTag+selectionNameBase+selectionName
852  if sample.pileupEnabled():
853  refPu = sample.pileupType(self._refRelease)
854  if refPu != "":
855  sel += "_"+refPu
856  return sel
857  refSelection = _createRefSelection(plotterFolder.getSelectionName(dqmSubFolder))
858 
859  # Construct reference directory name, and open reference file it it exists
860  refValFile = None
861  triedRefValFiles = []
862  tmp = [self._refRepository, self._refRelease]
863  if sample.fastsim():
864  tmp.extend(["fastsim", self._refRelease])
865  for selName in plotterFolder.getSelectionNameIterator(dqmSubFolder):
866  refSel = _createRefSelection(selName)
867  refdir = os.path.join(*(tmp+[refSel, sample.name()]))
868 
869  # Open reference file if it exists
870  refValFilePath = os.path.join(refdir, valname)
871  if os.path.exists(refValFilePath):
872  refSelection = refSel
873  refValFile = ROOT.TFile.Open(refValFilePath)
874  break
875  else:
876  triedRefValFiles.append(refValFilePath)
877  if refValFile is None:
878  if len(triedRefValFiles) == 1:
879  if plotting.verbose:
880  print "Reference file %s not found" % triedRefValFiles[0]
881  else:
882  if plotting.verbose:
883  print "None of the possible reference files %s not found" % ",".join(triedRefValFiles)
884 
885  return (refValFile, refSelection)
886 
887  def _doPlots(self, sample, harvestedFile, plotterFolder, dqmSubFolder, htmlReport):
888  """Do the real plotting work for a given sample and DQM subfolder"""
889  # Get GlobalTags
890  newGlobalTag = _getGlobalTag(sample, self._newRelease)
891 
892  # Construct selection string
893  selectionNameBase = "_"+sample.pileup()
894  newSelection = newGlobalTag+selectionNameBase+plotterFolder.getSelectionName(dqmSubFolder)
895  if sample.pileupEnabled():
896  newPu = sample.pileupType(self._newRelease)
897  if newPu != "":
898  newSelection += "_"+newPu
899 
900  valname = "val.{sample}.root".format(sample=sample.name())
901 
902  # Construct reference file and selection string
903  (refValFile, refSelection) = self._getRefFileAndSelection(sample, plotterFolder, dqmSubFolder, selectionNameBase, valname)
904 
905  # Construct new directory name
906  tmp = []
907  if sample.fastsim():
908  tmp.extend(["fastsim", self._newRelease])
909  tmp.extend([newSelection, sample.name()])
910  newsubdir = os.path.join(*tmp)
911  newdir = os.path.join(self._newBaseDir, newsubdir)
912  if not os.path.exists(newdir):
913  os.makedirs(newdir)
914  valnameFullPath = os.path.join(newdir, valname)
915 
916  # Copy the relevant histograms to a new validation root file
917  # TODO: treat the case where dqmSubFolder is empty
918  newValFile = _copySubDir(harvestedFile, valnameFullPath, plotterFolder.getPossibleDQMFolders(), dqmSubFolder.subfolder if dqmSubFolder is not None else None)
919  fileList = []
920 
921  # Do the plots
922  if plotting.verbose:
923  print "Comparing ref and new {sim} {sample} {translatedFolder}".format(
924  sim="FullSim" if not sample.fastsim() else "FastSim",
925  sample=sample.name(), translatedFolder=str(dqmSubFolder.translated) if dqmSubFolder is not None else "")
926  rootFiles = [refValFile, newValFile]
927  legendLabels = [
928  "%s, %s %s" % (sample.name(), _stripRelease(self._refRelease), refSelection) if self._refRelease is not None else "dummy",
929  "%s, %s %s" % (sample.name(), _stripRelease(self._newRelease), newSelection)
930  ]
931  plotterFolder.create(rootFiles, legendLabels, dqmSubFolder, isPileupSample=sample.pileupEnabled())
932  fileList.extend(plotterFolder.draw(directory=newdir, **self._plotterDrawArgs))
933  # Copy val file only if there were plots
934  if len(fileList) > 0:
935  fileList.append(valnameFullPath)
936 
937  # For tables we just try them all, and see which ones succeed
938  for tableCreator in plotterFolder.getTableCreators():
939  htmlReport.addTable(tableCreator.create(rootFiles, legendLabels, dqmSubFolder))
940 
941  newValFile.Close()
942  if refValFile is not None:
943  refValFile.Close()
944 
945  if len(fileList) == 0:
946  return []
947 
948  dups = _findDuplicates(fileList)
949  if len(dups) > 0:
950  print "Plotter produced multiple files with names", ", ".join(dups)
951  print "Typically this is a naming problem in the plotter configuration"
952  sys.exit(1)
953 
954  # Move plots to new directory
955  print "Created plots and %s in %s" % (valname, newdir)
956  return map(lambda n: n.replace(newdir, newsubdir), fileList)
957 
958  def _doPlotsFastFull(self, fastSample, fullSample, plotterFolder, dqmSubFolder, htmlReport):
959  """Do the real plotting work for FastSim vs. FullSim for a given algorithm, quality flag, and sample."""
960  # Get GlobalTags
961  fastGlobalTag = _getGlobalTag(fastSample, self._newRelease)
962  fullGlobalTag = _getGlobalTag(fullSample, self._newRelease)
963 
964  # Construct selection string
965  tmp = plotterFolder.getSelectionName(dqmSubFolder)
966  fastSelection = fastGlobalTag+"_"+fastSample.pileup()+tmp
967  fullSelection = fullGlobalTag+"_"+fullSample.pileup()+tmp
968  if fullSample.pileupEnabled():
969  fullSelection += "_"+fullSample.pileupType(self._newRelease)
970  fastSelection += "_"+fastSample.pileupType(self._newRelease)
971 
972  # Construct directories for FastSim, FullSim, and for the results
973  fastdir = os.path.join(self._newBaseDir, "fastsim", self._newRelease, fastSelection, fastSample.name())
974  fulldir = os.path.join(self._newBaseDir, fullSelection, fullSample.name())
975  newsubdir = os.path.join("fastfull", self._newRelease, fastSelection, fastSample.name())
976  newdir = os.path.join(self._newBaseDir, newsubdir)
977  if not os.path.exists(newdir):
978  os.makedirs(newdir)
979 
980  # Open input root files
981  valname = "val.{sample}.root".format(sample=fastSample.name())
982  fastValFilePath = os.path.join(fastdir, valname)
983  if not os.path.exists(fastValFilePath) and plotting.verbose:
984  print "FastSim file %s not found" % fastValFilePath
985  fullValFilePath = os.path.join(fulldir, valname)
986  if not os.path.exists(fullValFilePath) and plotting.verbose:
987  print "FullSim file %s not found" % fullValFilePath
988 
989  fastValFile = ROOT.TFile.Open(fastValFilePath)
990  fullValFile = ROOT.TFile.Open(fullValFilePath)
991 
992  # Do plots
993  if plotting.verbose:
994  print "Comparing FullSim and FastSim {sample} {translatedFolder}".format(
995  sample=fastSample.name(), translatedFolder=str(dqmSubFolder.translated) if dqmSubFolder is not None else "")
996  rootFiles = [fullValFile, fastValFile]
997  legendLabels = [
998  "FullSim %s, %s %s" % (fullSample.name(), _stripRelease(self._newRelease), fullSelection),
999  "FastSim %s, %s %s" % (fastSample.name(), _stripRelease(self._newRelease), fastSelection),
1000  ]
1001  plotterFolder.create(rootFiles, legendLabels, dqmSubFolder, isPileupSample=fastSample.pileupEnabled(), requireAllHistograms=True)
1002  fileList = plotterFolder.draw(directory=newdir, **self._plotterDrawArgs)
1003 
1004  # For tables we just try them all, and see which ones succeed
1005  for tableCreator in plotterFolder.getTableCreators():
1006  htmlReport.addTable(tableCreator.create(rootFiles, legendLabels, dqmSubFolder))
1007 
1008  fullValFile.Close()
1009  fastValFile.Close()
1010 
1011  if len(fileList) == 0:
1012  return []
1013 
1014  dups = _findDuplicates(fileList)
1015  if len(dups) > 0:
1016  print "Plotter produced multiple files with names", ", ".join(dups)
1017  print "Typically this is a naming problem in the plotter configuration"
1018  sys.exit(1)
1019 
1020  # Move plots to new directory
1021  print "Created plots in %s" % (newdir)
1022  return map(lambda n: n.replace(newdir, newsubdir), fileList)
1023 
1024  def _doPlotsPileup(self, pu140Sample, pu200Sample, plotterFolder, dqmSubFolder, htmlReport):
1025  """Do the real plotting work for two pileup scenarios for a given algorithm, quality flag, and sample."""
1026  # Get GlobalTags
1027  pu140GlobalTag = _getGlobalTag(pu140Sample, self._newRelease)
1028  pu200GlobalTag = _getGlobalTag(pu200Sample, self._newRelease)
1029 
1030  # Construct selection string
1031  tmp = plotterFolder.getSelectionName(dqmSubFolder)
1032  pu140Selection = pu140GlobalTag+"_"+pu140Sample.pileup()+tmp+"_"+pu140Sample.pileupType(self._newRelease)
1033  pu200Selection = pu200GlobalTag+"_"+pu200Sample.pileup()+tmp+"_"+pu200Sample.pileupType(self._newRelease)
1034 
1035  # Construct directories for
1036  pu140dir = os.path.join(self._newBaseDir, pu140Selection, pu140Sample.name())
1037  pu200dir = os.path.join(self._newBaseDir, pu200Selection, pu200Sample.name())
1038  newsubdir = os.path.join("pileup", self._newRelease, pu200Selection, pu200Sample.name())
1039  newdir = os.path.join(self._newBaseDir, newsubdir)
1040  if not os.path.exists(newdir):
1041  os.makedirs(newdir)
1042 
1043  # Open input root files
1044  valname = "val.{sample}.root".format(sample=pu140Sample.name())
1045  pu140ValFilePath = os.path.join(pu140dir, valname)
1046  if not os.path.exists(pu140ValFilePath):
1047  if plotting.verbose:
1048  print "PU140 file %s not found" % pu140ValFilePath
1049  return []
1050  pu200ValFilePath = os.path.join(pu200dir, valname)
1051  if not os.path.exists(pu200ValFilePath):
1052  if plotting.verbose:
1053  print "PU200 file %s not found" % pu200ValFilePath
1054  return []
1055 
1056  pu140ValFile = ROOT.TFile.Open(pu140ValFilePath)
1057  pu200ValFile = ROOT.TFile.Open(pu200ValFilePath)
1058 
1059  # Do plots
1060  if plotting.verbose:
1061  print "Comparing PU140 and PU200 {sample} {translatedFolder}".format(
1062  sample=pu200Sample.name(), translatedFolder=str(dqmSubFolder.translated) if dqmSubFolder is not None else "")
1063  rootFiles = [pu140ValFile, pu200ValFile]
1064  legendLabels = [
1065  "%s, %s %s" % (pu140Sample.name(), _stripRelease(self._newRelease), pu140Selection),
1066  "%s, %s %s" % (pu200Sample.name(), _stripRelease(self._newRelease), pu200Selection),
1067  ]
1068  plotterFolder.create(rootFiles, legendLabels, dqmSubFolder, isPileupSample=pu140Sample.pileupEnabled(), requireAllHistograms=True)
1069  fileList = plotterFolder.draw(directory=newdir, **self._plotterDrawArgs)
1070 
1071  # For tables we just try them all, and see which ones succeed
1072  for tableCreator in plotterFolder.getTableCreators():
1073  htmlReport.addTable(tableCreator.create(rootFiles, legendLabels, dqmSubFolder))
1074 
1075  pu200ValFile.Close()
1076  pu140ValFile.Close()
1077 
1078  if len(fileList) == 0:
1079  return []
1080 
1081  dups = _findDuplicates(fileList)
1082  if len(dups) > 0:
1083  print "Plotter produced multiple files with names", ", ".join(dups)
1084  print "Typically this is a naming problem in the plotter configuration"
1085  sys.exit(1)
1086 
1087  # Move plots to new directory
1088  print "Created plots in %s" % (newdir)
1089  return map(lambda n: n.replace(newdir, newsubdir), fileList)
1090 
1091 
1092 def _copySubDir(oldfile, newfile, basenames, dirname):
1093  """Copy a subdirectory from oldfile to newfile.
1094 
1095  Arguments:
1096  oldfile -- String for source TFile
1097  newfile -- String for destination TFile
1098  basenames -- List of strings for base directories, first existing one is picked
1099  dirname -- String for directory name under the base directory
1100  """
1101  oldf = ROOT.TFile.Open(oldfile)
1102 
1103  dirold = None
1104  for basename in basenames:
1105  dirold = oldf.GetDirectory(basename)
1106  if dirold:
1107  break
1108  if not dirold:
1109  raise Exception("Did not find any of %s directories from file %s" % (",".join(basenames), oldfile))
1110  if dirname:
1111  d = dirold.Get(dirname)
1112  if not d:
1113  raise Exception("Did not find directory %s under %s" % (dirname, dirold.GetPath()))
1114  dirold = d
1115 
1116  newf = ROOT.TFile.Open(newfile, "RECREATE")
1117  dirnew = newf
1118  for d in basenames[0].split("/"):
1119  dirnew = dirnew.mkdir(d)
1120  if dirname:
1121  dirnew = dirnew.mkdir(dirname)
1122  _copyDir(dirold, dirnew)
1123 
1124  oldf.Close()
1125  return newf
1126 
1127 def _copyDir(src, dst):
1128  """Copy non-TTree objects from src TDirectory to dst TDirectory."""
1129  keys = src.GetListOfKeys()
1130  for key in keys:
1131  classname = key.GetClassName()
1132  cl = ROOT.TClass.GetClass(classname)
1133  if not cl:
1134  continue
1135  if not (cl.InheritsFrom("TTree") and cl.InheritsFrom("TDirectory")):
1136  dst.cd()
1137  obj = key.ReadObj()
1138  obj.Write()
1139  obj.Delete()
1140 
1142  found = set()
1143  found2 = set()
1144  for x in lst:
1145  if x in found:
1146  found2.add(x)
1147  else:
1148  found.add(x)
1149  return list(found2)
1150 
1152  def __init__(self, label, name, fileLegends, pileup=True, customPileupLabel=""):
1153  self._label = label
1154  self._name = name
1155  self._fileLegends = fileLegends
1156  self._pileup = pileup
1157  self._customPileupLabel = customPileupLabel
1158 
1159  def digest(self):
1160  # Label should be unique among the plotting run, so it serves also as the digest
1161  return self._label
1162 
1163  def label(self):
1164  return self._label
1165 
1166  def name(self):
1167  return self._name
1168 
1169  def files(self):
1170  return [t[0] for t in self._fileLegends]
1171 
1172  def legendLabels(self):
1173  return [t[1] for t in self._fileLegends]
1174 
1175  def fastsim(self):
1176  # No need to emulate the release validation fastsim behaviour here
1177  return False
1178 
1179  def pileupEnabled(self):
1180  return self._pileup
1181 
1183  return self._customPileupLabel
1184 
1185  def doElectron(self):
1186  return True
1187 
1188  def doConversion(self):
1189  return True
1190 
1191  def doBHadron(self):
1192  return True
1193 
1195  def __init__(self, samples, newdir):
1196  self._samples = samples
1197  self._newdir = newdir
1198  if not os.path.exists(newdir):
1199  os.makedirs(newdir)
1200 
1202 
1203  def createHtmlReport(self, validationName=""):
1204  if hasattr(self._htmlReport, "write"):
1205  raise Exception("HTML report object already created. There is probably some logic error in the calling code.")
1206  self._htmlReport = html.HtmlReport(validationName, self._newdir)
1207  return self._htmlReport
1208 
1209  def doPlots(self, plotters, plotterDrawArgs={}, **kwargs):
1210  self._plotterDrawArgs = plotterDrawArgs
1211 
1212  for sample in self._samples:
1213  self._subdirprefix = sample.label()
1214  self._labels = sample.legendLabels()
1215  self._htmlReport.beginSample(sample)
1216 
1217  self._openFiles = []
1218  for f in sample.files():
1219  if os.path.exists(f):
1220  self._openFiles.append(ROOT.TFile.Open(f))
1221  else:
1222  print "File %s not found (from sample %s), ignoring it" % (f, sample.name())
1223  self._openFiles.append(None)
1224 
1225  for plotter in plotters:
1226  self._doPlotsForPlotter(plotter, sample, **kwargs)
1227 
1228  for tf in self._openFiles:
1229  if tf is not None:
1230  tf.Close()
1231  self._openFiles = []
1232 
1233  def _doPlotsForPlotter(self, plotter, sample, limitSubFoldersOnlyTo=None):
1234  plotterInstance = plotter.readDirs(*self._openFiles)
1235  for plotterFolder, dqmSubFolder in plotterInstance.iterFolders(limitSubFoldersOnlyTo=limitSubFoldersOnlyTo):
1236  if sample is not None and not _processPlotsForSample(plotterFolder, sample):
1237  continue
1238  plotFiles = self._doPlots(plotterFolder, dqmSubFolder)
1239  if len(plotFiles) > 0:
1240  self._htmlReport.addPlots(plotterFolder, dqmSubFolder, plotFiles)
1241 
1242  def _doPlots(self, plotterFolder, dqmSubFolder):
1243  plotterFolder.create(self._openFiles, self._labels, dqmSubFolder)
1244  newsubdir = self._subdirprefix+plotterFolder.getSelectionName(dqmSubFolder)
1245  newdir = os.path.join(self._newdir, newsubdir)
1246  if not os.path.exists(newdir):
1247  os.makedirs(newdir)
1248  fileList = plotterFolder.draw(directory=newdir, **self._plotterDrawArgs)
1249 
1250  for tableCreator in plotterFolder.getTableCreators():
1251  self._htmlReport.addTable(tableCreator.create(self._openFiles, self._labels, dqmSubFolder))
1252 
1253 
1254  if len(fileList) == 0:
1255  return fileList
1256 
1257  dups = _findDuplicates(fileList)
1258  if len(dups) > 0:
1259  print "Plotter produced multiple files with names", ", ".join(dups)
1260  print "Typically this is a naming problem in the plotter configuration"
1261  sys.exit(1)
1262 
1263  print "Created plots in %s" % newdir
1264  return map(lambda n: n.replace(newdir, newsubdir), fileList)
def name(self)
Definition: validation.py:503
def sample(self)
Definition: validation.py:499
_fastsimCorrespondingFullsimPileup
Definition: validation.py:472
def _getGlobalTag(sample, release)
Definition: validation.py:326
def _doPlotsPileup(self, pu140Sample, pu200Sample, plotterFolder, dqmSubFolder, htmlReport)
Definition: validation.py:1024
def createHtmlReport(self, validationName="")
Definition: validation.py:1203
def _getSelectionName(self, args, kwargs)
Definition: validation.py:682
def hasPileup(self)
Definition: validation.py:510
def dirname(self, newRepository, newRelease, newSelection)
Definition: validation.py:573
def fullsim(self)
Definition: validation.py:566
def filename(self, newRelease)
Definition: validation.py:588
def _getDirectoryName(self, args, kwargs)
Definition: validation.py:679
def __init__(self, label, name, fileLegends, pileup=True, customPileupLabel="")
Definition: validation.py:1152
def doBHadron(self)
Definition: validation.py:541
def datasetpattern(self, newRelease)
Definition: validation.py:625
def label(self)
Definition: validation.py:507
def _doPlots(self, plotterFolder, dqmSubFolder)
Definition: validation.py:1242
def hasScenario(self)
Definition: validation.py:550
def doConversion(self)
Definition: validation.py:538
def pileupType(self, release=None)
Definition: validation.py:525
def pileupNumber(self)
Definition: validation.py:532
def _doFastsimFastVsFullPlots(self, limitSubFoldersOnlyTo, htmlReport)
Definition: validation.py:777
def _getRelValUrl(release)
Definition: validation.py:417
def _stripRelease(release)
Definition: validation.py:319
def _processPlotsForSample(plotterFolder, sample)
Definition: validation.py:429
def hasOverrideGlobalTag(self)
Definition: validation.py:556
def _doPlotsFastFull(self, fastSample, fullSample, plotterFolder, dqmSubFolder, htmlReport)
Definition: validation.py:958
def doElectron(self)
Definition: validation.py:535
def digest(self)
Definition: validation.py:495
def version(self, release=None)
Definition: validation.py:544
def doPlots(self, plotters, plotterDrawArgs={}, kwargs)
Definition: validation.py:1209
def __init__(self, fullsimSamples, fastsimSamples, refRelease, refRepository, newRelease, newRepository, newFileModifier=None, selectionName="")
Definition: validation.py:650
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def _copyDir(src, dst)
Definition: validation.py:1127
def pileupEnabled(self)
Definition: validation.py:514
def _findDuplicates(lst)
Definition: validation.py:1141
def _copySubDir(oldfile, newfile, basenames, dirname)
Definition: validation.py:1092
def _doPhase2PileupPlots(self, limitSubFoldersOnlyTo, htmlReport)
Definition: validation.py:810
def scenario(self)
Definition: validation.py:553
def doPlots(self, plotter, plotterDrawArgs={}, limitSubFoldersOnlyTo=None, htmlReport=html.HtmlReportDummy(), doFastVsFull=True, doPhase2PU=False)
Definition: validation.py:737
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:445
def pileup(self)
Definition: validation.py:518
def fastsimCorrespondingFullsimPileup(self)
Definition: validation.py:570
def fastsim(self)
Definition: validation.py:562
def createHtmlReport(self)
Definition: validation.py:734
def _doPlotsForPlotter(self, plotter, sample, limitSubFoldersOnlyTo=None)
Definition: validation.py:1233
def __init__(self, samples, newdir)
Definition: validation.py:1195
double split
Definition: MVATrainer.cc:139
def _getRefFileAndSelection(self, sample, plotterFolder, dqmSubFolder, selectionNameBase, valname)
Definition: validation.py:845
def _doPlots(self, sample, harvestedFile, plotterFolder, dqmSubFolder, htmlReport)
Definition: validation.py:887
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:559