CMS 3D CMS Logo

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