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