1919import numpy as np
2020import pandas as pd
2121import rhalphalib as rl
22- from datacard_systematics import (
23- CONTROL_regions ,
24- SIG_regions ,
25- systs_from_parquets ,
26- systs_not_from_parquets ,
27- )
22+
2823from systematics import bkgs , sigs
2924from utils import get_template , labels , load_templates , shape_to_num
3025
4035def create_datacard (
4136 hists_templates , years , lep_channels , add_ttbar_constraint = True , add_wjets_constraint = True , do_unfolding = False
4237):
38+
39+ if do_unfolding :
40+ from datacard_systematics_unfoldinglnN import (
41+ CONTROL_regions ,
42+ SIG_regions ,
43+ systs_from_parquets ,
44+ systs_not_from_parquets ,
45+ )
46+ else :
47+ from datacard_systematics import (
48+ CONTROL_regions ,
49+ SIG_regions ,
50+ systs_from_parquets ,
51+ systs_not_from_parquets ,
52+ )
53+
4354 # define the systematics
4455 systs_dict , systs_dict_values = systs_not_from_parquets (years , lep_channels , do_unfolding )
4556 sys_from_parquets = systs_from_parquets (years )
@@ -51,7 +62,12 @@ def create_datacard(
5162 ttbarnormSF = rl .IndependentParameter ("ttbarnormSF" , 1.0 , 0 , 10 )
5263
5364 if add_wjets_constraint :
54- wjetsnormSF = rl .IndependentParameter ("wjetsnormSF" , 1.0 , 0 , 10 )
65+ # wjetsnormSF = rl.IndependentParameter("wjetsnormSF", 1.0, 0, 10)
66+ wjetsnormSF = {}
67+ wjetsnormSF ["VBF" ] = rl .IndependentParameter ("wjetsnormSFVBF" , 1.0 , 0 , 10 )
68+ wjetsnormSF ["WJetsCRpt250to350" ] = rl .IndependentParameter ("wjetsnormSFpt250to350" , 1.0 , 0 , 10 )
69+ wjetsnormSF ["WJetsCRpt350to500" ] = rl .IndependentParameter ("wjetsnormSFpt350to500" , 1.0 , 0 , 10 )
70+ wjetsnormSF ["WJetsCRpt500toInf" ] = rl .IndependentParameter ("wjetsnormSFpt500toInf" , 1.0 , 0 , 10 )
5571
5672 samples = sigs + bkgs
5773 if do_unfolding :
@@ -134,17 +150,25 @@ def create_datacard(
134150 elif eff_do == 1 : # if down is the same as nominal
135151 sample .setParamEffect (sys_value , eff_up )
136152 else :
137- sample .setParamEffect (sys_value , max (eff_up , eff_do ), min (eff_up , eff_do ))
153+ # symetrize if up/do are in same direction
154+ if (eff_up > 1 ) & (eff_do > 1 ):
155+ sample .setParamEffect (sys_value , max (eff_up , eff_do ), 2 - max (eff_up , eff_do ))
156+ elif (eff_up < 1 ) & (eff_do < 1 ):
157+ sample .setParamEffect (sys_value , 2 - min (eff_up , eff_do ), min (eff_up , eff_do ))
158+ else :
159+ sample .setParamEffect (sys_value , max (eff_up , eff_do ), min (eff_up , eff_do ))
138160
139161 else :
140162
141- up_temp = syst_up / np .where (nominal == 0 , 1.0 , nominal ) # to avoid divide by 0
142- do_temp = syst_do / np .where (nominal == 0 , 1.0 , nominal ) # to avoid divide by 0
163+ up_temp = syst_up / np .where (nominal == 0 , 1.0 , nominal ) # to avoid divide by 0
164+ do_temp = syst_do / np .where (nominal == 0 , 1.0 , nominal ) # to avoid divide by 0
143165
144- if ("JMR_2016" in sys_name ) or ("JMS_2016" in sys_name ): # do is same as nominal so must manually symmetrize
166+ if ("JMR_2016" in sys_name ) or (
167+ "JMS_2016" in sys_name
168+ ): # do is same as nominal so must manually symmetrize
145169 if syst_do .sum () == nominal .sum ():
146170 do_temp = nominal / np .where (syst_up == 0 , 1.0 , syst_up )
147-
171+
148172 sample .setParamEffect (sys_value , up_temp , do_temp )
149173
150174 if sName in sigs :
@@ -212,16 +236,54 @@ def create_datacard(
212236 ttbarpass .setParamEffect (ttbarnormSF , 1 * ttbarnormSF )
213237
214238 if add_wjets_constraint :
215- failCh = model ["WJetsCR" ]
239+ # failCh = model["WJetsCR"]
240+
241+ # wjetsfail = failCh["wjets"]
242+ # wjetsfail.setParamEffect(wjetsnormSF, 1 * wjetsnormSF)
243+
244+ # for sig_region in SIG_regions:
245+ # passCh = model[sig_region]
246+
247+ # wjetspass = passCh["wjets"]
248+ # wjetspass.setParamEffect(wjetsnormSF, 1 * wjetsnormSF)
216249
217- wjetsfail = failCh ["wjets" ]
218- wjetsfail .setParamEffect (wjetsnormSF , 1 * wjetsnormSF )
250+ relations = {
251+ "ggFpt250to350" : "WJetsCRpt250to350" ,
252+ "ggFpt350to500" : "WJetsCRpt350to500" ,
253+ "ggFpt500toInf" : "WJetsCRpt500toInf" ,
254+ }
219255
220256 for sig_region in SIG_regions :
257+ if sig_region == "VBF" :
258+ continue # special treatment
259+
260+ failCh = model [relations [sig_region ]]
261+
262+ wjetsfail = failCh ["wjets" ]
263+ wjetsfail .setParamEffect (wjetsnormSF [relations [sig_region ]], 1 * wjetsnormSF [relations [sig_region ]])
264+
221265 passCh = model [sig_region ]
222266
223267 wjetspass = passCh ["wjets" ]
224- wjetspass .setParamEffect (wjetsnormSF , 1 * wjetsnormSF )
268+ wjetspass .setParamEffect (wjetsnormSF [relations [sig_region ]], 1 * wjetsnormSF [relations [sig_region ]])
269+
270+ # VBF
271+ fractions = []
272+ for cr_region in ["WJetsCRpt250to350" , "WJetsCRpt350to500" , "WJetsCRpt500toInf" ]:
273+ failCh = model [cr_region ]
274+
275+ wjetsfail = failCh ["wjets" ]
276+ wjetsfail .setParamEffect (wjetsnormSF [cr_region ], 1 * wjetsnormSF [cr_region ])
277+
278+ fractions += [sum (wjetsfail .getExpectation (nominal = True ))]
279+
280+ normalized_fractions = [v / sum (fractions ) for v in fractions ]
281+ print ("normalized_fractions" , normalized_fractions )
282+
283+ passCh = model ["VBF" ]
284+
285+ wjetspass = passCh ["wjets" ]
286+ wjetspass .setParamEffect (wjetsnormSF ["VBF" ], normalized_fractions [0 ] * wjetsnormSF ["WJetsCRpt250to350" ] + normalized_fractions [1 ] * wjetsnormSF ["WJetsCRpt350to500" ] + normalized_fractions [2 ] * wjetsnormSF ["WJetsCRpt500toInf" ])
225287
226288 return model
227289
0 commit comments