Skip to content

Commit e6d1363

Browse files
Merge pull request cms-analysis#16 from JaLuka98/dev_higgsdnafinalfit_law_test_2023
Dev higgsdnafinalfit law test 2023
2 parents 8effc50 + 018a35e commit e6d1363

File tree

3 files changed

+229
-7
lines changed

3 files changed

+229
-7
lines changed

Trees2WS/law_trees2ws.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ def create_branch_map(self):
6565
for input_path in glob.glob(f"{self.input_paths}/{process}_M-{mass}_{self.era}/*.root")
6666
]
6767
branch_map = {i: mode_proc_mass for i, mode_proc_mass in enumerate(mode_proc_mass_list)}
68+
# Test if empty, then try naming convention with year in front
69+
# Note here: self.year = real year + era string (maybe should be improved)
70+
if not branch_map:
71+
print("branch_map is empty, trying with year+era at the end.")
72+
mode_proc_mass_list = [
73+
(mode, mass, input_path)
74+
for mode, process in production_modes
75+
for mass in input_masses
76+
for input_path in glob.glob(f"{self.input_paths}/{process}_M-{mass}_{self.year}/*.root")
77+
]
78+
branch_map = {i: mode_proc_mass for i, mode_proc_mass in enumerate(mode_proc_mass_list)}
6879
return branch_map
6980

7081
def output(self):
@@ -587,8 +598,8 @@ def requires(self):
587598

588599
tasks.append(Trees2WSSingleProcess(input_paths=path_to_root_files, era=era, apply_mass_cut=mass_cut, mass_cut_range=mass_cut_r, year=f"{self.year}{era}", doSystematics=doSystematics, doDiffSplitting=doDiffSplitting, doSTXSSplitting=doSTXSSplitting, doInOutSplitting=doInOutSplitting, output_dir=current_output_path, variable=var, version=f"v{i}", workflow=config['execution']))
589600
i += 1
590-
591-
return tasks
601+
return tasks
602+
592603
def output(self):
593604

594605
if self.variable == '':
@@ -618,7 +629,7 @@ def output(self):
618629
current_output_path = output_dir + "/input_output_{}_{}{}".format(var, self.year, era)
619630

620631
outputFolders.append(law.LocalFileTarget(current_output_path + '/ws_signal'))
621-
632+
622633
return outputFolders
623634

624635
def run(self):

commonTools/commonObjects.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
'merged':137.65,
2626
'2022preEE':8.00,
2727
'2022postEE':26.70,
28-
'2022': 34.7
28+
'2022': 34.7,
29+
'2023preBPix': 17.8,
30+
'2023postBPix': 9.5,
31+
'2023': 27.3
2932
}
3033

3134
def CreateVariableParameters(gen_variable, reco_variable, bins, year, BMW):
@@ -59,7 +62,7 @@ def CreateVariableParameters(gen_variable, reco_variable, bins, year, BMW):
5962
BR_W_qq = 67.41*0.01
6063

6164
# List of years
62-
years_to_process = ['2016','2017','2018','2022preEE','2022postEE']
65+
years_to_process = ['2016','2017','2018','2022preEE','2022postEE','2022preBPix','2022postBPix']
6366
# Production modes and decay channel: for extract XS from combine
6467
productionModes = ['ggH','qqH','ttH','tHq','tHW','ggZH', 'WH','ZH','bbH']
6568
decayMode = 'hgg'
@@ -81,25 +84,38 @@ def CreateVariableParameters(gen_variable, reco_variable, bins, year, BMW):
8184
input_masses = [120, 125, 130]
8285

8386
# Define an array of production modes and corresponding process strings
87+
# JLS 23th Jan 2025, also adding 2G naming conventions
8488
production_modes = [
8589
("ggh", "GluGluHtoGG"),
90+
("ggh", "GluGluHto2G"),
8691
("vbf", "VBFHtoGG"),
92+
("vbf", "VBFHto2G"),
8793
("vh", "VHtoGG"),
88-
("tth", "ttHtoGG")
94+
("vh", "VHto2G"),
95+
("tth", "ttHtoGG"),
96+
("tth", "ttHto2G"),
8997
]
9098

9199
# Define an array of eras
100+
# JLS 22th of Jan 2025: This syntax looks pretty criminal and should be improved at some point
92101
TwentyTwentyTwoEras = ["preEE", "postEE"]
102+
TwentyTwentyThreeEras = ["preBPix", "postBPix"]
103+
93104

94105
allErasMap = {
95-
'2022': TwentyTwentyTwoEras
106+
'2022': TwentyTwentyTwoEras,
107+
'2023': TwentyTwentyThreeEras
96108
}
97109

98110
conversionTable_ = {
99111
"GluGluHtoGG": "ggh",
112+
"GluGluHto2G": "ggh",
100113
"ttHtoGG": "tth",
114+
"ttHto2G": "tth",
101115
"VBFHtoGG": "vbf",
116+
"VBFHto2G": "vbf",
102117
"VHtoGG": "vh",
118+
"VHto2G": "vh",
103119
}
104120

