CMS 3D CMS Logo

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