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