105121
# List of all jet-related variables. Variables listed here will get the CMS_scale_j and CMS_res_j uncertainty in the datacard step.

config/2023_inclusive.yml

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Config file: options for signal fitting
2+
3+
outputFolder: '/.automount/net_rw/net__data_cms3a-1/spaeh/private/PhD/analyses/partial_Run3_differential/Hgg-PartialRun3-3A-ETH-Analysis/fitting/CMSSW_14_1_0_pre4/src/flashggFinalFit/test_law_branch_2023'
4+
5+
inputFiles:
6+
# Trees2WS
7+
Trees2WSData: '/eos/cms/store/group/phys_higgs/cmshgg/2023_2022_Hgg_differentials/2025_01_20_intermediateNTuples_2023/data/root/Data/allData_2023.root'
8+
Trees2WS: '/eos/cms/store/group/phys_higgs/cmshgg/2023_2022_Hgg_differentials/2025_01_20_intermediateNTuples_2023/signal/root'
9+
# Also does not work if we substitute the 2022 paths...
10+
11+
backgroundScriptCfg:
12+
# Setup
13+
cats: 'auto' # auto: automatically inferred from input ws
14+
catOffset: 0 # add offset to category numbers (useful for categories from different allData.root files)
15+
ext: 'backgroundPartialAnalysis' # extension to add to output directory
16+
year: '2023' # Use combined when merging all years in category (for plots)
17+
execution: 'local'
18+
19+
trees2wsCfg:
20+
inputTreeDir: 'DiphotonTree' # Name of RooDirectory storing input tree
21+
22+
apply_mass_cut: False # Apply cut on CMS_hgg_mass
23+
mass_cut_range: '100,180' # CMS_hgg_mass cut range
24+
doSTXSSplitting: False # Split output WS per STXS bin
25+
doDiffSplitting: False # Split output WS per differential bin
26+
doInOutSplitting: True # Split output WS into in/out fiducial based on some variable in the input trees (to be improved).
27+
doSystematics: True # Add systematics datasets to output WS
28+
29+
# Variables to be added to dataframe: use wildcard * for common strings
30+
mainVars:
31+
- "CMS_hgg_mass"
32+
- "weight"
33+
- "weight_central"
34+
- "dZ"
35+
- "*Up"
36+
- "*Down"
37+
- "fiducialGeometricFlag"
38+
39+
dataVars:
40+
- "CMS_hgg_mass"
41+
- "weight" # Vars to be added for data
42+
43+
stxsVar: ''
44+
diffVar: ''
45+
notagVars: [] # Vars to add to NOTAG RooDataset
46+
47+
systematicsVars:
48+
- "CMS_hgg_mass"
49+
- "weight"
50+
- "fiducialGeometricFlag"
51+
52+
# Do empty dict, only this way it works
53+
theoryWeightContainers: {}
54+
#weight_LHEPdf: 101
55+
#weight_LHEScale: 9
56+
57+
# List of systematics: use string YEAR for year-dependent systematics
58+
systematics:
59+
- "ScaleEB"
60+
- "ScaleEE"
61+
- "Smearing"
62+
#- "Material"
63+
#- "FNUF"
64+
- "energyErrShift"
65+
66+
cats: 'auto'
67+
68+
execution: 'local'
69+
70+
signalScriptCfg_2023_preBPix:
71+
# Setup
72+
procs: 'auto' # if auto: inferred automatically from filenames (requires names to be of form *pythia8_{PROC}.root)
73+
cats: 'auto' # if auto: inferred automatically from (0) workspace
74+
ext: 'signalPartialAnalysis_2023preBPix' # output directory extension
75+
analysis: 'earlyAnalysisInOut' # To specify replacement dataset and XS*BR mapping (defined in ./tools/replacementMap.py and ./tools/XSBRMap.py respectively)
76+
year: '2023preBPix' # Use 'combined' if merging all years: not recommended
77+
massPoints: '120,125,130' # You can now run with a single mass point if necessary
78+
79+
# Photon shape systematics
80+
scales: 'ScaleEE,ScaleEB' # separate nuisance per year
81+
scalesCorr: ''
82+
#scalesCorr: 'FNUF,Material' # correlated across years
83+
scalesGlobal: 'NonLinearity,Geant4' # affect all processes equally, correlated across years
84+
smears: 'Smearing' # separate nuisance per year
85+
86+
doPlots: True
87+
88+
beamspotWidthData: '3.2'
89+
beamspotWidthMC: '3.732'
90+
91+
92+
# Job submission options
93+
execution: 'local'
94+
95+
signalScriptCfg_2023_postBPix:
96+
# Setup
97+
procs: 'auto' # if auto: inferred automatically from filenames (requires names to be of form *pythia8_{PROC}.root)
98+
cats: 'auto' # if auto: inferred automatically from (0) workspace
99+
ext: 'signalPartialAnalysis_2023postBPix' # output directory extension
100+
analysis: 'earlyAnalysisInOut' # To specify replacement dataset and XS*BR mapping (defined in ./tools/replacementMap.py and ./tools/XSBRMap.py respectively)
101+
year: '2023postBPix' # Use 'combined' if merging all years: not recommended
102+
massPoints: '120,125,130' # You can now run with a single mass point if necessary
103+
104+
# Photon shape systematics
105+
scales: 'ScaleEE,ScaleEB' # separate nuisance per year
106+
scalesCorr: ''
107+
#scalesCorr: 'FNUF,Material' # correlated across years
108+
scalesGlobal: 'NonLinearity,Geant4' # affect all processes equally, correlated across years
109+
smears: 'Smearing' # separate nuisance per year
110+
111+
doPlots: True
112+
113+
114+
beamspotWidthData: '3.5'
115+
beamspotWidthMC: '3.732'
116+
117+
# Job submission options
118+
execution: 'local'
119+
120+
packaged_2023:
121+
cats: 'auto' # if auto: inferred automatically from (0) workspace
122+
massPoints: '120,125,130' # You can now run with a single mass point if necessary
123+
mergeYears: True # Merges the eras
124+
ext: ''
125+
execution: 'local'
126+
127+
datacard_yields:
128+
cats: 'auto' # if auto: inferred automatically from (0) workspace
129+
procs: 'auto' # if auto: inferred automatically from (0) workspace
130+
ext: 'earlyAnalysis' # Extension for saving
131+
# inputWSDirMap: '2023preBPix,2023postBPix'
132+
sigModelWSDir: './Models/signal' # Input signal model WS directory
133+
bkgModelWSDir: './Models/background' # Input background model WS directory
134+
bkgModelExt: 'multipdf' # Extension used when saving background model
135+
doSystematics: True # Include systematics calculations and add to datacard
136+
mergeYears: True # Merge category across years
137+
skipZeroes: True # Skip signal processes with 0 sum of weights
138+
ignore_warnings: True # Skip errors for missing systematics. Instead output warning message
139+
mass: '125' # Input workspace mass
140+
skipBkg: False # Only add signal processes to datacard
141+
bkgScaler: 1. # Add overall scale factor for background
142+
skipCOWCorr: True # Skip centralObjectWeight correction for events in acceptance. Use if no centralObjectWeight in workspace
143+
execution: 'local'
144+
145+
datacard:
146+
# For pruning processes
147+
prune: True # Prune proc x cat which make up less than pruneThreshold (default 0.1%) of given total category
148+
pruneThreshold: 0.001 # Threshold with which to prune proc x cat as fraction of total category yield (default=0.1%)
149+
doTrueYield: False # For pruning: use true number of expected events for proc x cat i.e. Product(XS,BR,eff*acc,lumi). Use only if NOTAG dataset has been included. If false then will use nominal_yield (i.e. sumEntries)
150+
analysis: 'earlyAnalysis' # Analysis extension: required for doTrueYield (see ./tools/XSBR.py for example)
151+
152+
# For yield/systematics:
153+
skipCOWCorr: True # Skip centralObjectWeight correction for events in acceptance
154+
doSystematics: True # Include systematics calculations and add to datacard
155+
doMCStatUncertainty: True # Add uncertainty for MC stats
156+
doSTXSMerging: False # Calculate additional migrations uncertainties for merged STXS bins (for 'mnorm' tier in systematics)
157+
doSTXSScaleCorrelationScheme: False # Partially de-correlate scale uncertainties for different phase space regions
158+
159+
# For output:
160+
saveDataFrame: False # Save final dataframe as pkl file
161+
output: 'Datacard_2023' # Datacard name
162+
163+
datacard_clean:
164+
factor: 10000 # Factor beyond which uncertainty is considered incorrect and is removed
165+
removeDoubleSided: False # Remove any nuisances which are listed as antisymmetric but both values point the same way
166+
removeNonDiagonal: False # Remove any nuisances which are affect processes unimportant in that category
167+
symmetrizeNuisance: 'CMS_hgg_SigmaEOverEShift,CMS_hgg_scale_0_shape,CMS_hgg_scale_1_shape,CMS_hgg_scale_3_shape' # Symmetrizes asymmetric nuisance. Enter in the format nuisance1,nuisance2,nuisance3,etc.
168+
verbose: False # Spit out all the cleaning being done
169+
170+
combine_fit:
171+
asimov_numPoints: 30 # Number of points the Asimov generator should generate for the NLL scan
172+
unblindedFit_numPoints: 100
173+
setParameterRange: "r=0,2"
174+
cminApproxPreFitTolerance: 0.01
175+
rMin: 0.7
176+
rMax: 1.6
177+
execution: 'local'
178+
179+
combine_impacts:
180+
exclude: "" # Nuisances that should be excluded from the impact computation
181+
cminApproxPreFitTolerance: 0.01
182+
setParameters: 1.000
183+
stepSize: 0.05
184+
setCrossingTolerance: 0.00005
185+
not_show_POI: False
186+
execution: 'htcondor'
187+
188+
combine_hesse:
189+
execution: 'local'
190+
191+
combine_mggToys:
192+
nToys: 1000 # Number of toys = nToys * 10
193+
loadSnapshot: 'MultiDimFit'
194+
doBands: True
195+
execution: 'htcondor'

0 commit comments

Comments
 (0)