From ba9c770b8bc8ba42de2cfc479f1d794272ddf31e Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Tue, 3 Mar 2026 21:19:17 +0100 Subject: [PATCH 01/20] fixing bin-by-bin subtraction for correction estimation + first draft for ml interface --- FF_calculation/FF_QCD.py | 196 +++++++++++++--------------- FF_calculation/FF_Wjets.py | 182 +++++++++++--------------- FF_calculation/FF_ttbar.py | 99 ++++----------- FF_calculation/fractions.py | 23 ++-- ff_corrections.py | 10 +- helper/ff_evaluators.py | 246 ++++++++++++++++++++++++++++++++++-- helper/ff_functions.py | 5 +- 7 files changed, 445 insertions(+), 316 deletions(-) diff --git a/FF_calculation/FF_QCD.py b/FF_calculation/FF_QCD.py index 896799a..44560cf 100644 --- a/FF_calculation/FF_QCD.py +++ b/FF_calculation/FF_QCD.py @@ -18,9 +18,7 @@ @logging_helper.LogDecorator().grouped_logs(extractor=lambda args: f"{args[6]}") -def calculation_QCD_FFs( - args: Tuple[Any, ...], -) -> Dict[str, Union[str, Dict[str, str]]]: +def calculation_QCD_FFs(args: Tuple[Any, ...]) -> Dict[str, Union[str, Dict[str, str]]]: """ This function calculates fake factors for the QCD process for a specific category (split). @@ -62,7 +60,6 @@ def calculation_QCD_FFs( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for QCD signal-like region log.info(f"Filtering events for the signal-like region. Target process: {process}") region_conf = copy.deepcopy(process_conf["SRlike_cuts"]) rdf_SRlike = ff_func.apply_region_filters( @@ -74,7 +71,6 @@ def calculation_QCD_FFs( logger=logger, ) - # event filter for QCD application-like region log.info(f"Filtering events for the application-like region. Target process: {process}") region_conf = copy.deepcopy(process_conf["ARlike_cuts"]) rdf_ARlike = ff_func.apply_region_filters( @@ -86,24 +82,20 @@ def calculation_QCD_FFs( logger=logger, ) - # get binning of the dependent variable xbinning = array.array("d", splitting.var_bins) nbinsx = len(splitting.var_bins) - 1 - # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( + SRlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( (process_conf["var_dependence"], f"{sample}", nbinsx, xbinning), process_conf["var_dependence"], "weight", - ) - SRlike_hists[sample] = h.GetValue() + ).GetValue() - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + ARlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( (process_conf["var_dependence"], f"{sample}", nbinsx, xbinning), process_conf["var_dependence"], "weight", - ) - ARlike_hists[sample] = h.GetValue() + ).GetValue() # calculate QCD enriched data by subtraction all the background samples SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() @@ -164,7 +156,7 @@ def calculation_QCD_FFs( save_data=True, ) - # producing some control plots + # producing control plots for _hist, _region in [ (SRlike_hists, "SR_like"), (ARlike_hists, "AR_like"), @@ -191,9 +183,7 @@ def calculation_QCD_FFs( @logging_helper.LogDecorator().grouped_logs(extractor=lambda args: f"{args[7]}") -def non_closure_correction( - args: Tuple[Any, ...], -) -> Dict[str, np.ndarray]: +def non_closure_correction(args: Tuple[Any, ...]) -> Dict[str, np.ndarray]: """ This function calculates non closure corrections for fake factors for QCD. @@ -229,9 +219,9 @@ def non_closure_correction( log = logging.getLogger(logger) - # init histogram dict for FF measurement SRlike_hists = dict() ARlike_hists = dict() + ARlike_hists_ff = dict() for sample_path in sample_paths: # getting the name of the process from the sample path @@ -244,7 +234,6 @@ def non_closure_correction( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for QCD signal-like region log.info(f"Filtering events for the signal-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["SRlike_cuts"]) rdf_SRlike = ff_func.apply_region_filters( @@ -256,7 +245,6 @@ def non_closure_correction( logger=logger, ) - # event filter for QCD application-like region log.info(f"Filtering events for the application-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["ARlike_cuts"]) rdf_ARlike = ff_func.apply_region_filters( @@ -268,85 +256,83 @@ def non_closure_correction( logger=logger, ) - # evaluate the measured fake factors for the specific processes - if sample == "data": - rdf_ARlike = evaluator.evaluate_fake_factor(rdf=rdf_ARlike) + rdf_ARlike = evaluator.evaluate_fake_factor(rdf=rdf_ARlike) - # additionally evaluate the previous corrections - corr_str = "" - for corr_evaluator in corr_evaluators: - rdf_ARlike = corr_evaluator.evaluate_correction(rdf=rdf_ARlike) - corr_str += f" * {corr_evaluator.corr_str}" + corr_str = "" + for corr_evaluator in corr_evaluators: + rdf_ARlike = corr_evaluator.evaluate_correction(rdf=rdf_ARlike) + corr_str += f" * {corr_evaluator.corr_str}" - rdf_ARlike = rdf_ARlike.Define( - "weight_ff", - f"weight * {process}_fake_factor{corr_str}", - ) + rdf_ARlike = rdf_ARlike.Define("weight_ff", f"weight * {process}_fake_factor{corr_str}") - # get binning of the dependent variable xbinning, nbinsx = array.array("d", splitting.var_bins), len(splitting.var_bins) - 1 - # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( + SRlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( (correction_conf["var_dependence"], f"{sample}", nbinsx, xbinning), correction_conf["var_dependence"], "weight", - ) - SRlike_hists[sample] = h.GetValue() + ).GetValue() - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( - ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - ARlike_hists[sample] = h.GetValue() - - if sample == "data": - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( - ( - correction_conf["var_dependence"], - f"{sample}_ff", - nbinsx, - xbinning, - ), - correction_conf["var_dependence"], - "weight_ff", - ) - ARlike_hists["data_ff"] = h.GetValue() + ARlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ar", nbinsx, xbinning), + correction_conf["var_dependence"], + "weight" + ).GetValue() - SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() - ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() + ARlike_hists_ff[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ff", nbinsx, xbinning), + correction_conf["var_dependence"], + "weight_ff", + ).GetValue() _pairs = [("data_subtracted", "data"), ("data", "data")] + SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() SRlike_hists_sub_up = {k1: SRlike_hists[k2].Clone() for k1, k2 in _pairs} SRlike_hists_sub_down = deepcopy(SRlike_hists_sub_up) - ARlike_hists_sub_up = {k1: ARlike_hists[k2].Clone() for k1, k2 in _pairs + [("data_ff", "data_ff")]} + ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() + ARlike_hists_sub_up = {k1: ARlike_hists[k2].Clone() for k1, k2 in _pairs} ARlike_hists_sub_down = deepcopy(ARlike_hists_sub_up) + data_ff_subtracted = ARlike_hists_ff["data"].Clone() + data_ff_subtracted_up = ARlike_hists_ff["data"].Clone() + data_ff_subtracted_down = ARlike_hists_ff["data"].Clone() + for hist in SRlike_hists: if hist not in ["data", "data_subtracted", "QCD"]: SRlike_hists["data_subtracted"].Add(SRlike_hists[hist].Clone(), -1) SRlike_hists_sub_up["data_subtracted"].Add(SRlike_hists[hist].Clone().AddError(1), -1) SRlike_hists_sub_down["data_subtracted"].Add(SRlike_hists[hist].Clone().AddError(-1), -1) for hist in ARlike_hists: - if hist not in ["data", "data_subtracted", "data_ff", "QCD"]: + if hist not in ["data", "data_subtracted", "QCD"]: ARlike_hists["data_subtracted"].Add(ARlike_hists[hist].Clone(), -1) ARlike_hists_sub_up["data_subtracted"].Add(ARlike_hists[hist].Clone().AddError(1), -1) ARlike_hists_sub_down["data_subtracted"].Add(ARlike_hists[hist].Clone().AddError(-1), -1) + for hist in ARlike_hists_ff: + if hist not in ["data", "QCD"]: + data_ff_subtracted.Add(ARlike_hists_ff[hist].Clone(), -1) + data_ff_subtracted_up.Add(ARlike_hists_ff[hist].Clone().AddError(1), -1) + data_ff_subtracted_down.Add(ARlike_hists_ff[hist].Clone().AddError(-1), -1) + + ARlike_hists["data_ff"] = data_ff_subtracted + ARlike_hists_sub_up["data_ff"] = data_ff_subtracted_up + ARlike_hists_sub_down["data_ff"] = data_ff_subtracted_down correction_hist, process_fraction = ff_func.calculate_non_closure_correction( SRlike=SRlike_hists, ARlike=ARlike_hists, + skip_frac=True, ) - nominal_draw_obj, smoothed_graph, correction_dict = ff_func.smooth_function( + nominal_draw_obj, _, correction_dict = ff_func.smooth_function( hist=correction_hist.Clone(), bin_edges=splitting.var_bins, correction_option=splitting.correction_option, bandwidth=splitting.bandwidth, mc_shifted_hist={ - "MCShiftUp": ff_func.calculate_non_closure_correction(SRlike_hists_sub_up, ARlike_hists_sub_up)[0].Clone(), - "MCShiftDown": ff_func.calculate_non_closure_correction(SRlike_hists_sub_down, ARlike_hists_sub_down)[0].Clone(), + "MCShiftUp": ff_func.calculate_non_closure_correction(SRlike_hists_sub_up, ARlike_hists_sub_up, skip_frac=True)[0].Clone(), + "MCShiftDown": ff_func.calculate_non_closure_correction(SRlike_hists_sub_down, ARlike_hists_sub_down, skip_frac=True)[0].Clone(), }, ) @@ -389,7 +375,7 @@ def non_closure_correction( save_data=save_data, ) - # producing some control plots + # producing control plots for yscale, save_data in zip(["linear", "log"], [True, False]): plotting.plot_data_mc_ratio( variable=correction_conf["var_dependence"], @@ -414,9 +400,7 @@ def non_closure_correction( @logging_helper.LogDecorator().grouped_logs(extractor=lambda args: f"{args[6]}") -def DR_SR_correction( - args: Tuple[Any, ...], -) -> Dict[str, np.ndarray]: +def DR_SR_correction(args: Tuple[Any, ...]) -> Dict[str, np.ndarray]: """ This function calculates DR to SR correction for fake factors for QCD. @@ -448,9 +432,9 @@ def DR_SR_correction( log = logging.getLogger(logger) - # init histogram dict for FF measurement SRlike_hists = dict() ARlike_hists = dict() + ARlike_hists_ff = dict() for sample_path in sample_paths: # getting the name of the process from the sample path @@ -463,7 +447,6 @@ def DR_SR_correction( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for QCD signal-like region log.info(f"Filtering events for the signal-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["SRlike_cuts"]) rdf_SRlike = ff_func.apply_region_filters( @@ -475,7 +458,6 @@ def DR_SR_correction( logger=logger, ) - # event filter for QCD application-like region log.info(f"Filtering events for the application-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["ARlike_cuts"]) rdf_ARlike = ff_func.apply_region_filters( @@ -487,75 +469,73 @@ def DR_SR_correction( logger=logger, ) - # evaluate the measured fake factors for the specific processes - if sample == "data": - rdf_ARlike = evaluator.evaluate_fake_factor(rdf=rdf_ARlike) + rdf_ARlike = evaluator.evaluate_fake_factor(rdf=rdf_ARlike) - # additionally evaluate the previous corrections - corr_str = "" - for corr_evaluator in corr_evaluators: - rdf_ARlike = corr_evaluator.evaluate_correction(rdf=rdf_ARlike) - corr_str += f" * {corr_evaluator.corr_str}" + corr_str = "" + for corr_evaluator in corr_evaluators: + rdf_ARlike = corr_evaluator.evaluate_correction(rdf=rdf_ARlike) + corr_str += f" * {corr_evaluator.corr_str}" - rdf_ARlike = rdf_ARlike.Define( - "weight_ff", - f"weight * {process}_fake_factor{corr_str}", - ) + rdf_ARlike = rdf_ARlike.Define("weight_ff", f"weight * {process}_fake_factor{corr_str}") - # get binning of the dependent variable xbinning, nbinsx = array.array("d", splitting.var_bins), len(splitting.var_bins) - 1 - # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( + SRlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( (correction_conf["var_dependence"], f"{sample}", nbinsx, xbinning), correction_conf["var_dependence"], "weight", - ) - SRlike_hists[sample] = h.GetValue() + ).GetValue() - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( - ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - ARlike_hists[sample] = h.GetValue() - - if sample == "data": - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( - ( - correction_conf["var_dependence"], - f"{sample}_ff", - nbinsx, - xbinning, - ), - correction_conf["var_dependence"], - "weight_ff", - ) - ARlike_hists["data_ff"] = h.GetValue() + ARlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ar", nbinsx, xbinning), + correction_conf["var_dependence"], + "weight" + ).GetValue() - SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() - ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() + ARlike_hists_ff[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ff", nbinsx, xbinning), + correction_conf["var_dependence"], + "weight_ff", + ).GetValue() _pairs = [("data_subtracted", "data"), ("data", "data")] + SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() SRlike_hists_sub_up = {k1: SRlike_hists[k2].Clone() for k1, k2 in _pairs} SRlike_hists_sub_down = deepcopy(SRlike_hists_sub_up) - ARlike_hists_sub_up = {k1: ARlike_hists[k2].Clone() for k1, k2 in _pairs + [("data_ff", "data_ff")]} + ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() + ARlike_hists_sub_up = {k1: ARlike_hists[k2].Clone() for k1, k2 in _pairs} ARlike_hists_sub_down = deepcopy(ARlike_hists_sub_up) + data_ff_subtracted = ARlike_hists_ff["data"].Clone() + data_ff_subtracted_up = ARlike_hists_ff["data"].Clone() + data_ff_subtracted_down = ARlike_hists_ff["data"].Clone() + for hist in SRlike_hists: if hist not in ["data", "data_subtracted", "QCD"]: SRlike_hists["data_subtracted"].Add(SRlike_hists[hist].Clone(), -1) SRlike_hists_sub_up["data_subtracted"].Add(SRlike_hists[hist].Clone().AddError(1), -1) SRlike_hists_sub_down["data_subtracted"].Add(SRlike_hists[hist].Clone().AddError(-1), -1) for hist in ARlike_hists: - if hist not in ["data", "data_subtracted", "data_ff", "QCD"]: + if hist not in ["data", "data_subtracted", "QCD"]: ARlike_hists["data_subtracted"].Add(ARlike_hists[hist].Clone(), -1) ARlike_hists_sub_up["data_subtracted"].Add(ARlike_hists[hist].Clone().AddError(1), -1) ARlike_hists_sub_down["data_subtracted"].Add(ARlike_hists[hist].Clone().AddError(-1), -1) + for hist in ARlike_hists_ff: + if hist not in ["data", "QCD"]: + data_ff_subtracted.Add(ARlike_hists_ff[hist].Clone(), -1) + data_ff_subtracted_up.Add(ARlike_hists_ff[hist].Clone().AddError(1), -1) + data_ff_subtracted_down.Add(ARlike_hists_ff[hist].Clone().AddError(-1), -1) + + ARlike_hists["data_ff"] = data_ff_subtracted + ARlike_hists_sub_up["data_ff"] = data_ff_subtracted_up + ARlike_hists_sub_down["data_ff"] = data_ff_subtracted_down correction_hist, process_fraction = ff_func.calculate_non_closure_correction( SRlike=SRlike_hists, ARlike=ARlike_hists, + skip_frac=True, ) nominal_draw_obj, smoothed_graph, correction_dict = ff_func.smooth_function( @@ -564,8 +544,8 @@ def DR_SR_correction( correction_option=splitting.correction_option, bandwidth=splitting.bandwidth, mc_shifted_hist={ - "MCShiftUp": ff_func.calculate_non_closure_correction(SRlike_hists_sub_up, ARlike_hists_sub_up)[0].Clone(), - "MCShiftDown": ff_func.calculate_non_closure_correction(SRlike_hists_sub_down, ARlike_hists_sub_down)[0].Clone(), + "MCShiftUp": ff_func.calculate_non_closure_correction(SRlike_hists_sub_up, ARlike_hists_sub_up, skip_frac=True)[0].Clone(), + "MCShiftDown": ff_func.calculate_non_closure_correction(SRlike_hists_sub_down, ARlike_hists_sub_down, skip_frac=True)[0].Clone(), }, ) diff --git a/FF_calculation/FF_Wjets.py b/FF_calculation/FF_Wjets.py index f8b02dc..91fa659 100644 --- a/FF_calculation/FF_Wjets.py +++ b/FF_calculation/FF_Wjets.py @@ -18,9 +18,7 @@ @logging_helper.LogDecorator().grouped_logs(extractor=lambda args: f"{args[6]}") -def calculation_Wjets_FFs( - args: Tuple[Any, ...], -) -> Dict[str, Union[Dict[str, str], Dict[str, Dict[str, str]]]]: +def calculation_Wjets_FFs(args: Tuple[Any, ...]) -> Dict[str, Union[Dict[str, str], Dict[str, Dict[str, str]]]]: """ This function calculates fake factors for the Wjets process for a specific category (split). @@ -248,9 +246,7 @@ def calculation_Wjets_FFs( @logging_helper.LogDecorator().grouped_logs(extractor=lambda args: f"{args[7]}") -def non_closure_correction( - args: Tuple[Any, ...], -) -> Dict[str, np.ndarray]: +def non_closure_correction(args: Tuple[Any, ...]) -> Dict[str, np.ndarray]: """ This function calculates the non closure correction for the Wjet process for a specific category. @@ -286,14 +282,14 @@ def non_closure_correction( log = logging.getLogger(logger) - # init histogram dict for FF measurement SRlike_hists = dict() ARlike_hists = dict() - - # init histogram dict for QCD SS/OS estimation SRlike_hists_qcd = dict() ARlike_hists_qcd = dict() + ARlike_hists_ff = dict() + ARlike_hists_qcd_ff = dict() + for sample_path in sample_paths: # getting the name of the process from the sample path sample = sample_path.rsplit("/")[-1].rsplit(".")[0] @@ -305,7 +301,6 @@ def non_closure_correction( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for Wjets signal-like region log.info(f"Filtering events for the signal-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["SRlike_cuts"]) rdf_SRlike = ff_func.apply_region_filters( @@ -317,8 +312,7 @@ def non_closure_correction( logger=logger, ) - # QCD estimation from same sign in signal-like region - if "tau_pair_sign" in region_conf: + if "tau_pair_sign" in region_conf: # QCD estimation from same sign in signal-like region region_conf["tau_pair_sign"] = "(q_1*q_2) > 0" # same sign else: raise ValueError(f"No tau pair sign cut defined in the {process} config. Is needed for the QCD estimation.") @@ -333,7 +327,6 @@ def non_closure_correction( logger=logger, ) - # event filter for Wjets application-like region log.info(f"Filtering events for the application-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["ARlike_cuts"]) rdf_ARlike = ff_func.apply_region_filters( @@ -345,24 +338,7 @@ def non_closure_correction( logger=logger, ) - # evaluate the measured fake factors for the specific processes - if sample == "data": - rdf_ARlike = evaluator.evaluate_fake_factor(rdf=rdf_ARlike) - - # additionally evaluate the previous corrections - corr_str = "" - for corr_evaluator in corr_evaluators: - rdf_ARlike = corr_evaluator.evaluate_correction( - rdf=rdf_ARlike, - ) - corr_str += f" * {corr_evaluator.corr_str}" - - rdf_ARlike = rdf_ARlike.Define( - "weight_ff", f"weight * {process}_fake_factor{corr_str}" - ) - - # QCD estimation from same sign in application-like region - if "tau_pair_sign" in region_conf: + if "tau_pair_sign" in region_conf: # QCD estimation from same sign in application-like region region_conf["tau_pair_sign"] = "(q_1*q_2) > 0" # same sign else: raise ValueError(f"No tau pair sign cut defined in the {process} config. Is needed for the QCD estimation.") @@ -377,88 +353,103 @@ def non_closure_correction( logger=logger, ) - # get binning of the dependent variable + rdf_ARlike = evaluator.evaluate_fake_factor(rdf=rdf_ARlike) + rdf_ARlike_qcd = evaluator.evaluate_fake_factor(rdf=rdf_ARlike_qcd) + + corr_str = "" + for corr_evaluator in corr_evaluators: + rdf_ARlike = corr_evaluator.evaluate_correction(rdf=rdf_ARlike) + rdf_ARlike_qcd = corr_evaluator.evaluate_correction(rdf=rdf_ARlike_qcd) + corr_str += f" * {corr_evaluator.corr_str}" + + rdf_ARlike = rdf_ARlike.Define("weight_ff", f"weight * {process}_fake_factor{corr_str}") + rdf_ARlike_qcd = rdf_ARlike_qcd.Define("weight_ff", f"weight * {process}_fake_factor{corr_str}") + xbinning = array.array("d", splitting.var_bins) nbinsx = len(splitting.var_bins) - 1 - # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( - (correction_conf["var_dependence"], f"{sample}", nbinsx, xbinning), - correction_conf["var_dependence"], - "weight", - ) - SRlike_hists[sample] = h.GetValue() + SRlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_sr", nbinsx, xbinning), + correction_conf["var_dependence"], "weight" + ).GetValue() - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( - ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - ARlike_hists[sample] = h.GetValue() + SRlike_hists_qcd[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike_qcd).Histo1D( + (correction_conf["var_dependence"], f"{sample}_sr_qcd", nbinsx, xbinning), + correction_conf["var_dependence"], "weight" + ).GetValue() - if sample == "data": - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( - ( - correction_conf["var_dependence"], - f"{sample}_ff", - nbinsx, - xbinning, - ), - correction_conf["var_dependence"], - "weight_ff", - ) - ARlike_hists["data_ff"] = h.GetValue() + ARlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ar", nbinsx, xbinning), + correction_conf["var_dependence"], "weight" + ).GetValue() - # making the histograms for QCD estimation - h_qcd = RuntimeVariables.RDataFrameWrapper(rdf_SRlike_qcd).Histo1D( - (correction_conf["var_dependence"], f"{sample}", nbinsx, xbinning), - correction_conf["var_dependence"], - "weight", - ) - SRlike_hists_qcd[sample] = h_qcd.GetValue() + ARlike_hists_qcd[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike_qcd).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ar_qcd", nbinsx, xbinning), + correction_conf["var_dependence"], "weight" + ).GetValue() - h_qcd = RuntimeVariables.RDataFrameWrapper(rdf_ARlike_qcd).Histo1D( - ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - ARlike_hists_qcd[sample] = h_qcd.GetValue() + ARlike_hists_ff[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ar_ff", nbinsx, xbinning), + correction_conf["var_dependence"], "weight_ff" + ).GetValue() + + ARlike_hists_qcd_ff[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike_qcd).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ar_qcd_ff", nbinsx, xbinning), + correction_conf["var_dependence"], "weight_ff" + ).GetValue() - # calculate QCD estimation SRlike_hists["QCD"] = ff_func.QCD_SS_estimate(hists=SRlike_hists_qcd) ARlike_hists["QCD"] = ff_func.QCD_SS_estimate(hists=ARlike_hists_qcd) - - SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() - ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() + ARlike_hists_ff["QCD"] = ff_func.QCD_SS_estimate(hists=ARlike_hists_qcd_ff) _pairs = [("data_subtracted", "data"), ("data", "data")] + SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() SRlike_hists_sub_up = {k1: SRlike_hists[k2].Clone() for k1, k2 in _pairs} SRlike_hists_sub_down = deepcopy(SRlike_hists_sub_up) - ARlike_hists_sub_up = {k1: ARlike_hists[k2].Clone() for k1, k2 in _pairs + [("data_ff", "data_ff")]} + ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() + ARlike_hists_sub_up = {k1: ARlike_hists[k2].Clone() for k1, k2 in _pairs} ARlike_hists_sub_down = deepcopy(ARlike_hists_sub_up) + data_ff_subtracted = ARlike_hists_ff["data"].Clone() + data_ff_subtracted_up = ARlike_hists_ff["data"].Clone() + data_ff_subtracted_down = ARlike_hists_ff["data"].Clone() + for hist in SRlike_hists: if hist not in ["data", "data_subtracted", "Wjets"]: SRlike_hists["data_subtracted"].Add(SRlike_hists[hist].Clone(), -1) SRlike_hists_sub_up["data_subtracted"].Add(SRlike_hists[hist].Clone().AddError(1), -1) SRlike_hists_sub_down["data_subtracted"].Add(SRlike_hists[hist].Clone().AddError(-1), -1) for hist in ARlike_hists: - if hist not in ["data", "data_subtracted", "data_ff", "Wjets"]: + if hist not in ["data", "data_subtracted", "Wjets"]: ARlike_hists["data_subtracted"].Add(ARlike_hists[hist].Clone(), -1) ARlike_hists_sub_up["data_subtracted"].Add(ARlike_hists[hist].Clone().AddError(1), -1) ARlike_hists_sub_down["data_subtracted"].Add(ARlike_hists[hist].Clone().AddError(-1), -1) + for hist in ARlike_hists_ff: + if hist not in ["data", "Wjets"]: + data_ff_subtracted.Add(ARlike_hists_ff[hist].Clone(), -1) + data_ff_subtracted_up.Add(ARlike_hists_ff[hist].Clone().AddError(1), -1) + data_ff_subtracted_down.Add(ARlike_hists_ff[hist].Clone().AddError(-1), -1) + + ARlike_hists["data_ff"] = data_ff_subtracted + ARlike_hists_sub_up["data_ff"] = data_ff_subtracted_up + ARlike_hists_sub_down["data_ff"] = data_ff_subtracted_down correction_hist, process_fraction = ff_func.calculate_non_closure_correction( SRlike=SRlike_hists, ARlike=ARlike_hists, + skip_frac=True, ) - nominal_draw_obj, smoothed_graph, correction_dict = ff_func.smooth_function( + nominal_draw_obj, _, correction_dict = ff_func.smooth_function( hist=correction_hist.Clone(), bin_edges=splitting.var_bins, correction_option=splitting.correction_option, bandwidth=splitting.bandwidth, mc_shifted_hist={ - "MCShiftUp": ff_func.calculate_non_closure_correction(SRlike_hists_sub_up, ARlike_hists_sub_up)[0].Clone(), - "MCShiftDown": ff_func.calculate_non_closure_correction(SRlike_hists_sub_down, ARlike_hists_sub_down)[0].Clone(), + "MCShiftUp": ff_func.calculate_non_closure_correction(SRlike_hists_sub_up, ARlike_hists_sub_up, skip_frac=True)[0].Clone(), + "MCShiftDown": ff_func.calculate_non_closure_correction(SRlike_hists_sub_down, ARlike_hists_sub_down, skip_frac=True)[0].Clone(), }, ) @@ -559,7 +550,6 @@ def DR_SR_correction( log = logging.getLogger(logger) - # init histogram dict for FF measurement SRlike_hists = dict() ARlike_hists = dict() @@ -575,7 +565,6 @@ def DR_SR_correction( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for Wjets signal-like region log.info(f"Filtering events for the signal-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["SRlike_cuts"]) rdf_SRlike = ff_func.apply_region_filters( @@ -587,7 +576,6 @@ def DR_SR_correction( logger=logger, ) - # event filter for Wjets application-like region log.info(f"Filtering events for the application-like region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["ARlike_cuts"]) rdf_ARlike = ff_func.apply_region_filters( @@ -603,48 +591,30 @@ def DR_SR_correction( # additionally evaluate the previous corrections corr_str = "" for corr_evaluator in corr_evaluators: - rdf_ARlike = corr_evaluator.evaluate_correction( - rdf=rdf_ARlike, - ) + rdf_ARlike = corr_evaluator.evaluate_correction(rdf=rdf_ARlike) corr_str += f" * {corr_evaluator.corr_str}" - rdf_ARlike = rdf_ARlike.Define( - "weight_ff", f"weight * {process}_fake_factor{corr_str}" - ) + rdf_ARlike = rdf_ARlike.Define("weight_ff", f"weight * {process}_fake_factor{corr_str}") - # get binning of the dependent variable xbinning, nbinsx = array.array("d", splitting.var_bins), len(splitting.var_bins) - 1 - # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( - ( - correction_conf["var_dependence"], - f"{sample}", - nbinsx, - xbinning, - ), + SRlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}", nbinsx, xbinning), correction_conf["var_dependence"], "weight", - ) - SRlike_hists[sample] = h.GetValue() - - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( - ( - correction_conf["var_dependence"], - f"{sample}_ff", - nbinsx, - xbinning, - ), + ).GetValue() + + ARlike_hists["Wjets_ff"] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + (correction_conf["var_dependence"], f"{sample}_ff", nbinsx, xbinning), correction_conf["var_dependence"], "weight_ff", - ) - ARlike_hists["Wjets_ff"] = h.GetValue() + ).GetValue() correction_hist = ff_func.calculate_non_closure_correction_Wjets_fromMC( SRlike=SRlike_hists, ARlike=ARlike_hists ) - nominal_draw_obj, smoothed_graph, correction_dict = ff_func.smooth_function( + nominal_draw_obj, _, correction_dict = ff_func.smooth_function( hist=correction_hist.Clone(), bin_edges=splitting.var_bins, correction_option=splitting.correction_option, diff --git a/FF_calculation/FF_ttbar.py b/FF_calculation/FF_ttbar.py index 8589d87..a1a4887 100644 --- a/FF_calculation/FF_ttbar.py +++ b/FF_calculation/FF_ttbar.py @@ -53,7 +53,6 @@ def calculation_ttbar_FFs( log = logging.getLogger(logger) - # init histogram dict for FF measurement from MC SR_hists = dict() AR_hists = dict() @@ -67,7 +66,6 @@ def calculation_ttbar_FFs( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for ttbar signal region log.info(f"Filtering events for the signal region. Target process: {process}") region_conf = copy.deepcopy(process_conf["SR_cuts"]) rdf_SR = ff_func.apply_region_filters( @@ -79,7 +77,6 @@ def calculation_ttbar_FFs( logger=logger, ) - # event filter for ttbar application region log.info(f"Filtering events for the application region. Target process: {process}") region_conf = copy.deepcopy(process_conf["AR_cuts"]) rdf_AR = ff_func.apply_region_filters( @@ -91,34 +88,21 @@ def calculation_ttbar_FFs( logger=logger, ) - # get binning of the dependent variable xbinning = array.array("d", splitting.var_bins) nbinsx = len(splitting.var_bins) - 1 # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_SR).Histo1D( - ( - process_conf["var_dependence"], - f"{sample}", - nbinsx, - xbinning, - ), + SR_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SR).Histo1D( + (process_conf["var_dependence"], f"{sample}", nbinsx, xbinning), process_conf["var_dependence"], "weight", - ) - SR_hists[sample] = h.GetValue() - - h = RuntimeVariables.RDataFrameWrapper(rdf_AR).Histo1D( - ( - process_conf["var_dependence"], - f"{sample}", - nbinsx, - xbinning, - ), + ).GetValue() + + AR_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_AR).Histo1D( + (process_conf["var_dependence"], f"{sample}", nbinsx, xbinning), process_conf["var_dependence"], "weight", - ) - AR_hists[sample] = h.GetValue() + ).GetValue() # Start of the FF calculation FF_hist = ff_func.calculate_ttbar_FF( @@ -150,7 +134,7 @@ def calculation_ttbar_FFs( save_data=True, ) - # doing some control plots + # doing control plots for _hist, _region, _data, _samples in [ (SRlike_hists, "SR_like", "data", ff_func.controlplot_samples(config["use_embedding"])), (ARlike_hists, "AR_like", "data", ff_func.controlplot_samples(config["use_embedding"])), @@ -203,10 +187,8 @@ def calculation_FF_data_scaling_factor( """ log = logging.getLogger(logger) - # init histogram dict for FF data correction SRlike_hists = dict() ARlike_hists = dict() - # init histogram dict for QCD SS/OS estimation SRlike_hists_qcd = dict() ARlike_hists_qcd = dict() @@ -218,7 +200,6 @@ def calculation_FF_data_scaling_factor( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for ttbar signal-like region log.info(f"Filtering events for the signal-like region. Target process: {process}") region_conf = copy.deepcopy(process_conf["SRlike_cuts"]) rdf_SRlike = ff_func.apply_region_filters( @@ -230,8 +211,7 @@ def calculation_FF_data_scaling_factor( logger=logger, ) - # QCD estimation from same sign in signal-like region - if "tau_pair_sign" in region_conf: + if "tau_pair_sign" in region_conf: # QCD estimation from same sign in signal-like region region_conf["tau_pair_sign"] = "(q_1*q_2) > 0" # same sign else: raise ValueError(f"No tau pair sign cut defined in the {process} config. Is needed for the QCD estimation.") @@ -246,7 +226,6 @@ def calculation_FF_data_scaling_factor( logger=logger, ) - # event filter for ttbar application-like region log.info(f"Filtering events for the application-like region. Target process: {process}") region_conf = copy.deepcopy(process_conf["ARlike_cuts"]) rdf_ARlike = ff_func.apply_region_filters( @@ -258,8 +237,7 @@ def calculation_FF_data_scaling_factor( logger=logger, ) - # QCD estimation from same sign in application-like region - if "tau_pair_sign" in region_conf: + if "tau_pair_sign" in region_conf: # QCD estimation from same sign in application-like region region_conf["tau_pair_sign"] = "(q_1*q_2) > 0" # same sign else: raise ValueError(f"No tau pair sign cut defined in the {process} config. Is needed for the QCD estimation.") @@ -275,26 +253,22 @@ def calculation_FF_data_scaling_factor( ) # make yield histograms for FF data correction - h = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( + SRlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike).Histo1D( ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - SRlike_hists[sample] = h.GetValue() + ).GetValue() - h = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( + ARlike_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike).Histo1D( ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - ARlike_hists[sample] = h.GetValue() + ).GetValue() # make yield histograms for QCD estimation - h_qcd = RuntimeVariables.RDataFrameWrapper(rdf_SRlike_qcd).Histo1D( + SRlike_hists_qcd[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SRlike_qcd).Histo1D( ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - SRlike_hists_qcd[sample] = h_qcd.GetValue() + ).GetValue() - h_qcd = RuntimeVariables.RDataFrameWrapper(rdf_ARlike_qcd).Histo1D( + ARlike_hists_qcd[sample] = RuntimeVariables.RDataFrameWrapper(rdf_ARlike_qcd).Histo1D( ("#phi(#slash{E}_{T})", f"{sample}", 1, -3.5, 3.5), "metphi", "weight" - ) - ARlike_hists_qcd[sample] = h_qcd.GetValue() + ).GetValue() # calculate QCD estimation SRlike_hists["QCD"] = ff_func.QCD_SS_estimate(hists=SRlike_hists_qcd) @@ -357,7 +331,6 @@ def non_closure_correction( log = logging.getLogger(logger) - # init histogram dict for FF measurement SR_hists = dict() AR_hists = dict() @@ -373,7 +346,6 @@ def non_closure_correction( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for ttbar signal region log.info(f"Filtering events for the signal region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["SR_cuts"]) rdf_SR = ff_func.apply_region_filters( @@ -385,7 +357,6 @@ def non_closure_correction( logger=logger, ) - # event filter for ttbar application region log.info(f"Filtering events for the application region. Target process: {process}") region_conf = copy.deepcopy(config["target_processes"][process]["AR_cuts"]) rdf_AR = ff_func.apply_region_filters( @@ -402,49 +373,33 @@ def non_closure_correction( # additionally evaluate the previous corrections corr_str = "" for corr_evaluator in corr_evaluators: - rdf_AR = corr_evaluator.evaluate_correction( - rdf=rdf_AR, - ) + rdf_AR = corr_evaluator.evaluate_correction(rdf=rdf_AR) corr_str += f" * {corr_evaluator.corr_str}" rdf_AR = rdf_AR.Define( "weight_ff", f"weight * {process}_fake_factor{corr_str}" ) - # get binning of the dependent variable xbinning = array.array("d", splitting.var_bins) nbinsx = len(splitting.var_bins) - 1 - # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_SR).Histo1D( - ( - correction_conf["var_dependence"], - f"{sample}", - nbinsx, - xbinning, - ), + SR_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SR).Histo1D( + (correction_conf["var_dependence"], f"{sample}", nbinsx, xbinning), correction_conf["var_dependence"], "weight", - ) - SR_hists[sample] = h.GetValue() - - h = RuntimeVariables.RDataFrameWrapper(rdf_AR).Histo1D( - ( - correction_conf["var_dependence"], - f"{sample}", - nbinsx, - xbinning, - ), + ).GetValue() + + AR_hists["ttbar_ff"] = RuntimeVariables.RDataFrameWrapper(rdf_AR).Histo1D( + (correction_conf["var_dependence"], f"{sample}", nbinsx, xbinning), correction_conf["var_dependence"], "weight_ff", - ) - AR_hists["ttbar_ff"] = h.GetValue() + ).GetValue() correction_hist = ff_func.calculate_non_closure_correction_ttbar_fromMC( SR=SR_hists, AR=AR_hists ) - nominal_draw_obj, smoothed_graph, correction_dict = ff_func.smooth_function( + nominal_draw_obj, _, correction_dict = ff_func.smooth_function( hist=correction_hist.Clone(), bin_edges=splitting.var_bins, correction_option=splitting.correction_option, diff --git a/FF_calculation/fractions.py b/FF_calculation/fractions.py index b125c08..3f75d59 100644 --- a/FF_calculation/fractions.py +++ b/FF_calculation/fractions.py @@ -50,6 +50,8 @@ def fraction_calculation( AR_hists = dict() SR_hists = dict() + frac_hists = dict() + SR_frac_hists = dict() for sample_path in sample_paths: # getting the name of the process from the sample path @@ -59,7 +61,6 @@ def fraction_calculation( rdf = ROOT.RDataFrame(config["tree"], sample_path) - # event filter for application region log.info("Filtering events for the fraction calculation in the application region.") region_conf = copy.deepcopy(process_conf["AR_cuts"]) rdf_AR = ff_func.apply_region_filters( @@ -71,7 +72,7 @@ def fraction_calculation( logger=logger, ) - # event filter for signal region; this is not needed for the FF calculation, just for control plots + # this is not needed for the FF calculation, just for control plots log.info("Filtering events for the fraction calculation in the signal region.") region_conf = copy.deepcopy(process_conf["SR_cuts"]) rdf_SR = ff_func.apply_region_filters( @@ -83,31 +84,25 @@ def fraction_calculation( logger=logger, ) - # get binning of the dependent variable xbinning = array.array("d", splitting.var_bins) nbinsx = len(splitting.var_bins) - 1 - # making the histograms - h = RuntimeVariables.RDataFrameWrapper(rdf_AR).Histo1D( + AR_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_AR).Histo1D( (process_conf["var_dependence"], f"{sample}", nbinsx, xbinning), process_conf["var_dependence"], "weight", - ) - AR_hists[sample] = h.GetValue() + ).GetValue() - h = RuntimeVariables.RDataFrameWrapper(rdf_SR).Histo1D( + SR_hists[sample] = RuntimeVariables.RDataFrameWrapper(rdf_SR).Histo1D( (process_conf["var_dependence"], f"{sample}", nbinsx, xbinning), process_conf["var_dependence"], "weight", - ) - SR_hists[sample] = h.GetValue() + ).GetValue() # calculate QCD estimation; here directly estimated as difference between mc and data without SS/OS AR_hists["QCD"] = ff_func.QCD_SS_estimate(hists=AR_hists) SR_hists["QCD"] = ff_func.QCD_SS_estimate(hists=SR_hists) - frac_hists = dict() - for p in config[process]["processes"]: frac_hists[p] = ff_func.calc_fraction( hists=AR_hists, @@ -119,8 +114,6 @@ def fraction_calculation( processes=config[process]["processes"], ) - SR_frac_hists = dict() - for p in config[process]["processes"]: SR_frac_hists[p] = ff_func.calc_fraction( hists=SR_hists, @@ -159,7 +152,7 @@ def fraction_calculation( save_data=True, ) - # producing some control plots + # producing control plots for _hist, _region in [ (SR_hists, "SR"), (AR_hists, "AR"), diff --git a/ff_corrections.py b/ff_corrections.py index e970322..7b5fcc8 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -20,7 +20,7 @@ import helper.ff_functions as ff_func import helper.functions as func from ff_calculation import FF_calculation -from helper.ff_evaluators import FakeFactorCorrectionEvaluator, FakeFactorEvaluator, DRSRCorrectionEvaluator +from helper.ff_evaluators import get_fake_factor_evaluator, FakeFactorCorrectionEvaluator, FakeFactorEvaluator, DRSRCorrectionEvaluator from helper.hooks_and_patches import Histo1DPatchedRDataFrame, PassThroughWrapper import CustomLogging as logging_helper @@ -384,7 +384,7 @@ def run_non_closure_correction_for_DRtoSR( assert "ttbar" not in process, "ttbar is not supported for DR to SR corrections" var_dependences = [config["target_processes"][process]["var_dependence"]] + list(config["target_processes"][process]["split_categories"].keys()) - evaluator = FakeFactorEvaluator.loading_from_file( + evaluator = get_fake_factor_evaluator( config=config, process=process, var_dependences=var_dependences, @@ -451,7 +451,7 @@ def run_correction( DR_SR_correction = None if "DR_SR" in corr_config["target_processes"][process]: - evaluator = FakeFactorEvaluator.loading_from_file( + evaluator = get_fake_factor_evaluator( config=config, process=process, var_dependences=var_dependences, @@ -553,7 +553,7 @@ def run_correction( ) if "non_closure" in corr_config["target_processes"][process]: - evaluator = FakeFactorEvaluator.loading_from_file( + evaluator = get_fake_factor_evaluator( config=config, process=process, var_dependences=var_dependences, @@ -718,7 +718,7 @@ def run_correction( for_DRtoSR=True, ) - ########### real fake factor corrections ########### + ########### non closure fake factor corrections ########### corrections = { "QCD": {}, diff --git a/helper/ff_evaluators.py b/helper/ff_evaluators.py index ba5bc78..a2ae1ec 100644 --- a/helper/ff_evaluators.py +++ b/helper/ff_evaluators.py @@ -1,11 +1,21 @@ import logging import os +import ctypes from typing import Any, Dict, List, Tuple, Union +import traceback import correctionlib import correctionlib.schemav2 as cs import ROOT +try: + import onnxruntime as ort + import numpy as np +except ImportError: + ort = None + np = None + +import helper.functions as func import CustomLogging as logging_helper @@ -45,7 +55,7 @@ def loading_from_file( f'at("{process}_fake_factors");' ) - return cls(process, var_dependences, for_DRtoSR) + return cls(process, var_dependences, for_DRtoSR, logger=logger) @classmethod def loading_from_CorrectionSet( @@ -69,13 +79,14 @@ def loading_from_CorrectionSet( f'at("{process}_fake_factors");' ) - return cls(process, var_dependences, for_DRtoSR) + return cls(process, var_dependences, for_DRtoSR, logger=logger) def __init__( self, process: str, var_dependences: List[str], for_DRtoSR: bool, + logger: Union[str, logging.Logger, None] = None, ): """ Initiating a new evaluator for fake factors using correctionlib. @@ -92,6 +103,8 @@ def __init__( self.for_DRtoSR = "for_DRtoSR" if for_DRtoSR else "" self.var_dependences = var_dependences + self.log = logging.getLogger(logger) if logger else logging.getLogger(__name__) + @property def str_var_dependences(self) -> List[str]: return ", ".join([f'(float){var}' for var in self.var_dependences]) @@ -107,11 +120,13 @@ def evaluate_fake_factor(self, rdf: Any) -> Any: Return: root DataFrame object with a new column with the evaluated fake factors """ + self.log.debug(f"Evaluating fake factor for process {self.process} with variables {self.var_dependences} and for_DRtoSR={self.for_DRtoSR}") eval_str = self.str_var_dependences + ', "nominal"' rdf = rdf.Define( f"{self.process}_fake_factor", f'{self.process}_{self.for_DRtoSR}->evaluate({{{eval_str}}})', ) + self.log.debug(f"Defined column '{self.process}_fake_factor' with evaluation string: {self.process}_{self.for_DRtoSR}->evaluate({{{eval_str}}})") return rdf @@ -155,7 +170,7 @@ def loading_from_file( f'->at("{process}_non_closure_{variable}_correction");' ) - return cls(process, corr_variable, for_DRtoSR) + return cls(process, corr_variable, for_DRtoSR, logger=logger) @classmethod def loading_from_CorrectionSet( @@ -181,13 +196,14 @@ def loading_from_CorrectionSet( f'->at("{process}_non_closure_{variable}_correction");' ) - return cls(process, corr_variable, for_DRtoSR) + return cls(process, corr_variable, for_DRtoSR, logger=logger) def __init__( self, process: str, corr_variable: Union[str, Tuple[str, ...]], for_DRtoSR: bool, + logger: Union[str, logging.Logger, None] = None, ): """ Initiating a new evaluator for fake factor corrections using correctionlib. @@ -210,6 +226,8 @@ def __init__( self.variable = corr_variable self.var_dependences = [corr_variable] + self.log = logging.getLogger(logger) if logger else logging.getLogger(__name__) + @property def corr_str(self) -> str: return f"{self.process}_ff_corr_{self.variable}" @@ -228,11 +246,13 @@ def evaluate_correction(self, rdf: Any) -> Any: Return: root DataFrame object with a new column with the evaluated fake factor corrections """ + self.log.debug(f"Evaluating fake factor correction for process {self.process} with variable {self.variable} and for_DRtoSR={self.for_DRtoSR}") eval_str = self.str_var_dependences + ', "nominal"' rdf = rdf.Define( self.corr_str, f"{self.process}_corr_{self.variable}_{self.for_DRtoSR}->evaluate({{{eval_str}}})", ) + self.log.debug(f"Defined column '{self.corr_str}' with evaluation string: {self.process}_corr_{self.variable}_{self.for_DRtoSR}->evaluate({{{eval_str}}})") return rdf @@ -276,7 +296,7 @@ def loading_from_file( f'->at("{process}_DR_SR_correction");' ) - return cls(process, corr_variable) + return cls(process, corr_variable, logger=logger) @classmethod def loading_from_CorrectionSet( @@ -313,12 +333,13 @@ def loading_from_CorrectionSet( f'->at("{process}_DR_SR_correction");' ) - return cls(process, corr_variable) + return cls(process, corr_variable, logger=logger) def __init__( self, process: str, corr_variable: Union[str, Tuple[str, ...]], + logger: Union[str, logging.Logger, None] = None ): """ Initializes the DR to SR correction evaluator. @@ -338,6 +359,8 @@ def __init__( self.variable = corr_variable self.var_dependences = [corr_variable] + self.log = logging.getLogger(logger) if logger else logging.getLogger(__name__) + @property def corr_str(self) -> str: """ @@ -362,12 +385,219 @@ def evaluate_correction(self, rdf: Any) -> Any: Returns: root DataFrame object with a new column with the evaluated DR to SR corrections """ + self.log.debug(f"Evaluating DR to SR correction for process {self.process} with variable {self.variable}") eval_str = ", ".join(self.str_var_dependences) + ', "nominal"' - root_corr_name = f"{self.process}_corr_DR_SR" - rdf = rdf.Define( self.corr_str, f"{root_corr_name}->evaluate({{{eval_str}}})", ) + self.log.debug(f"Defined column '{self.corr_str}' with evaluation string: {root_corr_name}->evaluate({{{eval_str}}})") return rdf + + +def _onnx_ctypes_callback(proc_id: int, features_ptr) -> float: + """ + Pure Python function called natively from C++. + Intercepts raw memory pointer of the RDataFrame array, zero-copy casts it to numpy, and + runs ONNX inference. + """ + try: + proc_info = _PROCESS_ID_MAP[proc_id] + sess = proc_info["sess"] + ort_input_names = proc_info["ort_input_names"] + ort_input_shapes = proc_info["ort_input_shapes"] + n_features = proc_info["n_features"] + + features_array = np.ctypeslib.as_array(features_ptr, shape=(n_features,)) + + if len(ort_input_names) == 1: + expected_shape = ort_input_shapes[0] + + target_shape = [1 if not isinstance(dim, int) else dim for dim in expected_shape] # Potential dynamic batch dim -> 1. + + tensor = features_array.astype(np.float32).reshape(target_shape) + inputs = {ort_input_names[0]: tensor} + else: + inputs = {} + for name, shape, val in zip(ort_input_names, ort_input_shapes, features_array): + target_shape = [1 if not isinstance(dim, int) else dim for dim in shape] + inputs[name] = np.array([val], dtype=np.float32).reshape(target_shape) + + out = sess.run(None, inputs) + + return float(np.asarray(out[0]).item()) + except Exception: + traceback.print_exc() + return -999.0 + + +# Global reference to the ctypes callback to avoid Python's Garbage Collector +_PROCESS_ID_MAP = {} +_C_CALLBACK_TYPE = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_int, ctypes.POINTER(ctypes.c_double)) + +_GLOBAL_C_CALLBACK = _C_CALLBACK_TYPE(_onnx_ctypes_callback) +_GLOBAL_C_CALLBACK_PTR = ctypes.cast(_GLOBAL_C_CALLBACK, ctypes.c_void_p).value + + +class ONNXFakeFactorEvaluator: + """ + Evaluator class to initiate a fake factor setup utilizing ONNX models. + The fake factors are evaluated dynamically inside the RDataFrame via ONNXRuntime. + """ + + @classmethod + def loading_from_config( + cls, + nn_config: Dict[str, Any], + process: str, + logger: str, + ) -> "ONNXFakeFactorEvaluator": + log = logging.getLogger(logger) + if process not in nn_config.get("target_processes", {}): + raise KeyError(f"Process {process} not found in NN config.") + + proc_config = nn_config["target_processes"][process] + model_path = proc_config["model_path"] + model_inputs = proc_config["model_input"] + define_cols = proc_config.get("define_columns", {}) + + log.info(f"Loading ONNX model from {model_path} for process {process}") + return cls(process, model_path, model_inputs, define_cols, logger) + + def __init__( + self, + process: str, + model_path: str, + model_inputs: List[str], + define_columns: Dict[str, str], + logger: Union[str, logging.Logger, None] = None + ): + if ort is None: + raise ImportError("onnxruntime and numpy are required for ONNXFakeFactorEvaluator") + + self.process = process + self.model_path = model_path + self.model_inputs = model_inputs + self.define_columns = define_columns + + self.log = logging.getLogger(logger) if logger else logging.getLogger(__name__) + self._is_initialized = False + + def __getstate__(self): + """ + Called when passing this object to a Multiprocessing Worker. + """ + state = self.__dict__.copy() + state['_is_initialized'] = False + if 'log' in state: + del state['log'] + return state + + def __setstate__(self, state): + """ + Called inside the Multiprocessing Worker to rebuild the object. + """ + self.__dict__.update(state) + self.log = logging.getLogger(self.log_name) + + def _initialize_worker_state(self): + """ + Lazy Initialization: Sets up ONNX and ROOT C++ injection the first + time it is needed in whatever process calls it. + """ + if self._is_initialized: + return + + self.log.debug(f"Initializing ONNX Session and C++ context for {self.process} in PID {os.getpid()}") + + if self.process not in [info.get("process") for info in _PROCESS_ID_MAP.values()]: + self.proc_id = len(_PROCESS_ID_MAP) + sess = ort.InferenceSession(self.model_path) + _PROCESS_ID_MAP[self.proc_id] = { + "process": self.process, + "sess": sess, + "ort_input_names": [inp.name for inp in sess.get_inputs()], + "ort_input_shapes": [inp.shape for inp in sess.get_inputs()], + "n_features": len(self.model_inputs) + } + else: + self.proc_id = next(k for k, v in _PROCESS_ID_MAP.items() if v["process"] == self.process) + + if not hasattr(ROOT, self.cxx_func_name): # Inject C++ Code into ROOT's Cling compiler just once + cpp_code = f""" + #ifndef ONNX_EVAL_DEFINED_{self.process} + #define ONNX_EVAL_DEFINED_{self.process} + double {self.cxx_func_name}(const ROOT::VecOps::RVec& features) {{ + typedef double (*CallbackType)(int, const double*); + CallbackType cb = (CallbackType){_GLOBAL_C_CALLBACK_PTR}ULL; + return cb({self.proc_id}, features.data()); + }} + #endif + """ + self.log.debug(f"Registering C++ execution wrapper for {self.process}") + ROOT.gInterpreter.Declare(cpp_code) + + self._is_initialized = True + + def evaluate_fake_factor(self, rdf: Any) -> Any: + """ + Evaluating the fake factors using the loaded ONNX model. + Missing columns are defined on the fly before inference. + """ + self._initialize_worker_state() + + existing_cols = [str(_column) for _column in rdf.GetColumnNames()] + + for column, expression in self.define_columns.items(): + if column not in existing_cols: + self.log.debug(f"Defining column '{column}' as '{expression}'") + rdf = rdf.Define(column, expression) + + rvec_col = f"{self.process}_onnx_features" + inputs_csv = ", ".join([f"(double){inp}" for inp in self.model_inputs]) + rvec_expr = f"ROOT::VecOps::RVec{{{inputs_csv}}}" + self.log.debug(f"Packaging {len(self.model_inputs)} inputs into RVec column '{rvec_col}'") + rdf = rdf.Define(rvec_col, rvec_expr) + + self.log.info(f"Applying ONNX fake factor evaluation for {self.process}") + rdf = rdf.Define(f"{self.process}_fake_factor", f"{self.cxx_func_name}({rvec_col})") + + return rdf + + +def get_fake_factor_evaluator( + config: Dict[str, Any], + process: str, + var_dependences: List[str], + for_DRtoSR: bool, + logger: str, +) -> Union[FakeFactorEvaluator, ONNXFakeFactorEvaluator]: + """ + Factory function to decide whether to load the traditional correctionlib JSON + evaluator or the new ONNX YAML-based NN evaluator. + """ + + if process in config.get("target_processes", {}) and "model_path" in config["target_processes"][process]: + return ONNXFakeFactorEvaluator.loading_from_config(config, process, logger) + + directories = ["workdir", config["workdir_name"], config["era"]] + if not for_DRtoSR: + yaml_path = os.path.join(*directories, f"fake_factors_models_{config['channel']}.yaml") + else: + yaml_path = os.path.join(*directories, f"fake_factors_models_DR_SR_{config['channel']}.yaml") + + # with open(yaml_path, "r") as f: + # nn_config = func.configured_yaml.load(f) + + # return ONNXFakeFactorEvaluator.loading_from_config(nn_config, process, logger) + + return FakeFactorEvaluator.loading_from_file(config, process, var_dependences, for_DRtoSR, logger) + + # if os.path.exists(yaml_path): + # with open(yaml_path, "r") as f: + # nn_config = func.configured_yaml.load(f) + # if process in nn_config.get("target_processes", {}) and "model_path" in nn_config["target_processes"][process]: + # return ONNXFakeFactorEvaluator.loading_from_config(nn_config, process, logger) + + # return FakeFactorEvaluator.loading_from_file(config, process, var_dependences, for_DRtoSR, logger) diff --git a/helper/ff_functions.py b/helper/ff_functions.py index b4ac06f..e301e89 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -1138,7 +1138,7 @@ def fit_function( def calculate_non_closure_correction( - SRlike: Dict[str, Any], ARlike: Dict[str, Any] + SRlike: Dict[str, Any], ARlike: Dict[str, Any], skip_frac: bool = False, ) -> Tuple[Any, Any]: """ Function which calculates non closure corrections based on the histograms from the determination regions. @@ -1146,12 +1146,13 @@ def calculate_non_closure_correction( Args: SRlike: Dictionary with histograms from the signal-like determination region for all relevant processes ARlike: Dictionary with histograms from the application-like determination region for all relevant processes + skip:frac: Skip the fraction scaling if FF * AR-like matches SR-like by FF construction. Set frac to 1.0 Return: 1. Ratio histogram of data (MC subtracted) in a signal-like region and data (scaled to MC subtracted) with applied fake factors in an application-like region, 2. Process fraction in the application-like region """ - frac = ARlike["data_subtracted"].GetMaximum() / ARlike["data"].GetMaximum() + frac = 1.0 if skip_frac else (ARlike["data_subtracted"].GetMaximum() / ARlike["data"].GetMaximum()) predicted = ARlike["data_ff"].Clone() predicted.Scale(frac) From 80418e5437ff4c1bdef04312d15c9c173fbf172d Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Wed, 4 Mar 2026 09:39:10 +0100 Subject: [PATCH 02/20] fixing missing attribute --- helper/ff_evaluators.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/helper/ff_evaluators.py b/helper/ff_evaluators.py index a2ae1ec..1247124 100644 --- a/helper/ff_evaluators.py +++ b/helper/ff_evaluators.py @@ -480,6 +480,7 @@ def __init__( self.model_path = model_path self.model_inputs = model_inputs self.define_columns = define_columns + self.cxx_func_name = f"onnx_eval_{self.process}" self.log = logging.getLogger(logger) if logger else logging.getLogger(__name__) self._is_initialized = False @@ -490,8 +491,6 @@ def __getstate__(self): """ state = self.__dict__.copy() state['_is_initialized'] = False - if 'log' in state: - del state['log'] return state def __setstate__(self, state): @@ -499,7 +498,6 @@ def __setstate__(self, state): Called inside the Multiprocessing Worker to rebuild the object. """ self.__dict__.update(state) - self.log = logging.getLogger(self.log_name) def _initialize_worker_state(self): """ From d55762824e9c668fd2e73c2427922e711c2d5d95 Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:52:52 +0100 Subject: [PATCH 03/20] enabling optionality of classic/model FF evaluators depending on --- ff_corrections.py | 4 ++-- helper/ff_evaluators.py | 23 +++++++++-------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/ff_corrections.py b/ff_corrections.py index 7b5fcc8..3bd6287 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -389,7 +389,7 @@ def run_non_closure_correction_for_DRtoSR( process=process, var_dependences=var_dependences, for_DRtoSR=True, - logger=f"ff_corrections.{process}", + logger=f"ff_corrections.{process}.DR_SR", ) corrections.update( @@ -402,7 +402,7 @@ def run_non_closure_correction_for_DRtoSR( output_path=output_path, for_DRtoSR=True, DR_SR_evaluator=None, - logger=f"ff_corrections.{process}", + logger=f"ff_corrections.{process}.DR_SR", ) ) else: diff --git a/helper/ff_evaluators.py b/helper/ff_evaluators.py index 1247124..1a75ddb 100644 --- a/helper/ff_evaluators.py +++ b/helper/ff_evaluators.py @@ -576,8 +576,7 @@ def get_fake_factor_evaluator( evaluator or the new ONNX YAML-based NN evaluator. """ - if process in config.get("target_processes", {}) and "model_path" in config["target_processes"][process]: - return ONNXFakeFactorEvaluator.loading_from_config(config, process, logger) + log = logging.getLogger(logger) directories = ["workdir", config["workdir_name"], config["era"]] if not for_DRtoSR: @@ -585,17 +584,13 @@ def get_fake_factor_evaluator( else: yaml_path = os.path.join(*directories, f"fake_factors_models_DR_SR_{config['channel']}.yaml") - # with open(yaml_path, "r") as f: - # nn_config = func.configured_yaml.load(f) - - # return ONNXFakeFactorEvaluator.loading_from_config(nn_config, process, logger) + if os.path.exists(yaml_path): + log.info(f"Found FF model config at {yaml_path}. Attempting to load ONNX-based evaluator for process {process}.") + with open(yaml_path, "r") as f: + nn_config = func.configured_yaml.load(f) + log.debug(f"NN Config for process {process}: {nn_config.get('target_processes', {}).get(process, {})}") + if process in nn_config.get("target_processes", {}) and "model_path" in nn_config["target_processes"][process]: + return ONNXFakeFactorEvaluator.loading_from_config(nn_config, process, logger) + log.info(f"Using classic correctionlib-based FakeFactorEvaluator for process {process}") return FakeFactorEvaluator.loading_from_file(config, process, var_dependences, for_DRtoSR, logger) - - # if os.path.exists(yaml_path): - # with open(yaml_path, "r") as f: - # nn_config = func.configured_yaml.load(f) - # if process in nn_config.get("target_processes", {}) and "model_path" in nn_config["target_processes"][process]: - # return ONNXFakeFactorEvaluator.loading_from_config(nn_config, process, logger) - - # return FakeFactorEvaluator.loading_from_file(config, process, var_dependences, for_DRtoSR, logger) From bb0648f3db80bef99eedba84d7cb0c2939e27c50 Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Thu, 5 Mar 2026 18:10:07 +0100 Subject: [PATCH 04/20] adjusted correction pruning --- configs/smhtt_ul/2018/common_settings.yaml | 4 + ff_corrections.py | 10 +- helper/ff_functions.py | 192 ++++++++++++++++++++- helper/functions.py | 7 + 4 files changed, 207 insertions(+), 6 deletions(-) diff --git a/configs/smhtt_ul/2018/common_settings.yaml b/configs/smhtt_ul/2018/common_settings.yaml index e292125..43b859c 100644 --- a/configs/smhtt_ul/2018/common_settings.yaml +++ b/configs/smhtt_ul/2018/common_settings.yaml @@ -24,3 +24,7 @@ tau_vs_jet_wgt_wps: use_embedding: true use_center_of_mass_bins: true + +skip_corrections_compatible_to_one: true +skip_uncertainties_of_corrections_compatible_to_one: true +skip_corrections_p_value: 0.05 diff --git a/ff_corrections.py b/ff_corrections.py index 3bd6287..bf7acf7 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -617,11 +617,15 @@ def run_correction( if config.get("use_center_of_mass_bins", True): func.RuntimeVariables.RDataFrameWrapper = Histo1DPatchedRDataFrame + func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE = corr_config.get("skip_corrections_compatible_to_one", False) + func.RuntimeVariables.SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE = corr_config.get("skip_uncertainties_of_corrections_compatible_to_one", False) + func.RuntimeVariables.SKIP_CORRECTIONS_P_VALUE = corr_config.get("skip_corrections_p_value", 0.05) + # setting default systematic variations if not present in the config if "correction_variations" not in corr_config: corr_config["correction_variations"] = ("Stat_1Sigma", "Syst_MCShift", "Syst_BandAsym") - ########### needed precalculations for DR to SR corrections ########### + # ########## needed precalculations for DR to SR corrections ########## # # initializing the fake factor calculation for DR to SR corrections ff_for_DRtoSR_file = os.path.join( @@ -718,7 +722,7 @@ def run_correction( for_DRtoSR=True, ) - ########### non closure fake factor corrections ########### + # ########## non closure fake factor corrections ########## # corrections = { "QCD": {}, @@ -747,6 +751,8 @@ def run_correction( for_DRtoSR=False, ) + ff_func.print_statistical_compatibility_summary(DR_SR_corrections, corrections, logger="ff_corrections") + with open(os.path.join(save_path, "done"), "w") as done_file: done_file.write("") diff --git a/helper/ff_functions.py b/helper/ff_functions.py index e301e89..c9c78d8 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -5,6 +5,7 @@ import array import functools import inspect +import io import itertools as itt import logging import os @@ -16,12 +17,14 @@ import numpy as np import ROOT +import scipy.stats +from rich.console import Console +from rich.table import Table from wurlitzer import STDOUT, pipes import configs.general_definitions as gd import helper.fitting_helper as fitting_helper import helper.functions as func -import CustomLogging as logging_helper import helper.weights as weights from configs.general_definitions import random_seed from helper.hooks_and_patches import (_EXTRA_PARAM_COUNTS, _EXTRA_PARAM_FLAG, @@ -1294,7 +1297,7 @@ def sparsify(edges: np.ndarray, values: np.ndarray, threshold: float = 0.01) -> step_size = v_range * threshold if step_size == 0: # all values are identical - return np.array([edges[0], edges[-1]]), np.array([values[0], values[-1]]) + return np.array([edges[0], edges[-1]]), np.array([values[0]]) total_variation = cumulative_activity[-1] @@ -1317,6 +1320,79 @@ def sparsify(edges: np.ndarray, values: np.ndarray, threshold: float = 0.01) -> return new_edges, new_values +def fit_to_constant(hist: ROOT.TH1) -> Tuple[float, float]: + """ + Fits a histogram to a constant function and returns the fit result and its uncertainty. + + Args: + hist: ROOT histogram to be fitted + Return: + Tuple containing the fit result (constant value) and its uncertainty + """ + fit_res = hist.Fit("pol0", "SQN0") + if int(fit_res) == 0: + return fit_res.Get().Parameter(0), fit_res.Get().ParError(0) + else: + return 1.0, 0.0 + + +def statistical_check( + hist: Any, + corr_dict: Dict[str, np.ndarray], + mc_shifted_hist: Union[Dict[str, Any], None] = None +) -> Dict[str, np.ndarray]: + """ + Performs chi2 test checking compatibility of the correction with 1.0 within data uncertainties. + If compatible and RuntimeVariables.AUTO_SKIP_COMPATIBLE is True, correction is set to 1.0. + Then additionally stat. and bandwidth variations are set to 1.0. For MCShift variations, + if histograms are provided, they are fitted to a constant if RuntimeVariables.AUTO_SKIP_UNCERTAINTIES is False, + otherwise they are set to 1.0 as well. + + Args: + hist: Histogram of the correction to be checked + corr_dict: Dictionary with the correction values and variations to be updated if the correction is compatible with 1.0 + mc_shifted_hist: Dictionary with histograms for the MC shifted variations + + Return: + Updated corr_dict with additional keys: + "p_value": p-value of the chi2 test, + "_auto_skipped": boolean if correction was set to 1.0 + """ + + _, _, y_val, _, _, err_dn, err_up = build_TGraph(hist, return_components=True, add_xerrors_in_graph=True) + + y, err = np.array(y_val), (np.array(err_dn) + np.array(err_up)).clip(min=1e-6) / 2.0 + chi2, ndf = np.sum(((y - 1.0) / err) ** 2), len(y) + p_value = scipy.stats.chi2.sf(chi2, ndf) + corr_dict["p_value"] = p_value + + if (p_value > func.RuntimeVariables.SKIP_CORRECTIONS_P_VALUE) and func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE: + corr_dict["_auto_skipped"] = True + corr_dict["nominal"] = np.ones_like(corr_dict["nominal"]) + + for key in list(corr_dict.keys()): + if key.startswith("Stat") or key.startswith("SystBand"): # no stat. unct. on constant, no bandwidth + corr_dict[key] = np.ones_like(corr_dict[key]) + + if func.RuntimeVariables.SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE: + for key in list(corr_dict.keys()): + if key.startswith("SystMCShift"): + corr_dict[key] = np.ones_like(corr_dict[key]) + else: + if mc_shifted_hist is None: + corr_dict["SystMCShiftUp"] = np.ones_like(corr_dict["nominal"]) + corr_dict["SystMCShiftDown"] = np.ones_like(corr_dict["nominal"]) + else: + mc_up_val, _ = fit_to_constant(mc_shifted_hist["MCShiftUp"]) + mc_dn_val, _ = fit_to_constant(mc_shifted_hist["MCShiftDown"]) + corr_dict["SystMCShiftUp"] = np.full_like(corr_dict["nominal"], mc_up_val) + corr_dict["SystMCShiftDown"] = np.full_like(corr_dict["nominal"], mc_dn_val) + else: + corr_dict["_auto_skipped"] = False + + return corr_dict + + def smooth_function( hist: Any, bin_edges: List[float], @@ -1398,15 +1474,17 @@ def smooth_function( corr_dict["SystBandAsymUp"] = _high["nominal"] corr_dict["SystBandAsymDown"] = _low["nominal"] + corr_dict = statistical_check(hist, corr_dict, mc_shifted_hist) + # individual downsampling for correctionlib storage, not used for plotting corr_dict["downsampled"] = {} for key in list(corr_dict): - if key in {"edges", "downsampled"}: + if key in {"edges", "downsampled", "p_value", "_auto_skipped"}: continue corr_dict["downsampled"][key] = { k: v for k, v in zip( ["edges", "content"], - sparsify(corr_dict["edges"], corr_dict[key]) + sparsify(corr_dict["edges"], corr_dict[key], threshold=sparsify_threshold), ) } @@ -1572,3 +1650,109 @@ def _append(a, b=None): len(smooth_x), smooth_x, smooth_y, 0, 0, smooth_y_down, smooth_y_up ) return nominal_graph, smooth_graph, corr_dict + + +def print_statistical_compatibility_summary(DR_SR_corrections: dict, non_closure_corrections: dict, logger: str) -> None: + """ + Generates an ASCII table summarizing which corrections were applied vs. set to 1.0 + due to compatibility with 1.0. + + Args: + DR_SR_corrections: Dictionary with DR/SR corrections + non_closure_corrections: Dictionary with non-closure corrections + """ + + log = logging.getLogger(logger) + + if not func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE: + return + + def flatten_categories(node, current_path=""): + if isinstance(node, dict) and "nominal" in node: + return {current_path if current_path else "Inclusive": node} + flattened = {} + if isinstance(node, dict): + for k, v in node.items(): + formatted_k = str(k).replace("#", " ") # i.e. "njets#==0" + new_path = f"{current_path} | {formatted_k}" if current_path else formatted_k + flattened.update(flatten_categories(v, new_path)) + return flattened + + merged = {} + for _dict in [DR_SR_corrections, non_closure_corrections]: + for process, correction in _dict.items(): + if process not in merged: + merged[process] = {} + for correction_name, correction_categories in correction.items(): + flat_correction_categories = flatten_categories(correction_categories) + if correction_name not in merged[process]: + merged[process][correction_name] = {} + merged[process][correction_name].update(flat_correction_categories) + + string_io = io.StringIO() # headless Console writing to a string buffer without ANSI + console = Console(file=string_io, force_terminal=False, color_system=None, width=300) + + log.info("Summary of corrections applied vs. set to 1.0 due to compatibility with 1.0:\n") + log.info(f"p-value threshold for auto-skipping: {func.RuntimeVariables.SKIP_CORRECTIONS_P_VALUE:.3f}") + log.info(f"Auto-skipping enabled: {func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE}") + log.info(f"MCshift variations also set to 1.0 if compatible: {func.RuntimeVariables.SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE}\n") + + for process, correction in merged.items(): + if not correction: + continue + + all_categories = set() + for correction_categories in correction.values(): + all_categories.update(correction_categories.keys()) + all_categories = sorted(list(all_categories), key=lambda x: ("", x) if x == "Inclusive" else (x, x)) + + table = Table(title=f"Process: {process}", show_header=True) + table.add_column("Correction", no_wrap=True) + + for category in all_categories: + table.add_column(f"Status\n{category}", justify="center") + + table.add_column("", justify="center", width=2) + + for category in all_categories: + table.add_column(f"p-value\n{category}", justify="center") + + for correction_name, correction_categories in correction.items(): + row = [correction_name.replace("non_closure_", "(nc) ")] + + for category in all_categories: + node = correction_categories.get(category) + if node is None: + row.append("—") + else: + if node.get("_auto_skipped", False): + row.append("1.0") + elif "p_value" not in node: + if np.all(np.array(node["nominal"]) == 1.0): + row.append("Skip") + else: + row.append("Binwise") + else: + row.append("Applied") + + row.append("") + + for category in all_categories: + node = correction_categories.get(category) + if node is None: + row.append("—") + else: + if "p_value" in node: + pval = node['p_value'] + row.append(f"{pval:.3f}") + else: + row.append("—") + + table.add_row(*row) + + console.print(table) + console.print() + + for line in string_io.getvalue().splitlines(): + if line.strip(): + log.info(line) diff --git a/helper/functions.py b/helper/functions.py index 2825806..b4f04ea 100644 --- a/helper/functions.py +++ b/helper/functions.py @@ -171,11 +171,18 @@ class RuntimeVariables(object): Attributes: USE_MULTIPROCESSING (bool): Flag to enable or disable multiprocessing globally + USE_CACHED_INTERMEDIATE_STEPS (bool): Flag to enable or disable caching of intermediate steps globally + RDataFrameWrapper (Any): A wrapper class for ROOT RDataFrame, can be set at runtime for different implementations histogram x-value extraction """ USE_MULTIPROCESSING = True USE_CACHED_INTERMEDIATE_STEPS = False + RDataFrameWrapper = None + SKIP_CORRECTIONS_COMPATIBLE_TO_ONE = True + SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE = False + SKIP_CORRECTIONS_P_VALUE = 0.05 + def __new__(cls) -> "RuntimeVariables": if not hasattr(cls, "instance"): cls.instance = super(RuntimeVariables, cls).__new__(cls) From 9f757259e04ada9eaa6f191406400141071e1e6d Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Fri, 6 Mar 2026 19:15:23 +0100 Subject: [PATCH 05/20] testing other p_value estimates --- configs/smhtt_ul/2018/common_settings.yaml | 2 +- helper/ff_functions.py | 26 +++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/configs/smhtt_ul/2018/common_settings.yaml b/configs/smhtt_ul/2018/common_settings.yaml index 43b859c..d89218a 100644 --- a/configs/smhtt_ul/2018/common_settings.yaml +++ b/configs/smhtt_ul/2018/common_settings.yaml @@ -26,5 +26,5 @@ use_embedding: true use_center_of_mass_bins: true skip_corrections_compatible_to_one: true -skip_uncertainties_of_corrections_compatible_to_one: true +skip_uncertainties_of_corrections_compatible_to_one: false skip_corrections_p_value: 0.05 diff --git a/helper/ff_functions.py b/helper/ff_functions.py index c9c78d8..4112ca8 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -1360,13 +1360,29 @@ def statistical_check( """ _, _, y_val, _, _, err_dn, err_up = build_TGraph(hist, return_components=True, add_xerrors_in_graph=True) - y, err = np.array(y_val), (np.array(err_dn) + np.array(err_up)).clip(min=1e-6) / 2.0 - chi2, ndf = np.sum(((y - 1.0) / err) ** 2), len(y) - p_value = scipy.stats.chi2.sf(chi2, ndf) - corr_dict["p_value"] = p_value - if (p_value > func.RuntimeVariables.SKIP_CORRECTIONS_P_VALUE) and func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE: + chi2_global, ndf = np.sum(((y - 1.0) / err) ** 2), len(y) + p_value_global = scipy.stats.chi2.sf(chi2_global, ndf) + + chi2_bins = ((y - 1.0) / err) ** 2 + p_values_bins = scipy.stats.chi2.sf(chi2_bins, 1) + p_values_bins_min = p_values_bins.min() + p_value_sidak = 1 - (1 - p_values_bins_min) ** len(p_values_bins) + + p_value_shape_min = 1.0 + pulls = (y - 1.0) / err + for window in range(1, ndf + 1): + for i in range(ndf - window + 1): + z_window = np.abs(np.sum(pulls[i: i + window]) / np.sqrt(window)) + p_window = scipy.stats.norm.sf(z_window) * 2 + if p_window < p_value_shape_min: + p_value_shape_min = p_window + p_shape = 1 - (1 - p_value_shape_min) ** len(y) + + corr_dict["p_value"] = min(p_value_global, p_value_sidak, p_shape) + + if (corr_dict["p_value"] > func.RuntimeVariables.SKIP_CORRECTIONS_P_VALUE) and func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE: corr_dict["_auto_skipped"] = True corr_dict["nominal"] = np.ones_like(corr_dict["nominal"]) From c10336899b303f27e564cab54828bc336eb5a820 Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Tue, 10 Mar 2026 00:22:47 +0100 Subject: [PATCH 06/20] adjustmetns to optional DR_SR derivations --- .gitignore | 1 + FF_calculation/FF_QCD.py | 6 +- FF_calculation/FF_Wjets.py | 86 ++++---- FF_calculation/FF_ttbar.py | 4 +- FF_calculation/fractions.py | 2 +- configs/smhtt_ul/2018/common_settings.yaml | 10 +- configs/smhtt_ul/2018/corrections_mt.yaml | 229 ++++++++++----------- configs/smhtt_ul/2018/fake_factors_mt.yaml | 56 ++--- ff_corrections.py | 35 +++- helper/correctionlib_json.py | 14 +- helper/ff_functions.py | 74 ++++++- helper/functions.py | 40 +++- helper/hooks_and_patches.py | 4 +- 13 files changed, 342 insertions(+), 219 deletions(-) diff --git a/.gitignore b/.gitignore index 15df29e..798d014 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ configs.*/ *.pdf *.png *.root +*.feather # C extensions *.so diff --git a/FF_calculation/FF_QCD.py b/FF_calculation/FF_QCD.py index 44560cf..28caedc 100644 --- a/FF_calculation/FF_QCD.py +++ b/FF_calculation/FF_QCD.py @@ -170,7 +170,7 @@ def calculation_QCD_FFs(args: Tuple[Any, ...]) -> Dict[str, Union[str, Dict[str, process=process, region=_region, data="data", - samples=ff_func.controlplot_samples(config["use_embedding"], add_qcd=False), + samples=ff_func.controlplot_samples(sample_paths, add_qcd=False), category=splitting.split or {"incl": ""}, output_path=output_path, logger=logger, @@ -385,7 +385,7 @@ def non_closure_correction(args: Tuple[Any, ...]) -> Dict[str, np.ndarray]: process=process, region=f"non_closure_{closure_variable}{add_str}_SRlike_hist", data="data", - samples=ff_func.controlplot_samples(config["use_embedding"], add_qcd=False), + samples=ff_func.controlplot_samples(sample_paths, add_qcd=False), category=splitting.split or {"incl": ""}, output_path=output_path, logger=logger, @@ -594,7 +594,7 @@ def DR_SR_correction(args: Tuple[Any, ...]) -> Dict[str, np.ndarray]: process=process, region="DR_SR" + "_SRlike_hist", data="data", - samples=ff_func.controlplot_samples(config["use_embedding"], add_qcd=False), + samples=ff_func.controlplot_samples(sample_paths, add_qcd=False), category=splitting.split or {"incl": ""}, output_path=output_path, logger=logger, diff --git a/FF_calculation/FF_Wjets.py b/FF_calculation/FF_Wjets.py index 91fa659..888686e 100644 --- a/FF_calculation/FF_Wjets.py +++ b/FF_calculation/FF_Wjets.py @@ -159,44 +159,56 @@ def calculation_Wjets_FFs(args: Tuple[Any, ...]) -> Dict[str, Union[Dict[str, st SRlike_hists["QCD"] = ff_func.QCD_SS_estimate(hists=SRlike_hists_qcd) ARlike_hists["QCD"] = ff_func.QCD_SS_estimate(hists=ARlike_hists_qcd) - # calculate Wjets enriched data by subtraction all there backgrould sample - SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() - ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() - SRlike_hists["data_subtracted_up"] = SRlike_hists["data"].Clone() - ARlike_hists["data_subtracted_up"] = ARlike_hists["data"].Clone() - SRlike_hists["data_subtracted_down"] = SRlike_hists["data"].Clone() - ARlike_hists["data_subtracted_down"] = ARlike_hists["data"].Clone() + use_data = process_conf.get("compute_different_set_of_fake_factors_using_data", True) + + if use_data: + # calculate Wjets enriched data by subtraction all there backgrould sample + SRlike_hists["data_subtracted"] = SRlike_hists["data"].Clone() + ARlike_hists["data_subtracted"] = ARlike_hists["data"].Clone() + SRlike_hists["data_subtracted_up"] = SRlike_hists["data"].Clone() + ARlike_hists["data_subtracted_up"] = ARlike_hists["data"].Clone() + SRlike_hists["data_subtracted_down"] = SRlike_hists["data"].Clone() + ARlike_hists["data_subtracted_down"] = ARlike_hists["data"].Clone() + + for hist in SRlike_hists: + if hist not in [ + "data", + "data_subtracted", + "data_subtracted_up", + "data_subtracted_down", + "Wjets", + ]: + SRlike_hists["data_subtracted"].Add(SRlike_hists[hist].Clone(), -1) + SRlike_hists["data_subtracted_up"].Add(SRlike_hists[hist].Clone().AddError(1), -1) + SRlike_hists["data_subtracted_down"].Add(SRlike_hists[hist].Clone().AddError(-1), -1) + for hist in ARlike_hists: + if hist not in [ + "data", + "data_subtracted", + "data_subtracted_up", + "data_subtracted_down", + "Wjets", + ]: + ARlike_hists["data_subtracted"].Add(ARlike_hists[hist].Clone(), -1) + ARlike_hists["data_subtracted_up"].Add(ARlike_hists[hist].Clone().AddError(1), -1) + ARlike_hists["data_subtracted_down"].Add(ARlike_hists[hist].Clone().AddError(-1), -1) + + # Start of the FF calculation + FF_hist, FF_hist_up, FF_hist_down = ff_func.calculate_Wjets_FF( + SRlike=SRlike_hists, ARlike=ARlike_hists + ) + ff_hists_to_fit = [FF_hist.Clone(), FF_hist_up, FF_hist_down] + else: + SRlike_hists["data_subtracted"] = SRlike_hists["Wjets"].Clone() + ARlike_hists["data_subtracted"] = ARlike_hists["Wjets"].Clone() - for hist in SRlike_hists: - if hist not in [ - "data", - "data_subtracted", - "data_subtracted_up", - "data_subtracted_down", - "Wjets", - ]: - SRlike_hists["data_subtracted"].Add(SRlike_hists[hist].Clone(), -1) - SRlike_hists["data_subtracted_up"].Add(SRlike_hists[hist].Clone().AddError(1), -1) - SRlike_hists["data_subtracted_down"].Add(SRlike_hists[hist].Clone().AddError(-1), -1) - for hist in ARlike_hists: - if hist not in [ - "data", - "data_subtracted", - "data_subtracted_up", - "data_subtracted_down", - "Wjets", - ]: - ARlike_hists["data_subtracted"].Add(ARlike_hists[hist].Clone(), -1) - ARlike_hists["data_subtracted_up"].Add(ARlike_hists[hist].Clone().AddError(1), -1) - ARlike_hists["data_subtracted_down"].Add(ARlike_hists[hist].Clone().AddError(-1), -1) + FF_hist = SRlike_hists["Wjets"].Clone() + FF_hist.Divide(ARlike_hists["Wjets"]) + ff_hists_to_fit = FF_hist.Clone() - # Start of the FF calculation - FF_hist, FF_hist_up, FF_hist_down = ff_func.calculate_Wjets_FF( - SRlike=SRlike_hists, ARlike=ARlike_hists - ) # performing the fit and calculating the uncertainties nominal_draw_obj, fit_graphs, corrlib_exp, used_fit = ff_func.fit_function( - ff_hists=[FF_hist.Clone(), FF_hist_up, FF_hist_down], + ff_hists=ff_hists_to_fit, bin_edges=splitting.var_bins, logger=logger, fit_option=splitting.fit_option, @@ -219,8 +231,8 @@ def calculation_Wjets_FFs(args: Tuple[Any, ...]) -> Dict[str, Union[Dict[str, st # producing some control plots for _hist, _region, _data, _samples in [ - (SRlike_hists, "SR_like", "data", ff_func.controlplot_samples(config["use_embedding"])), - (ARlike_hists, "AR_like", "data", ff_func.controlplot_samples(config["use_embedding"])), + (SRlike_hists, "SR_like", "data", ff_func.controlplot_samples(sample_paths)), + (ARlike_hists, "AR_like", "data", ff_func.controlplot_samples(sample_paths)), (SRlike_hists, "SR_like", "data_subtracted", ["Wjets"]), (ARlike_hists, "AR_like", "data_subtracted", ["Wjets"]), ]: @@ -500,7 +512,7 @@ def non_closure_correction(args: Tuple[Any, ...]) -> Dict[str, np.ndarray]: process=process, region=f"non_closure_{closure_variable}{add_str}_SRlike", data="data", - samples=ff_func.controlplot_samples(config["use_embedding"]), + samples=ff_func.controlplot_samples(sample_paths), category=splitting.split or {"incl": ""}, output_path=output_path, logger=logger, diff --git a/FF_calculation/FF_ttbar.py b/FF_calculation/FF_ttbar.py index a1a4887..637aea5 100644 --- a/FF_calculation/FF_ttbar.py +++ b/FF_calculation/FF_ttbar.py @@ -136,8 +136,8 @@ def calculation_ttbar_FFs( # doing control plots for _hist, _region, _data, _samples in [ - (SRlike_hists, "SR_like", "data", ff_func.controlplot_samples(config["use_embedding"])), - (ARlike_hists, "AR_like", "data", ff_func.controlplot_samples(config["use_embedding"])), + (SRlike_hists, "SR_like", "data", ff_func.controlplot_samples(sample_paths)), + (ARlike_hists, "AR_like", "data", ff_func.controlplot_samples(sample_paths)), (SRlike_hists, "SR_like", "data_subtracted", ["ttbar_J"]), (ARlike_hists, "AR_like", "data_subtracted", ["ttbar_J"]), ]: diff --git a/FF_calculation/fractions.py b/FF_calculation/fractions.py index 3f75d59..c5b22cf 100644 --- a/FF_calculation/fractions.py +++ b/FF_calculation/fractions.py @@ -166,7 +166,7 @@ def fraction_calculation( process=process, region=_region, data="data", - samples=ff_func.controlplot_samples(config["use_embedding"]), + samples=ff_func.controlplot_samples(sample_paths), category=splitting.split, output_path=output_path, logger=logger, diff --git a/configs/smhtt_ul/2018/common_settings.yaml b/configs/smhtt_ul/2018/common_settings.yaml index d89218a..65d8f76 100644 --- a/configs/smhtt_ul/2018/common_settings.yaml +++ b/configs/smhtt_ul/2018/common_settings.yaml @@ -1,9 +1,9 @@ -ntuple_path: "root://cmsdcache-kit-disk.gridka.de//store/user/amonsch/CROWN/ntuples/ff_and_cr_production_2018UL_mt__2025-11-03_wo_syst_v1/CROWNRun" -output_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_production_2018UL_mt__2025-08-21_wo_syst_v2_2025-11-03 +ntuple_path: "root://cmsdcache-kit-disk.gridka.de//store/user/amonsch/CROWN/ntuples/ff_and_cr_production_2018UL_mt__2025-11-22_w_syst_v1/CROWNRun" +output_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_production_2018UL_mt__2025-08-21_wo_syst_v2_2025-11-03__with_events_and_rest friends: ["fastmtt_v1"] -file_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_production_2018UL_mt__2025-08-21_wo_syst_v2_2025-11-03 +file_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_production_2018UL_mt__2025-08-21_wo_syst_v2_2025-11-03__with_events_and_rest -workdir_name: extended_corrections_set_with_applied_es_corrections +workdir_name: test_v1 era: '2018' tree: ntuple @@ -25,6 +25,6 @@ tau_vs_jet_wgt_wps: use_embedding: true use_center_of_mass_bins: true -skip_corrections_compatible_to_one: true +skip_corrections_compatible_to_one: false skip_uncertainties_of_corrections_compatible_to_one: false skip_corrections_p_value: 0.05 diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml b/configs/smhtt_ul/2018/corrections_mt.yaml index 01d85ca..8a1f88c 100644 --- a/configs/smhtt_ul/2018/corrections_mt.yaml +++ b/configs/smhtt_ul/2018/corrections_mt.yaml @@ -135,7 +135,7 @@ templates: variable_config: met: min: 0.0 - max: 175.0 + max: 150.0 rounding: 2 correction_option: "smoothed" bandwidth: 25 @@ -225,7 +225,7 @@ templates: equipopulated_binning_options: &m_vis__eq_bin_opt variable_config: m_vis: - min: 10.0 + min: 40.0 max: 250.0 rounding: 2 correction_option: "smoothed" @@ -246,9 +246,9 @@ target_processes: <<: [*eta_1__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [0.8, 1.0, 1.0] var_bins: - "==0": [-2.1, -1.56, -1.26, -0.86, -0.5, -0.14, 0.22, 0.56, 0.93, 1.3, 1.63, 2.1] - "==1": [-2.1, -1.51, -1.13, -0.66, -0.22, 0.22, 0.7, 1.15, 1.54, 2.1] - ">=2": [-2.1, -1.37, -0.82, -0.33, 0.23, 0.81, 1.37, 2.1] + "==0": [-2.1, -1.56, -1.26, -0.86, -0.49, -0.14, 0.22, 0.56, 0.93, 1.3, 1.63, 2.1] + "==1": [-2.1, -1.51, -1.14, -0.65, -0.22, 0.22, 0.7, 1.15, 1.55, 2.1] + ">=2": [-2.1, -1.38, -0.85, -0.34, 0.21, 0.81, 1.38, 2.1] eta_2: <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -256,8 +256,8 @@ target_processes: bandwidth: [0.9, 1.1, 1.5] var_bins: "==0": [-2.5, -1.68, -1.28, -0.92, -0.57, -0.18, 0.24, 0.62, 0.99, 1.31, 1.78, 2.5] - "==1": [-2.5, -1.67, -1.19, -0.73, -0.25, 0.28, 0.72, 1.17, 1.59, 2.5] - ">=2": [-2.5, -1.41, -0.87, -0.21, 0.4, 0.94, 1.55, 2.5] + "==1": [-2.5, -1.68, -1.2, -0.74, -0.27, 0.28, 0.73, 1.18, 1.59, 2.5] + ">=2": [-2.5, -1.43, -0.88, -0.23, 0.4, 0.96, 1.57, 2.5] jeta_1: <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -267,8 +267,8 @@ target_processes: bandwidth: [1.0, 2.5, 2.5] var_bins: "==0": [-5.0, 5.0] - "==1": [-5.0, -2.73, -1.63, -0.92, -0.28, 0.34, 0.92, 1.65, 2.61, 5.0] - ">=2": [-5.0, -2.02, -1.07, -0.33, 0.31, 0.99, 1.98, 5.0] + "==1": [-5.0, -2.77, -1.64, -0.93, -0.29, 0.34, 0.89, 1.65, 2.61, 5.0] + ">=2": [-5.0, -2.02, -1.03, -0.32, 0.3, 0.98, 1.94, 5.0] jeta_2: <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -279,7 +279,7 @@ target_processes: var_bins: "==0": [-5.0, 5.0] "==1": [-5.0, 5.0] - ">=2": [-5.0, -2.1, -1.13, -0.36, 0.33, 1.16, 2.2, 5.0] + ">=2": [-5.0, -2.1, -1.18, -0.36, 0.32, 1.14, 2.21, 5.0] jpt_1: <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -288,8 +288,8 @@ target_processes: bandwidth: [1.0, 50.0, 60.0] var_bins: "==0": [30.0, 150.0] - "==1": [30.0, 31.86, 34.0, 36.75, 40.41, 45.06, 51.5, 61.09, 150.0] - ">=2": [30.0, 42.38, 51.03, 59.81, 71.12, 86.0, 150.0] + "==1": [30.0, 31.83, 33.84, 36.34, 39.88, 44.28, 50.31, 59.16, 150.0] + ">=2": [30.0, 42.0, 50.56, 59.31, 70.81, 85.38, 150.0] jpt_2: <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -299,34 +299,34 @@ target_processes: var_bins: "==0": [30.0, 150.0] "==1": [30.0, 150.0] - ">=2": [30.0, 32.44, 35.62, 39.5, 45.22, 54.28, 150.0] + ">=2": [30.0, 32.28, 35.5, 39.41, 44.91, 53.94, 150.0] met: <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*met__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [25.0, 45.0, 60.0] var_bins: - "==0": [0.0, 8.43, 12.17, 15.46, 18.63, 21.79, 25.19, 29.1, 33.7, 39.63, 48.85, 150.0] - "==1": [0.0, 10.73, 15.77, 20.26, 25.23, 30.93, 37.33, 46.39, 60.81, 150.0] - ">=2": [0.0, 15.33, 23.41, 32.63, 41.85, 54.06, 76.44, 150.0] + "==0": [0.0, 8.44, 12.18, 15.48, 18.65, 21.82, 25.23, 29.13, 33.78, 39.65, 49.01, 150.0] + "==1": [0.0, 10.83, 15.93, 20.3, 25.3, 30.94, 37.39, 46.41, 60.91, 150.0] + ">=2": [0.0, 15.65, 23.57, 32.4, 41.67, 53.44, 73.99, 150.0] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaEta_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [1.25, 1.5, 2.0] var_bins: - "==0": [-4.9, -2.13, -1.42, -0.93, -0.53, -0.18, 0.16, 0.56, 0.96, 1.43, 2.08, 4.9] - "==1": [-4.9, -2.0, -1.23, -0.65, -0.23, 0.25, 0.72, 1.28, 2.04, 4.9] - ">=2": [-4.9, -1.9, -1.03, -0.39, 0.26, 0.87, 1.76, 4.9] + "==0": [-4.9, -2.13, -1.43, -0.94, -0.54, -0.18, 0.16, 0.56, 0.96, 1.44, 2.08, 4.9] + "==1": [-4.9, -2.03, -1.31, -0.69, -0.24, 0.28, 0.77, 1.34, 2.08, 4.9] + ">=2": [-4.9, -1.95, -1.15, -0.47, 0.29, 0.99, 1.83, 4.9] deltaR_ditaupair: <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [0.8, 1.1, 1.2] var_bins: - "==0": [0.5, 2.6814, 2.869, 2.9787, 3.0526, 3.1104, 3.1696, 3.2609, 3.3865, 3.5747, 3.9186, 5.0] - "==1": [0.5, 1.653, 2.227, 2.5243, 2.7304, 2.9125, 3.0715, 3.2696, 3.6723, 5.0] - ">=2": [0.5, 1.3291, 1.9185, 2.3753, 2.7661, 3.0644, 3.4088, 5.0] + "==0": [0.5, 2.6888, 2.8726, 2.98, 3.0543, 3.1115, 3.1707, 3.2617, 3.388, 3.5757, 3.919, 5.0] + "==1": [0.5, 1.942, 2.3564, 2.5984, 2.782, 2.9473, 3.0925, 3.2939, 3.6937, 5.0] + ">=2": [0.5, 1.6602, 2.1007, 2.5053, 2.8475, 3.1032, 3.4388, 5.0] deltaR_1j1: <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -334,8 +334,8 @@ target_processes: correction_option: ["skip", "smoothed", "smoothed"] var_bins: "==0": [0.5, 7.0] - "==1": [0.5, 1.67, 2.205, 2.51, 2.774, 3.019, 3.235, 3.586, 4.235, 7.0] - ">=2": [0.5, 1.825, 2.382, 2.761, 3.009, 3.272, 3.759, 7.0] + "==1": [0.5, 1.632, 2.174, 2.464, 2.74, 3.001, 3.217, 3.578, 4.264, 7.0] + ">=2": [0.5, 1.772, 2.358, 2.733, 2.991, 3.241, 3.738, 7.0] deltaR_12j1: <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -344,8 +344,8 @@ target_processes: bandwidth: [1.0, 1.5, 1.5] var_bins: "==0": [0.0, 10.0] - "==1": [0.0, 2.28, 2.73, 2.96, 3.11, 3.27, 3.55, 3.98, 4.87, 10.0] - ">=2": [0.0, 2.26, 2.72, 2.95, 3.14, 3.46, 4.06, 10.0] + "==1": [0.0, 2.25, 2.71, 2.94, 3.1, 3.27, 3.55, 4.0, 4.91, 10.0] + ">=2": [0.0, 2.22, 2.7, 2.94, 3.13, 3.43, 4.07, 10.0] pt_ttjj: <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -355,34 +355,34 @@ target_processes: var_bins: "==0": [0.0, 150.0] "==1": [0.0, 150.0] - ">=2": [0.0, 15.52, 22.28, 30.06, 38.0, 49.31, 69.77, 150.0] + ">=2": [0.0, 15.8, 22.78, 30.11, 38.03, 49.21, 69.47, 150.0] mass_2: <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mass_2__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [0.25, 0.35, 0.4] var_bins: - "==0": [0.0, 0.2, 0.5107, 0.6216, 0.7388, 0.835, 0.9121, 0.9941, 1.0732, 1.1543, 1.25, 1.3623, 2.0] - "==1": [0.0, 0.2, 0.5322, 0.665, 0.79, 0.896, 1.0088, 1.0957, 1.1982, 1.3271, 2.0] - ">=2": [0.0, 0.2, 0.564, 0.7314, 0.8735, 0.9932, 1.1123, 1.2715, 2.0] + "==0": [0.0, 0.2, 0.5107, 0.6216, 0.7388, 0.835, 0.9131, 0.9941, 1.0732, 1.1553, 1.25, 1.3613, 2.0] + "==1": [0.0, 0.2, 0.5322, 0.665, 0.79, 0.8979, 1.0088, 1.0967, 1.1992, 1.3262, 2.0] + ">=2": [0.0, 0.2, 0.5586, 0.7266, 0.8647, 0.9917, 1.1104, 1.2715, 2.0] mt_tot: <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_tot__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [25, 50, 60] var_bins: - "==0": [50.0, 72.17, 77.52, 81.84, 85.76, 89.79, 94.23, 99.24, 105.25, 113.61, 130.06, 250.0] - "==1": [0.0, 59.33, 72.18, 80.25, 87.75, 95.78, 103.33, 114.05, 132.26, 250.0] - ">=2": [0.0, 53.08, 71.56, 83.98, 96.25, 111.26, 137.98, 250.0] + "==0": [50.0, 72.47, 77.61, 81.9, 85.85, 89.88, 94.29, 99.29, 105.32, 113.72, 130.11, 250.0] + "==1": [0.0, 64.61, 74.79, 82.4, 89.35, 97.26, 104.71, 115.38, 133.78, 250.0] + ">=2": [0.0, 60.36, 75.94, 87.15, 99.78, 113.99, 141.39, 250.0] m_vis: <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*m_vis__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [25, 40.0, 60.0] var_bins: - "==0": [10.0, 62.57, 66.96, 71.28, 75.86, 80.81, 86.89, 94.51, 105.32, 121.43, 147.86, 250.0] - "==1": [10.0, 52.87, 64.52, 71.76, 79.13, 87.73, 99.12, 117.93, 148.5, 250.0] - ">=2": [10.0, 50.01, 66.18, 78.78, 94.87, 113.93, 146.55, 250.0] + "==0": [40.0, 62.77, 67.12, 71.4, 75.97, 80.87, 87.03, 94.65, 105.53, 121.52, 147.95, 250.0] + "==1": [40.0, 59.53, 67.51, 74.21, 81.05, 89.85, 101.46, 120.46, 151.46, 250.0] + ">=2": [40.0, 59.6, 71.14, 82.96, 98.79, 118.59, 150.46, 250.0] iso_1: <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -395,9 +395,9 @@ target_processes: bandwidth: [0.04, 0.04, 0.04] correction_option: "smoothed" var_bins: - "==0": [0.05, 0.056882, 0.063543, 0.070468, 0.078181, 0.086647, 0.095377, 0.105744, 0.115638, 0.126327, 0.137486, 0.15] - "==1": [0.05, 0.057096, 0.065105, 0.073987, 0.083517, 0.096737, 0.108642, 0.122276, 0.13489, 0.15] - ">=2": [0.05, 0.059351, 0.068657, 0.081325, 0.096132, 0.110882, 0.128247, 0.15] + "==0": [0.05, 0.05689, 0.063581, 0.070489, 0.07823, 0.086695, 0.095464, 0.10584, 0.115682, 0.126434, 0.137512, 0.15] + "==1": [0.05, 0.057221, 0.065234, 0.074146, 0.083714, 0.096804, 0.108508, 0.122276, 0.134837, 0.15] + ">=2": [0.05, 0.059209, 0.068444, 0.080423, 0.09482, 0.110154, 0.128044, 0.15] DR_SR: <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] @@ -409,9 +409,9 @@ target_processes: ">=2": 5 bandwidth: [25.0, 40.0, 40.0] var_bins: - "==0": [0.0, 8.28, 12.42, 16.22, 19.91, 23.9, 28.63, 34.4, 43.76, 150.0] - "==1": [0.0, 25.39, 36.58, 46.12, 55.76, 68.1, 86.99, 150.0] - ">=2": [0.0, 38.69, 61.59, 82.53, 106.93, 150.0] + "==0": [0.0, 8.27, 12.39, 16.19, 19.88, 23.87, 28.55, 34.3, 43.56, 150.0] + "==1": [0.0, 24.76, 35.61, 45.11, 54.28, 66.31, 85.0, 150.0] + ">=2": [0.0, 36.33, 59.77, 80.39, 105.5, 150.0] SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! lep_mt: (mt_1 < 50) nbtag: (nbtag >= 0) @@ -423,7 +423,7 @@ target_processes: tau_pair_sign: ((q_1*q_2) > 0) lep_iso: "(!((iso_1 >= 0.05) && (iso_1 <= 0.15)))" AR_SR_cuts: - lep_mt: (mt_1 < 70) + lep_mt: (mt_1 < 50) nbtag: (nbtag >= 0) tau_pair_sign: ((q_1*q_2) < 0) lep_iso: "(!((iso_1 >= 0.05) && (iso_1 <= 0.15)))" @@ -449,18 +449,18 @@ target_processes: ">=2": 5 bandwidth: [0.65, 0.85, 1.25] var_bins: - "==0": [-2.1, -1.73, -1.43, -1.15, -0.88, -0.62, -0.38, -0.12, 0.12, 0.38, 0.64, 0.89, 1.16, 1.45, 1.75, 2.1] - "==1": [-2.1, -1.61, -1.22, -0.85, -0.49, -0.13, 0.2, 0.55, 0.89, 1.25, 1.64, 2.1] - ">=2": [-2.1, -1.1, -0.33, 0.39, 1.16, 2.1] + "==0": [-2.1, -1.73, -1.43, -1.15, -0.88, -0.62, -0.38, -0.12, 0.12, 0.38, 0.63, 0.89, 1.17, 1.45, 1.75, 2.1] + "==1": [-2.1, -1.61, -1.22, -0.85, -0.5, -0.13, 0.19, 0.55, 0.89, 1.25, 1.64, 2.1] + ">=2": [-2.1, -1.1, -0.34, 0.39, 1.15, 2.1] eta_2: <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*eta_2__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.6, 0.9, 1.2] var_bins: - "==0": [-2.5, -1.64, -1.28, -1.03, -0.78, -0.55, -0.32, -0.09, 0.15, 0.37, 0.58, 0.81, 1.03, 1.29, 1.67, 2.5] - "==1": [-2.5, -1.52, -1.12, -0.78, -0.43, -0.11, 0.22, 0.51, 0.82, 1.14, 1.55, 2.5] - ">=2": [-2.5, -1.41, -0.95, -0.55, -0.14, 0.25, 0.63, 1.0, 1.43, 2.5] + "==0": [-2.5, -1.65, -1.28, -1.02, -0.78, -0.55, -0.32, -0.09, 0.15, 0.37, 0.58, 0.81, 1.03, 1.29, 1.67, 2.5] + "==1": [-2.5, -1.53, -1.12, -0.78, -0.43, -0.11, 0.21, 0.5, 0.81, 1.13, 1.55, 2.5] + ">=2": [-2.5, -1.42, -0.95, -0.55, -0.15, 0.25, 0.62, 1.0, 1.42, 2.5] jeta_1: <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -470,8 +470,8 @@ target_processes: bandwidth: [1.0, 2.0, 2.0] var_bins: "==0": [-5.0, 5.0] - "==1": [-5.0, -2.71, -1.69, -0.94, -0.3, 0.34, 1.0, 1.77, 2.77, 5.0] - ">=2": [-5.0, -2.03, -1.07, -0.35, 0.35, 1.08, 2.07, 5.0] + "==1": [-5.0, -2.72, -1.69, -0.94, -0.31, 0.33, 0.99, 1.77, 2.77, 5.0] + ">=2": [-5.0, -2.03, -1.07, -0.36, 0.34, 1.08, 2.06, 5.0] jeta_2: <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -482,7 +482,7 @@ target_processes: var_bins: "==0": [-5.0, 5.0] "==1": [-5.0, 5.0] - ">=2": [-5.0, -2.35, -1.22, -0.36, 0.39, 1.2, 2.28, 5.0] + ">=2": [-5.0, -2.34, -1.21, -0.34, 0.39, 1.21, 2.28, 5.0] jpt_1: <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -491,8 +491,8 @@ target_processes: bandwidth: [1.0, 40.0, 55.0] var_bins: "==0": [30.0, 150.0] - "==1": [30.0, 31.75, 33.75, 36.06, 38.91, 42.56, 46.97, 52.62, 59.94, 70.38, 150.0] - ">=2": [30.0, 40.97, 48.16, 55.28, 63.12, 71.88, 82.69, 97.0, 150.0] + "==1": [30.0, 31.75, 33.75, 36.06, 38.94, 42.59, 47.06, 52.75, 60.12, 70.56, 150.0] + ">=2": [30.0, 40.94, 48.16, 55.28, 63.16, 72.0, 82.88, 97.31, 150.0] jpt_2: <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -502,34 +502,34 @@ target_processes: var_bins: "==0": [30.0, 150.0] "==1": [30.0, 150.0] - ">=2": [30.0, 31.98, 34.44, 37.22, 41.0, 45.97, 52.78, 62.31, 150.0] + ">=2": [30.0, 32.0, 34.5, 37.25, 41.06, 46.03, 52.94, 62.47, 150.0] met: <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*met__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [20.0, 30.0, 60.0] var_bins: - "==0": [0.0, 26.44, 31.36, 35.36, 38.87, 42.19, 45.55, 48.79, 52.11, 55.63, 59.36, 63.63, 68.67, 74.99, 85.01, 150.0] - "==1": [0.0, 30.7, 37.25, 42.61, 47.21, 52.07, 57.24, 62.89, 69.93, 79.35, 94.81, 150.0] - ">=2": [0.0, 34.6, 43.53, 51.39, 58.87, 67.67, 77.63, 91.67, 113.58, 150.0] + "==0": [0.0, 26.08, 30.86, 34.72, 38.15, 41.34, 44.55, 47.71, 50.93, 54.36, 58.02, 62.26, 67.2, 73.68, 83.91, 150.0] + "==1": [0.0, 30.24, 36.69, 42.02, 46.59, 51.47, 56.55, 62.11, 69.15, 78.23, 93.44, 150.0] + ">=2": [0.0, 33.94, 42.91, 50.5, 57.96, 66.32, 76.13, 88.78, 107.65, 150.0] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaEta_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.8, 1.1, 1.25] var_bins: - "==0": [-4.9, -1.9, -1.36, -1.02, -0.75, -0.52, -0.31, -0.11, 0.09, 0.3, 0.51, 0.74, 1.0, 1.34, 1.87, 4.9] - "==1": [-4.9, -1.75, -1.16, -0.75, -0.43, -0.14, 0.14, 0.43, 0.74, 1.14, 1.74, 4.9] - ">=2": [-4.9, -1.56, -0.96, -0.53, -0.16, 0.19, 0.54, 0.95, 1.54, 4.9] + "==0": [-4.9, -1.94, -1.41, -1.07, -0.79, -0.55, -0.32, -0.11, 0.09, 0.31, 0.53, 0.77, 1.04, 1.39, 1.91, 4.9] + "==1": [-4.9, -1.79, -1.21, -0.8, -0.45, -0.15, 0.14, 0.45, 0.79, 1.19, 1.78, 4.9] + ">=2": [-4.9, -1.6, -1.0, -0.56, -0.16, 0.2, 0.56, 0.98, 1.58, 4.9] deltaR_ditaupair: <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.5, 0.6, 0.7] var_bins: - "==0": [0.5, 1.291, 1.6664, 1.9482, 2.1706, 2.3528, 2.5196, 2.6606, 2.783, 2.8902, 2.9821, 3.0643, 3.1321, 3.2287, 3.4481, 5.0] - "==1": [0.5, 1.1946, 1.5966, 1.9154, 2.1746, 2.4058, 2.6139, 2.801, 2.9638, 3.1049, 3.3191, 5.0] - ">=2": [0.5, 1.1567, 1.5816, 1.9338, 2.2206, 2.4933, 2.7366, 2.9631, 3.1951, 5.0] + "==0": [0.5, 1.5899, 1.8712, 2.0958, 2.2841, 2.4445, 2.5916, 2.7159, 2.8263, 2.9219, 3.0057, 3.0797, 3.1417, 3.2459, 3.4663, 5.0] + "==1": [0.5, 1.4292, 1.7591, 2.0364, 2.2665, 2.4768, 2.6654, 2.8359, 2.9873, 3.1187, 3.3378, 5.0] + ">=2": [0.5, 1.3299, 1.705, 2.0138, 2.289, 2.5419, 2.7705, 2.9859, 3.2134, 5.0] deltaR_1j1: <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -538,8 +538,8 @@ target_processes: bandwidth: [1.0, 1.0, 1.2] var_bins: "==0": [0.5, 7.0] - "==1": [0.5, 1.257, 1.688, 2.026, 2.312, 2.572, 2.811, 3.037, 3.282, 3.69, 4.342, 7.0] - ">=2": [0.5, 1.242, 1.733, 2.12, 2.446, 2.72, 2.978, 3.261, 3.842, 7.0] + "==1": [0.5, 1.237, 1.659, 1.993, 2.281, 2.545, 2.794, 3.024, 3.273, 3.685, 4.346, 7.0] + ">=2": [0.5, 1.226, 1.705, 2.102, 2.427, 2.71, 2.968, 3.252, 3.832, 7.0] deltaR_12j1: <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -548,8 +548,8 @@ target_processes: bandwidth: [1.0, 1.5, 1.75] var_bins: "==0": [0.0, 10.0] - "==1": [0.0, 1.78, 2.26, 2.55, 2.77, 2.94, 3.1, 3.29, 3.58, 4.02, 4.82, 10.0] - ">=2": [0.0, 1.78, 2.28, 2.61, 2.84, 3.04, 3.23, 3.57, 4.21, 10.0] + "==1": [0.0, 1.76, 2.25, 2.54, 2.76, 2.94, 3.1, 3.3, 3.59, 4.04, 4.85, 10.0] + ">=2": [0.0, 1.78, 2.28, 2.61, 2.85, 3.05, 3.23, 3.57, 4.22, 10.0] pt_ttjj: <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -559,43 +559,43 @@ target_processes: var_bins: "==0": [0.0, 150.0] "==1": [0.0, 150.0] - ">=2": [0.0, 13.13, 19.85, 25.75, 31.71, 38.56, 46.7, 57.79, 75.16, 150.0] + ">=2": [0.0, 13.21, 19.9, 25.84, 31.84, 38.72, 46.93, 58.04, 75.39, 150.0] mass_2: <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mass_2__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.225, 0.225, 0.25] var_bins: - "==0": [0.0, 0.2, 0.4827, 0.5635, 0.6396, 0.707, 0.7681, 0.8281, 0.8857, 0.9453, 1.0078, 1.0713, 1.1377, 1.2109, 1.2949, 1.4092, 2.0] - "==1": [0.0, 0.2, 0.5088, 0.6177, 0.7119, 0.7959, 0.8696, 0.9551, 1.0381, 1.1279, 1.2285, 1.3545, 2.0] - ">=2": [0.0, 0.2, 0.5308, 0.6577, 0.7612, 0.8506, 0.957, 1.0625, 1.1758, 1.3076, 2.0] + "==0": [0.0, 0.2, 0.4827, 0.5654, 0.6406, 0.708, 0.769, 0.8291, 0.8867, 0.9468, 1.0088, 1.0723, 1.1387, 1.2119, 1.2949, 1.4102, 2.0] + "==1": [0.0, 0.2, 0.5083, 0.6167, 0.7109, 0.7949, 0.8677, 0.9546, 1.0371, 1.127, 1.2285, 1.3545, 2.0] + ">=2": [0.0, 0.2, 0.5312, 0.6582, 0.7612, 0.8506, 0.957, 1.0635, 1.1748, 1.3086, 2.0] mt_tot: <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_tot__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [20.0, 30.0, 50.0] var_bins: - "==0": [90.0, 107.0, 114.05, 118.88, 122.8, 126.47, 129.96, 133.5, 137.38, 141.66, 146.66, 152.62, 160.27, 171.17, 189.87, 250.0] - "==1": [80.0, 105.43, 113.18, 120.11, 126.5, 133.37, 140.45, 148.83, 158.49, 171.81, 194.95, 250.0] - ">=2": [80.0, 107.35, 119.32, 129.92, 139.77, 150.85, 163.8, 180.28, 204.68, 250.0] + "==0": [90.0, 106.8, 113.93, 118.9, 122.89, 126.65, 130.22, 133.82, 137.83, 142.26, 147.38, 153.52, 161.24, 172.4, 191.21, 250.0] + "==1": [80.0, 105.8, 113.59, 120.7, 127.13, 134.25, 141.61, 150.06, 159.82, 173.39, 196.55, 250.0] + ">=2": [80.0, 108.15, 120.64, 131.18, 141.22, 152.68, 165.39, 182.22, 206.29, 250.0] m_vis: <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*m_vis__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [20, 30, 40] var_bins: - "==0": [10.0, 42.86, 56.57, 65.25, 71.44, 76.81, 82.65, 88.89, 94.81, 101.38, 108.76, 117.89, 129.67, 146.41, 173.6, 250.0] - "==1": [10.0, 47.9, 61.79, 70.4, 78.55, 87.62, 97.03, 108.32, 123.11, 142.49, 172.66, 250.0] - ">=2": [10.0, 52.86, 67.26, 77.69, 90.57, 104.12, 120.68, 142.58, 175.33, 250.0] + "==0": [40.0, 53.81, 63.19, 69.57, 74.63, 80.07, 85.73, 91.46, 97.14, 103.66, 111.09, 120.22, 132.11, 148.61, 175.66, 250.0] + "==1": [40.0, 56.8, 66.41, 74.1, 82.15, 90.75, 100.06, 111.42, 126.0, 145.26, 175.05, 250.0] + ">=2": [40.0, 59.87, 70.97, 81.27, 93.8, 107.02, 123.57, 145.41, 177.53, 250.0] iso_1: <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*iso_1__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.03, 0.04, 0.05] var_bins: - "==0": [0.0, 0.00005, 0.004932, 0.007516, 0.010087, 0.012785, 0.015814, 0.019493, 0.023479, 0.028324, 0.034053, 0.040962, 0.049714, 0.060662, 0.075963, 0.100649, 0.15] - "==1": [0.0, 0.00005, 0.005621, 0.009072, 0.012884, 0.017279, 0.022713, 0.029417, 0.037605, 0.049066, 0.064637, 0.090462, 0.15] - ">=2": [0.0, 0.00005, 0.005602, 0.009668, 0.014723, 0.020748, 0.028099, 0.039254, 0.055474, 0.082078, 0.15] + "==0": [0.0, 0.00005, 0.004834, 0.007351, 0.009837, 0.012504, 0.015492, 0.019098, 0.023015, 0.02771, 0.033411, 0.040272, 0.048838, 0.05981, 0.07515, 0.099763, 0.15] + "==1": [0.0, 0.00005, 0.005532, 0.008912, 0.012683, 0.016988, 0.022286, 0.028948, 0.037248, 0.048451, 0.063764, 0.08923, 0.15] + ">=2": [0.0, 0.00005, 0.005483, 0.009502, 0.014473, 0.020446, 0.027858, 0.038669, 0.0548, 0.081201, 0.15] DR_SR: <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] @@ -607,9 +607,9 @@ target_processes: ">=2": 7 bandwidth: [25.0, 40.0, 50.0] var_bins: - "==0": [0.0, 6.74, 9.78, 12.39, 14.84, 17.3, 19.85, 22.57, 25.6, 29.06, 33.27, 38.82, 47.6, 150.0] - "==1": [0.0, 23.29, 32.66, 40.35, 48.0, 55.9, 65.43, 78.07, 98.38, 150.0] - ">=2": [0.0, 32.56, 49.55, 65.25, 80.72, 98.18, 119.72, 150.0] + "==0": [0.0, 6.73, 9.78, 12.39, 14.84, 17.3, 19.85, 22.57, 25.6, 29.05, 33.26, 38.81, 47.58, 150.0] + "==1": [0.0, 23.16, 32.5, 40.16, 47.73, 55.6, 64.97, 77.54, 97.85, 150.0] + ">=2": [0.0, 32.16, 49.05, 64.62, 80.11, 97.64, 119.22, 150.0] SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! lep_mt: (mt_1 > 0) nbtag: (nbtag == 0) @@ -620,7 +620,7 @@ target_processes: nbtag: (nbtag == 0) tau_pair_sign: ((q_1*q_2) < 0) lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) - AR_SR_cuts: + AR_SR_cuts: # this is only on MC! lep_mt: (mt_1 < 70) nbtag: (nbtag >= 0) tau_pair_sign: ((q_1*q_2) < 0) @@ -642,16 +642,16 @@ target_processes: <<: [*eta_1__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.6, 1.0] var_bins: - "<=1": [-2.1, -1.49, -1.13, -0.8, -0.46, -0.13, 0.11, 0.46, 0.78, 1.18, 1.51, 2.1] - ">=2": [-2.1, -1.66, -1.38, -1.07, -0.82, -0.6, -0.37, -0.09, 0.1, 0.32, 0.57, 0.82, 1.05, 1.31, 1.7, 2.1] + "<=1": [-2.1, -1.59, -1.19, -0.81, -0.48, -0.12, 0.2, 0.5, 0.84, 1.22, 1.6, 2.1] + ">=2": [-2.1, -1.72, -1.42, -1.14, -0.86, -0.61, -0.39, -0.13, 0.1, 0.35, 0.58, 0.83, 1.08, 1.4, 1.71, 2.1] eta_2: <<: [*eta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*eta_2__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.7, 0.7] var_bins: - "<=1": [-2.5, -1.54, -1.03, -0.71, -0.36, -0.05, 0.26, 0.58, 0.87, 1.2, 1.64, 2.5] - ">=2": [-2.5, -1.82, -1.52, -1.2, -0.95, -0.65, -0.39, -0.16, 0.1, 0.39, 0.65, 0.91, 1.17, 1.47, 1.83, 2.5] + "<=1": [-2.5, -1.55, -1.11, -0.74, -0.42, -0.08, 0.25, 0.56, 0.88, 1.19, 1.61, 2.5] + ">=2": [-2.5, -1.82, -1.43, -1.16, -0.86, -0.62, -0.34, -0.09, 0.19, 0.44, 0.66, 0.92, 1.17, 1.45, 1.86, 2.5] jeta_1: <<: [*jeta_1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -659,8 +659,8 @@ target_processes: correction_option: "smoothed" bandwidth: [1.0, 2.0] var_bins: - "<=1": [-5.0, -1.81, -1.27, -0.75, -0.42, -0.17, 0.3, 0.86, 1.39, 1.75, 2.2, 5.0] - ">=2": [-5.0, -2.17, -1.71, -1.34, -1.06, -0.68, -0.4, -0.21, 0.09, 0.36, 0.66, 0.99, 1.36, 1.74, 2.15, 5.0] + "<=1": [-5.0, -2.13, -1.4, -0.97, -0.57, -0.2, 0.18, 0.56, 0.98, 1.49, 2.08, 5.0] + ">=2": [-5.0, -2.28, -1.8, -1.36, -1.06, -0.72, -0.44, -0.18, 0.15, 0.46, 0.76, 1.09, 1.42, 1.87, 2.26, 5.0] jeta_2: <<: [*jeta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -669,15 +669,15 @@ target_processes: correction_option: ["skip", "smoothed"] var_bins: "<=1": [-5.0, 5.0] - ">=2": [-5.0, -2.29, -1.78, -1.35, -1.03, -0.77, -0.42, -0.08, 0.18, 0.43, 0.69, 1.02, 1.35, 1.71, 2.3, 5.0] + ">=2": [-5.0, -2.62, -1.96, -1.44, -1.08, -0.77, -0.46, -0.17, 0.13, 0.46, 0.76, 1.1, 1.5, 1.96, 2.59, 5.0] jpt_1: <<: [*jpt_1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*jpt_1__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [30.0, 20.0] var_bins: - "<=1": [30.0, 32.38, 35.75, 39.12, 41.78, 47.94, 53.25, 60.53, 67.19, 80.25, 98.12, 150.0] - ">=2": [30.0, 44.72, 49.97, 55.5, 60.47, 65.44, 69.75, 74.75, 80.44, 87.81, 93.75, 100.25, 108.81, 120.31, 133.88, 150.0] + "<=1": [30.0, 32.88, 35.75, 38.97, 42.47, 46.53, 51.03, 56.12, 62.88, 71.88, 85.25, 150.0] + ">=2": [30.0, 40.09, 45.03, 48.84, 52.97, 57.0, 60.91, 65.0, 69.38, 74.25, 80.25, 87.31, 95.0, 105.94, 124.06, 150.0] jpt_2: <<: [*jpt_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -686,38 +686,38 @@ target_processes: correction_option: ["skip", "smoothed"] var_bins: "<=1": [30.0, 150.0] - ">=2": [30.0, 32.59, 35.66, 38.44, 40.5, 43.03, 45.84, 49.53, 52.69, 56.81, 62.22, 68.44, 75.0, 84.88, 104.12, 150.0] + ">=2": [30.0, 31.55, 33.22, 34.81, 36.66, 38.72, 40.69, 43.09, 45.69, 49.09, 52.78, 57.97, 64.62, 73.38, 88.88, 150.0] met: <<: [*met, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*met__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [40.0, 35.0] var_bins: - "<=1": [0.0, 9.22, 13.78, 18.12, 21.91, 25.8, 29.35, 34.7, 41.03, 48.98, 64.82, 150.0] - ">=2": [0.0, 10.67, 16.47, 21.16, 26.32, 30.32, 35.4, 40.28, 45.93, 51.92, 58.67, 68.58, 77.57, 90.43, 114.09, 150.0] + "<=1": [0.0, 6.42, 9.61, 12.29, 14.89, 17.59, 20.76, 23.87, 28.1, 33.71, 43.03, 150.0] + ">=2": [0.0, 7.56, 11.11, 14.34, 17.17, 19.81, 22.54, 25.46, 28.64, 32.58, 37.14, 43.54, 50.89, 62.27, 84.77, 150.0] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaEta_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [1.5, 1.75] var_bins: - "<=1": [-4.9, -1.79, -1.25, -0.8, -0.45, -0.21, 0.1, 0.35, 0.7, 1.02, 1.58, 4.9] - ">=2": [-4.9, -2.13, -1.5, -1.12, -0.84, -0.59, -0.35, -0.11, 0.1, 0.36, 0.6, 0.86, 1.17, 1.55, 2.08, 4.9] + "<=1": [-4.9, -1.79, -1.18, -0.8, -0.47, -0.17, 0.11, 0.4, 0.73, 1.1, 1.7, 4.9] + ">=2": [-4.9, -2.2, -1.63, -1.24, -0.96, -0.69, -0.43, -0.19, 0.06, 0.32, 0.61, 0.89, 1.19, 1.6, 2.18, 4.9] deltaR_ditaupair: <<: [*deltaR_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.75, 1.0] var_bins: - "<=1": [0.5, 1.3127, 1.8146, 2.1011, 2.4094, 2.5761, 2.7567, 2.8974, 3.0268, 3.135, 3.3705, 5.0] - ">=2": [0.5, 0.8992, 1.2307, 1.4672, 1.6895, 1.8938, 2.0824, 2.2625, 2.4282, 2.5938, 2.7408, 2.9351, 3.0912, 3.2107, 3.5425, 5.0] + "<=1": [0.5, 1.8185, 2.2501, 2.5022, 2.6998, 2.843, 2.9625, 3.0535, 3.1262, 3.2298, 3.4783, 5.0] + ">=2": [0.5, 1.1451, 1.4219, 1.6541, 1.8355, 2.0329, 2.2002, 2.365, 2.5182, 2.6805, 2.829, 2.9692, 3.1, 3.225, 3.5263, 5.0] deltaR_1j1: <<: [*deltaR_1j1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_1j1__eq_bin_opt, *ttbar_var_dependence_n_bins] var_bins: - "<=1": [0.5, 1.463, 1.926, 2.258, 2.439, 2.576, 2.729, 2.877, 3.041, 3.194, 3.576, 7.0] - ">=2": [0.5, 1.184, 1.565, 1.866, 2.105, 2.308, 2.508, 2.634, 2.772, 2.901, 3.014, 3.105, 3.252, 3.49, 3.886, 7.0] + "<=1": [0.5, 1.712, 2.041, 2.233, 2.368, 2.491, 2.609, 2.732, 2.884, 3.052, 3.322, 7.0] + ">=2": [0.5, 1.277, 1.668, 1.911, 2.119, 2.294, 2.448, 2.601, 2.738, 2.866, 2.972, 3.084, 3.206, 3.464, 3.926, 7.0] deltaR_12j1: <<: [*deltaR_12j1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -725,8 +725,8 @@ target_processes: correction_option: "smoothed" bandwidth: [1.5, 1.5] var_bins: - "<=1": [0.0, 1.95, 2.47, 2.74, 2.89, 2.98, 3.06, 3.14, 3.29, 3.62, 4.16, 10.0] - ">=2": [0.0, 1.52, 2.0, 2.26, 2.46, 2.6, 2.72, 2.84, 2.95, 3.04, 3.15, 3.24, 3.39, 3.64, 4.21, 10.0] + "<=1": [0.0, 2.45, 2.74, 2.87, 2.97, 3.04, 3.11, 3.19, 3.31, 3.54, 4.01, 10.0] + ">=2": [0.0, 1.8, 2.21, 2.41, 2.57, 2.71, 2.82, 2.91, 3.0, 3.07, 3.16, 3.28, 3.46, 3.76, 4.33, 10.0] pt_ttjj: <<: [*pt_ttjj, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -734,37 +734,36 @@ target_processes: correction_option: ["skip", "smoothed"] var_bins: "<=1": [0.0, 150.0] - ">=2": [0.0, 12.41, 17.29, 22.62, 27.07, 31.94, 36.75, 41.57, 45.61, 50.55, 57.19, 63.8, 72.66, 84.61, 100.26, 150.0] + ">=2": [0.0, 10.01, 15.05, 18.51, 22.24, 26.35, 29.98, 33.82, 37.48, 42.35, 47.08, 52.65, 60.81, 71.28, 88.2, 150.0] mass_2: <<: [*mass_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*mass_2__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.225, 0.175] var_bins: - "<=1": [0.0, 0.2, 0.5444, 0.6445, 0.728, 0.8008, 0.8672, 0.9683, 1.0303, 1.1143, 1.2314, 1.3623, 2.0] - ">=2": [0.0, 0.2, 0.4619, 0.5469, 0.6182, 0.6982, 0.7715, 0.8232, 0.8687, 0.938, 0.9937, 1.0635, 1.1367, 1.2285, 1.3125, 1.3984, 2.0] + "<=1": [0.0, 0.2, 0.5073, 0.6138, 0.709, 0.7949, 0.8745, 0.9595, 1.043, 1.1299, 1.2266, 1.3516, 2.0] + ">=2": [0.0, 0.2, 0.4607, 0.5352, 0.6128, 0.6851, 0.7598, 0.8218, 0.874, 0.9316, 0.9941, 1.0527, 1.123, 1.1992, 1.2793, 1.3926, 2.0] mt_tot: <<: [*mt_tot, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_tot__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [35.0, 40.0] var_bins: - "<=1": [0.0, 63.54, 78.85, 85.94, 92.79, 98.62, 104.47, 115.13, 125.29, 139.43, 162.49, 250.0] - ">=2": [0.0, 49.93, 64.75, 75.18, 84.76, 92.22, 99.33, 105.61, 111.19, 118.26, 125.95, 136.61, 150.02, 166.48, 192.71, 250.0] + "<=1": [0.0, 69.47, 78.15, 84.38, 89.97, 95.26, 100.7, 106.88, 114.3, 125.28, 144.01, 250.0] + ">=2": [0.0, 50.83, 63.88, 72.33, 79.91, 86.61, 92.35, 97.84, 103.22, 109.07, 115.24, 123.47, 133.88, 148.13, 174.05, 250.0] m_vis: <<: [*m_vis, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*m_vis__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [20, 20] var_bins: - "<=1": [10.0, 55.86, 65.63, 72.36, 79.46, 86.85, 92.84, 101.48, 112.62, 129.11, 156.72, 250.0] - ">=2": [10.0, 38.19, 49.23, 58.54, 66.52, 73.73, 80.35, 87.79, 94.93, 103.08, 111.97, 122.64, 136.18, 155.85, 185.32, 250.0] + "<=1": [40.0, 60.36, 67.73, 74.07, 81.14, 88.19, 94.03, 102.97, 114.17, 130.62, 157.95, 250.0] + ">=2": [40.0, 49.61, 58.39, 65.84, 72.69, 78.41, 85.03, 92.35, 98.95, 106.61, 115.19, 126.1, 139.34, 159.49, 187.88, 250.0] iso_1: <<: [*iso_1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*iso_1__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.05, 0.05] var_bins: - "<=1": [0.0, 0.00005, 0.006302, 0.010062, 0.015117, 0.019868, 0.026705, 0.034487, 0.042188, 0.053464, 0.070283, 0.09919, 0.15] - ">=2": [0.0, 0.00005, 0.00474, 0.0073, 0.009086, 0.012093, 0.015567, 0.01926, 0.024698, 0.029262, 0.036078, 0.044737, 0.054924, 0.067122, 0.08194, 0.107338, 0.15] - \ No newline at end of file + "<=1": [0.0, 0.00005, 0.006077, 0.009416, 0.013132, 0.017296, 0.022391, 0.029646, 0.038035, 0.049376, 0.065149, 0.092747, 0.15] + ">=2": [0.0, 0.00005, 0.004505, 0.00665, 0.008761, 0.0109, 0.013594, 0.016488, 0.019765, 0.024123, 0.029846, 0.037418, 0.045143, 0.056147, 0.072582, 0.094662, 0.15] diff --git a/configs/smhtt_ul/2018/fake_factors_mt.yaml b/configs/smhtt_ul/2018/fake_factors_mt.yaml index d36d389..ba274b1 100644 --- a/configs/smhtt_ul/2018/fake_factors_mt.yaml +++ b/configs/smhtt_ul/2018/fake_factors_mt.yaml @@ -39,27 +39,27 @@ target_processes: var_dependence: pt_2 # in case of individual splitting var_bins: - "==0": [30.0, 31.05, 32.32, 33.68, 35.36, 37.3, 39.72, 43.02, 47.71, 55.77, 150.0] - "==1": [30.0, 32.24, 35.38, 40.3, 50.88, 150.0] - ">=2": [30.0, 33.58, 39.16, 51.85, 150.0] + "==0": [30.0, 31.06, 32.33, 33.69, 35.37, 37.31, 39.73, 43.04, 47.73, 55.82, 150.0] + "==1": [30.0, 32.33, 35.62, 40.69, 51.56, 150.0] + ">=2": [30.0, 33.69, 39.49, 52.66, 150.0] fit_option: "==0": ["poly_1"] "==1": ["poly_1", "poly_2"] - ">=2": ["poly_1", "poly_2"] + ">=2": ["poly_1"] Wjets: split_categories: njets: ["==0", "==1", ">=2"] pt_1: - "==0": [<=35.96, '>35.96#&&#<=48.5', '>48.5#&&#<=64.78', '>64.78'] - "==1": [<=37.18, '>37.18#&&#<=49.53', '>49.53#&&#<=68.79', '>68.79'] - ">=2": [<=38.88, '>38.88#&&#<=54.94', '>54.94#&&#<=82.16', '>82.16'] + "==0": [<=37.47, '>37.47#&&#<=50.12', '>50.12#&&#<=65.82', '>65.82'] + "==1": [<=38.11, '>38.11#&&#<=50.8', '>50.8#&&#<=70.26', '>70.26'] + ">=2": [<=39.7, '>39.7#&&#<=56.33', '>56.33#&&#<=83.95', '>83.95'] split_categories_binedges: njets: [-0.5, 0.5, 1.5, 22.5] pt_1: - "==0": [0.0, 35.959999084473, 48.5, 64.779998779297, 1000.0] - "==1": [0.0, 37.180000305176, 49.529998779297, 68.790000915527, 1000.0] - ">=2": [0.0, 38.880001068115, 54.939998626709, 82.160003662109, 1000.0] + "==0": [0.0, 37.470001220703, 50.119998931885, 65.819999694824, 1000.0] + "==1": [0.0, 38.110000610352, 50.799999237061, 70.26000213623, 1000.0] + ">=2": [0.0, 39.700000762939, 56.330001831055, 83.949996948242, 1000.0] equipopulated_binning_options: variable_config: pt_2: @@ -97,23 +97,23 @@ target_processes: var_dependence: pt_2 var_bins: "==0": - "<=35.96": [30.0, 30.84, 31.77, 32.82, 34.12, 35.57, 37.42, 39.8, 43.43, 50.59, 150.0] - ">35.96#&&#<=48.5": [30.0, 30.82, 31.71, 32.7, 33.87, 35.35, 37.12, 39.54, 43.27, 50.62, 150.0] - ">48.5#&&#<=64.78": [30.0, 30.94, 32.04, 33.2, 34.62, 36.22, 38.18, 40.94, 45.15, 52.58, 150.0] - ">64.78": [30.0, 32.15, 34.48, 36.96, 39.95, 43.47, 48.0, 53.68, 62.03, 77.31, 150.0] + "<=37.47": [30.0, 30.91, 31.9, 32.99, 34.32, 35.85, 37.84, 40.3, 44.38, 52.02, 150.0] + ">37.47#&&#<=50.12": [30.0, 30.83, 31.76, 32.79, 34.0, 35.49, 37.33, 39.8, 43.54, 51.14, 150.0] + ">50.12#&&#<=65.82": [30.0, 30.98, 32.09, 33.29, 34.74, 36.37, 38.35, 41.21, 45.46, 52.83, 150.0] + ">65.82": [30.0, 32.28, 34.65, 37.21, 40.28, 43.94, 48.54, 54.36, 62.74, 78.44, 150.0] "==1": - "<=37.18": [30.0, 32.63, 36.04, 40.94, 50.97, 150.0] - ">37.18#&&#<=49.53": [30.0, 32.59, 35.95, 40.96, 51.57, 150.0] - ">49.53#&&#<=68.79": [30.0, 33.13, 36.88, 42.74, 54.42, 150.0] - ">68.79": [30.0, 34.67, 41.45, 52.01, 70.7, 150.0] + "<=38.11": [30.0, 32.76, 36.25, 41.29, 51.88, 150.0] + ">38.11#&&#<=50.8": [30.0, 32.69, 36.18, 41.2, 52.23, 150.0] + ">50.8#&&#<=70.26": [30.0, 33.24, 37.22, 43.47, 55.58, 150.0] + ">70.26": [30.0, 34.78, 41.68, 52.52, 71.29, 150.0] ">=2": - "<=38.88": [30.0, 33.56, 38.22, 45.83, 62.27, 150.0] - ">38.88#&&#<=54.94": [30.0, 33.26, 38.84, 46.82, 62.86, 150.0] - ">54.94#&&#<=82.16": [30.0, 34.01, 39.54, 48.62, 65.91, 150.0] - ">82.16": [30.0, 35.3, 42.61, 54.79, 76.48, 150.0] + "<=39.7": [30.0, 33.71, 38.59, 46.75, 64.03, 150.0] + ">39.7#&&#<=56.33": [30.0, 33.33, 39.27, 48.06, 64.51, 150.0] + ">56.33#&&#<=83.95": [30.0, 34.18, 39.84, 48.93, 66.5, 150.0] + ">83.95": [30.0, 35.44, 43.03, 55.19, 77.0, 150.0] fit_option: "==0": ["poly_1", "poly_2"] - "==1": ["poly_1", "poly_2", "poly_3"] + "==1": ["poly_1", "poly_2"] ">=2": ["poly_1", "poly_2"] ttbar: @@ -171,8 +171,8 @@ target_processes: var_dependence: pt_2 var_bins: - "<=1": [30.0, 30.85, 31.77, 32.76, 33.78, 34.99, 36.3, 37.86, 39.58, 41.58, 44.13, 47.07, 51.67, 58.63, 71.12, 150.0] - ">=2": [30.0, 31.69, 33.63, 35.9, 38.56, 42.03, 46.12, 52.56, 62.75, 82.88, 150.0] + "<=1": [30.0, 30.86, 31.82, 32.84, 33.87, 35.12, 36.43, 38.04, 39.75, 41.81, 44.39, 47.34, 51.99, 59.05, 71.81, 150.0] + ">=2": [30.0, 31.77, 33.82, 36.2, 38.94, 42.51, 46.87, 53.32, 63.98, 83.61, 150.0] fit_option: ["poly_1", "poly_2", "poly_3"] process_fractions: @@ -214,6 +214,6 @@ process_fractions: var_dependence: mt_1 var_bins: - "==0": [0.0, 1.98, 3.99, 6.06, 8.26, 10.57, 13.01, 15.57, 18.3, 21.21, 24.25, 27.42, 30.73, 34.12, 37.54, 40.95, 44.28, 47.59, 50.77, 53.85, 56.81, 59.62, 62.37, 64.98, 67.54, 70.0] - "==1": [0.0, 3.49, 7.01, 10.68, 14.5, 18.32, 22.25, 26.23, 30.17, 34.21, 38.07, 41.79, 45.44, 48.97, 52.36, 55.59, 58.71, 61.7, 64.55, 67.33, 70.0] - ">=2": [0.0, 5.06, 10.07, 15.09, 20.24, 25.29, 30.43, 35.54, 40.46, 45.17, 49.65, 53.9, 58.18, 62.23, 66.13, 70.0] + "==0": [0.0, 1.97, 3.96, 6.02, 8.2, 10.5, 12.92, 15.46, 18.16, 21.05, 24.07, 27.22, 30.51, 33.88, 37.28, 40.68, 44.01, 47.32, 50.52, 53.63, 56.6, 59.44, 62.21, 64.88, 67.48, 70.0] + "==1": [0.0, 3.47, 6.95, 10.58, 14.36, 18.15, 22.04, 26.0, 29.92, 33.94, 37.79, 41.5, 45.16, 48.71, 52.11, 55.36, 58.53, 61.57, 64.46, 67.29, 70.0] + ">=2": [0.0, 5.1, 10.13, 15.16, 20.27, 25.33, 30.46, 35.49, 40.39, 45.1, 49.58, 53.83, 58.12, 62.2, 66.11, 70.0] diff --git a/ff_corrections.py b/ff_corrections.py index bf7acf7..58c40dd 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -309,7 +309,7 @@ def run_ff_calculation_for_DRtoSR( str, Dict[str, Union[Dict, List, str]], Dict[str, Union[Dict, str]], - List[str], + func.SamplePathList, str, ] ) -> Union[Dict, None]: @@ -333,11 +333,22 @@ def run_ff_calculation_for_DRtoSR( process=process, to_AR_SR=False, ) + + use_data_flag = corr_config["target_processes"][process]["DR_SR"].get("compute_different_set_of_fake_factors_using_data", True) + if process.startswith("QCD") and not use_data_flag: + raise NotImplementedError("compute_different_set_of_fake_factors_using_data=False is not currently implemented for QCD.") + ff_config["target_processes"][process]["compute_different_set_of_fake_factors_using_data"] = use_data_flag + log.info(f"Calculating fake factors for the DR to SR correction for the {process} process.") log.info("-" * 50) result = FF_calculation( config=ff_config, - sample_paths=sample_paths, + sample_paths=sample_paths.switch_embedding_state( + corr_config["target_processes"][process]["DR_SR"].get( + "use_embedding", + config.get("use_embedding", False) + ) + ), output_path=output_path, process=process, logger=f"ff_corrections.{process}", @@ -398,7 +409,12 @@ def run_non_closure_correction_for_DRtoSR( corr_config=corr_config, process=process, evaluator=evaluator, - sample_paths=sample_paths, + sample_paths=sample_paths.switch_embedding_state( + process_config["DR_SR"].get( + "use_embedding", + config.get("use_embedding", False) + ) + ), output_path=output_path, for_DRtoSR=True, DR_SR_evaluator=None, @@ -455,14 +471,14 @@ def run_correction( config=config, process=process, var_dependences=var_dependences, - for_DRtoSR=True, + for_DRtoSR=corr_config["target_processes"][process]["DR_SR"].get("compute_different_set_of_fake_factors", True), logger=f"ff_corrections.{process}", ) corr_evaluators = [] DR_SR_config = corr_config["target_processes"][process]["DR_SR"] - for corr_var in DR_SR_config["non_closure"].keys(): + for corr_var in DR_SR_config.get("non_closure", {}).keys(): non_closure_corr_vars_DR_SR = corr_var if "split_categories" in DR_SR_config["non_closure"][corr_var]: split_variables = list(DR_SR_config["non_closure"][corr_var]["split_categories"].keys()) @@ -511,10 +527,10 @@ def run_correction( args_list=[ ( split_collection, - config, + ff_config, DR_SR_config, process, - sample_paths, + sample_paths.switch_embedding_state(DR_SR_config.get("use_embedding", config.get("use_embedding", False))), save_path, f"ff_corrections.{process}", evaluator, @@ -649,8 +665,8 @@ def run_correction( test_config = corr_config["target_processes"][proc].get("DR_SR", {}) is_valid_cache = all( - func.nested_object_comparison(__test_config[k], test_config[k]) - for k in ("SRlike_cuts", "ARlike_cuts", "AR_SR_cuts") + func.nested_object_comparison(__test_config.get(k), test_config.get(k)) + for k in ("SRlike_cuts", "ARlike_cuts", "AR_SR_cuts", "use_embedding", "compute_different_set_of_fake_factors_using_data") ) else: is_valid_cache = False @@ -685,6 +701,7 @@ def run_correction( fractions_subleading=None, output_path=save_path, for_corrections=True, + variation_scheme={process: {"unc_up": "FFuncUp", "unc_down": "FFuncDown"} for process in corr_config["target_processes"]}, ) with open(cached_DR_SR_ffs, "wb") as f: diff --git a/helper/correctionlib_json.py b/helper/correctionlib_json.py index c0ed7d3..e7ac9b5 100644 --- a/helper/correctionlib_json.py +++ b/helper/correctionlib_json.py @@ -115,6 +115,7 @@ def generate_ff_corrlib_json( fractions_subleading: Union[Dict[str, Dict[str, Dict[str, List[float]]]], None], output_path: Union[str, None] = None, for_corrections: bool = False, + variation_scheme: Union[Dict[str, Dict[str, str]], None] = None, ) -> cs.CorrectionSet: """ Function which produces a correctionlib file based on the measured fake factors and fractions (including variations). @@ -126,6 +127,7 @@ def generate_ff_corrlib_json( fractions_subleading: Second dictionary of fraction values, e.g. fractions[CATEGORY][VARIATION][PROCESS] (can be relvant for tt channel) output_path: Path where the generated correctionlib files should be stored for_corrections: Boolean which decides where the produced correctionlib file is stored, this is needed because additional fake factors are needed to calculate some corrections and therefore they are stored in a different place (default: False) + variation_scheme: Process dictionary containing key: variation type combinaitons if provided. If none is provided gd.ff_variation_dict[process] definition is used. Passed to make_2D_ff and make_1D_ff Return: None @@ -144,6 +146,7 @@ def generate_ff_corrlib_json( process_conf=proc_conf, variable_info=(var, binning), ff_functions=ff_functions[process], + variation_scheme=variation_scheme, ) elif len(proc_conf["split_categories"]) == 2: process_ff = make_2D_ff( @@ -151,6 +154,7 @@ def generate_ff_corrlib_json( process_conf=proc_conf, variable_info=(var, binning), ff_functions=ff_functions[process], + variation_scheme=variation_scheme, ) corrlib_corrections.append(process_ff) @@ -210,6 +214,7 @@ def make_1D_ff( process_conf: Dict[str, Union[Dict, List, str]], variable_info: Tuple[str, List[float]], ff_functions: Dict[str, Dict[str, str]], + variation_scheme: Union[Dict[str, Dict[str, str]], None] = None, ) -> cs.Correction: """ Function which produces a correctionlib Correction based on the measured fake factors (including variations) for the case of 1D categories. @@ -219,6 +224,7 @@ def make_1D_ff( process_conf: A dictionary with all the relevant information for the fake factors of a specific "process" variable_info: Tuple with information (name and binning) about the variable the fake factors depends on ff_functions: Dictionary of fake factor functions as strings, e.g. ff_function[PROCESS][CATEGORY_1][VARIATION] + variation_scheme: Process dictionary containing key: variation type combinaitons if provided. If none is provided gd.ff_variation_dict[process] definition is used Return: Correction object from correcionlib @@ -226,6 +232,7 @@ def make_1D_ff( # get categories from config cat_inputs = list(process_conf["split_categories"].keys()) cat_values = [process_conf["split_categories"][cat] for cat in process_conf["split_categories"]] + variation_scheme = variation_scheme or gd.ff_variation_dict ff = cs.Correction( name=f"{process}_fake_factors", @@ -283,7 +290,7 @@ def make_1D_ff( flow="clamp", ), ) - for unc, unc_name in gd.ff_variation_dict[process].items() + for unc, unc_name in variation_scheme[process].items() ], default=cs.Binning( nodetype="binning", @@ -316,6 +323,7 @@ def make_2D_ff( process_conf: Dict[str, Union[Dict, List, str]], variable_info: Tuple[str, List[float]], ff_functions: Dict[str, Dict[str, Dict[str, str]]], + variation_scheme: Union[Dict[str, Dict[str, str]], None] = None, ) -> cs.Correction: """ Function which produces a correctionlib Correction based on the measured fake factors (including variations) for the case of 2D categories. @@ -325,6 +333,7 @@ def make_2D_ff( process_conf: A dictionary with all the relevant information for the fake factors of a specific "process" variable_info: Tuple with information (name and binning) about the variable the fake factors depends on ff_functions: Dictionary of fake factor functions as strings, e.g. ff_function[PROCESS][CATEGORY_1][CATEGORY_2][VARIATION] + variation_scheme: Process dictionary containing key: variation type combinaitons if provided. If none is provided gd.ff_variation_dict[process] definition is used Return: Correction object from correcionlib @@ -333,6 +342,7 @@ def make_2D_ff( cat_inputs = list(process_conf["split_categories"].keys()) cat_values_conf = process_conf["split_categories"] binedges_conf = process_conf["split_categories_binedges"] + variation_scheme = variation_scheme or gd.ff_variation_dict cat2_values_for_desc = [] cat2_conf = cat_values_conf[cat_inputs[1]] if isinstance(cat2_conf, dict): # New format @@ -416,7 +426,7 @@ def make_2D_ff( flow="clamp", ), ) - for unc, unc_name in gd.ff_variation_dict[process].items() + for unc, unc_name in variation_scheme[process].items() ], default=cs.Binning( nodetype="binning", diff --git a/helper/ff_functions.py b/helper/ff_functions.py index 4112ca8..2582d47 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -97,9 +97,70 @@ def wrapper(*args: Any, **kwargs: Any) -> ROOT.RDataFrame: log.warning("Filter resulted in zero events. Creating an empty snapshot with the correct schema.") f = ROOT.TFile(cache_filepath, "RECREATE") tree = ROOT.TTree(tree_name, tree_name) + _refs = [] # Keep references in memory to prevent GC during branch assignment for c in cols: - arr = ROOT.std.vector("float")() - tree.Branch(c, arr) + col_type = str(filtered_rdf.GetColumnType(c)).replace("ROOT::VecOps::RVec", "std::vector") + + if col_type.startswith("std::vector"): + inner = col_type[col_type.find("<") + 1: col_type.rfind(">")] + try: + vec = ROOT.std.vector(inner)() + except Exception: + vec = ROOT.std.vector("float")() + tree.Branch(c, vec) + _refs.append(vec) + elif "string" in col_type: + s = ROOT.std.string() + tree.Branch(c, s) + _refs.append(s) + elif "Double" in col_type or "double" in col_type: + arr = array.array("d", [0.0]) + tree.Branch(c, arr, f"{c}/D") + _refs.append(arr) + elif "Float" in col_type or "float" in col_type: + arr = array.array("f", [0.0]) + tree.Branch(c, arr, f"{c}/F") + _refs.append(arr) + elif "ULong" in col_type or "unsigned long" in col_type: + arr = array.array("Q", [0]) + tree.Branch(c, arr, f"{c}/l") + _refs.append(arr) + elif "Long" in col_type or "long" in col_type: + arr = array.array("q", [0]) + tree.Branch(c, arr, f"{c}/L") + _refs.append(arr) + elif "UInt" in col_type or "unsigned int" in col_type: + arr = array.array("I", [0]) + tree.Branch(c, arr, f"{c}/i") + _refs.append(arr) + elif "Int" in col_type or "int" in col_type: + arr = array.array("i", [0]) + tree.Branch(c, arr, f"{c}/I") + _refs.append(arr) + elif "UShort" in col_type or "unsigned short" in col_type: + arr = array.array("H", [0]) + tree.Branch(c, arr, f"{c}/s") + _refs.append(arr) + elif "Short" in col_type or "short" in col_type: + arr = array.array("h", [0]) + tree.Branch(c, arr, f"{c}/S") + _refs.append(arr) + elif "UChar" in col_type or "unsigned char" in col_type: + arr = array.array("B", [0]) + tree.Branch(c, arr, f"{c}/b") + _refs.append(arr) + elif "Char" in col_type or "char" in col_type: + arr = array.array("b", [0]) + tree.Branch(c, arr, f"{c}/B") + _refs.append(arr) + elif "Bool" in col_type or "bool" in col_type: + arr = array.array("b", [0]) + tree.Branch(c, arr, f"{c}/O") + _refs.append(arr) + else: + arr = array.array("f", [0.0]) + tree.Branch(c, arr, f"{c}/F") + _refs.append(arr) tree.Write() f.Close() else: @@ -622,19 +683,20 @@ def rng_seed(seed: int) -> Generator[None, None, None]: def controlplot_samples( - use_embedding: bool, + sample_paths: List[str], add_qcd: bool = True, ) -> List[str]: """ Returns the list of samples that should be used for the control plots. Args: - use_embedding: Boolean to use embedding or MC for genuine tau processes + sample_paths: List of sample paths to dynamically determine if embedding is used add_qcd: Add QCD samples to the collection of samples to be plotted. Returns: List of samples used for controlplots """ + use_embedding = any("embedding" == p.rsplit("/")[-1].rsplit(".")[0] for p in sample_paths) samples = [ "diboson_J", "diboson_L", @@ -1745,7 +1807,7 @@ def flatten_categories(node, current_path=""): row.append("1.0") elif "p_value" not in node: if np.all(np.array(node["nominal"]) == 1.0): - row.append("Skip") + row.append("-") else: row.append("Binwise") else: @@ -1762,7 +1824,7 @@ def flatten_categories(node, current_path=""): pval = node['p_value'] row.append(f"{pval:.3f}") else: - row.append("—") + row.append("-") table.add_row(*row) diff --git a/helper/functions.py b/helper/functions.py index b4f04ea..cb746ed 100644 --- a/helper/functions.py +++ b/helper/functions.py @@ -285,6 +285,7 @@ def correction_config_comparison( is_same &= nested_object_comparison(_test_config["SRlike_cuts"], _config["SRlike_cuts"]) is_same &= nested_object_comparison(_test_config["ARlike_cuts"], _config["ARlike_cuts"]) + is_same &= nested_object_comparison(_test_config.get("use_embedding"), _config.get("use_embedding")) _test_config = _test_config["non_closure"][closure_corr] _config = _config["non_closure"][closure_corr] @@ -682,6 +683,35 @@ def define_columns(rdf: Any, column_definitions: dict, process: str) -> Any: return rdf +class SamplePathList(list): + """ + A list-like object holding sample paths that can safely toggle between + embedding and MC-only states while preserving the full unmodified list in memory. + """ + def __init__(self, all_paths: List[str], use_embedding: bool): + self.all_paths = all_paths + self.is_embedded = use_embedding + + filtered_paths = [] + for f in all_paths: + sample = f.rsplit("/")[-1].rsplit(".")[0] + if use_embedding and "_T" in sample: + continue + elif not use_embedding and sample == "embedding": + continue + filtered_paths.append(f) + + super().__init__(filtered_paths) + + def switch_embedding_state(self, use_embedding: bool) -> 'SamplePathList': + if use_embedding == self.is_embedded: + return self + return SamplePathList(self.all_paths, use_embedding) + + def __reduce__(self): + return (self.__class__, (self.all_paths, self.is_embedded)) + + def get_samples(config: Dict[str, Union[str, Dict, List]]) -> List[str]: """ Function to get a list of all sample paths which will be used for the fake factor calculation. @@ -703,15 +733,7 @@ def get_samples(config: Dict[str, Union[str, Dict, List]]) -> List[str]: f"The following files are loaded for era: {config['era']}, channel: {config['channel']} from {general_sample_path}" ) log.info("-" * 50) - sample_paths = glob.glob(general_sample_path) - tmp_list = glob.glob(general_sample_path) - - for f in tmp_list: - sample = f.rsplit("/")[-1].rsplit(".")[0] - if config["use_embedding"] and "_T" in sample: - sample_paths.remove(f) - elif not config["use_embedding"] and sample == "embedding": - sample_paths.remove(f) + sample_paths = SamplePathList(glob.glob(general_sample_path), config.get("use_embedding", False)) for f in sample_paths: log.info(f) diff --git a/helper/hooks_and_patches.py b/helper/hooks_and_patches.py index 126c4cc..4f273d2 100644 --- a/helper/hooks_and_patches.py +++ b/helper/hooks_and_patches.py @@ -39,7 +39,7 @@ def __getattribute__(self, name: str) -> Any: Returns: Attribute value. """ - try: # Try to get the attribute from this instance or subclass. + try: # Try to get the attribute from this instance or subclass. return object.__getattribute__(self, name) except AttributeError: # Fallback: delegate to the wrapped object. _obj = object.__getattribute__(self, "_obj") @@ -69,7 +69,7 @@ def __delattr__(self, name: str) -> None: class Histo1DPatchedRDataFrame(PassThroughWrapper): """ - A wrapper around ROOT.RDataFrame patching Histo1D method adding extra attributes + A wrapper around ROOT.RDataFrame patching Histo1D method adding extra attributes (weighted counts and weighted means) to the produced histograms. """ From 1da198f7bace7b566204a754b8b3ead09b4fda53 Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Thu, 12 Mar 2026 16:43:16 +0100 Subject: [PATCH 07/20] adding updated smhtt_ul 2018 config --- adjust_binning.py | 2 +- configs/smhtt_ul/2018/corrections_mt.yaml | 286 ++++++++++++--------- configs/smhtt_ul/2018/fake_factors_mt.yaml | 52 ++-- 3 files changed, 189 insertions(+), 151 deletions(-) diff --git a/adjust_binning.py b/adjust_binning.py index 6f82f40..6e887e9 100644 --- a/adjust_binning.py +++ b/adjust_binning.py @@ -76,7 +76,7 @@ def _equipopulated_binned_variable( return np.quantile( a=item, q=np.linspace(0, 1, n_bins + 1), - weights=weights, + weights=abs(weights) if weights is not None else None, method="linear" if weights is None else "inverted_cdf", ) diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml b/configs/smhtt_ul/2018/corrections_mt.yaml index 8a1f88c..d42c851 100644 --- a/configs/smhtt_ul/2018/corrections_mt.yaml +++ b/configs/smhtt_ul/2018/corrections_mt.yaml @@ -139,6 +139,16 @@ templates: rounding: 2 correction_option: "smoothed" bandwidth: 25 + mt_1: &mt_1 + var_dependence: mt_1 + equipopulated_binning_options: &mt_1__eq_bin_opt + variable_config: + mt_1: + min: 0.0 + max: 70.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 20 pt_tt: &pt_tt var_dependence: pt_tt equipopulated_binning_options: &pt_tt__eq_bin_opt @@ -234,7 +244,7 @@ templates: channel: mt target_processes: QCD: - chain_DR_SR_to_non_closure: false + chain_DR_SR_to_non_closure: true non_closure: tau_decaymode_2: @@ -246,9 +256,9 @@ target_processes: <<: [*eta_1__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [0.8, 1.0, 1.0] var_bins: - "==0": [-2.1, -1.56, -1.26, -0.86, -0.49, -0.14, 0.22, 0.56, 0.93, 1.3, 1.63, 2.1] - "==1": [-2.1, -1.51, -1.14, -0.65, -0.22, 0.22, 0.7, 1.15, 1.55, 2.1] - ">=2": [-2.1, -1.38, -0.85, -0.34, 0.21, 0.81, 1.38, 2.1] + "==0": [-2.1, -1.56, -1.26, -0.86, -0.5, -0.14, 0.22, 0.56, 0.93, 1.3, 1.63, 2.1] + "==1": [-2.1, -1.51, -1.13, -0.66, -0.22, 0.22, 0.7, 1.15, 1.54, 2.1] + ">=2": [-2.1, -1.37, -0.82, -0.33, 0.23, 0.81, 1.37, 2.1] eta_2: <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -256,8 +266,8 @@ target_processes: bandwidth: [0.9, 1.1, 1.5] var_bins: "==0": [-2.5, -1.68, -1.28, -0.92, -0.57, -0.18, 0.24, 0.62, 0.99, 1.31, 1.78, 2.5] - "==1": [-2.5, -1.68, -1.2, -0.74, -0.27, 0.28, 0.73, 1.18, 1.59, 2.5] - ">=2": [-2.5, -1.43, -0.88, -0.23, 0.4, 0.96, 1.57, 2.5] + "==1": [-2.5, -1.67, -1.19, -0.73, -0.25, 0.28, 0.72, 1.17, 1.59, 2.5] + ">=2": [-2.5, -1.41, -0.87, -0.21, 0.4, 0.94, 1.55, 2.5] jeta_1: <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -267,8 +277,8 @@ target_processes: bandwidth: [1.0, 2.5, 2.5] var_bins: "==0": [-5.0, 5.0] - "==1": [-5.0, -2.77, -1.64, -0.93, -0.29, 0.34, 0.89, 1.65, 2.61, 5.0] - ">=2": [-5.0, -2.02, -1.03, -0.32, 0.3, 0.98, 1.94, 5.0] + "==1": [-5.0, -2.73, -1.63, -0.92, -0.28, 0.34, 0.92, 1.65, 2.61, 5.0] + ">=2": [-5.0, -2.02, -1.07, -0.33, 0.31, 0.99, 1.98, 5.0] jeta_2: <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -279,7 +289,7 @@ target_processes: var_bins: "==0": [-5.0, 5.0] "==1": [-5.0, 5.0] - ">=2": [-5.0, -2.1, -1.18, -0.36, 0.32, 1.14, 2.21, 5.0] + ">=2": [-5.0, -2.1, -1.13, -0.36, 0.33, 1.16, 2.2, 5.0] jpt_1: <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -288,8 +298,8 @@ target_processes: bandwidth: [1.0, 50.0, 60.0] var_bins: "==0": [30.0, 150.0] - "==1": [30.0, 31.83, 33.84, 36.34, 39.88, 44.28, 50.31, 59.16, 150.0] - ">=2": [30.0, 42.0, 50.56, 59.31, 70.81, 85.38, 150.0] + "==1": [30.0, 31.86, 34.0, 36.75, 40.41, 45.06, 51.5, 61.09, 78.06, 150.0] + ">=2": [30.0, 42.38, 51.03, 59.81, 71.12, 86.0, 110.12, 150.0] jpt_2: <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -299,34 +309,43 @@ target_processes: var_bins: "==0": [30.0, 150.0] "==1": [30.0, 150.0] - ">=2": [30.0, 32.28, 35.5, 39.41, 44.91, 53.94, 150.0] + ">=2": [30.0, 32.44, 35.62, 39.5, 45.22, 54.28, 70.0, 150.0] met: <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*met__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [25.0, 45.0, 60.0] var_bins: - "==0": [0.0, 8.44, 12.18, 15.48, 18.65, 21.82, 25.23, 29.13, 33.78, 39.65, 49.01, 150.0] - "==1": [0.0, 10.83, 15.93, 20.3, 25.3, 30.94, 37.39, 46.41, 60.91, 150.0] - ">=2": [0.0, 15.65, 23.57, 32.4, 41.67, 53.44, 73.99, 150.0] + "==0": [0.0, 8.43, 12.17, 15.46, 18.63, 21.79, 25.19, 29.1, 33.7, 39.62, 48.82, 150.0] + "==1": [0.0, 10.72, 15.73, 20.25, 25.21, 30.93, 37.27, 46.11, 60.71, 150.0] + ">=2": [0.0, 15.22, 23.13, 32.17, 41.67, 53.45, 74.36, 150.0] + pt_tt: + <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_tt__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [25.0, 35.0, 50.0] + var_bins: + "==0": [0.0, 7.38, 10.89, 13.94, 16.75, 19.51, 22.79, 26.2, 30.58, 36.0, 44.1, 150.0] + "==1": [0.0, 20.06, 28.4, 35.9, 42.23, 49.73, 57.79, 68.77, 85.18, 150.0] + ">=2": [0.0, 27.36, 44.71, 60.61, 75.95, 91.15, 112.19, 150.0] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaEta_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [1.25, 1.5, 2.0] var_bins: - "==0": [-4.9, -2.13, -1.43, -0.94, -0.54, -0.18, 0.16, 0.56, 0.96, 1.44, 2.08, 4.9] - "==1": [-4.9, -2.03, -1.31, -0.69, -0.24, 0.28, 0.77, 1.34, 2.08, 4.9] - ">=2": [-4.9, -1.95, -1.15, -0.47, 0.29, 0.99, 1.83, 4.9] + "==0": [-4.9, -2.13, -1.42, -0.93, -0.53, -0.18, 0.16, 0.56, 0.96, 1.43, 2.08, 4.9] + "==1": [-4.9, -2.0, -1.23, -0.65, -0.23, 0.25, 0.72, 1.28, 2.04, 4.9] + ">=2": [-4.9, -1.9, -1.03, -0.39, 0.26, 0.87, 1.76, 4.9] deltaR_ditaupair: <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [0.8, 1.1, 1.2] var_bins: - "==0": [0.5, 2.6888, 2.8726, 2.98, 3.0543, 3.1115, 3.1707, 3.2617, 3.388, 3.5757, 3.919, 5.0] - "==1": [0.5, 1.942, 2.3564, 2.5984, 2.782, 2.9473, 3.0925, 3.2939, 3.6937, 5.0] - ">=2": [0.5, 1.6602, 2.1007, 2.5053, 2.8475, 3.1032, 3.4388, 5.0] + "==0": [0.5, 2.6814, 2.869, 2.9787, 3.0526, 3.1104, 3.1696, 3.2609, 3.3865, 3.5747, 3.9186, 5.0] + "==1": [0.5, 1.653, 2.227, 2.5243, 2.7304, 2.9125, 3.0715, 3.2696, 3.6723, 5.0] + ">=2": [0.5, 1.3291, 1.9185, 2.3753, 2.7661, 3.0644, 3.4088, 5.0] deltaR_1j1: <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -334,8 +353,8 @@ target_processes: correction_option: ["skip", "smoothed", "smoothed"] var_bins: "==0": [0.5, 7.0] - "==1": [0.5, 1.632, 2.174, 2.464, 2.74, 3.001, 3.217, 3.578, 4.264, 7.0] - ">=2": [0.5, 1.772, 2.358, 2.733, 2.991, 3.241, 3.738, 7.0] + "==1": [0.5, 1.67, 2.205, 2.51, 2.774, 3.019, 3.235, 3.586, 4.235, 7.0] + ">=2": [0.5, 1.825, 2.382, 2.761, 3.009, 3.272, 3.759, 7.0] deltaR_12j1: <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -344,8 +363,8 @@ target_processes: bandwidth: [1.0, 1.5, 1.5] var_bins: "==0": [0.0, 10.0] - "==1": [0.0, 2.25, 2.71, 2.94, 3.1, 3.27, 3.55, 4.0, 4.91, 10.0] - ">=2": [0.0, 2.22, 2.7, 2.94, 3.13, 3.43, 4.07, 10.0] + "==1": [0.0, 2.28, 2.73, 2.96, 3.11, 3.27, 3.55, 3.98, 4.87, 10.0] + ">=2": [0.0, 2.26, 2.72, 2.95, 3.14, 3.46, 4.06, 10.0] pt_ttjj: <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -355,25 +374,25 @@ target_processes: var_bins: "==0": [0.0, 150.0] "==1": [0.0, 150.0] - ">=2": [0.0, 15.8, 22.78, 30.11, 38.03, 49.21, 69.47, 150.0] + ">=2": [0.0, 15.52, 22.28, 30.06, 38.0, 49.31, 69.77, 150.0] mass_2: <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mass_2__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [0.25, 0.35, 0.4] var_bins: - "==0": [0.0, 0.2, 0.5107, 0.6216, 0.7388, 0.835, 0.9131, 0.9941, 1.0732, 1.1553, 1.25, 1.3613, 2.0] - "==1": [0.0, 0.2, 0.5322, 0.665, 0.79, 0.8979, 1.0088, 1.0967, 1.1992, 1.3262, 2.0] - ">=2": [0.0, 0.2, 0.5586, 0.7266, 0.8647, 0.9917, 1.1104, 1.2715, 2.0] + "==0": [0.0, 0.2, 0.5107, 0.6216, 0.7388, 0.835, 0.9121, 0.9941, 1.0732, 1.1543, 1.25, 1.3623, 2.0] + "==1": [0.0, 0.2, 0.5322, 0.665, 0.79, 0.896, 1.0088, 1.0957, 1.1982, 1.3271, 2.0] + ">=2": [0.0, 0.2, 0.564, 0.7314, 0.8735, 0.9932, 1.1123, 1.2715, 2.0] mt_tot: <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_tot__eq_bin_opt, *QCD_var_dependence_n_bins] bandwidth: [25, 50, 60] var_bins: - "==0": [50.0, 72.47, 77.61, 81.9, 85.85, 89.88, 94.29, 99.29, 105.32, 113.72, 130.11, 250.0] - "==1": [0.0, 64.61, 74.79, 82.4, 89.35, 97.26, 104.71, 115.38, 133.78, 250.0] - ">=2": [0.0, 60.36, 75.94, 87.15, 99.78, 113.99, 141.39, 250.0] + "==0": [50.0, 72.17, 77.52, 81.84, 85.76, 89.79, 94.23, 99.24, 105.25, 113.61, 130.06, 250.0] + "==1": [0.0, 59.33, 72.18, 80.25, 87.75, 95.78, 103.33, 114.05, 132.26, 250.0] + ">=2": [0.0, 53.08, 71.56, 83.98, 96.25, 111.26, 137.98, 250.0] m_vis: <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -395,45 +414,49 @@ target_processes: bandwidth: [0.04, 0.04, 0.04] correction_option: "smoothed" var_bins: - "==0": [0.05, 0.05689, 0.063581, 0.070489, 0.07823, 0.086695, 0.095464, 0.10584, 0.115682, 0.126434, 0.137512, 0.15] - "==1": [0.05, 0.057221, 0.065234, 0.074146, 0.083714, 0.096804, 0.108508, 0.122276, 0.134837, 0.15] - ">=2": [0.05, 0.059209, 0.068444, 0.080423, 0.09482, 0.110154, 0.128044, 0.15] + "==0": [0.05, 0.056882, 0.063543, 0.070468, 0.078181, 0.086647, 0.095377, 0.105744, 0.115638, 0.126327, 0.137486, 0.15] + "==1": [0.05, 0.057096, 0.065105, 0.073987, 0.083517, 0.096737, 0.108642, 0.122276, 0.13489, 0.15] + ">=2": [0.05, 0.059351, 0.068657, 0.081325, 0.096132, 0.110882, 0.128247, 0.15] DR_SR: - <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] + use_embedding: false + compute_different_set_of_fake_factors: true + compute_different_set_of_fake_factors_using_data: true + <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: - <<: [*pt_tt__eq_bin_opt, *QCD_var_dependence_n_bins] + <<: [*mt_1__eq_bin_opt, *QCD_var_dependence_n_bins] var_dependence_n_bins: "==0": 9 "==1": 7 ">=2": 5 + variable_config: + mt_1: + min: 0.0 + max: 50.0 + rounding: 2 bandwidth: [25.0, 40.0, 40.0] var_bins: - "==0": [0.0, 8.27, 12.39, 16.19, 19.88, 23.87, 28.55, 34.3, 43.56, 150.0] - "==1": [0.0, 24.76, 35.61, 45.11, 54.28, 66.31, 85.0, 150.0] - ">=2": [0.0, 36.33, 59.77, 80.39, 105.5, 150.0] + "==0": [0.0, 3.07, 6.12, 9.59, 13.53, 17.81, 23.01, 29.07, 37.62, 50.0] + "==1": [0.0, 4.49, 9.31, 15.38, 21.65, 29.06, 38.65, 50.0] + ">=2": [0.0, 6.97, 14.92, 24.8, 36.54, 50.0] SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! lep_mt: (mt_1 < 50) nbtag: (nbtag >= 0) tau_pair_sign: ((q_1*q_2) > 0) - lep_iso: "(!((iso_1 >= 0.05) && (iso_1 <= 0.15)))" + lep_iso: "(iso_1 > 0.15)" ARlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! lep_mt: (mt_1 < 50) nbtag: (nbtag >= 0) tau_pair_sign: ((q_1*q_2) > 0) - lep_iso: "(!((iso_1 >= 0.05) && (iso_1 <= 0.15)))" + lep_iso: "(iso_1 > 0.15)" AR_SR_cuts: lep_mt: (mt_1 < 50) nbtag: (nbtag >= 0) tau_pair_sign: ((q_1*q_2) < 0) - lep_iso: "(!((iso_1 >= 0.05) && (iso_1 <= 0.15)))" - non_closure: - nbtag: - <<: [*nbtag, *3j_split] - correction_variations: ["Stat1Sigma", "SystMCShift"] + lep_iso: "(iso_1 > 0.15)" Wjets: - chain_DR_SR_to_non_closure: false + chain_DR_SR_to_non_closure: true non_closure: tau_decaymode_2: @@ -449,18 +472,18 @@ target_processes: ">=2": 5 bandwidth: [0.65, 0.85, 1.25] var_bins: - "==0": [-2.1, -1.73, -1.43, -1.15, -0.88, -0.62, -0.38, -0.12, 0.12, 0.38, 0.63, 0.89, 1.17, 1.45, 1.75, 2.1] - "==1": [-2.1, -1.61, -1.22, -0.85, -0.5, -0.13, 0.19, 0.55, 0.89, 1.25, 1.64, 2.1] - ">=2": [-2.1, -1.1, -0.34, 0.39, 1.15, 2.1] + "==0": [-2.1, -1.73, -1.43, -1.15, -0.88, -0.62, -0.38, -0.12, 0.12, 0.38, 0.64, 0.89, 1.16, 1.45, 1.75, 2.1] + "==1": [-2.1, -1.61, -1.22, -0.85, -0.49, -0.13, 0.2, 0.55, 0.89, 1.25, 1.64, 2.1] + ">=2": [-2.1, -1.1, -0.33, 0.39, 1.16, 2.1] eta_2: <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*eta_2__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.6, 0.9, 1.2] var_bins: - "==0": [-2.5, -1.65, -1.28, -1.02, -0.78, -0.55, -0.32, -0.09, 0.15, 0.37, 0.58, 0.81, 1.03, 1.29, 1.67, 2.5] - "==1": [-2.5, -1.53, -1.12, -0.78, -0.43, -0.11, 0.21, 0.5, 0.81, 1.13, 1.55, 2.5] - ">=2": [-2.5, -1.42, -0.95, -0.55, -0.15, 0.25, 0.62, 1.0, 1.42, 2.5] + "==0": [-2.5, -1.64, -1.28, -1.03, -0.78, -0.55, -0.32, -0.09, 0.15, 0.37, 0.58, 0.81, 1.03, 1.29, 1.67, 2.5] + "==1": [-2.5, -1.52, -1.12, -0.78, -0.43, -0.11, 0.22, 0.51, 0.82, 1.14, 1.55, 2.5] + ">=2": [-2.5, -1.41, -0.95, -0.55, -0.14, 0.25, 0.63, 1.0, 1.43, 2.5] jeta_1: <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -470,8 +493,8 @@ target_processes: bandwidth: [1.0, 2.0, 2.0] var_bins: "==0": [-5.0, 5.0] - "==1": [-5.0, -2.72, -1.69, -0.94, -0.31, 0.33, 0.99, 1.77, 2.77, 5.0] - ">=2": [-5.0, -2.03, -1.07, -0.36, 0.34, 1.08, 2.06, 5.0] + "==1": [-5.0, -2.71, -1.69, -0.94, -0.3, 0.34, 1.0, 1.77, 2.77, 5.0] + ">=2": [-5.0, -2.03, -1.07, -0.35, 0.35, 1.08, 2.07, 5.0] jeta_2: <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -482,7 +505,7 @@ target_processes: var_bins: "==0": [-5.0, 5.0] "==1": [-5.0, 5.0] - ">=2": [-5.0, -2.34, -1.21, -0.34, 0.39, 1.21, 2.28, 5.0] + ">=2": [-5.0, -2.35, -1.22, -0.36, 0.39, 1.2, 2.28, 5.0] jpt_1: <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -491,8 +514,8 @@ target_processes: bandwidth: [1.0, 40.0, 55.0] var_bins: "==0": [30.0, 150.0] - "==1": [30.0, 31.75, 33.75, 36.06, 38.94, 42.59, 47.06, 52.75, 60.12, 70.56, 150.0] - ">=2": [30.0, 40.94, 48.16, 55.28, 63.16, 72.0, 82.88, 97.31, 150.0] + "==1": [30.0, 31.75, 33.75, 36.06, 38.91, 42.56, 46.97, 52.62, 59.94, 70.38, 89.44, 150.0] + ">=2": [30.0, 40.97, 48.16, 55.28, 63.12, 71.88, 82.69, 97.0, 117.88, 150.0] jpt_2: <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -502,34 +525,43 @@ target_processes: var_bins: "==0": [30.0, 150.0] "==1": [30.0, 150.0] - ">=2": [30.0, 32.0, 34.5, 37.25, 41.06, 46.03, 52.94, 62.47, 150.0] + ">=2": [30.0, 31.98, 34.44, 37.22, 41.0, 45.97, 52.78, 62.31, 79.88, 150.0] met: <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*met__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [20.0, 30.0, 60.0] var_bins: - "==0": [0.0, 26.08, 30.86, 34.72, 38.15, 41.34, 44.55, 47.71, 50.93, 54.36, 58.02, 62.26, 67.2, 73.68, 83.91, 150.0] - "==1": [0.0, 30.24, 36.69, 42.02, 46.59, 51.47, 56.55, 62.11, 69.15, 78.23, 93.44, 150.0] - ">=2": [0.0, 33.94, 42.91, 50.5, 57.96, 66.32, 76.13, 88.78, 107.65, 150.0] + "==0": [0.0, 26.44, 31.34, 35.35, 38.85, 42.17, 45.53, 48.76, 52.09, 55.59, 59.33, 63.57, 68.59, 74.89, 84.82, 150.0] + "==1": [0.0, 30.65, 37.18, 42.51, 47.1, 51.9, 56.98, 62.52, 69.52, 78.66, 93.41, 150.0] + ">=2": [0.0, 34.19, 43.15, 50.77, 58.13, 66.48, 76.11, 88.39, 107.4, 150.0] + pt_tt: + <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_tt__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [25.0, 35.0, 50.0] + var_bins: + "==0": [0.0, 6.97, 10.21, 12.86, 15.37, 17.8, 20.33, 22.96, 25.8, 28.95, 32.51, 36.56, 41.44, 47.79, 57.64, 150.0] + "==1": [0.0, 20.67, 28.94, 35.54, 41.79, 48.14, 54.45, 61.69, 70.13, 81.43, 99.35, 150.0] + ">=2": [0.0, 28.71, 41.98, 53.14, 64.21, 75.14, 87.86, 102.82, 121.49, 150.0] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaEta_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.8, 1.1, 1.25] var_bins: - "==0": [-4.9, -1.94, -1.41, -1.07, -0.79, -0.55, -0.32, -0.11, 0.09, 0.31, 0.53, 0.77, 1.04, 1.39, 1.91, 4.9] - "==1": [-4.9, -1.79, -1.21, -0.8, -0.45, -0.15, 0.14, 0.45, 0.79, 1.19, 1.78, 4.9] - ">=2": [-4.9, -1.6, -1.0, -0.56, -0.16, 0.2, 0.56, 0.98, 1.58, 4.9] + "==0": [-4.9, -1.9, -1.36, -1.02, -0.75, -0.52, -0.31, -0.11, 0.09, 0.3, 0.51, 0.74, 1.0, 1.34, 1.87, 4.9] + "==1": [-4.9, -1.75, -1.16, -0.75, -0.43, -0.14, 0.14, 0.43, 0.74, 1.14, 1.74, 4.9] + ">=2": [-4.9, -1.56, -0.96, -0.53, -0.16, 0.19, 0.54, 0.95, 1.54, 4.9] deltaR_ditaupair: <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.5, 0.6, 0.7] var_bins: - "==0": [0.5, 1.5899, 1.8712, 2.0958, 2.2841, 2.4445, 2.5916, 2.7159, 2.8263, 2.9219, 3.0057, 3.0797, 3.1417, 3.2459, 3.4663, 5.0] - "==1": [0.5, 1.4292, 1.7591, 2.0364, 2.2665, 2.4768, 2.6654, 2.8359, 2.9873, 3.1187, 3.3378, 5.0] - ">=2": [0.5, 1.3299, 1.705, 2.0138, 2.289, 2.5419, 2.7705, 2.9859, 3.2134, 5.0] + "==0": [0.5, 1.291, 1.6664, 1.9482, 2.1706, 2.3528, 2.5196, 2.6606, 2.783, 2.8902, 2.9821, 3.0643, 3.1321, 3.2287, 3.4481, 5.0] + "==1": [0.5, 1.1946, 1.5966, 1.9154, 2.1746, 2.4058, 2.6139, 2.801, 2.9638, 3.1049, 3.3191, 5.0] + ">=2": [0.5, 1.1567, 1.5816, 1.9338, 2.2206, 2.4933, 2.7366, 2.9631, 3.1951, 5.0] deltaR_1j1: <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -538,8 +570,8 @@ target_processes: bandwidth: [1.0, 1.0, 1.2] var_bins: "==0": [0.5, 7.0] - "==1": [0.5, 1.237, 1.659, 1.993, 2.281, 2.545, 2.794, 3.024, 3.273, 3.685, 4.346, 7.0] - ">=2": [0.5, 1.226, 1.705, 2.102, 2.427, 2.71, 2.968, 3.252, 3.832, 7.0] + "==1": [0.5, 1.257, 1.688, 2.026, 2.312, 2.572, 2.811, 3.037, 3.282, 3.69, 4.342, 7.0] + ">=2": [0.5, 1.242, 1.733, 2.12, 2.446, 2.72, 2.978, 3.261, 3.842, 7.0] deltaR_12j1: <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -548,8 +580,8 @@ target_processes: bandwidth: [1.0, 1.5, 1.75] var_bins: "==0": [0.0, 10.0] - "==1": [0.0, 1.76, 2.25, 2.54, 2.76, 2.94, 3.1, 3.3, 3.59, 4.04, 4.85, 10.0] - ">=2": [0.0, 1.78, 2.28, 2.61, 2.85, 3.05, 3.23, 3.57, 4.22, 10.0] + "==1": [0.0, 1.78, 2.26, 2.55, 2.77, 2.94, 3.1, 3.29, 3.58, 4.02, 4.82, 10.0] + ">=2": [0.0, 1.78, 2.28, 2.61, 2.84, 3.04, 3.23, 3.57, 4.21, 10.0] pt_ttjj: <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -559,25 +591,25 @@ target_processes: var_bins: "==0": [0.0, 150.0] "==1": [0.0, 150.0] - ">=2": [0.0, 13.21, 19.9, 25.84, 31.84, 38.72, 46.93, 58.04, 75.39, 150.0] + ">=2": [0.0, 13.13, 19.85, 25.75, 31.71, 38.56, 46.7, 57.79, 75.16, 150.0] mass_2: <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mass_2__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.225, 0.225, 0.25] var_bins: - "==0": [0.0, 0.2, 0.4827, 0.5654, 0.6406, 0.708, 0.769, 0.8291, 0.8867, 0.9468, 1.0088, 1.0723, 1.1387, 1.2119, 1.2949, 1.4102, 2.0] - "==1": [0.0, 0.2, 0.5083, 0.6167, 0.7109, 0.7949, 0.8677, 0.9546, 1.0371, 1.127, 1.2285, 1.3545, 2.0] - ">=2": [0.0, 0.2, 0.5312, 0.6582, 0.7612, 0.8506, 0.957, 1.0635, 1.1748, 1.3086, 2.0] + "==0": [0.0, 0.2, 0.4827, 0.5635, 0.6396, 0.707, 0.7681, 0.8281, 0.8857, 0.9453, 1.0078, 1.0713, 1.1377, 1.2109, 1.2949, 1.4092, 2.0] + "==1": [0.0, 0.2, 0.5088, 0.6177, 0.7119, 0.7959, 0.8696, 0.9551, 1.0381, 1.1279, 1.2285, 1.3545, 2.0] + ">=2": [0.0, 0.2, 0.5308, 0.6577, 0.7612, 0.8506, 0.957, 1.0625, 1.1758, 1.3076, 2.0] mt_tot: <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_tot__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [20.0, 30.0, 50.0] var_bins: - "==0": [90.0, 106.8, 113.93, 118.9, 122.89, 126.65, 130.22, 133.82, 137.83, 142.26, 147.38, 153.52, 161.24, 172.4, 191.21, 250.0] - "==1": [80.0, 105.8, 113.59, 120.7, 127.13, 134.25, 141.61, 150.06, 159.82, 173.39, 196.55, 250.0] - ">=2": [80.0, 108.15, 120.64, 131.18, 141.22, 152.68, 165.39, 182.22, 206.29, 250.0] + "==0": [90.0, 107.0, 114.05, 118.88, 122.8, 126.47, 129.96, 133.5, 137.38, 141.66, 146.66, 152.62, 160.27, 171.17, 189.87, 250.0] + "==1": [80.0, 105.43, 113.18, 120.11, 126.5, 133.37, 140.45, 148.83, 158.49, 171.81, 194.95, 250.0] + ">=2": [80.0, 107.35, 119.32, 129.92, 139.77, 150.85, 163.8, 180.28, 204.68, 250.0] m_vis: <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -593,30 +625,33 @@ target_processes: <<: [*iso_1__eq_bin_opt, *Wjets_var_dependence_n_bins] bandwidth: [0.03, 0.04, 0.05] var_bins: - "==0": [0.0, 0.00005, 0.004834, 0.007351, 0.009837, 0.012504, 0.015492, 0.019098, 0.023015, 0.02771, 0.033411, 0.040272, 0.048838, 0.05981, 0.07515, 0.099763, 0.15] - "==1": [0.0, 0.00005, 0.005532, 0.008912, 0.012683, 0.016988, 0.022286, 0.028948, 0.037248, 0.048451, 0.063764, 0.08923, 0.15] - ">=2": [0.0, 0.00005, 0.005483, 0.009502, 0.014473, 0.020446, 0.027858, 0.038669, 0.0548, 0.081201, 0.15] + "==0": [0.0, 0.00005, 0.004932, 0.007516, 0.010087, 0.012785, 0.015814, 0.019493, 0.023479, 0.028324, 0.034053, 0.040962, 0.049714, 0.060662, 0.075963, 0.100649, 0.15] + "==1": [0.0, 0.00005, 0.005621, 0.009072, 0.012884, 0.017279, 0.022713, 0.029417, 0.037605, 0.049066, 0.064637, 0.090462, 0.15] + ">=2": [0.0, 0.00005, 0.005602, 0.009668, 0.014723, 0.020748, 0.028099, 0.039254, 0.055474, 0.082078, 0.15] DR_SR: - <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] + use_embedding: true + compute_different_set_of_fake_factors: true + compute_different_set_of_fake_factors_using_data: false + <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: - <<: [*pt_tt__eq_bin_opt, *Wjets_var_dependence_n_bins] + <<: [*mt_1__eq_bin_opt, *Wjets_var_dependence_n_bins] var_dependence_n_bins: "==0": 13 "==1": 9 ">=2": 7 bandwidth: [25.0, 40.0, 50.0] var_bins: - "==0": [0.0, 6.73, 9.78, 12.39, 14.84, 17.3, 19.85, 22.57, 25.6, 29.05, 33.26, 38.81, 47.58, 150.0] - "==1": [0.0, 23.16, 32.5, 40.16, 47.73, 55.6, 64.97, 77.54, 97.85, 150.0] - ">=2": [0.0, 32.16, 49.05, 64.62, 80.11, 97.64, 119.22, 150.0] + "==0": [0.0, 2.48, 5.08, 7.83, 10.91, 14.38, 18.35, 23.16, 28.9, 35.74, 43.7, 52.34, 61.16, 70.0] + "==1": [0.0, 5.24, 11.06, 17.27, 24.28, 32.24, 40.86, 50.19, 59.96, 70.0] + ">=2": [0.0, 6.96, 14.47, 22.71, 32.19, 43.21, 56.0, 70.0] SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! - lep_mt: (mt_1 > 0) + lep_mt: (mt_1 > 70) nbtag: (nbtag == 0) tau_pair_sign: ((q_1*q_2) < 0) lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) ARlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! - lep_mt: (mt_1 > 0) + lep_mt: (mt_1 > 70) nbtag: (nbtag == 0) tau_pair_sign: ((q_1*q_2) < 0) lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) @@ -625,11 +660,6 @@ target_processes: nbtag: (nbtag >= 0) tau_pair_sign: ((q_1*q_2) < 0) lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) - non_closure: - nbtag: - <<: [*nbtag, *3j_split] - var_bins: [-0.5, 0.5, 22.5] - correction_variations: ["Stat1Sigma", "SystMCShift"] ttbar: non_closure: @@ -642,16 +672,16 @@ target_processes: <<: [*eta_1__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.6, 1.0] var_bins: - "<=1": [-2.1, -1.59, -1.19, -0.81, -0.48, -0.12, 0.2, 0.5, 0.84, 1.22, 1.6, 2.1] - ">=2": [-2.1, -1.72, -1.42, -1.14, -0.86, -0.61, -0.39, -0.13, 0.1, 0.35, 0.58, 0.83, 1.08, 1.4, 1.71, 2.1] + "<=1": [-2.1, -1.52, -1.08, -0.74, -0.44, -0.14, 0.13, 0.43, 0.72, 1.08, 1.51, 2.1] + ">=2": [-2.1, -1.61, -1.28, -1.0, -0.76, -0.53, -0.32, -0.1, 0.1, 0.33, 0.53, 0.76, 1.01, 1.29, 1.62, 2.1] eta_2: <<: [*eta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*eta_2__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.7, 0.7] var_bins: - "<=1": [-2.5, -1.55, -1.11, -0.74, -0.42, -0.08, 0.25, 0.56, 0.88, 1.19, 1.61, 2.5] - ">=2": [-2.5, -1.82, -1.43, -1.16, -0.86, -0.62, -0.34, -0.09, 0.19, 0.44, 0.66, 0.92, 1.17, 1.45, 1.86, 2.5] + "<=1": [-2.5, -1.6, -1.18, -0.83, -0.48, -0.14, 0.19, 0.51, 0.87, 1.19, 1.59, 2.5] + ">=2": [-2.5, -1.83, -1.42, -1.15, -0.89, -0.62, -0.36, -0.1, 0.15, 0.4, 0.66, 0.93, 1.18, 1.44, 1.83, 2.5] jeta_1: <<: [*jeta_1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -659,8 +689,8 @@ target_processes: correction_option: "smoothed" bandwidth: [1.0, 2.0] var_bins: - "<=1": [-5.0, -2.13, -1.4, -0.97, -0.57, -0.2, 0.18, 0.56, 0.98, 1.49, 2.08, 5.0] - ">=2": [-5.0, -2.28, -1.8, -1.36, -1.06, -0.72, -0.44, -0.18, 0.15, 0.46, 0.76, 1.09, 1.42, 1.87, 2.26, 5.0] + "<=1": [-5.0, -1.8, -1.25, -0.85, -0.48, -0.17, 0.16, 0.49, 0.83, 1.24, 1.83, 5.0] + ">=2": [-5.0, -2.06, -1.56, -1.19, -0.88, -0.62, -0.36, -0.12, 0.13, 0.37, 0.63, 0.91, 1.22, 1.58, 2.08, 5.0] jeta_2: <<: [*jeta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -669,15 +699,15 @@ target_processes: correction_option: ["skip", "smoothed"] var_bins: "<=1": [-5.0, 5.0] - ">=2": [-5.0, -2.62, -1.96, -1.44, -1.08, -0.77, -0.46, -0.17, 0.13, 0.46, 0.76, 1.1, 1.5, 1.96, 2.59, 5.0] + ">=2": [-5.0, -2.23, -1.67, -1.27, -0.95, -0.66, -0.39, -0.12, 0.13, 0.39, 0.67, 0.95, 1.29, 1.69, 2.25, 5.0] jpt_1: <<: [*jpt_1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*jpt_1__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [30.0, 20.0] var_bins: - "<=1": [30.0, 32.88, 35.75, 38.97, 42.47, 46.53, 51.03, 56.12, 62.88, 71.88, 85.25, 150.0] - ">=2": [30.0, 40.09, 45.03, 48.84, 52.97, 57.0, 60.91, 65.0, 69.38, 74.25, 80.25, 87.31, 95.0, 105.94, 124.06, 150.0] + "<=1": [30.0, 35.36, 40.96, 46.65, 52.23, 58.54, 65.09, 72.75, 82.08, 94.53, 111.82, 150.0] + ">=2": [30.0, 47.65, 54.97, 60.91, 66.28, 71.41, 76.42, 81.65, 87.12, 92.85, 99.07, 105.86, 113.72, 123.2, 135.2, 150.0] jpt_2: <<: [*jpt_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -686,38 +716,46 @@ target_processes: correction_option: ["skip", "smoothed"] var_bins: "<=1": [30.0, 150.0] - ">=2": [30.0, 31.55, 33.22, 34.81, 36.66, 38.72, 40.69, 43.09, 45.69, 49.09, 52.78, 57.97, 64.62, 73.38, 88.88, 150.0] + ">=2": [30.0, 34.04, 37.51, 40.9, 44.36, 47.9, 51.37, 55.15, 59.19, 63.62, 68.59, 74.66, 82.46, 93.05, 109.69, 150.0] met: <<: [*met, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*met__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [40.0, 35.0] var_bins: - "<=1": [0.0, 6.42, 9.61, 12.29, 14.89, 17.59, 20.76, 23.87, 28.1, 33.71, 43.03, 150.0] - ">=2": [0.0, 7.56, 11.11, 14.34, 17.17, 19.81, 22.54, 25.46, 28.64, 32.58, 37.14, 43.54, 50.89, 62.27, 84.77, 150.0] + "<=1": [0.0, 14.66, 22.03, 28.03, 34.31, 40.61, 47.23, 55.17, 64.25, 76.67, 95.52, 150.0] + ">=2": [0.0, 13.5, 19.68, 25.11, 30.24, 35.17, 40.53, 46.2, 52.21, 58.7, 66.15, 74.85, 85.02, 97.62, 116.03, 150.0] + pt_tt: + <<: [*pt_tt, *2j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_tt__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [25.0, 35.0] + var_bins: + "<=1": [0.0, 24.45, 35.1, 43.91, 52.13, 60.74, 69.18, 78.19, 87.94, 100.55, 117.97, 150.0] + ">=2": [0.0, 25.92, 38.05, 47.24, 55.39, 62.86, 69.81, 76.99, 84.08, 91.29, 98.76, 106.54, 115.17, 124.87, 136.3, 150.0] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaEta_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [1.5, 1.75] var_bins: - "<=1": [-4.9, -1.79, -1.18, -0.8, -0.47, -0.17, 0.11, 0.4, 0.73, 1.1, 1.7, 4.9] - ">=2": [-4.9, -2.2, -1.63, -1.24, -0.96, -0.69, -0.43, -0.19, 0.06, 0.32, 0.61, 0.89, 1.19, 1.6, 2.18, 4.9] + "<=1": [-4.9, -1.57, -1.06, -0.71, -0.43, -0.17, 0.11, 0.39, 0.69, 1.05, 1.56, 4.9] + ">=2": [-4.9, -2.0, -1.47, -1.1, -0.82, -0.58, -0.35, -0.12, 0.1, 0.33, 0.55, 0.79, 1.07, 1.43, 1.99, 4.9] deltaR_ditaupair: <<: [*deltaR_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.75, 1.0] var_bins: - "<=1": [0.5, 1.8185, 2.2501, 2.5022, 2.6998, 2.843, 2.9625, 3.0535, 3.1262, 3.2298, 3.4783, 5.0] - ">=2": [0.5, 1.1451, 1.4219, 1.6541, 1.8355, 2.0329, 2.2002, 2.365, 2.5182, 2.6805, 2.829, 2.9692, 3.1, 3.225, 3.5263, 5.0] + "<=1": [0.5, 1.2589, 1.6931, 2.0017, 2.272, 2.4783, 2.6662, 2.8297, 2.9717, 3.103, 3.283, 5.0] + ">=2": [0.5, 0.9472, 1.2341, 1.4726, 1.6983, 1.9055, 2.0972, 2.2769, 2.4468, 2.6064, 2.7588, 2.9015, 3.0423, 3.1826, 3.465, 5.0] deltaR_1j1: <<: [*deltaR_1j1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*deltaR_1j1__eq_bin_opt, *ttbar_var_dependence_n_bins] var_bins: - "<=1": [0.5, 1.712, 2.041, 2.233, 2.368, 2.491, 2.609, 2.732, 2.884, 3.052, 3.322, 7.0] - ">=2": [0.5, 1.277, 1.668, 1.911, 2.119, 2.294, 2.448, 2.601, 2.738, 2.866, 2.972, 3.084, 3.206, 3.464, 3.926, 7.0] + "<=1": [0.5, 1.343, 1.785, 2.09, 2.344, 2.552, 2.723, 2.882, 3.037, 3.185, 3.478, 7.0] + ">=2": [0.5, 1.158, 1.535, 1.836, 2.086, 2.291, 2.467, 2.618, 2.754, 2.872, 2.984, 3.087, 3.201, 3.395, 3.767, 7.0] deltaR_12j1: <<: [*deltaR_12j1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -725,8 +763,8 @@ target_processes: correction_option: "smoothed" bandwidth: [1.5, 1.5] var_bins: - "<=1": [0.0, 2.45, 2.74, 2.87, 2.97, 3.04, 3.11, 3.19, 3.31, 3.54, 4.01, 10.0] - ">=2": [0.0, 1.8, 2.21, 2.41, 2.57, 2.71, 2.82, 2.91, 3.0, 3.07, 3.16, 3.28, 3.46, 3.76, 4.33, 10.0] + "<=1": [0.0, 1.8, 2.26, 2.53, 2.73, 2.88, 3.0, 3.11, 3.25, 3.48, 3.87, 10.0] + ">=2": [0.0, 1.5, 1.94, 2.22, 2.42, 2.58, 2.72, 2.83, 2.94, 3.03, 3.12, 3.23, 3.39, 3.64, 4.09, 10.0] pt_ttjj: <<: [*pt_ttjj, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: @@ -734,36 +772,36 @@ target_processes: correction_option: ["skip", "smoothed"] var_bins: "<=1": [0.0, 150.0] - ">=2": [0.0, 10.01, 15.05, 18.51, 22.24, 26.35, 29.98, 33.82, 37.48, 42.35, 47.08, 52.65, 60.81, 71.28, 88.2, 150.0] + ">=2": [0.0, 15.23, 22.09, 27.98, 33.27, 38.42, 43.61, 48.82, 54.23, 60.19, 66.83, 74.34, 83.25, 95.43, 112.85, 150.0] mass_2: <<: [*mass_2, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*mass_2__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.225, 0.175] var_bins: - "<=1": [0.0, 0.2, 0.5073, 0.6138, 0.709, 0.7949, 0.8745, 0.9595, 1.043, 1.1299, 1.2266, 1.3516, 2.0] - ">=2": [0.0, 0.2, 0.4607, 0.5352, 0.6128, 0.6851, 0.7598, 0.8218, 0.874, 0.9316, 0.9941, 1.0527, 1.123, 1.1992, 1.2793, 1.3926, 2.0] + "<=1": [0.0, 0.2, 0.5542, 0.7139, 0.8491, 0.9507, 1.0391, 1.1172, 1.1963, 1.2773, 1.374, 1.4785, 2.0] + ">=2": [0.0, 0.2, 0.4985, 0.6196, 0.7344, 0.8311, 0.9072, 0.9736, 1.0352, 1.0957, 1.1553, 1.2168, 1.2793, 1.3447, 1.416, 1.5039, 2.0] mt_tot: <<: [*mt_tot, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_tot__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [35.0, 40.0] var_bins: - "<=1": [0.0, 69.47, 78.15, 84.38, 89.97, 95.26, 100.7, 106.88, 114.3, 125.28, 144.01, 250.0] - ">=2": [0.0, 50.83, 63.88, 72.33, 79.91, 86.61, 92.35, 97.84, 103.22, 109.07, 115.24, 123.47, 133.88, 148.13, 174.05, 250.0] + "<=1": [0.0, 71.15, 85.76, 95.51, 104.09, 111.98, 120.16, 129.15, 140.06, 155.19, 180.06, 250.0] + ">=2": [0.0, 54.45, 70.52, 80.81, 88.59, 95.47, 102.0, 108.62, 115.3, 122.53, 130.56, 139.48, 150.09, 164.95, 189.62, 250.0] m_vis: <<: [*m_vis, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*m_vis__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [20, 20] var_bins: - "<=1": [40.0, 60.36, 67.73, 74.07, 81.14, 88.19, 94.03, 102.97, 114.17, 130.62, 157.95, 250.0] - ">=2": [40.0, 49.61, 58.39, 65.84, 72.69, 78.41, 85.03, 92.35, 98.95, 106.61, 115.19, 126.1, 139.34, 159.49, 187.88, 250.0] + "<=1": [40.0, 57.23, 66.64, 74.08, 80.63, 87.14, 94.16, 102.36, 112.55, 128.21, 163.02, 250.0] + ">=2": [40.0, 52.04, 60.23, 66.79, 72.63, 78.31, 83.65, 89.47, 95.56, 102.24, 110.06, 119.97, 133.62, 153.79, 184.28, 250.0] iso_1: <<: [*iso_1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: <<: [*iso_1__eq_bin_opt, *ttbar_var_dependence_n_bins] bandwidth: [0.05, 0.05] var_bins: - "<=1": [0.0, 0.00005, 0.006077, 0.009416, 0.013132, 0.017296, 0.022391, 0.029646, 0.038035, 0.049376, 0.065149, 0.092747, 0.15] - ">=2": [0.0, 0.00005, 0.004505, 0.00665, 0.008761, 0.0109, 0.013594, 0.016488, 0.019765, 0.024123, 0.029846, 0.037418, 0.045143, 0.056147, 0.072582, 0.094662, 0.15] + "<=1": [0.0, 0.00005, 0.006133, 0.009499, 0.01269, 0.017176, 0.022144, 0.027969, 0.0369, 0.048008, 0.063692, 0.090369, 0.15] + ">=2": [0.0, 0.00005, 0.004676, 0.007108, 0.009587, 0.012164, 0.015111, 0.018535, 0.022638, 0.027259, 0.032977, 0.039821, 0.048317, 0.060037, 0.075678, 0.101079, 0.15] diff --git a/configs/smhtt_ul/2018/fake_factors_mt.yaml b/configs/smhtt_ul/2018/fake_factors_mt.yaml index ba274b1..5bfa0a6 100644 --- a/configs/smhtt_ul/2018/fake_factors_mt.yaml +++ b/configs/smhtt_ul/2018/fake_factors_mt.yaml @@ -39,9 +39,9 @@ target_processes: var_dependence: pt_2 # in case of individual splitting var_bins: - "==0": [30.0, 31.06, 32.33, 33.69, 35.37, 37.31, 39.73, 43.04, 47.73, 55.82, 150.0] - "==1": [30.0, 32.33, 35.62, 40.69, 51.56, 150.0] - ">=2": [30.0, 33.69, 39.49, 52.66, 150.0] + "==0": [30.0, 31.05, 32.32, 33.68, 35.36, 37.3, 39.72, 43.02, 47.71, 55.77, 150.0] + "==1": [30.0, 32.24, 35.38, 40.3, 50.88, 150.0] + ">=2": [30.0, 33.58, 39.16, 51.85, 150.0] fit_option: "==0": ["poly_1"] "==1": ["poly_1", "poly_2"] @@ -51,15 +51,15 @@ target_processes: split_categories: njets: ["==0", "==1", ">=2"] pt_1: - "==0": [<=37.47, '>37.47#&&#<=50.12', '>50.12#&&#<=65.82', '>65.82'] - "==1": [<=38.11, '>38.11#&&#<=50.8', '>50.8#&&#<=70.26', '>70.26'] - ">=2": [<=39.7, '>39.7#&&#<=56.33', '>56.33#&&#<=83.95', '>83.95'] + "==0": [<=35.96, '>35.96#&&#<=48.5', '>48.5#&&#<=64.78', '>64.78'] + "==1": [<=37.18, '>37.18#&&#<=49.53', '>49.53#&&#<=68.79', '>68.79'] + ">=2": [<=38.88, '>38.88#&&#<=54.94', '>54.94#&&#<=82.16', '>82.16'] split_categories_binedges: njets: [-0.5, 0.5, 1.5, 22.5] pt_1: - "==0": [0.0, 37.470001220703, 50.119998931885, 65.819999694824, 1000.0] - "==1": [0.0, 38.110000610352, 50.799999237061, 70.26000213623, 1000.0] - ">=2": [0.0, 39.700000762939, 56.330001831055, 83.949996948242, 1000.0] + "==0": [0.0, 35.959999084473, 48.5, 64.779998779297, 1000.0] + "==1": [0.0, 37.180000305176, 49.529998779297, 68.790000915527, 1000.0] + ">=2": [0.0, 38.880001068115, 54.939998626709, 82.160003662109, 1000.0] equipopulated_binning_options: variable_config: pt_2: @@ -97,20 +97,20 @@ target_processes: var_dependence: pt_2 var_bins: "==0": - "<=37.47": [30.0, 30.91, 31.9, 32.99, 34.32, 35.85, 37.84, 40.3, 44.38, 52.02, 150.0] - ">37.47#&&#<=50.12": [30.0, 30.83, 31.76, 32.79, 34.0, 35.49, 37.33, 39.8, 43.54, 51.14, 150.0] - ">50.12#&&#<=65.82": [30.0, 30.98, 32.09, 33.29, 34.74, 36.37, 38.35, 41.21, 45.46, 52.83, 150.0] - ">65.82": [30.0, 32.28, 34.65, 37.21, 40.28, 43.94, 48.54, 54.36, 62.74, 78.44, 150.0] + "<=35.96": [30.0, 30.84, 31.77, 32.82, 34.12, 35.57, 37.42, 39.8, 43.43, 50.59, 150.0] + ">35.96#&&#<=48.5": [30.0, 30.82, 31.71, 32.7, 33.87, 35.35, 37.12, 39.54, 43.27, 50.62, 150.0] + ">48.5#&&#<=64.78": [30.0, 30.94, 32.04, 33.2, 34.62, 36.22, 38.18, 40.94, 45.15, 52.58, 150.0] + ">64.78": [30.0, 32.15, 34.48, 36.96, 39.95, 43.47, 48.0, 53.68, 62.03, 77.31, 150.0] "==1": - "<=38.11": [30.0, 32.76, 36.25, 41.29, 51.88, 150.0] - ">38.11#&&#<=50.8": [30.0, 32.69, 36.18, 41.2, 52.23, 150.0] - ">50.8#&&#<=70.26": [30.0, 33.24, 37.22, 43.47, 55.58, 150.0] - ">70.26": [30.0, 34.78, 41.68, 52.52, 71.29, 150.0] + "<=37.18": [30.0, 32.63, 36.04, 40.94, 50.97, 150.0] + ">37.18#&&#<=49.53": [30.0, 32.59, 35.95, 40.96, 51.57, 150.0] + ">49.53#&&#<=68.79": [30.0, 33.13, 36.88, 42.74, 54.42, 150.0] + ">68.79": [30.0, 34.67, 41.45, 52.01, 70.7, 150.0] ">=2": - "<=39.7": [30.0, 33.71, 38.59, 46.75, 64.03, 150.0] - ">39.7#&&#<=56.33": [30.0, 33.33, 39.27, 48.06, 64.51, 150.0] - ">56.33#&&#<=83.95": [30.0, 34.18, 39.84, 48.93, 66.5, 150.0] - ">83.95": [30.0, 35.44, 43.03, 55.19, 77.0, 150.0] + "<=38.88": [30.0, 33.56, 38.22, 45.83, 62.27, 150.0] + ">38.88#&&#<=54.94": [30.0, 33.26, 38.84, 46.82, 62.86, 150.0] + ">54.94#&&#<=82.16": [30.0, 34.01, 39.54, 48.62, 65.91, 150.0] + ">82.16": [30.0, 35.3, 42.61, 54.79, 76.48, 150.0] fit_option: "==0": ["poly_1", "poly_2"] "==1": ["poly_1", "poly_2"] @@ -171,8 +171,8 @@ target_processes: var_dependence: pt_2 var_bins: - "<=1": [30.0, 30.86, 31.82, 32.84, 33.87, 35.12, 36.43, 38.04, 39.75, 41.81, 44.39, 47.34, 51.99, 59.05, 71.81, 150.0] - ">=2": [30.0, 31.77, 33.82, 36.2, 38.94, 42.51, 46.87, 53.32, 63.98, 83.61, 150.0] + "<=1": [30.0, 31.28, 32.49, 33.8, 35.35, 36.97, 38.95, 41.11, 43.83, 46.97, 50.76, 55.49, 62.17, 71.39, 87.69, 150.0] + ">=2": [30.0, 31.64, 33.56, 35.83, 38.52, 41.85, 46.3, 52.31, 61.8, 79.32, 150.0] fit_option: ["poly_1", "poly_2", "poly_3"] process_fractions: @@ -214,6 +214,6 @@ process_fractions: var_dependence: mt_1 var_bins: - "==0": [0.0, 1.97, 3.96, 6.02, 8.2, 10.5, 12.92, 15.46, 18.16, 21.05, 24.07, 27.22, 30.51, 33.88, 37.28, 40.68, 44.01, 47.32, 50.52, 53.63, 56.6, 59.44, 62.21, 64.88, 67.48, 70.0] - "==1": [0.0, 3.47, 6.95, 10.58, 14.36, 18.15, 22.04, 26.0, 29.92, 33.94, 37.79, 41.5, 45.16, 48.71, 52.11, 55.36, 58.53, 61.57, 64.46, 67.29, 70.0] - ">=2": [0.0, 5.1, 10.13, 15.16, 20.27, 25.33, 30.46, 35.49, 40.39, 45.1, 49.58, 53.83, 58.12, 62.2, 66.11, 70.0] + "==0": [0.0, 1.98, 3.99, 6.06, 8.26, 10.57, 13.01, 15.57, 18.3, 21.21, 24.25, 27.42, 30.73, 34.12, 37.54, 40.95, 44.28, 47.59, 50.77, 53.85, 56.81, 59.62, 62.37, 64.98, 67.54, 70.0] + "==1": [0.0, 3.49, 7.01, 10.68, 14.5, 18.32, 22.25, 26.23, 30.17, 34.21, 38.07, 41.79, 45.44, 48.97, 52.36, 55.59, 58.71, 61.7, 64.55, 67.33, 70.0] + ">=2": [0.0, 5.06, 10.07, 15.09, 20.24, 25.29, 30.43, 35.54, 40.46, 45.17, 49.65, 53.9, 58.18, 62.23, 66.13, 70.0] From 2f72f7ee7a90281ce397f6a9af0f88169ebeaa08 Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Fri, 13 Mar 2026 13:55:49 +0100 Subject: [PATCH 08/20] minor adjsutmetns for sctatistical test procedure for correction selection --- configs/smhtt_ul/2018/common_settings.yaml | 4 +- ff_corrections.py | 2 +- helper/ff_functions.py | 59 ++++++----- helper/functions.py | 2 +- helper/hooks_and_patches.py | 111 +++++++++++++++++++++ 5 files changed, 149 insertions(+), 29 deletions(-) diff --git a/configs/smhtt_ul/2018/common_settings.yaml b/configs/smhtt_ul/2018/common_settings.yaml index 65d8f76..e2c5c5b 100644 --- a/configs/smhtt_ul/2018/common_settings.yaml +++ b/configs/smhtt_ul/2018/common_settings.yaml @@ -25,6 +25,6 @@ tau_vs_jet_wgt_wps: use_embedding: true use_center_of_mass_bins: true -skip_corrections_compatible_to_one: false -skip_uncertainties_of_corrections_compatible_to_one: false +skip_corrections_compatible_to_one: true skip_corrections_p_value: 0.05 +use_suppressed_mc_errors_for_correction_selection: true diff --git a/ff_corrections.py b/ff_corrections.py index 58c40dd..c4f40f1 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -634,8 +634,8 @@ def run_correction( func.RuntimeVariables.RDataFrameWrapper = Histo1DPatchedRDataFrame func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE = corr_config.get("skip_corrections_compatible_to_one", False) - func.RuntimeVariables.SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE = corr_config.get("skip_uncertainties_of_corrections_compatible_to_one", False) func.RuntimeVariables.SKIP_CORRECTIONS_P_VALUE = corr_config.get("skip_corrections_p_value", 0.05) + func.RuntimeVariables.USE_SUPPRESSED_MC_ERRORS_FOR_CORRECTION_SELECTION = corr_config.get("use_suppressed_mc_errors_for_correction_selection", True) # setting default systematic variations if not present in the config if "correction_variations" not in corr_config: diff --git a/helper/ff_functions.py b/helper/ff_functions.py index 2582d47..14c81da 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -1422,22 +1422,27 @@ def statistical_check( """ _, _, y_val, _, _, err_dn, err_up = build_TGraph(hist, return_components=True, add_xerrors_in_graph=True) - y, err = np.array(y_val), (np.array(err_dn) + np.array(err_up)).clip(min=1e-6) / 2.0 - chi2_global, ndf = np.sum(((y - 1.0) / err) ** 2), len(y) - p_value_global = scipy.stats.chi2.sf(chi2_global, ndf) + if hasattr(hist, "_extra_base_errors_mc_suppressed"): + if func.RuntimeVariables.USE_SUPPRESSED_MC_ERRORS_FOR_CORRECTION_SELECTION: + err = hist._extra_base_errors_mc_suppressed.clip(min=1e-6) + else: + err = hist._extra_base_errors_std.clip(min=1e-6) + else: # fallback + err = (np.array(err_dn) + np.array(err_up)).clip(min=1e-6) / 2.0 + + y, ndf = np.array(y_val), len(y_val) + + p_value_global = scipy.stats.chi2.sf(np.sum(((y - 1.0) / err) ** 2), ndf) - chi2_bins = ((y - 1.0) / err) ** 2 - p_values_bins = scipy.stats.chi2.sf(chi2_bins, 1) - p_values_bins_min = p_values_bins.min() - p_value_sidak = 1 - (1 - p_values_bins_min) ** len(p_values_bins) + p_values_bins_min = scipy.stats.chi2.sf(((y - 1.0) / err) ** 2, 1).min() + p_value_sidak = 1 - (1 - p_values_bins_min) ** ndf - p_value_shape_min = 1.0 - pulls = (y - 1.0) / err + p_value_shape_min, pulls = 1.0, (y - 1.0) / err for window in range(1, ndf + 1): for i in range(ndf - window + 1): z_window = np.abs(np.sum(pulls[i: i + window]) / np.sqrt(window)) - p_window = scipy.stats.norm.sf(z_window) * 2 + p_window = scipy.stats.norm.sf(z_window) * 2 # two-sided p-value if p_window < p_value_shape_min: p_value_shape_min = p_window p_shape = 1 - (1 - p_value_shape_min) ** len(y) @@ -1448,23 +1453,28 @@ def statistical_check( corr_dict["_auto_skipped"] = True corr_dict["nominal"] = np.ones_like(corr_dict["nominal"]) + stat_unct_inclusive = 1.0 / np.sqrt(np.sum(1.0 / err**2)) + for key in list(corr_dict.keys()): - if key.startswith("Stat") or key.startswith("SystBand"): # no stat. unct. on constant, no bandwidth + if key.startswith("SystBand"): # No bandwidth uncertainty for a flat line corr_dict[key] = np.ones_like(corr_dict[key]) - - if func.RuntimeVariables.SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE: - for key in list(corr_dict.keys()): - if key.startswith("SystMCShift"): - corr_dict[key] = np.ones_like(corr_dict[key]) + elif "Stat1SigmaUp" in key or key == "StatUp": + corr_dict[key] = np.full_like(corr_dict[key], 1.0 + stat_unct_inclusive) + elif "Stat1SigmaDown" in key or key == "StatDown": + corr_dict[key] = np.full_like(corr_dict[key], 1.0 - stat_unct_inclusive) + elif "Stat2SigmaUp" in key: + corr_dict[key] = np.full_like(corr_dict[key], 1.0 + 2.0 * stat_unct_inclusive) + elif "Stat2SigmaDown" in key: + corr_dict[key] = np.full_like(corr_dict[key], 1.0 - 2.0 * stat_unct_inclusive) + + if mc_shifted_hist is None: + corr_dict["SystMCShiftUp"] = np.ones_like(corr_dict["nominal"]) + corr_dict["SystMCShiftDown"] = np.ones_like(corr_dict["nominal"]) else: - if mc_shifted_hist is None: - corr_dict["SystMCShiftUp"] = np.ones_like(corr_dict["nominal"]) - corr_dict["SystMCShiftDown"] = np.ones_like(corr_dict["nominal"]) - else: - mc_up_val, _ = fit_to_constant(mc_shifted_hist["MCShiftUp"]) - mc_dn_val, _ = fit_to_constant(mc_shifted_hist["MCShiftDown"]) - corr_dict["SystMCShiftUp"] = np.full_like(corr_dict["nominal"], mc_up_val) - corr_dict["SystMCShiftDown"] = np.full_like(corr_dict["nominal"], mc_dn_val) + mc_up_val, _ = fit_to_constant(mc_shifted_hist["MCShiftUp"]) + mc_dn_val, _ = fit_to_constant(mc_shifted_hist["MCShiftDown"]) + corr_dict["SystMCShiftUp"] = np.full_like(corr_dict["nominal"], mc_up_val) + corr_dict["SystMCShiftDown"] = np.full_like(corr_dict["nominal"], mc_dn_val) else: corr_dict["_auto_skipped"] = False @@ -1773,7 +1783,6 @@ def flatten_categories(node, current_path=""): log.info("Summary of corrections applied vs. set to 1.0 due to compatibility with 1.0:\n") log.info(f"p-value threshold for auto-skipping: {func.RuntimeVariables.SKIP_CORRECTIONS_P_VALUE:.3f}") log.info(f"Auto-skipping enabled: {func.RuntimeVariables.SKIP_CORRECTIONS_COMPATIBLE_TO_ONE}") - log.info(f"MCshift variations also set to 1.0 if compatible: {func.RuntimeVariables.SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE}\n") for process, correction in merged.items(): if not correction: diff --git a/helper/functions.py b/helper/functions.py index cb746ed..4633f07 100644 --- a/helper/functions.py +++ b/helper/functions.py @@ -180,8 +180,8 @@ class RuntimeVariables(object): RDataFrameWrapper = None SKIP_CORRECTIONS_COMPATIBLE_TO_ONE = True - SKIP_UNCERTAINTIES_OF_CORRECTIONS_COMPATIBLE_TO_ONE = False SKIP_CORRECTIONS_P_VALUE = 0.05 + USE_SUPPRESSED_MC_ERRORS_FOR_CORRECTION_SELECTION = True def __new__(cls) -> "RuntimeVariables": if not hasattr(cls, "instance"): diff --git a/helper/hooks_and_patches.py b/helper/hooks_and_patches.py index 4f273d2..becd6d6 100644 --- a/helper/hooks_and_patches.py +++ b/helper/hooks_and_patches.py @@ -7,6 +7,9 @@ _EXTRA_PARAM_MEANS = "_extra_weighted_means" _EXTRA_PARAM_COUNTS = "_extra_weighted_counts" _EXTRA_PARAM_FLAG = "_has_extra_params" +_EXTRA_PARAM_BASE_VALUES = "_extra_base_values" +_EXTRA_PARAM_BASE_ERRORS_STD = "_extra_base_errors_std" +_EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED = "_extra_base_errors_mc_suppressed" class PassThroughWrapper: @@ -134,6 +137,14 @@ def new_GetValue(): setattr(main_hist, _EXTRA_PARAM_MEANS, weighted_means) setattr(main_hist, _EXTRA_PARAM_FLAG, flag) + N_bins = main_hist.GetNbinsX() + values = np.array([main_hist.GetBinContent(i) for i in range(1, N_bins + 1)]) + errors = np.array([main_hist.GetBinError(i) for i in range(1, N_bins + 1)]) + + setattr(main_hist, _EXTRA_PARAM_BASE_VALUES, values) + setattr(main_hist, _EXTRA_PARAM_BASE_ERRORS_STD, errors) + setattr(main_hist, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, errors.copy()) + # Overwrite GetValue so further calls return the histogram directly. main_hist.GetValue = lambda: main_hist return main_hist @@ -228,6 +239,14 @@ def _AddError(self: ROOT.TH1, scale: float = 1.0) -> ROOT.TH1: setattr(clone, _EXTRA_PARAM_MEANS, new_means) setattr(clone, _EXTRA_PARAM_FLAG, True) + if hasattr(self, _EXTRA_PARAM_BASE_VALUES): + values = getattr(self, _EXTRA_PARAM_BASE_VALUES) + error_std = getattr(self, _EXTRA_PARAM_BASE_ERRORS_STD) + error_supressed = getattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED) + setattr(clone, _EXTRA_PARAM_BASE_VALUES, values + scale * error_std) + setattr(clone, _EXTRA_PARAM_BASE_ERRORS_STD, error_std.copy()) + setattr(clone, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, error_supressed.copy()) + return clone @@ -275,6 +294,30 @@ def patched_Add( setattr(self, _EXTRA_PARAM_MEANS, _means) setattr(self, _EXTRA_PARAM_FLAG, True) + values_1 = getattr(self, _EXTRA_PARAM_BASE_VALUES, None) + values_2 = getattr(other, _EXTRA_PARAM_BASE_VALUES, None) + if values_1 is not None and values_2 is not None: + values = values_1 + factor * values_2 + + errors_std_1 = getattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, None) + errors_std_2 = getattr(other, _EXTRA_PARAM_BASE_ERRORS_STD, None) + + assert errors_std_1 is not None and errors_std_2 is not None, "Both histograms must have _extra_base_errors_std for error propagation." + errors_std = np.sqrt(errors_std_1 ** 2 + (factor * errors_std_2) ** 2) + + errors_supressed_1 = getattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, None) + errors_supressed_2 = getattr(other, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, None) + + assert errors_supressed_1 is not None and errors_supressed_2 is not None, "Both histograms must have _extra_base_errors_mc_suppressed for error propagation." + if factor < 0: + errors_supressed = errors_supressed_1.copy() + else: + errors_supressed = np.sqrt(errors_supressed_1 ** 2 + (factor * errors_supressed_2) ** 2) + + setattr(self, _EXTRA_PARAM_BASE_VALUES, values) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, errors_std) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, errors_supressed) + return self @@ -312,6 +355,31 @@ def patched_Multiply( setattr(self, _EXTRA_PARAM_MEANS, _means) setattr(self, _EXTRA_PARAM_FLAG, True) + values_1 = getattr(self, _EXTRA_PARAM_BASE_VALUES, None) + values_2 = getattr(other, _EXTRA_PARAM_BASE_VALUES, None) + if values_1 is not None and values_2 is not None: + values = values_1 * (factor * values_2) + + error_std_1 = getattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, None) + error_std_2 = getattr(other, _EXTRA_PARAM_BASE_ERRORS_STD, None) + + assert error_std_1 is not None and error_std_2 is not None, "Both histograms must have _extra_base_errors_std for error propagation." + relative_error_std_1 = np.divide(error_std_1, values_1, out=np.zeros_like(error_std_1), where=(values_1 != 0)) + relative_error_std_2 = np.divide(error_std_2, values_2, out=np.zeros_like(error_std_2), where=(values_2 != 0)) + error_std = np.abs(values) * np.sqrt(relative_error_std_1 ** 2 + relative_error_std_2 ** 2) + + error_supressed_1 = getattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, None) + error_supressed_2 = getattr(other, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, None) + assert error_supressed_1 is not None and error_supressed_2 is not None, "Both histograms must have _extra_base_errors_mc_suppressed for error propagation." + + relative_error_supressed_1 = np.divide(error_supressed_1, values_1, out=np.zeros_like(error_supressed_1), where=(values_1 != 0)) + relative_error_supressed_2 = np.divide(error_supressed_2, values_2, out=np.zeros_like(error_supressed_2), where=(values_2 != 0)) + error_supressed = np.abs(values) * np.sqrt(relative_error_supressed_1 ** 2 + relative_error_supressed_2 ** 2) + + setattr(self, _EXTRA_PARAM_BASE_VALUES, values) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, error_std) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, error_supressed) + return self @@ -348,6 +416,31 @@ def patched_Divide( setattr(self, _EXTRA_PARAM_MEANS, _means) setattr(self, _EXTRA_PARAM_FLAG, True) + values_1 = getattr(self, _EXTRA_PARAM_BASE_VALUES, None) + values_2 = getattr(other, _EXTRA_PARAM_BASE_VALUES, None) + if values_1 is not None and values_2 is not None: + values = np.divide(values_1, factor * values_2, out=np.zeros_like(values_1), where=(values_2 != 0)) + + error_std_1 = getattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, None) + error_std_2 = getattr(other, _EXTRA_PARAM_BASE_ERRORS_STD, None) + assert error_std_1 is not None and error_std_2 is not None, "Both histograms must have _extra_base_errors_std for error propagation." + + relative_error_std_1 = np.divide(error_std_1, values_1, out=np.zeros_like(error_std_1), where=(values_1 != 0)) + relative_error_std_2 = np.divide(error_std_2, values_2, out=np.zeros_like(error_std_2), where=(values_2 != 0)) + error_std = np.abs(values) * np.sqrt(relative_error_std_1 ** 2 + relative_error_std_2 ** 2) + + error_supressed_1 = getattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, None) + error_supressed_2 = getattr(other, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, None) + assert error_supressed_1 is not None and error_supressed_2 is not None, "Both histograms must have _extra_base_errors_mc_suppressed for error propagation." + + relative_error_supressed_1 = np.divide(error_supressed_1, values_1, out=np.zeros_like(error_supressed_1), where=(values_1 != 0)) + relative_error_supressed_2 = np.divide(error_supressed_2, values_2, out=np.zeros_like(error_supressed_2), where=(values_2 != 0)) + error_supressed = np.abs(values) * np.sqrt(relative_error_supressed_1 ** 2 + relative_error_supressed_2 ** 2) + + setattr(self, _EXTRA_PARAM_BASE_VALUES, values) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, error_std) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, error_supressed) + return self @@ -380,6 +473,18 @@ def patched_Scale( setattr(self, _EXTRA_PARAM_MEANS, _means) setattr(self, _EXTRA_PARAM_FLAG, True) + values = getattr(self, _EXTRA_PARAM_BASE_VALUES, None) + if values is not None: + error_std = getattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, None) + error_std_supressed = getattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, None) + + assert error_std is not None and error_std_supressed is not None, "Histogram must have _extra_base_errors_std and _extra_base_errors_mc_suppressed for error propagation." + assert error_std_supressed is not None, "Histogram must have _extra_base_errors_mc_suppressed for error propagation." + + setattr(self, _EXTRA_PARAM_BASE_VALUES, values * factor) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_STD, error_std * abs(factor)) + setattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, error_std_supressed * abs(factor)) + return self @@ -408,6 +513,12 @@ def patched_Clone( setattr(clone, _EXTRA_PARAM_COUNTS, getattr(self, _EXTRA_PARAM_COUNTS)) if hasattr(self, _EXTRA_PARAM_MEANS): setattr(clone, _EXTRA_PARAM_MEANS, getattr(self, _EXTRA_PARAM_MEANS)) + if hasattr(self, _EXTRA_PARAM_BASE_VALUES): + setattr(clone, _EXTRA_PARAM_BASE_VALUES, getattr(self, _EXTRA_PARAM_BASE_VALUES).copy()) + if hasattr(self, _EXTRA_PARAM_BASE_ERRORS_STD): + setattr(clone, _EXTRA_PARAM_BASE_ERRORS_STD, getattr(self, _EXTRA_PARAM_BASE_ERRORS_STD).copy()) + if hasattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED): + setattr(clone, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED, getattr(self, _EXTRA_PARAM_BASE_ERRORS_MC_SUPPRESSED).copy()) return clone From 45bc1a50f827605dcb1402f591e0662d23b2c926 Mon Sep 17 00:00:00 2001 From: Artur Monsch <60860160+a-monsch@users.noreply.github.com> Date: Mon, 6 Apr 2026 22:50:40 +0200 Subject: [PATCH 09/20] minor adjustments, fraction uncertainty fix --- FF_calculation/fractions.py | 67 +- configs/general_definitions.py | 4 +- configs/smhtt_ul/2018/common_settings.yaml | 10 +- configs/smhtt_ul/2018/corrections_mt.yaml | 808 +----------------- .../smhtt_ul/2018/corrections_mt.yaml.classic | 802 +++++++++++++++++ configs/smhtt_ul/2018/corrections_mt.yaml.ml | 430 ++++++++++ configs/smhtt_ul/2018/fake_factors_mt.yaml | 4 +- configs/smhtt_ul/2018/preselection_mt.yaml | 71 +- ff_calculation.py | 22 +- helper/ff_evaluators.py | 1 - helper/weights.py | 4 +- 11 files changed, 1345 insertions(+), 878 deletions(-) mode change 100644 => 120000 configs/smhtt_ul/2018/corrections_mt.yaml create mode 100644 configs/smhtt_ul/2018/corrections_mt.yaml.classic create mode 100644 configs/smhtt_ul/2018/corrections_mt.yaml.ml diff --git a/FF_calculation/fractions.py b/FF_calculation/fractions.py index c5b22cf..1fdf649 100644 --- a/FF_calculation/fractions.py +++ b/FF_calculation/fractions.py @@ -15,6 +15,48 @@ from helper.functions import RuntimeVariables +def get_mc_shifted_fractions(hists: Dict[str, Any], processes: List[str]) -> Dict[str, Dict[str, Any]]: + """ + Function to calculate the fractions of the processes for the fake factor calculation with shifted variations. + + Args: + hists: Dictionary containing the histograms of the processes for the fraction calculation + processes: List of processes for which the fractions should be calculated + + Returns: + Dictionary containing the fractions of the processes for the nominal and shifted variations + """ + + variations = {} + variations["nominal"] = {} + for process in processes: + variations["nominal"][process] = ff_func.calc_fraction(hists, process, processes) + + for variation_process in processes: + hists_up, hists_down = {}, {} + for process in processes: + hists_up[process] = hists[process].Clone() + hists_down[process] = hists[process].Clone() + if process == variation_process: + hists_up[process] = hists_up[process].AddError(1) + hists_down[process] = hists_down[process].AddError(-1) + + for b in range(1, hists_down[process].GetNbinsX() + 1): + if hists_down[process].GetBinContent(b) < 0.0: + hists_down[process].SetBinContent(b, 0.0) + if hists_up[process].GetBinContent(b) < 0.0: + hists_up[process].SetBinContent(b, 0.0) + + variations[f"frac_{variation_process}_up"] = {} + variations[f"frac_{variation_process}_down"] = {} + + for process in processes: + variations[f"frac_{variation_process}_up"][process] = ff_func.calc_fraction(hists_up, process, processes) + variations[f"frac_{variation_process}_down"][process] = ff_func.calc_fraction(hists_down, process, processes) + + return variations + + @logging_helper.LogDecorator().grouped_logs(extractor=lambda args: f"{args[6]}") def fraction_calculation( args: Tuple[Any, ...], @@ -50,8 +92,6 @@ def fraction_calculation( AR_hists = dict() SR_hists = dict() - frac_hists = dict() - SR_frac_hists = dict() for sample_path in sample_paths: # getting the name of the process from the sample path @@ -103,27 +143,10 @@ def fraction_calculation( AR_hists["QCD"] = ff_func.QCD_SS_estimate(hists=AR_hists) SR_hists["QCD"] = ff_func.QCD_SS_estimate(hists=SR_hists) - for p in config[process]["processes"]: - frac_hists[p] = ff_func.calc_fraction( - hists=AR_hists, - target=p, - processes=config[process]["processes"], - ) - frac_hists = ff_func.add_fraction_variations( - hists=frac_hists, - processes=config[process]["processes"], - ) + processes_list = config[process]["processes"] - for p in config[process]["processes"]: - SR_frac_hists[p] = ff_func.calc_fraction( - hists=SR_hists, - target=p, - processes=config[process]["processes"], - ) - SR_frac_hists = ff_func.add_fraction_variations( - hists=SR_frac_hists, - processes=config[process]["processes"], - ) + frac_hists = get_mc_shifted_fractions(AR_hists, processes_list) + SR_frac_hists = get_mc_shifted_fractions(SR_hists, processes_list) plotting.plot_fractions( variable=process_conf["var_dependence"], diff --git a/configs/general_definitions.py b/configs/general_definitions.py index 78d5ab0..1ed3af3 100644 --- a/configs/general_definitions.py +++ b/configs/general_definitions.py @@ -99,8 +99,8 @@ def get_default_bandwidth( { "2016preVFP": r"$19.5\,fb^{-1}$ (2016preVFP, 13 TeV)", "2016postVFP": r"$16.8\,fb^{-1}$ (2016postVFP, 13 TeV)", - "2017": r"$41.5\,fb^{-1}$ (2017, 13 TeV)", - "2018": r"$59.8\,fb^{-1}$ (2018, 13 TeV)", + "2017": r"$42.07\,fb^{-1}$ (2017, 13 TeV)", + "2018": r"$59.56\,fb^{-1}$ (2018, 13 TeV)", } ) diff --git a/configs/smhtt_ul/2018/common_settings.yaml b/configs/smhtt_ul/2018/common_settings.yaml index e2c5c5b..71fe319 100644 --- a/configs/smhtt_ul/2018/common_settings.yaml +++ b/configs/smhtt_ul/2018/common_settings.yaml @@ -1,9 +1,9 @@ -ntuple_path: "root://cmsdcache-kit-disk.gridka.de//store/user/amonsch/CROWN/ntuples/ff_and_cr_production_2018UL_mt__2025-11-22_w_syst_v1/CROWNRun" -output_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_production_2018UL_mt__2025-08-21_wo_syst_v2_2025-11-03__with_events_and_rest +ntuple_path: "root://cmsdcache-kit-disk.gridka.de//store/user/amonsch/CROWN/ntuples/ff_and_cr_2018UL_mt__2026-03-27__v2/CROWNRun" +output_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_2018UL_mt__2026-03-27__v2 friends: ["fastmtt_v1"] -file_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_production_2018UL_mt__2025-08-21_wo_syst_v2_2025-11-03__with_events_and_rest +file_path: /ceph/amonsch/FFmethod/smhtt_ul/ff_and_cr_2018UL_mt__2026-03-27__v2 -workdir_name: test_v1 +workdir_name: version_2025-03-28_classic era: '2018' tree: ntuple @@ -25,6 +25,6 @@ tau_vs_jet_wgt_wps: use_embedding: true use_center_of_mass_bins: true -skip_corrections_compatible_to_one: true +skip_corrections_compatible_to_one: false skip_corrections_p_value: 0.05 use_suppressed_mc_errors_for_correction_selection: true diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml b/configs/smhtt_ul/2018/corrections_mt.yaml deleted file mode 100644 index d42c851..0000000 --- a/configs/smhtt_ul/2018/corrections_mt.yaml +++ /dev/null @@ -1,807 +0,0 @@ -templates: - split_schemes: - 3j: &3j_split - split_categories: - njets: ["==0", "==1", ">=2"] - split_categories_binedges: - njets: [-0.5, 0.5, 1.5, 22.5] - correction_option: - "==0": "smoothed" - "==1": "smoothed" - ">=2": "smoothed" - bandwidth: - "==0": 1.0 - "==1": 1.0 - ">=2": 1.0 - 2j: &2j_split - split_categories: - njets: ["<=1", ">=2"] - split_categories_binedges: - njets: [-0.5, 1.5, 22.5] - correction_option: - "<=1": "smoothed" - ">=2": "smoothed" - bandwidth: - "<=1": 1 - ">=2": 1 - var_dependence_n_bins: - QCD: - equipopulated_binning_options: &QCD_var_dependence_n_bins - var_dependence_n_bins: - "==0": 11 - "==1": 9 - ">=2": 7 - Wjets: - equipopulated_binning_options: &Wjets_var_dependence_n_bins - var_dependence_n_bins: - "==0": 15 - "==1": 11 - ">=2": 9 - ttbar: - equipopulated_binning_options: &ttbar_var_dependence_n_bins - var_dependence_n_bins: - "<=1": 11 - ">=2": 15 - correction_variations__with_mc_subtraction_shift: &correction_variations__with_mc_subtraction_shift - correction_variations: - - Stat1Sigma - - SystMCShift - - SystBandAsym - correction_variations__without_mc_subtraction_shift: &correction_variations__without_mc_subtraction_shift - correction_variations: - - Stat1Sigma - - SystBandAsym - variables: - eta_1: &eta_1 - var_dependence: eta_1 - equipopulated_binning_options: &eta_1__eq_bin_opt - variable_config: - eta_1: - min: -2.1 - max: +2.1 - rounding: 2 - correction_option: "smoothed" - bandwidth: 1.0 - eta_2: &eta_2 - var_dependence: eta_2 - equipopulated_binning_options: &eta_2__eq_bin_opt - variable_config: - eta_2: - min: -2.5 - max: +2.5 - rounding: 2 - correction_option: "smoothed" - bandwidth: 1.5 - deltaEta_ditaupair: &deltaEta_ditaupair - var_dependence: deltaEta_ditaupair - equipopulated_binning_options: &deltaEta_ditaupair__eq_bin_opt - variable_config: - deltaEta_ditaupair: - min: -4.9 - max: +4.9 - rounding: 2 - correction_option: "smoothed" - bandwidth: 1.75 - deltaR_ditaupair: &deltaR_ditaupair - var_dependence: deltaR_ditaupair - equipopulated_binning_options: &deltaR_ditaupair__eq_bin_opt - variable_config: - deltaR_ditaupair: - min: 0.5 - max: 5.0 - rounding: 4 - correction_option: "smoothed" - jeta_1: &jeta_1 - var_dependence: jeta_1 - equipopulated_binning_options: &jeta_1__eq_bin_opt - variable_config: - jeta_1: - min: -5.0 - max: +5.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 2.0 - jeta_2: &jeta_2 - var_dependence: jeta_2 - equipopulated_binning_options: &jeta_2__eq_bin_opt - variable_config: - jeta_2: - min: -5.0 - max: +5.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 2.0 - jpt_1: &jpt_1 - var_dependence: jpt_1 - equipopulated_binning_options: &jpt_1__eq_bin_opt - variable_config: - jpt_1: - min: 30.0 - max: 150.0 - rounding: 2 - correction_option: "smoothed" - jpt_2: &jpt_2 - var_dependence: jpt_2 - equipopulated_binning_options: &jpt_2__eq_bin_opt - variable_config: - jpt_2: - min: 30.0 - max: 150.0 - rounding: 2 - correction_option: "smoothed" - met: &met - var_dependence: met - equipopulated_binning_options: &met__eq_bin_opt - variable_config: - met: - min: 0.0 - max: 150.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 25 - mt_1: &mt_1 - var_dependence: mt_1 - equipopulated_binning_options: &mt_1__eq_bin_opt - variable_config: - mt_1: - min: 0.0 - max: 70.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 20 - pt_tt: &pt_tt - var_dependence: pt_tt - equipopulated_binning_options: &pt_tt__eq_bin_opt - variable_config: - pt_tt: - min: 0.0 - max: 150.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 25 - pt_ttjj: &pt_ttjj - var_dependence: pt_ttjj - equipopulated_binning_options: &pt_ttjj__eq_bin_opt - variable_config: - pt_ttjj: - min: 0.0 - max: 150.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 25 - mt_tot: &mt_tot - var_dependence: mt_tot - equipopulated_binning_options: &mt_tot__eq_bin_opt - variable_config: - mt_tot: - min: 0.0 - max: 250.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 40 - mass_2: &mass_2 - var_dependence: mass_2 - equipopulated_binning_options: &mass_2__eq_bin_opt - variable_config: - mass_2: - min: 0.2 - max: 2.0 - rounding: 4 - add_left: [0.0] - correction_option: "binwise#[0]+smoothed" - bandwidth: 0.3 - tau_decaymode_2: &tau_decaymode_2 - var_dependence: tau_decaymode_2 - correction_option: "binwise" - bandwidth: 1.0 - var_bins: [-0.5, 0.5, 9.5, 10.5, 11.5] - nbtag: &nbtag - var_dependence: nbtag - correction_option: "binwise" - bandwidth: 1.0 - var_bins: [-0.5, 0.5, 1.5, 2.5, 22.5] - iso_1: &iso_1 - var_dependence: iso_1 - equipopulated_binning_options: &iso_1__eq_bin_opt - variable_config: - iso_1: - min: 0.00005 - max: 0.15 - rounding: 6 - add_left: [0.0] - correction_option: "binwise#[0]+smoothed" - bandwidth: 0.02 - deltaR_1j1: &deltaR_1j1 - var_dependence: deltaR_1j1 - equipopulated_binning_options: &deltaR_1j1__eq_bin_opt - variable_config: - deltaR_1j1: - min: 0.5 - max: 7.0 - rounding: 3 - correction_option: "smoothed" - bandwidth: 0.9 - deltaR_12j1: &deltaR_12j1 - var_dependence: deltaR_12j1 - equipopulated_binning_options: &deltaR_12j1__eq_bin_opt - variable_config: - deltaR_12j1: - min: 0.0 - max: 10.0 - correction_option: "smoothed" - bandwidth: 1.25 - m_vis: &m_vis - var_dependence: m_vis - equipopulated_binning_options: &m_vis__eq_bin_opt - variable_config: - m_vis: - min: 40.0 - max: 250.0 - rounding: 2 - correction_option: "smoothed" - bandwidth: 30 - -channel: mt -target_processes: - QCD: - chain_DR_SR_to_non_closure: true - - non_closure: - tau_decaymode_2: - <<: [*tau_decaymode_2, *3j_split] - correction_variations: ["Stat1Sigma", "SystMCShift"] - eta_1: - <<: [*eta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*eta_1__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [0.8, 1.0, 1.0] - var_bins: - "==0": [-2.1, -1.56, -1.26, -0.86, -0.5, -0.14, 0.22, 0.56, 0.93, 1.3, 1.63, 2.1] - "==1": [-2.1, -1.51, -1.13, -0.66, -0.22, 0.22, 0.7, 1.15, 1.54, 2.1] - ">=2": [-2.1, -1.37, -0.82, -0.33, 0.23, 0.81, 1.37, 2.1] - eta_2: - <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*eta_2__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [0.9, 1.1, 1.5] - var_bins: - "==0": [-2.5, -1.68, -1.28, -0.92, -0.57, -0.18, 0.24, 0.62, 0.99, 1.31, 1.78, 2.5] - "==1": [-2.5, -1.67, -1.19, -0.73, -0.25, 0.28, 0.72, 1.17, 1.59, 2.5] - ">=2": [-2.5, -1.41, -0.87, -0.21, 0.4, 0.94, 1.55, 2.5] - jeta_1: - <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jeta_1__eq_bin_opt, *QCD_var_dependence_n_bins] - var_dependence_n_bins: [1, 9, 7] - correction_option: ["skip", "smoothed", "smoothed"] - bandwidth: [1.0, 2.5, 2.5] - var_bins: - "==0": [-5.0, 5.0] - "==1": [-5.0, -2.73, -1.63, -0.92, -0.28, 0.34, 0.92, 1.65, 2.61, 5.0] - ">=2": [-5.0, -2.02, -1.07, -0.33, 0.31, 0.99, 1.98, 5.0] - jeta_2: - <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jeta_2__eq_bin_opt, *QCD_var_dependence_n_bins] - var_dependence_n_bins: [1, 1, 7] - correction_option: ["skip", "skip", "smoothed"] - bandwidth: [1.0, 1.0, 4] - var_bins: - "==0": [-5.0, 5.0] - "==1": [-5.0, 5.0] - ">=2": [-5.0, -2.1, -1.13, -0.36, 0.33, 1.16, 2.2, 5.0] - jpt_1: - <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jpt_1__eq_bin_opt, *QCD_var_dependence_n_bins] - correction_option: ["skip", "smoothed", "smoothed"] - bandwidth: [1.0, 50.0, 60.0] - var_bins: - "==0": [30.0, 150.0] - "==1": [30.0, 31.86, 34.0, 36.75, 40.41, 45.06, 51.5, 61.09, 78.06, 150.0] - ">=2": [30.0, 42.38, 51.03, 59.81, 71.12, 86.0, 110.12, 150.0] - jpt_2: - <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jpt_2__eq_bin_opt, *QCD_var_dependence_n_bins] - correction_option: ["skip", "skip", "smoothed"] - bandwidth: [1.0, 1.0, 45.0] - var_bins: - "==0": [30.0, 150.0] - "==1": [30.0, 150.0] - ">=2": [30.0, 32.44, 35.62, 39.5, 45.22, 54.28, 70.0, 150.0] - met: - <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*met__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [25.0, 45.0, 60.0] - var_bins: - "==0": [0.0, 8.43, 12.17, 15.46, 18.63, 21.79, 25.19, 29.1, 33.7, 39.62, 48.82, 150.0] - "==1": [0.0, 10.72, 15.73, 20.25, 25.21, 30.93, 37.27, 46.11, 60.71, 150.0] - ">=2": [0.0, 15.22, 23.13, 32.17, 41.67, 53.45, 74.36, 150.0] - pt_tt: - <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*pt_tt__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [25.0, 35.0, 50.0] - var_bins: - "==0": [0.0, 7.38, 10.89, 13.94, 16.75, 19.51, 22.79, 26.2, 30.58, 36.0, 44.1, 150.0] - "==1": [0.0, 20.06, 28.4, 35.9, 42.23, 49.73, 57.79, 68.77, 85.18, 150.0] - ">=2": [0.0, 27.36, 44.71, 60.61, 75.95, 91.15, 112.19, 150.0] - deltaEta_ditaupair: - <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaEta_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [1.25, 1.5, 2.0] - var_bins: - "==0": [-4.9, -2.13, -1.42, -0.93, -0.53, -0.18, 0.16, 0.56, 0.96, 1.43, 2.08, 4.9] - "==1": [-4.9, -2.0, -1.23, -0.65, -0.23, 0.25, 0.72, 1.28, 2.04, 4.9] - ">=2": [-4.9, -1.9, -1.03, -0.39, 0.26, 0.87, 1.76, 4.9] - deltaR_ditaupair: - <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [0.8, 1.1, 1.2] - var_bins: - "==0": [0.5, 2.6814, 2.869, 2.9787, 3.0526, 3.1104, 3.1696, 3.2609, 3.3865, 3.5747, 3.9186, 5.0] - "==1": [0.5, 1.653, 2.227, 2.5243, 2.7304, 2.9125, 3.0715, 3.2696, 3.6723, 5.0] - ">=2": [0.5, 1.3291, 1.9185, 2.3753, 2.7661, 3.0644, 3.4088, 5.0] - deltaR_1j1: - <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_1j1__eq_bin_opt, *QCD_var_dependence_n_bins] - correction_option: ["skip", "smoothed", "smoothed"] - var_bins: - "==0": [0.5, 7.0] - "==1": [0.5, 1.67, 2.205, 2.51, 2.774, 3.019, 3.235, 3.586, 4.235, 7.0] - ">=2": [0.5, 1.825, 2.382, 2.761, 3.009, 3.272, 3.759, 7.0] - deltaR_12j1: - <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_12j1__eq_bin_opt, *QCD_var_dependence_n_bins] - correction_option: ["skip", "smoothed", "smoothed"] - bandwidth: [1.0, 1.5, 1.5] - var_bins: - "==0": [0.0, 10.0] - "==1": [0.0, 2.28, 2.73, 2.96, 3.11, 3.27, 3.55, 3.98, 4.87, 10.0] - ">=2": [0.0, 2.26, 2.72, 2.95, 3.14, 3.46, 4.06, 10.0] - pt_ttjj: - <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*pt_ttjj__eq_bin_opt, *QCD_var_dependence_n_bins] - correction_option: ["skip", "skip", "smoothed"] - bandwidth: [1.0, 1.0, 35.0] - var_bins: - "==0": [0.0, 150.0] - "==1": [0.0, 150.0] - ">=2": [0.0, 15.52, 22.28, 30.06, 38.0, 49.31, 69.77, 150.0] - mass_2: - <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mass_2__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [0.25, 0.35, 0.4] - var_bins: - "==0": [0.0, 0.2, 0.5107, 0.6216, 0.7388, 0.835, 0.9121, 0.9941, 1.0732, 1.1543, 1.25, 1.3623, 2.0] - "==1": [0.0, 0.2, 0.5322, 0.665, 0.79, 0.896, 1.0088, 1.0957, 1.1982, 1.3271, 2.0] - ">=2": [0.0, 0.2, 0.564, 0.7314, 0.8735, 0.9932, 1.1123, 1.2715, 2.0] - mt_tot: - <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mt_tot__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [25, 50, 60] - var_bins: - "==0": [50.0, 72.17, 77.52, 81.84, 85.76, 89.79, 94.23, 99.24, 105.25, 113.61, 130.06, 250.0] - "==1": [0.0, 59.33, 72.18, 80.25, 87.75, 95.78, 103.33, 114.05, 132.26, 250.0] - ">=2": [0.0, 53.08, 71.56, 83.98, 96.25, 111.26, 137.98, 250.0] - m_vis: - <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*m_vis__eq_bin_opt, *QCD_var_dependence_n_bins] - bandwidth: [25, 40.0, 60.0] - var_bins: - "==0": [40.0, 62.77, 67.12, 71.4, 75.97, 80.87, 87.03, 94.65, 105.53, 121.52, 147.95, 250.0] - "==1": [40.0, 59.53, 67.51, 74.21, 81.05, 89.85, 101.46, 120.46, 151.46, 250.0] - ">=2": [40.0, 59.6, 71.14, 82.96, 98.79, 118.59, 150.46, 250.0] - iso_1: - <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: *QCD_var_dependence_n_bins - variable_config: - iso_1: - min: 0.05 - max: 0.15 - rounding: 6 - bandwidth: [0.04, 0.04, 0.04] - correction_option: "smoothed" - var_bins: - "==0": [0.05, 0.056882, 0.063543, 0.070468, 0.078181, 0.086647, 0.095377, 0.105744, 0.115638, 0.126327, 0.137486, 0.15] - "==1": [0.05, 0.057096, 0.065105, 0.073987, 0.083517, 0.096737, 0.108642, 0.122276, 0.13489, 0.15] - ">=2": [0.05, 0.059351, 0.068657, 0.081325, 0.096132, 0.110882, 0.128247, 0.15] - - DR_SR: - use_embedding: false - compute_different_set_of_fake_factors: true - compute_different_set_of_fake_factors_using_data: true - <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mt_1__eq_bin_opt, *QCD_var_dependence_n_bins] - var_dependence_n_bins: - "==0": 9 - "==1": 7 - ">=2": 5 - variable_config: - mt_1: - min: 0.0 - max: 50.0 - rounding: 2 - bandwidth: [25.0, 40.0, 40.0] - var_bins: - "==0": [0.0, 3.07, 6.12, 9.59, 13.53, 17.81, 23.01, 29.07, 37.62, 50.0] - "==1": [0.0, 4.49, 9.31, 15.38, 21.65, 29.06, 38.65, 50.0] - ">=2": [0.0, 6.97, 14.92, 24.8, 36.54, 50.0] - SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! - lep_mt: (mt_1 < 50) - nbtag: (nbtag >= 0) - tau_pair_sign: ((q_1*q_2) > 0) - lep_iso: "(iso_1 > 0.15)" - ARlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! - lep_mt: (mt_1 < 50) - nbtag: (nbtag >= 0) - tau_pair_sign: ((q_1*q_2) > 0) - lep_iso: "(iso_1 > 0.15)" - AR_SR_cuts: - lep_mt: (mt_1 < 50) - nbtag: (nbtag >= 0) - tau_pair_sign: ((q_1*q_2) < 0) - lep_iso: "(iso_1 > 0.15)" - - Wjets: - chain_DR_SR_to_non_closure: true - - non_closure: - tau_decaymode_2: - <<: [*tau_decaymode_2, *3j_split] - correction_variations: ["Stat1Sigma", "SystMCShift"] - eta_1: - <<: [*eta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*eta_1__eq_bin_opt, *Wjets_var_dependence_n_bins] - var_dependence_n_bins: - "==0": 15 - "==1": 11 - ">=2": 5 - bandwidth: [0.65, 0.85, 1.25] - var_bins: - "==0": [-2.1, -1.73, -1.43, -1.15, -0.88, -0.62, -0.38, -0.12, 0.12, 0.38, 0.64, 0.89, 1.16, 1.45, 1.75, 2.1] - "==1": [-2.1, -1.61, -1.22, -0.85, -0.49, -0.13, 0.2, 0.55, 0.89, 1.25, 1.64, 2.1] - ">=2": [-2.1, -1.1, -0.33, 0.39, 1.16, 2.1] - eta_2: - <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*eta_2__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [0.6, 0.9, 1.2] - var_bins: - "==0": [-2.5, -1.64, -1.28, -1.03, -0.78, -0.55, -0.32, -0.09, 0.15, 0.37, 0.58, 0.81, 1.03, 1.29, 1.67, 2.5] - "==1": [-2.5, -1.52, -1.12, -0.78, -0.43, -0.11, 0.22, 0.51, 0.82, 1.14, 1.55, 2.5] - ">=2": [-2.5, -1.41, -0.95, -0.55, -0.14, 0.25, 0.63, 1.0, 1.43, 2.5] - jeta_1: - <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jeta_1__eq_bin_opt, *Wjets_var_dependence_n_bins] - var_dependence_n_bins: [1, 9, 7] - correction_option: ["skip", "smoothed", "smoothed"] - bandwidth: [1.0, 2.0, 2.0] - var_bins: - "==0": [-5.0, 5.0] - "==1": [-5.0, -2.71, -1.69, -0.94, -0.3, 0.34, 1.0, 1.77, 2.77, 5.0] - ">=2": [-5.0, -2.03, -1.07, -0.35, 0.35, 1.08, 2.07, 5.0] - jeta_2: - <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jeta_2__eq_bin_opt, *Wjets_var_dependence_n_bins] - var_dependence_n_bins: [1, 1, 7] - correction_option: ["skip", "skip", "smoothed"] - bandwidth: [1.0, 1.0, 3.0] - var_bins: - "==0": [-5.0, 5.0] - "==1": [-5.0, 5.0] - ">=2": [-5.0, -2.35, -1.22, -0.36, 0.39, 1.2, 2.28, 5.0] - jpt_1: - <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jpt_1__eq_bin_opt, *Wjets_var_dependence_n_bins] - correction_option: ["skip", "smoothed", "smoothed"] - bandwidth: [1.0, 40.0, 55.0] - var_bins: - "==0": [30.0, 150.0] - "==1": [30.0, 31.75, 33.75, 36.06, 38.91, 42.56, 46.97, 52.62, 59.94, 70.38, 89.44, 150.0] - ">=2": [30.0, 40.97, 48.16, 55.28, 63.12, 71.88, 82.69, 97.0, 117.88, 150.0] - jpt_2: - <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jpt_2__eq_bin_opt, *Wjets_var_dependence_n_bins] - correction_option: ["skip", "skip", "smoothed"] - bandwidth: [1.0, 1.0, 45.0] - var_bins: - "==0": [30.0, 150.0] - "==1": [30.0, 150.0] - ">=2": [30.0, 31.98, 34.44, 37.22, 41.0, 45.97, 52.78, 62.31, 79.88, 150.0] - met: - <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*met__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [20.0, 30.0, 60.0] - var_bins: - "==0": [0.0, 26.44, 31.34, 35.35, 38.85, 42.17, 45.53, 48.76, 52.09, 55.59, 59.33, 63.57, 68.59, 74.89, 84.82, 150.0] - "==1": [0.0, 30.65, 37.18, 42.51, 47.1, 51.9, 56.98, 62.52, 69.52, 78.66, 93.41, 150.0] - ">=2": [0.0, 34.19, 43.15, 50.77, 58.13, 66.48, 76.11, 88.39, 107.4, 150.0] - pt_tt: - <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*pt_tt__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [25.0, 35.0, 50.0] - var_bins: - "==0": [0.0, 6.97, 10.21, 12.86, 15.37, 17.8, 20.33, 22.96, 25.8, 28.95, 32.51, 36.56, 41.44, 47.79, 57.64, 150.0] - "==1": [0.0, 20.67, 28.94, 35.54, 41.79, 48.14, 54.45, 61.69, 70.13, 81.43, 99.35, 150.0] - ">=2": [0.0, 28.71, 41.98, 53.14, 64.21, 75.14, 87.86, 102.82, 121.49, 150.0] - deltaEta_ditaupair: - <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaEta_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [0.8, 1.1, 1.25] - var_bins: - "==0": [-4.9, -1.9, -1.36, -1.02, -0.75, -0.52, -0.31, -0.11, 0.09, 0.3, 0.51, 0.74, 1.0, 1.34, 1.87, 4.9] - "==1": [-4.9, -1.75, -1.16, -0.75, -0.43, -0.14, 0.14, 0.43, 0.74, 1.14, 1.74, 4.9] - ">=2": [-4.9, -1.56, -0.96, -0.53, -0.16, 0.19, 0.54, 0.95, 1.54, 4.9] - deltaR_ditaupair: - <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [0.5, 0.6, 0.7] - var_bins: - "==0": [0.5, 1.291, 1.6664, 1.9482, 2.1706, 2.3528, 2.5196, 2.6606, 2.783, 2.8902, 2.9821, 3.0643, 3.1321, 3.2287, 3.4481, 5.0] - "==1": [0.5, 1.1946, 1.5966, 1.9154, 2.1746, 2.4058, 2.6139, 2.801, 2.9638, 3.1049, 3.3191, 5.0] - ">=2": [0.5, 1.1567, 1.5816, 1.9338, 2.2206, 2.4933, 2.7366, 2.9631, 3.1951, 5.0] - deltaR_1j1: - <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_1j1__eq_bin_opt, *Wjets_var_dependence_n_bins] - correction_option: ["skip", "smoothed", "smoothed"] - bandwidth: [1.0, 1.0, 1.2] - var_bins: - "==0": [0.5, 7.0] - "==1": [0.5, 1.257, 1.688, 2.026, 2.312, 2.572, 2.811, 3.037, 3.282, 3.69, 4.342, 7.0] - ">=2": [0.5, 1.242, 1.733, 2.12, 2.446, 2.72, 2.978, 3.261, 3.842, 7.0] - deltaR_12j1: - <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_12j1__eq_bin_opt, *Wjets_var_dependence_n_bins] - correction_option: ["skip", "smoothed", "smoothed"] - bandwidth: [1.0, 1.5, 1.75] - var_bins: - "==0": [0.0, 10.0] - "==1": [0.0, 1.78, 2.26, 2.55, 2.77, 2.94, 3.1, 3.29, 3.58, 4.02, 4.82, 10.0] - ">=2": [0.0, 1.78, 2.28, 2.61, 2.84, 3.04, 3.23, 3.57, 4.21, 10.0] - pt_ttjj: - <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*pt_ttjj__eq_bin_opt, *Wjets_var_dependence_n_bins] - correction_option: ["skip", "skip", "smoothed"] - bandwidth: [1.0, 1.0, 30] - var_bins: - "==0": [0.0, 150.0] - "==1": [0.0, 150.0] - ">=2": [0.0, 13.13, 19.85, 25.75, 31.71, 38.56, 46.7, 57.79, 75.16, 150.0] - mass_2: - <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mass_2__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [0.225, 0.225, 0.25] - var_bins: - "==0": [0.0, 0.2, 0.4827, 0.5635, 0.6396, 0.707, 0.7681, 0.8281, 0.8857, 0.9453, 1.0078, 1.0713, 1.1377, 1.2109, 1.2949, 1.4092, 2.0] - "==1": [0.0, 0.2, 0.5088, 0.6177, 0.7119, 0.7959, 0.8696, 0.9551, 1.0381, 1.1279, 1.2285, 1.3545, 2.0] - ">=2": [0.0, 0.2, 0.5308, 0.6577, 0.7612, 0.8506, 0.957, 1.0625, 1.1758, 1.3076, 2.0] - mt_tot: - <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mt_tot__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [20.0, 30.0, 50.0] - var_bins: - "==0": [90.0, 107.0, 114.05, 118.88, 122.8, 126.47, 129.96, 133.5, 137.38, 141.66, 146.66, 152.62, 160.27, 171.17, 189.87, 250.0] - "==1": [80.0, 105.43, 113.18, 120.11, 126.5, 133.37, 140.45, 148.83, 158.49, 171.81, 194.95, 250.0] - ">=2": [80.0, 107.35, 119.32, 129.92, 139.77, 150.85, 163.8, 180.28, 204.68, 250.0] - m_vis: - <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*m_vis__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [20, 30, 40] - var_bins: - "==0": [40.0, 53.81, 63.19, 69.57, 74.63, 80.07, 85.73, 91.46, 97.14, 103.66, 111.09, 120.22, 132.11, 148.61, 175.66, 250.0] - "==1": [40.0, 56.8, 66.41, 74.1, 82.15, 90.75, 100.06, 111.42, 126.0, 145.26, 175.05, 250.0] - ">=2": [40.0, 59.87, 70.97, 81.27, 93.8, 107.02, 123.57, 145.41, 177.53, 250.0] - iso_1: - <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*iso_1__eq_bin_opt, *Wjets_var_dependence_n_bins] - bandwidth: [0.03, 0.04, 0.05] - var_bins: - "==0": [0.0, 0.00005, 0.004932, 0.007516, 0.010087, 0.012785, 0.015814, 0.019493, 0.023479, 0.028324, 0.034053, 0.040962, 0.049714, 0.060662, 0.075963, 0.100649, 0.15] - "==1": [0.0, 0.00005, 0.005621, 0.009072, 0.012884, 0.017279, 0.022713, 0.029417, 0.037605, 0.049066, 0.064637, 0.090462, 0.15] - ">=2": [0.0, 0.00005, 0.005602, 0.009668, 0.014723, 0.020748, 0.028099, 0.039254, 0.055474, 0.082078, 0.15] - - DR_SR: - use_embedding: true - compute_different_set_of_fake_factors: true - compute_different_set_of_fake_factors_using_data: false - <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mt_1__eq_bin_opt, *Wjets_var_dependence_n_bins] - var_dependence_n_bins: - "==0": 13 - "==1": 9 - ">=2": 7 - bandwidth: [25.0, 40.0, 50.0] - var_bins: - "==0": [0.0, 2.48, 5.08, 7.83, 10.91, 14.38, 18.35, 23.16, 28.9, 35.74, 43.7, 52.34, 61.16, 70.0] - "==1": [0.0, 5.24, 11.06, 17.27, 24.28, 32.24, 40.86, 50.19, 59.96, 70.0] - ">=2": [0.0, 6.96, 14.47, 22.71, 32.19, 43.21, 56.0, 70.0] - SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! - lep_mt: (mt_1 > 70) - nbtag: (nbtag == 0) - tau_pair_sign: ((q_1*q_2) < 0) - lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) - ARlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! - lep_mt: (mt_1 > 70) - nbtag: (nbtag == 0) - tau_pair_sign: ((q_1*q_2) < 0) - lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) - AR_SR_cuts: # this is only on MC! - lep_mt: (mt_1 < 70) - nbtag: (nbtag >= 0) - tau_pair_sign: ((q_1*q_2) < 0) - lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) - - ttbar: - non_closure: - tau_decaymode_2: - <<: [*tau_decaymode_2, *2j_split] - correction_variations: ["Stat1Sigma"] - eta_1: - <<: [*eta_1, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*eta_1__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [0.6, 1.0] - var_bins: - "<=1": [-2.1, -1.52, -1.08, -0.74, -0.44, -0.14, 0.13, 0.43, 0.72, 1.08, 1.51, 2.1] - ">=2": [-2.1, -1.61, -1.28, -1.0, -0.76, -0.53, -0.32, -0.1, 0.1, 0.33, 0.53, 0.76, 1.01, 1.29, 1.62, 2.1] - eta_2: - <<: [*eta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*eta_2__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [0.7, 0.7] - var_bins: - "<=1": [-2.5, -1.6, -1.18, -0.83, -0.48, -0.14, 0.19, 0.51, 0.87, 1.19, 1.59, 2.5] - ">=2": [-2.5, -1.83, -1.42, -1.15, -0.89, -0.62, -0.36, -0.1, 0.15, 0.4, 0.66, 0.93, 1.18, 1.44, 1.83, 2.5] - jeta_1: - <<: [*jeta_1, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jeta_1__eq_bin_opt, *ttbar_var_dependence_n_bins] - correction_option: "smoothed" - bandwidth: [1.0, 2.0] - var_bins: - "<=1": [-5.0, -1.8, -1.25, -0.85, -0.48, -0.17, 0.16, 0.49, 0.83, 1.24, 1.83, 5.0] - ">=2": [-5.0, -2.06, -1.56, -1.19, -0.88, -0.62, -0.36, -0.12, 0.13, 0.37, 0.63, 0.91, 1.22, 1.58, 2.08, 5.0] - jeta_2: - <<: [*jeta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jeta_2__eq_bin_opt, *ttbar_var_dependence_n_bins] - var_dependence_n_bins: [1, 15] - correction_option: ["skip", "smoothed"] - var_bins: - "<=1": [-5.0, 5.0] - ">=2": [-5.0, -2.23, -1.67, -1.27, -0.95, -0.66, -0.39, -0.12, 0.13, 0.39, 0.67, 0.95, 1.29, 1.69, 2.25, 5.0] - jpt_1: - <<: [*jpt_1, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jpt_1__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [30.0, 20.0] - var_bins: - "<=1": [30.0, 35.36, 40.96, 46.65, 52.23, 58.54, 65.09, 72.75, 82.08, 94.53, 111.82, 150.0] - ">=2": [30.0, 47.65, 54.97, 60.91, 66.28, 71.41, 76.42, 81.65, 87.12, 92.85, 99.07, 105.86, 113.72, 123.2, 135.2, 150.0] - jpt_2: - <<: [*jpt_2, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*jpt_2__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [30.0, 30.0] - correction_option: ["skip", "smoothed"] - var_bins: - "<=1": [30.0, 150.0] - ">=2": [30.0, 34.04, 37.51, 40.9, 44.36, 47.9, 51.37, 55.15, 59.19, 63.62, 68.59, 74.66, 82.46, 93.05, 109.69, 150.0] - met: - <<: [*met, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*met__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [40.0, 35.0] - var_bins: - "<=1": [0.0, 14.66, 22.03, 28.03, 34.31, 40.61, 47.23, 55.17, 64.25, 76.67, 95.52, 150.0] - ">=2": [0.0, 13.5, 19.68, 25.11, 30.24, 35.17, 40.53, 46.2, 52.21, 58.7, 66.15, 74.85, 85.02, 97.62, 116.03, 150.0] - pt_tt: - <<: [*pt_tt, *2j_split, *correction_variations__with_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*pt_tt__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [25.0, 35.0] - var_bins: - "<=1": [0.0, 24.45, 35.1, 43.91, 52.13, 60.74, 69.18, 78.19, 87.94, 100.55, 117.97, 150.0] - ">=2": [0.0, 25.92, 38.05, 47.24, 55.39, 62.86, 69.81, 76.99, 84.08, 91.29, 98.76, 106.54, 115.17, 124.87, 136.3, 150.0] - deltaEta_ditaupair: - <<: [*deltaEta_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaEta_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [1.5, 1.75] - var_bins: - "<=1": [-4.9, -1.57, -1.06, -0.71, -0.43, -0.17, 0.11, 0.39, 0.69, 1.05, 1.56, 4.9] - ">=2": [-4.9, -2.0, -1.47, -1.1, -0.82, -0.58, -0.35, -0.12, 0.1, 0.33, 0.55, 0.79, 1.07, 1.43, 1.99, 4.9] - deltaR_ditaupair: - <<: [*deltaR_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [0.75, 1.0] - var_bins: - "<=1": [0.5, 1.2589, 1.6931, 2.0017, 2.272, 2.4783, 2.6662, 2.8297, 2.9717, 3.103, 3.283, 5.0] - ">=2": [0.5, 0.9472, 1.2341, 1.4726, 1.6983, 1.9055, 2.0972, 2.2769, 2.4468, 2.6064, 2.7588, 2.9015, 3.0423, 3.1826, 3.465, 5.0] - deltaR_1j1: - <<: [*deltaR_1j1, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_1j1__eq_bin_opt, *ttbar_var_dependence_n_bins] - var_bins: - "<=1": [0.5, 1.343, 1.785, 2.09, 2.344, 2.552, 2.723, 2.882, 3.037, 3.185, 3.478, 7.0] - ">=2": [0.5, 1.158, 1.535, 1.836, 2.086, 2.291, 2.467, 2.618, 2.754, 2.872, 2.984, 3.087, 3.201, 3.395, 3.767, 7.0] - deltaR_12j1: - <<: [*deltaR_12j1, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*deltaR_12j1__eq_bin_opt, *ttbar_var_dependence_n_bins] - correction_option: "smoothed" - bandwidth: [1.5, 1.5] - var_bins: - "<=1": [0.0, 1.8, 2.26, 2.53, 2.73, 2.88, 3.0, 3.11, 3.25, 3.48, 3.87, 10.0] - ">=2": [0.0, 1.5, 1.94, 2.22, 2.42, 2.58, 2.72, 2.83, 2.94, 3.03, 3.12, 3.23, 3.39, 3.64, 4.09, 10.0] - pt_ttjj: - <<: [*pt_ttjj, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*pt_ttjj__eq_bin_opt, *ttbar_var_dependence_n_bins] - correction_option: ["skip", "smoothed"] - var_bins: - "<=1": [0.0, 150.0] - ">=2": [0.0, 15.23, 22.09, 27.98, 33.27, 38.42, 43.61, 48.82, 54.23, 60.19, 66.83, 74.34, 83.25, 95.43, 112.85, 150.0] - mass_2: - <<: [*mass_2, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mass_2__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [0.225, 0.175] - var_bins: - "<=1": [0.0, 0.2, 0.5542, 0.7139, 0.8491, 0.9507, 1.0391, 1.1172, 1.1963, 1.2773, 1.374, 1.4785, 2.0] - ">=2": [0.0, 0.2, 0.4985, 0.6196, 0.7344, 0.8311, 0.9072, 0.9736, 1.0352, 1.0957, 1.1553, 1.2168, 1.2793, 1.3447, 1.416, 1.5039, 2.0] - mt_tot: - <<: [*mt_tot, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*mt_tot__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [35.0, 40.0] - var_bins: - "<=1": [0.0, 71.15, 85.76, 95.51, 104.09, 111.98, 120.16, 129.15, 140.06, 155.19, 180.06, 250.0] - ">=2": [0.0, 54.45, 70.52, 80.81, 88.59, 95.47, 102.0, 108.62, 115.3, 122.53, 130.56, 139.48, 150.09, 164.95, 189.62, 250.0] - m_vis: - <<: [*m_vis, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*m_vis__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [20, 20] - var_bins: - "<=1": [40.0, 57.23, 66.64, 74.08, 80.63, 87.14, 94.16, 102.36, 112.55, 128.21, 163.02, 250.0] - ">=2": [40.0, 52.04, 60.23, 66.79, 72.63, 78.31, 83.65, 89.47, 95.56, 102.24, 110.06, 119.97, 133.62, 153.79, 184.28, 250.0] - iso_1: - <<: [*iso_1, *2j_split, *correction_variations__without_mc_subtraction_shift] - equipopulated_binning_options: - <<: [*iso_1__eq_bin_opt, *ttbar_var_dependence_n_bins] - bandwidth: [0.05, 0.05] - var_bins: - "<=1": [0.0, 0.00005, 0.006133, 0.009499, 0.01269, 0.017176, 0.022144, 0.027969, 0.0369, 0.048008, 0.063692, 0.090369, 0.15] - ">=2": [0.0, 0.00005, 0.004676, 0.007108, 0.009587, 0.012164, 0.015111, 0.018535, 0.022638, 0.027259, 0.032977, 0.039821, 0.048317, 0.060037, 0.075678, 0.101079, 0.15] diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml b/configs/smhtt_ul/2018/corrections_mt.yaml new file mode 120000 index 0000000..a7cd0ae --- /dev/null +++ b/configs/smhtt_ul/2018/corrections_mt.yaml @@ -0,0 +1 @@ +corrections_mt.yaml.classic \ No newline at end of file diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml.classic b/configs/smhtt_ul/2018/corrections_mt.yaml.classic new file mode 100644 index 0000000..6c7c82e --- /dev/null +++ b/configs/smhtt_ul/2018/corrections_mt.yaml.classic @@ -0,0 +1,802 @@ +templates: + split_schemes: + 3j: &3j_split + split_categories: + njets: ["==0", "==1", ">=2"] + split_categories_binedges: + njets: [-0.5, 0.5, 1.5, 22.5] + correction_option: + "==0": "smoothed" + "==1": "smoothed" + ">=2": "smoothed" + bandwidth: + "==0": 1.0 + "==1": 1.0 + ">=2": 1.0 + 2j: &2j_split + split_categories: + njets: ["<=1", ">=2"] + split_categories_binedges: + njets: [-0.5, 1.5, 22.5] + correction_option: + "<=1": "smoothed" + ">=2": "smoothed" + bandwidth: + "<=1": 1 + ">=2": 1 + var_dependence_n_bins: + QCD: + equipopulated_binning_options: &QCD_var_dependence_n_bins + var_dependence_n_bins: + "==0": 11 + "==1": 9 + ">=2": 7 + Wjets: + equipopulated_binning_options: &Wjets_var_dependence_n_bins + var_dependence_n_bins: + "==0": 15 + "==1": 11 + ">=2": 9 + ttbar: + equipopulated_binning_options: &ttbar_var_dependence_n_bins + var_dependence_n_bins: + "<=1": 11 + ">=2": 15 + correction_variations__with_mc_subtraction_shift: &correction_variations__with_mc_subtraction_shift + correction_variations: + - Stat1Sigma + - SystMCShift + - SystBandAsym + correction_variations__without_mc_subtraction_shift: &correction_variations__without_mc_subtraction_shift + correction_variations: + - Stat1Sigma + - SystBandAsym + variables: + eta_1: &eta_1 + var_dependence: eta_1 + equipopulated_binning_options: &eta_1__eq_bin_opt + variable_config: + eta_1: + min: -2.1 + max: +2.1 + rounding: 2 + correction_option: "smoothed" + bandwidth: 1.0 + eta_2: &eta_2 + var_dependence: eta_2 + equipopulated_binning_options: &eta_2__eq_bin_opt + variable_config: + eta_2: + min: -2.5 + max: +2.5 + rounding: 2 + correction_option: "smoothed" + bandwidth: 1.5 + deltaEta_ditaupair: &deltaEta_ditaupair + var_dependence: deltaEta_ditaupair + equipopulated_binning_options: &deltaEta_ditaupair__eq_bin_opt + variable_config: + deltaEta_ditaupair: + min: -4.9 + max: +4.9 + rounding: 2 + correction_option: "smoothed" + bandwidth: 1.75 + deltaR_ditaupair: &deltaR_ditaupair + var_dependence: deltaR_ditaupair + equipopulated_binning_options: &deltaR_ditaupair__eq_bin_opt + variable_config: + deltaR_ditaupair: + min: 0.5 + max: 5.0 + rounding: 4 + correction_option: "smoothed" + jeta_1: &jeta_1 + var_dependence: jeta_1 + equipopulated_binning_options: &jeta_1__eq_bin_opt + variable_config: + jeta_1: + min: -5.0 + max: +5.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 2.0 + jeta_2: &jeta_2 + var_dependence: jeta_2 + equipopulated_binning_options: &jeta_2__eq_bin_opt + variable_config: + jeta_2: + min: -5.0 + max: +5.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 2.0 + jpt_1: &jpt_1 + var_dependence: jpt_1 + equipopulated_binning_options: &jpt_1__eq_bin_opt + variable_config: + jpt_1: + min: 30.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + jpt_2: &jpt_2 + var_dependence: jpt_2 + equipopulated_binning_options: &jpt_2__eq_bin_opt + variable_config: + jpt_2: + min: 30.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + met: &met + var_dependence: met + equipopulated_binning_options: &met__eq_bin_opt + variable_config: + met: + min: 0.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 25 + mt_1: &mt_1 + var_dependence: mt_1 + equipopulated_binning_options: &mt_1__eq_bin_opt + variable_config: + mt_1: + min: 0.0 + max: 70.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 20 + pt_tt: &pt_tt + var_dependence: pt_tt + equipopulated_binning_options: &pt_tt__eq_bin_opt + variable_config: + pt_tt: + min: 0.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 25 + pt_ttjj: &pt_ttjj + var_dependence: pt_ttjj + equipopulated_binning_options: &pt_ttjj__eq_bin_opt + variable_config: + pt_ttjj: + min: 0.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 25 + mt_tot: &mt_tot + var_dependence: mt_tot + equipopulated_binning_options: &mt_tot__eq_bin_opt + variable_config: + mt_tot: + min: 0.0 + max: 250.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 40 + mass_2: &mass_2 + var_dependence: mass_2 + equipopulated_binning_options: &mass_2__eq_bin_opt + variable_config: + mass_2: + min: 0.2 + max: 2.0 + rounding: 4 + add_left: [0.0] + correction_option: "binwise#[0]+smoothed" + bandwidth: 0.3 + tau_decaymode_2: &tau_decaymode_2 + var_dependence: tau_decaymode_2 + correction_option: "binwise" + bandwidth: 1.0 + var_bins: [-0.5, 0.5, 9.5, 10.5, 11.5] + iso_1: &iso_1 + var_dependence: iso_1 + equipopulated_binning_options: &iso_1__eq_bin_opt + variable_config: + iso_1: + min: 0.00005 + max: 0.15 + rounding: 6 + add_left: [0.0] + correction_option: "binwise#[0]+smoothed" + bandwidth: 0.02 + deltaR_1j1: &deltaR_1j1 + var_dependence: deltaR_1j1 + equipopulated_binning_options: &deltaR_1j1__eq_bin_opt + variable_config: + deltaR_1j1: + min: 0.5 + max: 7.0 + rounding: 3 + correction_option: "smoothed" + bandwidth: 0.9 + deltaR_12j1: &deltaR_12j1 + var_dependence: deltaR_12j1 + equipopulated_binning_options: &deltaR_12j1__eq_bin_opt + variable_config: + deltaR_12j1: + min: 0.0 + max: 10.0 + correction_option: "smoothed" + bandwidth: 1.25 + m_vis: &m_vis + var_dependence: m_vis + equipopulated_binning_options: &m_vis__eq_bin_opt + variable_config: + m_vis: + min: 40.0 + max: 250.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 30 + +channel: mt +target_processes: + QCD: + chain_DR_SR_to_non_closure: true + + non_closure: + tau_decaymode_2: + <<: [*tau_decaymode_2, *3j_split] + correction_variations: ["Stat1Sigma", "SystMCShift"] + eta_1: + <<: [*eta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*eta_1__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [0.8, 1.0, 1.0] + var_bins: + "==0": [-2.1, -1.56, -1.26, -0.86, -0.5, -0.14, 0.22, 0.56, 0.93, 1.3, 1.63, 2.1] + "==1": [-2.1, -1.51, -1.13, -0.66, -0.22, 0.22, 0.7, 1.15, 1.54, 2.1] + ">=2": [-2.1, -1.37, -0.82, -0.33, 0.23, 0.81, 1.37, 2.1] + eta_2: + <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*eta_2__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [0.9, 1.1, 1.5] + var_bins: + "==0": [-2.5, -1.68, -1.28, -0.92, -0.57, -0.18, 0.24, 0.62, 0.99, 1.31, 1.78, 2.5] + "==1": [-2.5, -1.67, -1.19, -0.73, -0.25, 0.28, 0.72, 1.17, 1.59, 2.5] + ">=2": [-2.5, -1.41, -0.87, -0.21, 0.4, 0.94, 1.55, 2.5] + jeta_1: + <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jeta_1__eq_bin_opt, *QCD_var_dependence_n_bins] + var_dependence_n_bins: [1, 9, 7] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 2.5, 2.5] + var_bins: + "==0": [-5.0, 5.0] + "==1": [-5.0, -2.73, -1.63, -0.92, -0.28, 0.34, 0.92, 1.65, 2.61, 5.0] + ">=2": [-5.0, -2.02, -1.07, -0.33, 0.31, 0.99, 1.98, 5.0] + jeta_2: + <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jeta_2__eq_bin_opt, *QCD_var_dependence_n_bins] + var_dependence_n_bins: [1, 1, 7] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 4] + var_bins: + "==0": [-5.0, 5.0] + "==1": [-5.0, 5.0] + ">=2": [-5.0, -2.1, -1.13, -0.36, 0.33, 1.16, 2.2, 5.0] + jpt_1: + <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jpt_1__eq_bin_opt, *QCD_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 50.0, 60.0] + var_bins: + "==0": [30.0, 150.0] + "==1": [30.0, 31.86, 34.0, 36.75, 40.41, 45.06, 51.5, 61.09, 78.06, 150.0] + ">=2": [30.0, 42.38, 51.03, 59.81, 71.12, 86.0, 110.12, 150.0] + jpt_2: + <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jpt_2__eq_bin_opt, *QCD_var_dependence_n_bins] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 45.0] + var_bins: + "==0": [30.0, 150.0] + "==1": [30.0, 150.0] + ">=2": [30.0, 32.44, 35.62, 39.5, 45.22, 54.28, 70.0, 150.0] + met: + <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*met__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [25.0, 45.0, 60.0] + var_bins: + "==0": [0.0, 8.43, 12.17, 15.46, 18.63, 21.79, 25.19, 29.1, 33.7, 39.62, 48.82, 150.0] + "==1": [0.0, 10.72, 15.73, 20.25, 25.21, 30.93, 37.27, 46.11, 60.71, 150.0] + ">=2": [0.0, 15.22, 23.13, 32.17, 41.67, 53.45, 74.36, 150.0] + pt_tt: + <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_tt__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [25.0, 35.0, 50.0] + var_bins: + "==0": [0.0, 7.38, 10.89, 13.94, 16.75, 19.51, 22.79, 26.2, 30.58, 36.0, 44.1, 150.0] + "==1": [0.0, 20.06, 28.4, 35.9, 42.23, 49.73, 57.79, 68.77, 85.18, 150.0] + ">=2": [0.0, 27.36, 44.71, 60.61, 75.95, 91.15, 112.19, 150.0] + deltaEta_ditaupair: + <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaEta_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [1.25, 1.5, 2.0] + var_bins: + "==0": [-4.9, -2.13, -1.42, -0.93, -0.53, -0.18, 0.16, 0.56, 0.96, 1.43, 2.08, 4.9] + "==1": [-4.9, -2.0, -1.23, -0.65, -0.23, 0.25, 0.72, 1.28, 2.04, 4.9] + ">=2": [-4.9, -1.9, -1.03, -0.39, 0.26, 0.87, 1.76, 4.9] + deltaR_ditaupair: + <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [0.8, 1.1, 1.2] + var_bins: + "==0": [0.5, 2.6814, 2.869, 2.9787, 3.0526, 3.1104, 3.1696, 3.2609, 3.3865, 3.5747, 3.9186, 5.0] + "==1": [0.5, 1.653, 2.227, 2.5243, 2.7304, 2.9125, 3.0715, 3.2696, 3.6723, 5.0] + ">=2": [0.5, 1.3291, 1.9185, 2.3753, 2.7661, 3.0644, 3.4088, 5.0] + deltaR_1j1: + <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_1j1__eq_bin_opt, *QCD_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + var_bins: + "==0": [0.5, 7.0] + "==1": [0.5, 1.67, 2.205, 2.51, 2.774, 3.019, 3.235, 3.586, 4.235, 7.0] + ">=2": [0.5, 1.825, 2.382, 2.761, 3.009, 3.272, 3.759, 7.0] + deltaR_12j1: + <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_12j1__eq_bin_opt, *QCD_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 1.5, 1.5] + var_bins: + "==0": [0.0, 10.0] + "==1": [0.0, 2.28, 2.73, 2.96, 3.11, 3.27, 3.55, 3.98, 4.87, 10.0] + ">=2": [0.0, 2.26, 2.72, 2.95, 3.14, 3.46, 4.06, 10.0] + pt_ttjj: + <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_ttjj__eq_bin_opt, *QCD_var_dependence_n_bins] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 35.0] + var_bins: + "==0": [0.0, 150.0] + "==1": [0.0, 150.0] + ">=2": [0.0, 15.52, 22.28, 30.06, 38.0, 49.31, 69.77, 150.0] + mass_2: + <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mass_2__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [0.25, 0.35, 0.4] + var_bins: + "==0": [0.0, 0.2, 0.5107, 0.6216, 0.7388, 0.835, 0.9121, 0.9941, 1.0732, 1.1543, 1.25, 1.3623, 2.0] + "==1": [0.0, 0.2, 0.5322, 0.665, 0.79, 0.896, 1.0088, 1.0957, 1.1982, 1.3271, 2.0] + ">=2": [0.0, 0.2, 0.564, 0.7314, 0.8735, 0.9932, 1.1123, 1.2715, 2.0] + mt_tot: + <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mt_tot__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [25, 50, 60] + var_bins: + "==0": [50.0, 72.17, 77.52, 81.84, 85.76, 89.79, 94.23, 99.24, 105.25, 113.61, 130.06, 250.0] + "==1": [0.0, 59.33, 72.18, 80.25, 87.75, 95.78, 103.33, 114.05, 132.26, 250.0] + ">=2": [0.0, 53.08, 71.56, 83.98, 96.25, 111.26, 137.98, 250.0] + m_vis: + <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*m_vis__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [25, 40.0, 60.0] + var_bins: + "==0": [40.0, 62.77, 67.12, 71.4, 75.97, 80.87, 87.03, 94.65, 105.53, 121.52, 147.95, 250.0] + "==1": [40.0, 59.53, 67.51, 74.21, 81.05, 89.85, 101.46, 120.46, 151.46, 250.0] + ">=2": [40.0, 59.6, 71.14, 82.96, 98.79, 118.59, 150.46, 250.0] + iso_1: + <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: *QCD_var_dependence_n_bins + variable_config: + iso_1: + min: 0.05 + max: 0.15 + rounding: 6 + bandwidth: [0.04, 0.04, 0.04] + correction_option: "smoothed" + var_bins: + "==0": [0.05, 0.056882, 0.063543, 0.070468, 0.078181, 0.086647, 0.095377, 0.105744, 0.115638, 0.126327, 0.137486, 0.15] + "==1": [0.05, 0.057096, 0.065105, 0.073987, 0.083517, 0.096737, 0.108642, 0.122276, 0.13489, 0.15] + ">=2": [0.05, 0.059351, 0.068657, 0.081325, 0.096132, 0.110882, 0.128247, 0.15] + + DR_SR: + use_embedding: false + compute_different_set_of_fake_factors: true + compute_different_set_of_fake_factors_using_data: true + <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mt_1__eq_bin_opt, *QCD_var_dependence_n_bins] + var_dependence_n_bins: + "==0": 9 + "==1": 7 + ">=2": 5 + variable_config: + mt_1: + min: 0.0 + max: 50.0 + rounding: 2 + bandwidth: [25.0, 40.0, 40.0] + var_bins: + "==0": [0.0, 3.07, 6.12, 9.59, 13.53, 17.81, 23.01, 29.07, 37.62, 50.0] + "==1": [0.0, 4.49, 9.31, 15.38, 21.65, 29.06, 38.65, 50.0] + ">=2": [0.0, 6.97, 14.92, 24.8, 36.54, 50.0] + SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! + lep_mt: (mt_1 < 50) + nbtag: (nbtag >= 0) + tau_pair_sign: ((q_1*q_2) > 0) + lep_iso: "(iso_1 > 0.15)" + ARlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! + lep_mt: (mt_1 < 50) + nbtag: (nbtag >= 0) + tau_pair_sign: ((q_1*q_2) > 0) + lep_iso: "(iso_1 > 0.15)" + AR_SR_cuts: + lep_mt: (mt_1 < 50) + nbtag: (nbtag >= 0) + tau_pair_sign: ((q_1*q_2) < 0) + lep_iso: "(iso_1 > 0.15)" + + Wjets: + chain_DR_SR_to_non_closure: true + + non_closure: + tau_decaymode_2: + <<: [*tau_decaymode_2, *3j_split] + correction_variations: ["Stat1Sigma", "SystMCShift"] + eta_1: + <<: [*eta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*eta_1__eq_bin_opt, *Wjets_var_dependence_n_bins] + var_dependence_n_bins: + "==0": 15 + "==1": 11 + ">=2": 5 + bandwidth: [0.65, 0.85, 1.25] + var_bins: + "==0": [-2.1, -1.73, -1.43, -1.15, -0.88, -0.62, -0.38, -0.12, 0.12, 0.38, 0.64, 0.89, 1.16, 1.45, 1.75, 2.1] + "==1": [-2.1, -1.61, -1.22, -0.85, -0.49, -0.13, 0.2, 0.55, 0.89, 1.25, 1.64, 2.1] + ">=2": [-2.1, -1.1, -0.33, 0.39, 1.16, 2.1] + eta_2: + <<: [*eta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*eta_2__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.6, 0.9, 1.2] + var_bins: + "==0": [-2.5, -1.64, -1.28, -1.03, -0.78, -0.55, -0.32, -0.09, 0.15, 0.37, 0.58, 0.81, 1.03, 1.29, 1.67, 2.5] + "==1": [-2.5, -1.52, -1.12, -0.78, -0.43, -0.11, 0.22, 0.51, 0.82, 1.14, 1.55, 2.5] + ">=2": [-2.5, -1.41, -0.95, -0.55, -0.14, 0.25, 0.63, 1.0, 1.43, 2.5] + jeta_1: + <<: [*jeta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jeta_1__eq_bin_opt, *Wjets_var_dependence_n_bins] + var_dependence_n_bins: [1, 9, 7] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 2.0, 2.0] + var_bins: + "==0": [-5.0, 5.0] + "==1": [-5.0, -2.71, -1.69, -0.94, -0.3, 0.34, 1.0, 1.77, 2.77, 5.0] + ">=2": [-5.0, -2.03, -1.07, -0.35, 0.35, 1.08, 2.07, 5.0] + jeta_2: + <<: [*jeta_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jeta_2__eq_bin_opt, *Wjets_var_dependence_n_bins] + var_dependence_n_bins: [1, 1, 7] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 3.0] + var_bins: + "==0": [-5.0, 5.0] + "==1": [-5.0, 5.0] + ">=2": [-5.0, -2.35, -1.22, -0.36, 0.39, 1.2, 2.28, 5.0] + jpt_1: + <<: [*jpt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jpt_1__eq_bin_opt, *Wjets_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 40.0, 55.0] + var_bins: + "==0": [30.0, 150.0] + "==1": [30.0, 31.75, 33.75, 36.06, 38.91, 42.56, 46.97, 52.62, 59.94, 70.38, 89.44, 150.0] + ">=2": [30.0, 40.97, 48.16, 55.28, 63.12, 71.88, 82.69, 97.0, 117.88, 150.0] + jpt_2: + <<: [*jpt_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jpt_2__eq_bin_opt, *Wjets_var_dependence_n_bins] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 45.0] + var_bins: + "==0": [30.0, 150.0] + "==1": [30.0, 150.0] + ">=2": [30.0, 31.98, 34.44, 37.22, 41.0, 45.97, 52.78, 62.31, 79.88, 150.0] + met: + <<: [*met, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*met__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [20.0, 30.0, 60.0] + var_bins: + "==0": [0.0, 26.44, 31.34, 35.35, 38.85, 42.17, 45.53, 48.76, 52.09, 55.59, 59.33, 63.57, 68.59, 74.89, 84.82, 150.0] + "==1": [0.0, 30.65, 37.18, 42.51, 47.1, 51.9, 56.98, 62.52, 69.52, 78.66, 93.41, 150.0] + ">=2": [0.0, 34.19, 43.15, 50.77, 58.13, 66.48, 76.11, 88.39, 107.4, 150.0] + pt_tt: + <<: [*pt_tt, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_tt__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [25.0, 35.0, 50.0] + var_bins: + "==0": [0.0, 6.97, 10.21, 12.86, 15.37, 17.8, 20.33, 22.96, 25.8, 28.95, 32.51, 36.56, 41.44, 47.79, 57.64, 150.0] + "==1": [0.0, 20.67, 28.94, 35.54, 41.79, 48.14, 54.45, 61.69, 70.13, 81.43, 99.35, 150.0] + ">=2": [0.0, 28.71, 41.98, 53.14, 64.21, 75.14, 87.86, 102.82, 121.49, 150.0] + deltaEta_ditaupair: + <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaEta_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.8, 1.1, 1.25] + var_bins: + "==0": [-4.9, -1.9, -1.36, -1.02, -0.75, -0.52, -0.31, -0.11, 0.09, 0.3, 0.51, 0.74, 1.0, 1.34, 1.87, 4.9] + "==1": [-4.9, -1.75, -1.16, -0.75, -0.43, -0.14, 0.14, 0.43, 0.74, 1.14, 1.74, 4.9] + ">=2": [-4.9, -1.56, -0.96, -0.53, -0.16, 0.19, 0.54, 0.95, 1.54, 4.9] + deltaR_ditaupair: + <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.5, 0.6, 0.7] + var_bins: + "==0": [0.5, 1.291, 1.6664, 1.9482, 2.1706, 2.3528, 2.5196, 2.6606, 2.783, 2.8902, 2.9821, 3.0643, 3.1321, 3.2287, 3.4481, 5.0] + "==1": [0.5, 1.1946, 1.5966, 1.9154, 2.1746, 2.4058, 2.6139, 2.801, 2.9638, 3.1049, 3.3191, 5.0] + ">=2": [0.5, 1.1567, 1.5816, 1.9338, 2.2206, 2.4933, 2.7366, 2.9631, 3.1951, 5.0] + deltaR_1j1: + <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_1j1__eq_bin_opt, *Wjets_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 1.0, 1.2] + var_bins: + "==0": [0.5, 7.0] + "==1": [0.5, 1.257, 1.688, 2.026, 2.312, 2.572, 2.811, 3.037, 3.282, 3.69, 4.342, 7.0] + ">=2": [0.5, 1.242, 1.733, 2.12, 2.446, 2.72, 2.978, 3.261, 3.842, 7.0] + deltaR_12j1: + <<: [*deltaR_12j1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_12j1__eq_bin_opt, *Wjets_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 1.5, 1.75] + var_bins: + "==0": [0.0, 10.0] + "==1": [0.0, 1.78, 2.26, 2.55, 2.77, 2.94, 3.1, 3.29, 3.58, 4.02, 4.82, 10.0] + ">=2": [0.0, 1.78, 2.28, 2.61, 2.84, 3.04, 3.23, 3.57, 4.21, 10.0] + pt_ttjj: + <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_ttjj__eq_bin_opt, *Wjets_var_dependence_n_bins] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 30] + var_bins: + "==0": [0.0, 150.0] + "==1": [0.0, 150.0] + ">=2": [0.0, 13.13, 19.85, 25.75, 31.71, 38.56, 46.7, 57.79, 75.16, 150.0] + mass_2: + <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mass_2__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.225, 0.225, 0.25] + var_bins: + "==0": [0.0, 0.2, 0.4827, 0.5635, 0.6396, 0.707, 0.7681, 0.8281, 0.8857, 0.9453, 1.0078, 1.0713, 1.1377, 1.2109, 1.2949, 1.4092, 2.0] + "==1": [0.0, 0.2, 0.5088, 0.6177, 0.7119, 0.7959, 0.8696, 0.9551, 1.0381, 1.1279, 1.2285, 1.3545, 2.0] + ">=2": [0.0, 0.2, 0.5308, 0.6577, 0.7612, 0.8506, 0.957, 1.0625, 1.1758, 1.3076, 2.0] + mt_tot: + <<: [*mt_tot, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mt_tot__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [20.0, 30.0, 50.0] + var_bins: + "==0": [90.0, 107.0, 114.05, 118.88, 122.8, 126.47, 129.96, 133.5, 137.38, 141.66, 146.66, 152.62, 160.27, 171.17, 189.87, 250.0] + "==1": [80.0, 105.43, 113.18, 120.11, 126.5, 133.37, 140.45, 148.83, 158.49, 171.81, 194.95, 250.0] + ">=2": [80.0, 107.35, 119.32, 129.92, 139.77, 150.85, 163.8, 180.28, 204.68, 250.0] + m_vis: + <<: [*m_vis, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*m_vis__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [20, 30, 40] + var_bins: + "==0": [40.0, 53.81, 63.19, 69.57, 74.63, 80.07, 85.73, 91.46, 97.14, 103.66, 111.09, 120.22, 132.11, 148.61, 175.66, 250.0] + "==1": [40.0, 56.8, 66.41, 74.1, 82.15, 90.75, 100.06, 111.42, 126.0, 145.26, 175.05, 250.0] + ">=2": [40.0, 59.87, 70.97, 81.27, 93.8, 107.02, 123.57, 145.41, 177.53, 250.0] + iso_1: + <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*iso_1__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.03, 0.04, 0.05] + var_bins: + "==0": [0.0, 0.00005, 0.004932, 0.007516, 0.010087, 0.012785, 0.015814, 0.019493, 0.023479, 0.028324, 0.034053, 0.040962, 0.049714, 0.060662, 0.075963, 0.100649, 0.15] + "==1": [0.0, 0.00005, 0.005621, 0.009072, 0.012884, 0.017279, 0.022713, 0.029417, 0.037605, 0.049066, 0.064637, 0.090462, 0.15] + ">=2": [0.0, 0.00005, 0.005602, 0.009668, 0.014723, 0.020748, 0.028099, 0.039254, 0.055474, 0.082078, 0.15] + + DR_SR: + use_embedding: true + compute_different_set_of_fake_factors: true + compute_different_set_of_fake_factors_using_data: false + <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mt_1__eq_bin_opt, *Wjets_var_dependence_n_bins] + var_dependence_n_bins: + "==0": 13 + "==1": 9 + ">=2": 7 + bandwidth: [25.0, 40.0, 50.0] + var_bins: + "==0": [0.0, 2.48, 5.08, 7.83, 10.91, 14.38, 18.35, 23.16, 28.9, 35.74, 43.7, 52.34, 61.16, 70.0] + "==1": [0.0, 5.24, 11.06, 17.27, 24.28, 32.24, 40.86, 50.19, 59.96, 70.0] + ">=2": [0.0, 6.96, 14.47, 22.71, 32.19, 43.21, 56.0, 70.0] + SRlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! + lep_mt: (mt_1 > 70) + nbtag: (nbtag == 0) + tau_pair_sign: ((q_1*q_2) < 0) + lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) + ARlike_cuts: # Try for yet perpendicular to the fake_factors_mt.yaml definition! + lep_mt: (mt_1 > 70) + nbtag: (nbtag == 0) + tau_pair_sign: ((q_1*q_2) < 0) + lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) + AR_SR_cuts: # this is only on MC! + lep_mt: (mt_1 < 70) + nbtag: (nbtag >= 0) + tau_pair_sign: ((q_1*q_2) < 0) + lep_iso: ((iso_1 >= 0.0) && (iso_1 <= 0.15)) + + ttbar: + non_closure: + tau_decaymode_2: + <<: [*tau_decaymode_2, *2j_split] + correction_variations: ["Stat1Sigma"] + eta_1: + <<: [*eta_1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*eta_1__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.6, 1.0] + var_bins: + "<=1": [-2.1, -1.52, -1.08, -0.74, -0.44, -0.14, 0.13, 0.43, 0.72, 1.08, 1.51, 2.1] + ">=2": [-2.1, -1.61, -1.28, -1.0, -0.76, -0.53, -0.32, -0.1, 0.1, 0.33, 0.53, 0.76, 1.01, 1.29, 1.62, 2.1] + eta_2: + <<: [*eta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*eta_2__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.7, 0.7] + var_bins: + "<=1": [-2.5, -1.6, -1.18, -0.83, -0.48, -0.14, 0.19, 0.51, 0.87, 1.19, 1.59, 2.5] + ">=2": [-2.5, -1.83, -1.42, -1.15, -0.89, -0.62, -0.36, -0.1, 0.15, 0.4, 0.66, 0.93, 1.18, 1.44, 1.83, 2.5] + jeta_1: + <<: [*jeta_1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jeta_1__eq_bin_opt, *ttbar_var_dependence_n_bins] + correction_option: "smoothed" + bandwidth: [1.0, 2.0] + var_bins: + "<=1": [-5.0, -1.8, -1.25, -0.85, -0.48, -0.17, 0.16, 0.49, 0.83, 1.24, 1.83, 5.0] + ">=2": [-5.0, -2.06, -1.56, -1.19, -0.88, -0.62, -0.36, -0.12, 0.13, 0.37, 0.63, 0.91, 1.22, 1.58, 2.08, 5.0] + jeta_2: + <<: [*jeta_2, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jeta_2__eq_bin_opt, *ttbar_var_dependence_n_bins] + var_dependence_n_bins: [1, 15] + correction_option: ["skip", "smoothed"] + var_bins: + "<=1": [-5.0, 5.0] + ">=2": [-5.0, -2.23, -1.67, -1.27, -0.95, -0.66, -0.39, -0.12, 0.13, 0.39, 0.67, 0.95, 1.29, 1.69, 2.25, 5.0] + jpt_1: + <<: [*jpt_1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jpt_1__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [30.0, 20.0] + var_bins: + "<=1": [30.0, 35.36, 40.96, 46.65, 52.23, 58.54, 65.09, 72.75, 82.08, 94.53, 111.82, 150.0] + ">=2": [30.0, 47.65, 54.97, 60.91, 66.28, 71.41, 76.42, 81.65, 87.12, 92.85, 99.07, 105.86, 113.72, 123.2, 135.2, 150.0] + jpt_2: + <<: [*jpt_2, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*jpt_2__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [30.0, 30.0] + correction_option: ["skip", "smoothed"] + var_bins: + "<=1": [30.0, 150.0] + ">=2": [30.0, 34.04, 37.51, 40.9, 44.36, 47.9, 51.37, 55.15, 59.19, 63.62, 68.59, 74.66, 82.46, 93.05, 109.69, 150.0] + met: + <<: [*met, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*met__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [40.0, 35.0] + var_bins: + "<=1": [0.0, 14.66, 22.03, 28.03, 34.31, 40.61, 47.23, 55.17, 64.25, 76.67, 95.52, 150.0] + ">=2": [0.0, 13.5, 19.68, 25.11, 30.24, 35.17, 40.53, 46.2, 52.21, 58.7, 66.15, 74.85, 85.02, 97.62, 116.03, 150.0] + pt_tt: + <<: [*pt_tt, *2j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_tt__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [25.0, 35.0] + var_bins: + "<=1": [0.0, 24.45, 35.1, 43.91, 52.13, 60.74, 69.18, 78.19, 87.94, 100.55, 117.97, 150.0] + ">=2": [0.0, 25.92, 38.05, 47.24, 55.39, 62.86, 69.81, 76.99, 84.08, 91.29, 98.76, 106.54, 115.17, 124.87, 136.3, 150.0] + deltaEta_ditaupair: + <<: [*deltaEta_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaEta_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [1.5, 1.75] + var_bins: + "<=1": [-4.9, -1.57, -1.06, -0.71, -0.43, -0.17, 0.11, 0.39, 0.69, 1.05, 1.56, 4.9] + ">=2": [-4.9, -2.0, -1.47, -1.1, -0.82, -0.58, -0.35, -0.12, 0.1, 0.33, 0.55, 0.79, 1.07, 1.43, 1.99, 4.9] + deltaR_ditaupair: + <<: [*deltaR_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.75, 1.0] + var_bins: + "<=1": [0.5, 1.2589, 1.6931, 2.0017, 2.272, 2.4783, 2.6662, 2.8297, 2.9717, 3.103, 3.283, 5.0] + ">=2": [0.5, 0.9472, 1.2341, 1.4726, 1.6983, 1.9055, 2.0972, 2.2769, 2.4468, 2.6064, 2.7588, 2.9015, 3.0423, 3.1826, 3.465, 5.0] + deltaR_1j1: + <<: [*deltaR_1j1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_1j1__eq_bin_opt, *ttbar_var_dependence_n_bins] + var_bins: + "<=1": [0.5, 1.343, 1.785, 2.09, 2.344, 2.552, 2.723, 2.882, 3.037, 3.185, 3.478, 7.0] + ">=2": [0.5, 1.158, 1.535, 1.836, 2.086, 2.291, 2.467, 2.618, 2.754, 2.872, 2.984, 3.087, 3.201, 3.395, 3.767, 7.0] + deltaR_12j1: + <<: [*deltaR_12j1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_12j1__eq_bin_opt, *ttbar_var_dependence_n_bins] + correction_option: "smoothed" + bandwidth: [1.5, 1.5] + var_bins: + "<=1": [0.0, 1.8, 2.26, 2.53, 2.73, 2.88, 3.0, 3.11, 3.25, 3.48, 3.87, 10.0] + ">=2": [0.0, 1.5, 1.94, 2.22, 2.42, 2.58, 2.72, 2.83, 2.94, 3.03, 3.12, 3.23, 3.39, 3.64, 4.09, 10.0] + pt_ttjj: + <<: [*pt_ttjj, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_ttjj__eq_bin_opt, *ttbar_var_dependence_n_bins] + correction_option: ["skip", "smoothed"] + var_bins: + "<=1": [0.0, 150.0] + ">=2": [0.0, 15.23, 22.09, 27.98, 33.27, 38.42, 43.61, 48.82, 54.23, 60.19, 66.83, 74.34, 83.25, 95.43, 112.85, 150.0] + mass_2: + <<: [*mass_2, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mass_2__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.225, 0.175] + var_bins: + "<=1": [0.0, 0.2, 0.5542, 0.7139, 0.8491, 0.9507, 1.0391, 1.1172, 1.1963, 1.2773, 1.374, 1.4785, 2.0] + ">=2": [0.0, 0.2, 0.4985, 0.6196, 0.7344, 0.8311, 0.9072, 0.9736, 1.0352, 1.0957, 1.1553, 1.2168, 1.2793, 1.3447, 1.416, 1.5039, 2.0] + mt_tot: + <<: [*mt_tot, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mt_tot__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [35.0, 40.0] + var_bins: + "<=1": [0.0, 71.15, 85.76, 95.51, 104.09, 111.98, 120.16, 129.15, 140.06, 155.19, 180.06, 250.0] + ">=2": [0.0, 54.45, 70.52, 80.81, 88.59, 95.47, 102.0, 108.62, 115.3, 122.53, 130.56, 139.48, 150.09, 164.95, 189.62, 250.0] + m_vis: + <<: [*m_vis, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*m_vis__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [20, 20] + var_bins: + "<=1": [40.0, 57.23, 66.64, 74.08, 80.63, 87.14, 94.16, 102.36, 112.55, 128.21, 163.02, 250.0] + ">=2": [40.0, 52.04, 60.23, 66.79, 72.63, 78.31, 83.65, 89.47, 95.56, 102.24, 110.06, 119.97, 133.62, 153.79, 184.28, 250.0] + iso_1: + <<: [*iso_1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*iso_1__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.05, 0.05] + var_bins: + "<=1": [0.0, 0.00005, 0.006133, 0.009499, 0.01269, 0.017176, 0.022144, 0.027969, 0.0369, 0.048008, 0.063692, 0.090369, 0.15] + ">=2": [0.0, 0.00005, 0.004676, 0.007108, 0.009587, 0.012164, 0.015111, 0.018535, 0.022638, 0.027259, 0.032977, 0.039821, 0.048317, 0.060037, 0.075678, 0.101079, 0.15] diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml.ml b/configs/smhtt_ul/2018/corrections_mt.yaml.ml new file mode 100644 index 0000000..f6eee93 --- /dev/null +++ b/configs/smhtt_ul/2018/corrections_mt.yaml.ml @@ -0,0 +1,430 @@ +templates: + split_schemes: + 3j: &3j_split + split_categories: + njets: ["==0", "==1", ">=2"] + split_categories_binedges: + njets: [-0.5, 0.5, 1.5, 22.5] + correction_option: + "==0": "smoothed" + "==1": "smoothed" + ">=2": "smoothed" + bandwidth: + "==0": 1.0 + "==1": 1.0 + ">=2": 1.0 + 2j: &2j_split + split_categories: + njets: ["<=1", ">=2"] + split_categories_binedges: + njets: [-0.5, 1.5, 22.5] + correction_option: + "<=1": "smoothed" + ">=2": "smoothed" + bandwidth: + "<=1": 1 + ">=2": 1 + var_dependence_n_bins: + QCD: + equipopulated_binning_options: &QCD_var_dependence_n_bins + var_dependence_n_bins: + "==0": 11 + "==1": 9 + ">=2": 7 + Wjets: + equipopulated_binning_options: &Wjets_var_dependence_n_bins + var_dependence_n_bins: + "==0": 15 + "==1": 11 + ">=2": 9 + ttbar: + equipopulated_binning_options: &ttbar_var_dependence_n_bins + var_dependence_n_bins: + "<=1": 11 + ">=2": 15 + correction_variations__with_mc_subtraction_shift: &correction_variations__with_mc_subtraction_shift + correction_variations: + - Stat1Sigma + - SystMCShift + - SystBandAsym + correction_variations__without_mc_subtraction_shift: &correction_variations__without_mc_subtraction_shift + correction_variations: + - Stat1Sigma + - SystBandAsym + variables: + eta_1: + var_dependence: eta_1 + equipopulated_binning_options: + variable_config: + eta_1: + min: -2.1 + max: +2.1 + rounding: 2 + correction_option: "smoothed" + bandwidth: 1.0 + eta_2: + var_dependence: eta_2 + equipopulated_binning_options: + variable_config: + eta_2: + min: -2.5 + max: +2.5 + rounding: 2 + correction_option: "smoothed" + bandwidth: 1.5 + deltaEta_ditaupair: &deltaEta_ditaupair + var_dependence: deltaEta_ditaupair + equipopulated_binning_options: &deltaEta_ditaupair__eq_bin_opt + variable_config: + deltaEta_ditaupair: + min: -4.9 + max: +4.9 + rounding: 2 + correction_option: "smoothed" + bandwidth: 1.75 + deltaR_ditaupair: &deltaR_ditaupair + var_dependence: deltaR_ditaupair + equipopulated_binning_options: &deltaR_ditaupair__eq_bin_opt + variable_config: + deltaR_ditaupair: + min: 0.5 + max: 5.0 + rounding: 4 + correction_option: "smoothed" + jeta_1: + var_dependence: jeta_1 + equipopulated_binning_options: + variable_config: + jeta_1: + min: -5.0 + max: +5.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 2.0 + jeta_2: + var_dependence: jeta_2 + equipopulated_binning_options: + variable_config: + jeta_2: + min: -5.0 + max: +5.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 2.0 + jpt_1: + var_dependence: jpt_1 + equipopulated_binning_options: + variable_config: + jpt_1: + min: 30.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + jpt_2: + var_dependence: jpt_2 + equipopulated_binning_options: + variable_config: + jpt_2: + min: 30.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + met: + var_dependence: met + equipopulated_binning_options: + variable_config: + met: + min: 0.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 25 + mt_1: + var_dependence: mt_1 + equipopulated_binning_options: + variable_config: + mt_1: + min: 0.0 + max: 70.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 20 + pt_tt: + var_dependence: pt_tt + equipopulated_binning_options: + variable_config: + pt_tt: + min: 0.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 25 + pt_ttjj: &pt_ttjj + var_dependence: pt_ttjj + equipopulated_binning_options: &pt_ttjj__eq_bin_opt + variable_config: + pt_ttjj: + min: 0.0 + max: 150.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 25 + mt_tot: + var_dependence: mt_tot + equipopulated_binning_options: + variable_config: + mt_tot: + min: 0.0 + max: 250.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 40 + mass_2: &mass_2 + var_dependence: mass_2 + equipopulated_binning_options: &mass_2__eq_bin_opt + variable_config: + mass_2: + min: 0.2 + max: 2.0 + rounding: 4 + add_left: [0.0] + correction_option: "binwise#[0]+smoothed" + bandwidth: 0.3 + tau_decaymode_2: &tau_decaymode_2 + var_dependence: tau_decaymode_2 + correction_option: "binwise" + bandwidth: 1.0 + var_bins: [-0.5, 0.5, 9.5, 10.5, 11.5] + nbtag: + var_dependence: nbtag + correction_option: "binwise" + bandwidth: 1.0 + var_bins: [-0.5, 0.5, 1.5, 2.5, 22.5] + iso_1: &iso_1 + var_dependence: iso_1 + equipopulated_binning_options: &iso_1__eq_bin_opt + variable_config: + iso_1: + min: 0.00005 + max: 0.15 + rounding: 6 + add_left: [0.0] + correction_option: "binwise#[0]+smoothed" + bandwidth: 0.02 + deltaR_1j1: &deltaR_1j1 + var_dependence: deltaR_1j1 + equipopulated_binning_options: &deltaR_1j1__eq_bin_opt + variable_config: + deltaR_1j1: + min: 0.5 + max: 7.0 + rounding: 3 + correction_option: "smoothed" + bandwidth: 0.9 + deltaR_12j1: + var_dependence: deltaR_12j1 + equipopulated_binning_options: + variable_config: + deltaR_12j1: + min: 0.0 + max: 10.0 + correction_option: "smoothed" + bandwidth: 1.25 + m_vis: &m_vis + var_dependence: m_vis + equipopulated_binning_options: &m_vis__eq_bin_opt + variable_config: + m_vis: + min: 40.0 + max: 250.0 + rounding: 2 + correction_option: "smoothed" + bandwidth: 30 + +channel: mt +target_processes: + QCD: + chain_DR_SR_to_non_closure: false + + non_closure: + tau_decaymode_2: + <<: [*tau_decaymode_2, *3j_split] + correction_variations: ["Stat1Sigma", "SystMCShift"] + deltaEta_ditaupair: + <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaEta_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [1.25, 1.5, 2.0] + var_bins: + "==0": [-4.9, -2.13, -1.42, -0.93, -0.53, -0.18, 0.16, 0.56, 0.96, 1.43, 2.08, 4.9] + "==1": [-4.9, -2.0, -1.23, -0.65, -0.23, 0.25, 0.72, 1.28, 2.04, 4.9] + ">=2": [-4.9, -1.9, -1.03, -0.39, 0.26, 0.87, 1.76, 4.9] + deltaR_ditaupair: + <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_ditaupair__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [0.8, 1.1, 1.2] + var_bins: + "==0": [0.5, 2.6814, 2.869, 2.9787, 3.0526, 3.1104, 3.1696, 3.2609, 3.3865, 3.5747, 3.9186, 5.0] + "==1": [0.5, 1.653, 2.227, 2.5243, 2.7304, 2.9125, 3.0715, 3.2696, 3.6723, 5.0] + ">=2": [0.5, 1.3291, 1.9185, 2.3753, 2.7661, 3.0644, 3.4088, 5.0] + deltaR_1j1: + <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_1j1__eq_bin_opt, *QCD_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + var_bins: + "==0": [0.5, 7.0] + "==1": [0.5, 1.67, 2.205, 2.51, 2.774, 3.019, 3.235, 3.586, 4.235, 7.0] + ">=2": [0.5, 1.825, 2.382, 2.761, 3.009, 3.272, 3.759, 7.0] + pt_ttjj: + <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_ttjj__eq_bin_opt, *QCD_var_dependence_n_bins] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 35.0] + var_bins: + "==0": [0.0, 150.0] + "==1": [0.0, 150.0] + ">=2": [0.0, 15.52, 22.28, 30.06, 38.0, 49.31, 69.77, 150.0] + mass_2: + <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mass_2__eq_bin_opt, *QCD_var_dependence_n_bins] + bandwidth: [0.25, 0.35, 0.4] + var_bins: + "==0": [0.0, 0.2, 0.5107, 0.6216, 0.7388, 0.835, 0.9121, 0.9941, 1.0732, 1.1543, 1.25, 1.3623, 2.0] + "==1": [0.0, 0.2, 0.5322, 0.665, 0.79, 0.896, 1.0088, 1.0957, 1.1982, 1.3271, 2.0] + ">=2": [0.0, 0.2, 0.564, 0.7314, 0.8735, 0.9932, 1.1123, 1.2715, 2.0] + iso_1: + <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: *QCD_var_dependence_n_bins + variable_config: + iso_1: + min: 0.05 + max: 0.15 + rounding: 6 + bandwidth: [0.04, 0.04, 0.04] + correction_option: "smoothed" + var_bins: + "==0": [0.05, 0.056882, 0.063543, 0.070468, 0.078181, 0.086647, 0.095377, 0.105744, 0.115638, 0.126327, 0.137486, 0.15] + "==1": [0.05, 0.057096, 0.065105, 0.073987, 0.083517, 0.096737, 0.108642, 0.122276, 0.13489, 0.15] + ">=2": [0.05, 0.059351, 0.068657, 0.081325, 0.096132, 0.110882, 0.128247, 0.15] + + Wjets: + chain_DR_SR_to_non_closure: false + + non_closure: + tau_decaymode_2: + <<: [*tau_decaymode_2, *3j_split] + correction_variations: ["Stat1Sigma", "SystMCShift"] + deltaEta_ditaupair: + <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaEta_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.8, 1.1, 1.25] + var_bins: + "==0": [-4.9, -1.9, -1.36, -1.02, -0.75, -0.52, -0.31, -0.11, 0.09, 0.3, 0.51, 0.74, 1.0, 1.34, 1.87, 4.9] + "==1": [-4.9, -1.75, -1.16, -0.75, -0.43, -0.14, 0.14, 0.43, 0.74, 1.14, 1.74, 4.9] + ">=2": [-4.9, -1.56, -0.96, -0.53, -0.16, 0.19, 0.54, 0.95, 1.54, 4.9] + deltaR_ditaupair: + <<: [*deltaR_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_ditaupair__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.5, 0.6, 0.7] + var_bins: + "==0": [0.5, 1.291, 1.6664, 1.9482, 2.1706, 2.3528, 2.5196, 2.6606, 2.783, 2.8902, 2.9821, 3.0643, 3.1321, 3.2287, 3.4481, 5.0] + "==1": [0.5, 1.1946, 1.5966, 1.9154, 2.1746, 2.4058, 2.6139, 2.801, 2.9638, 3.1049, 3.3191, 5.0] + ">=2": [0.5, 1.1567, 1.5816, 1.9338, 2.2206, 2.4933, 2.7366, 2.9631, 3.1951, 5.0] + deltaR_1j1: + <<: [*deltaR_1j1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_1j1__eq_bin_opt, *Wjets_var_dependence_n_bins] + correction_option: ["skip", "smoothed", "smoothed"] + bandwidth: [1.0, 1.0, 1.2] + var_bins: + "==0": [0.5, 7.0] + "==1": [0.5, 1.257, 1.688, 2.026, 2.312, 2.572, 2.811, 3.037, 3.282, 3.69, 4.342, 7.0] + ">=2": [0.5, 1.242, 1.733, 2.12, 2.446, 2.72, 2.978, 3.261, 3.842, 7.0] + pt_ttjj: + <<: [*pt_ttjj, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_ttjj__eq_bin_opt, *Wjets_var_dependence_n_bins] + correction_option: ["skip", "skip", "smoothed"] + bandwidth: [1.0, 1.0, 30] + var_bins: + "==0": [0.0, 150.0] + "==1": [0.0, 150.0] + ">=2": [0.0, 13.13, 19.85, 25.75, 31.71, 38.56, 46.7, 57.79, 75.16, 150.0] + mass_2: + <<: [*mass_2, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mass_2__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.225, 0.225, 0.25] + var_bins: + "==0": [0.0, 0.2, 0.4827, 0.5635, 0.6396, 0.707, 0.7681, 0.8281, 0.8857, 0.9453, 1.0078, 1.0713, 1.1377, 1.2109, 1.2949, 1.4092, 2.0] + "==1": [0.0, 0.2, 0.5088, 0.6177, 0.7119, 0.7959, 0.8696, 0.9551, 1.0381, 1.1279, 1.2285, 1.3545, 2.0] + ">=2": [0.0, 0.2, 0.5308, 0.6577, 0.7612, 0.8506, 0.957, 1.0625, 1.1758, 1.3076, 2.0] + iso_1: + <<: [*iso_1, *3j_split, *correction_variations__with_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*iso_1__eq_bin_opt, *Wjets_var_dependence_n_bins] + bandwidth: [0.03, 0.04, 0.05] + var_bins: + "==0": [0.0, 0.00005, 0.004932, 0.007516, 0.010087, 0.012785, 0.015814, 0.019493, 0.023479, 0.028324, 0.034053, 0.040962, 0.049714, 0.060662, 0.075963, 0.100649, 0.15] + "==1": [0.0, 0.00005, 0.005621, 0.009072, 0.012884, 0.017279, 0.022713, 0.029417, 0.037605, 0.049066, 0.064637, 0.090462, 0.15] + ">=2": [0.0, 0.00005, 0.005602, 0.009668, 0.014723, 0.020748, 0.028099, 0.039254, 0.055474, 0.082078, 0.15] + + ttbar: + non_closure: + tau_decaymode_2: + <<: [*tau_decaymode_2, *2j_split] + correction_variations: ["Stat1Sigma"] + deltaEta_ditaupair: + <<: [*deltaEta_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaEta_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [1.5, 1.75] + var_bins: + "<=1": [-4.9, -1.57, -1.06, -0.71, -0.43, -0.17, 0.11, 0.39, 0.69, 1.05, 1.56, 4.9] + ">=2": [-4.9, -2.0, -1.47, -1.1, -0.82, -0.58, -0.35, -0.12, 0.1, 0.33, 0.55, 0.79, 1.07, 1.43, 1.99, 4.9] + deltaR_ditaupair: + <<: [*deltaR_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_ditaupair__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.75, 1.0] + var_bins: + "<=1": [0.5, 1.2589, 1.6931, 2.0017, 2.272, 2.4783, 2.6662, 2.8297, 2.9717, 3.103, 3.283, 5.0] + ">=2": [0.5, 0.9472, 1.2341, 1.4726, 1.6983, 1.9055, 2.0972, 2.2769, 2.4468, 2.6064, 2.7588, 2.9015, 3.0423, 3.1826, 3.465, 5.0] + deltaR_1j1: + <<: [*deltaR_1j1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*deltaR_1j1__eq_bin_opt, *ttbar_var_dependence_n_bins] + var_bins: + "<=1": [0.5, 1.343, 1.785, 2.09, 2.344, 2.552, 2.723, 2.882, 3.037, 3.185, 3.478, 7.0] + ">=2": [0.5, 1.158, 1.535, 1.836, 2.086, 2.291, 2.467, 2.618, 2.754, 2.872, 2.984, 3.087, 3.201, 3.395, 3.767, 7.0] + pt_ttjj: + <<: [*pt_ttjj, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*pt_ttjj__eq_bin_opt, *ttbar_var_dependence_n_bins] + correction_option: ["skip", "smoothed"] + var_bins: + "<=1": [0.0, 150.0] + ">=2": [0.0, 15.23, 22.09, 27.98, 33.27, 38.42, 43.61, 48.82, 54.23, 60.19, 66.83, 74.34, 83.25, 95.43, 112.85, 150.0] + mass_2: + <<: [*mass_2, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*mass_2__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.225, 0.175] + var_bins: + "<=1": [0.0, 0.2, 0.5542, 0.7139, 0.8491, 0.9507, 1.0391, 1.1172, 1.1963, 1.2773, 1.374, 1.4785, 2.0] + ">=2": [0.0, 0.2, 0.4985, 0.6196, 0.7344, 0.8311, 0.9072, 0.9736, 1.0352, 1.0957, 1.1553, 1.2168, 1.2793, 1.3447, 1.416, 1.5039, 2.0] + iso_1: + <<: [*iso_1, *2j_split, *correction_variations__without_mc_subtraction_shift] + equipopulated_binning_options: + <<: [*iso_1__eq_bin_opt, *ttbar_var_dependence_n_bins] + bandwidth: [0.05, 0.05] + var_bins: + "<=1": [0.0, 0.00005, 0.006133, 0.009499, 0.01269, 0.017176, 0.022144, 0.027969, 0.0369, 0.048008, 0.063692, 0.090369, 0.15] + ">=2": [0.0, 0.00005, 0.004676, 0.007108, 0.009587, 0.012164, 0.015111, 0.018535, 0.022638, 0.027259, 0.032977, 0.039821, 0.048317, 0.060037, 0.075678, 0.101079, 0.15] diff --git a/configs/smhtt_ul/2018/fake_factors_mt.yaml b/configs/smhtt_ul/2018/fake_factors_mt.yaml index 5bfa0a6..3ef78c9 100644 --- a/configs/smhtt_ul/2018/fake_factors_mt.yaml +++ b/configs/smhtt_ul/2018/fake_factors_mt.yaml @@ -171,8 +171,8 @@ target_processes: var_dependence: pt_2 var_bins: - "<=1": [30.0, 31.28, 32.49, 33.8, 35.35, 36.97, 38.95, 41.11, 43.83, 46.97, 50.76, 55.49, 62.17, 71.39, 87.69, 150.0] - ">=2": [30.0, 31.64, 33.56, 35.83, 38.52, 41.85, 46.3, 52.31, 61.8, 79.32, 150.0] + "<=1": [30.0, 31.73, 33.36, 35.22, 37.27, 39.68, 42.23, 45.17, 48.65, 52.51, 57.21, 63.16, 70.71, 80.98, 96.82, 150.0] + ">=2": [30.0, 31.85, 33.99, 36.45, 39.37, 42.98, 47.76, 54.3, 63.96, 81.06, 150.0] fit_option: ["poly_1", "poly_2", "poly_3"] process_fractions: diff --git a/configs/smhtt_ul/2018/preselection_mt.yaml b/configs/smhtt_ul/2018/preselection_mt.yaml index a8e2ed7..35d9af9 100644 --- a/configs/smhtt_ul/2018/preselection_mt.yaml +++ b/configs/smhtt_ul/2018/preselection_mt.yaml @@ -66,6 +66,10 @@ processes: - T - L +column_definitions: + event_parity: + expression: event % 2 + event_selection: had_tau_decay_mode: (tau_decaymode_2 == 0) || (tau_decaymode_2 == 1) || (tau_decaymode_2 == 10) || (tau_decaymode_2 == 11) had_tau_id_vs_ele: id_tau_vsEle_VVLoose_2 > 0.5 @@ -80,38 +84,26 @@ mc_weights: stitching: - DYjets - Wjets - had_tau_id_vs_ele: (gen_match_2==5) * ((id_tau_vsEle_VVLoose_2>0.5)*id_wgt_tau_vsEle_VVLoose_2 + (id_tau_vsEle_VVLoose_2<0.5)) + (gen_match_2!=5) - had_tau_id_vs_mu: (gen_match_2==5) * ((id_tau_vsMu_Tight_2>0.5)*id_wgt_tau_vsMu_Tight_2 + (id_tau_vsMu_Tight_2<0.5)) + (gen_match_2!=5) + had_tau_id_vs_ele: id_wgt_tau_vsEle_VVLoose_2 + had_tau_id_vs_mu: id_wgt_tau_vsMu_Tight_2 lep_id: id_wgt_mu_1 lep_iso: iso_wgt_mu_1 lumi: "" pileup: puweight - single_trigger: trg_wgt_single_mu24ormu27 + single_trigger: ((pt_1>25)*trg_wgt_single_mu24ormu27) + # for ml ffs add this + # had_tau_id_vs_jet: ((gen_match_2 == 5) * ((id_tau_vsJet_Tight_2 > 0.5) * id_wgt_tau_vsJet_Tight_2 + (id_tau_vsJet_Tight_2 < 0.5)) + (gen_match_2 != 5)) + # btag: btag_weight + emb_weights: - generator: (emb_genweight * emb_idsel_wgt_1 * emb_idsel_wgt_2 * emb_triggersel_wgt) + generator: (emb_genweight * emb_idsel_wgt_1 * emb_idsel_wgt_2 * emb_triggersel_wgt) * (gen_match_1==4 && gen_match_2==5) lep_id: id_wgt_mu_1 lep_iso: iso_wgt_mu_1 single_trigger: trg_wgt_single_mu24ormu27 + # for ml ffs add this + # had_tau_id_vs_jet: ((gen_match_2 == 5) * ((id_tau_vsJet_Tight_2 > 0.5) * id_wgt_tau_vsJet_Tight_2 + (id_tau_vsJet_Tight_2 < 0.5)) + (gen_match_2 != 5)) output_features: - - mt_1 - - dilepton_veto - - weight - - btag_weight - - q_1 - - pt_2 - - q_2 - - gen_match_2 - - pt_1 - - extramuon_veto - - extraelec_veto - - dimuon_veto - - tau_decaymode_1 - - tau_decaymode_2 - - mass_1 - - mass_2 - - iso_1 - - iso_2 - beta_1 - beta_2 - bphi_1 @@ -120,6 +112,7 @@ output_features: - bpt_2 - btag_value_1 - btag_value_2 + - btag_weight - deltaEta_12j1 - deltaEta_12j2 - deltaEta_12jj @@ -147,18 +140,37 @@ output_features: - deltaR_2j2 - deltaR_ditaupair - deltaR_jj + - dilepton_veto + - dimuon_veto + - dxy_1 + - dxy_2 + - dz_1 + - dz_2 - eta_1 - eta_2 + - eta_fastmtt + - event + - event_parity + - extraelec_veto + - extramuon_veto + - gen_match_2 + - iso_1 + - iso_2 - jeta_1 - jeta_2 - jphi_1 - jphi_2 - jpt_1 - jpt_2 + - lumi + - m_fastmtt - m_vis + - mass_1 + - mass_2 - met - metphi - mjj + - mt_1 - mt_2 - mt_tot - nbtag @@ -167,11 +179,18 @@ output_features: - pfmetphi - phi_1 - phi_2 + - phi_fastmtt + - pt_1 + - pt_2 - pt_dijet + - pt_fastmtt - pt_tt - pt_ttjj - pt_vis - - eta_fastmtt - - m_fastmtt - - phi_fastmtt - - pt_fastmtt + - pzetamissvis + - q_1 + - q_2 + - run + - tau_decaymode_1 + - tau_decaymode_2 + - weight diff --git a/ff_calculation.py b/ff_calculation.py index 60756f6..a2783c1 100644 --- a/ff_calculation.py +++ b/ff_calculation.py @@ -7,13 +7,13 @@ import os from typing import Dict, List, Tuple, Union +import CustomLogging as logging_helper import FF_calculation.FF_QCD as FF_QCD import FF_calculation.FF_ttbar as FF_ttbar import FF_calculation.FF_Wjets as FF_Wjets import helper.correctionlib_json as corrlib import helper.ff_functions as ff_func import helper.functions as func -import CustomLogging as logging_helper from FF_calculation.fractions import fraction_calculation from helper.hooks_and_patches import Histo1DPatchedRDataFrame, PassThroughWrapper @@ -55,13 +55,15 @@ } FF_DATA_SCALING_FACTOR_CALCULATION_FUNCTIONS = { - **{k: lambda *args, **kwargs: (None, None) for k in { - "QCD", - "QCD_subleading", - "Wjets", - "process_fractions", - "process_fractions_subleading", - } + **{ + k: lambda *args, **kwargs: (None, None) + for k in { + "QCD", + "QCD_subleading", + "Wjets", + "process_fractions", + "process_fractions_subleading", + } }, # only necessary for ttbar and ttbar_subleading "ttbar": FF_ttbar.calculation_FF_data_scaling_factor, "ttbar_subleading": FF_ttbar.calculation_FF_data_scaling_factor, @@ -142,9 +144,7 @@ def FF_calculation( @logging_helper.LogDecorator().grouped_logs(extractor=lambda args: f"ff_calculation.{args[0]}") -def run_ff_calculation( - args: Tuple[str, Dict[str, Union[Dict, List, str]], List[str], str] -) -> Tuple[Tuple, Dict]: +def run_ff_calculation(args: Tuple[str, Dict[str, Union[Dict, List, str]], List[str], str]) -> Tuple[Tuple, Dict]: """ This function can be used for multiprocessing. It runs the fake factor calculation step for a specified process. diff --git a/helper/ff_evaluators.py b/helper/ff_evaluators.py index 1a75ddb..6087640 100644 --- a/helper/ff_evaluators.py +++ b/helper/ff_evaluators.py @@ -16,7 +16,6 @@ np = None import helper.functions as func -import CustomLogging as logging_helper class FakeFactorEvaluator: diff --git a/helper/weights.py b/helper/weights.py index 5c61f0a..f468e77 100644 --- a/helper/weights.py +++ b/helper/weights.py @@ -91,9 +91,9 @@ def lumi_weight(rdf: Any, era: str) -> Any: elif era == "2016postVFP": rdf = rdf.Redefine("weight", "weight * 16.81 * 1000.") elif era == "2017": - rdf = rdf.Redefine("weight", "weight * 41.48 * 1000.") + rdf = rdf.Redefine("weight", "weight * 42.07 * 1000.") elif era == "2018": - rdf = rdf.Redefine("weight", "weight * 59.83 * 1000.") + rdf = rdf.Redefine("weight", "weight * 59.56 * 1000.") elif era == "2022preEE": rdf = rdf.Redefine("weight", "weight * 7.9804 * 1000.") elif era == "2022postEE": From 23cb78ca459bf7b041c265d7286e8040847f66c3 Mon Sep 17 00:00:00 2001 From: Sofia Giappichini Date: Fri, 17 Apr 2026 11:30:56 +0200 Subject: [PATCH 10/20] removed dy selection --- preselection.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/preselection.py b/preselection.py index 627f131..ad0e982 100644 --- a/preselection.py +++ b/preselection.py @@ -97,13 +97,6 @@ def run_sample_preselection(args: Tuple[str, Dict[str, Union[Dict, List, str]], for cut in selection_conf: rdf = rdf.Filter(f"({selection_conf[cut]})", f"cut on {cut}") - # For Run 3 DY samples, we need to collect the events from two samples, that need to be selected - # for different flavors - if sample.startswith("DYto2L"): - rdf = rdf.Filter("lhe_drell_yan_decay_flavor == 11 || lhe_drell_yan_decay_flavor == 13", "DY e/mu selection") - if sample.startswith("DYto2Tau"): - rdf = rdf.Filter("lhe_drell_yan_decay_flavor == 15", "DY tau selection") - if process == "embedding": rdf = filters.emb_tau_gen_match(rdf=rdf, channel=config["channel"]) From b84897b28b7c5e82557d0f205bd4f5adf8daf842 Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Fri, 17 Apr 2026 15:38:46 +0200 Subject: [PATCH 11/20] revert change regarding DR_SR fake factor related config parameters --- FF_calculation/FF_Wjets.py | 2 +- ff_corrections.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/FF_calculation/FF_Wjets.py b/FF_calculation/FF_Wjets.py index f9235d3..604c0a1 100644 --- a/FF_calculation/FF_Wjets.py +++ b/FF_calculation/FF_Wjets.py @@ -172,7 +172,7 @@ def calculation_Wjets_FFs(args: Tuple[Any, ...]) -> Dict[str, Union[Dict[str, st SRlike_hists["QCD"] = ff_func.QCD_SS_estimate(hists=SRlike_hists_qcd) ARlike_hists["QCD"] = ff_func.QCD_SS_estimate(hists=ARlike_hists_qcd) - use_data = process_conf.get("compute_different_set_of_fake_factors_using_data", True) + use_data = process_conf.get("compute_orthogonal_fake_factors_using_data", True) if use_data: # calculate Wjets enriched data by subtraction all there backgrould sample diff --git a/ff_corrections.py b/ff_corrections.py index 5e62d9b..46023f3 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -335,10 +335,10 @@ def run_ff_calculation_for_DRtoSR( to_AR_SR=False, ) - use_data_str = corr_config["target_processes"][process]["DR_SR"].get("orthogonal_fake_factors", "use_data") - if process.startswith("QCD") and use_data_str != "use_data": - raise NotImplementedError("orthogonal_fake_factors!='use_data' is not currently implemented for QCD.") - ff_config["target_processes"][process]["orthogonal_fake_factors"] = use_data_str + use_data_flag = corr_config["target_processes"][process]["DR_SR"].get("compute_orthogonal_fake_factors_using_data", True) + if process.startswith("QCD") and not use_data_flag: + raise NotImplementedError("compute_orthogonal_fake_factors_using_data=False is not currently implemented for QCD.") + ff_config["target_processes"][process]["compute_orthogonal_fake_factors_using_data"] = use_data_flag log.info(f"Calculating fake factors for the DR to SR correction for the {process} process.") log.info("-" * 50) @@ -472,7 +472,7 @@ def run_correction( config=config, process=process, var_dependences=var_dependences, - for_DRtoSR=False if corr_config["target_processes"][process]["DR_SR"].get("orthogonal_fake_factors", None) == None else True, + for_DRtoSR=corr_config["target_processes"][process]["DR_SR"].get("use_orthogonal_fake_factors", True), logger=f"ff_corrections.{process}", ) @@ -666,7 +666,7 @@ def run_correction( is_valid_cache = all( func.nested_object_comparison(__test_config.get(k), test_config.get(k)) - for k in ("SRlike_cuts", "ARlike_cuts", "AR_SR_cuts", "use_embedding", "orthogonal_fake_factors") + for k in ("SRlike_cuts", "ARlike_cuts", "AR_SR_cuts", "use_embedding", "compute_fake_factors_using_data") ) else: is_valid_cache = False From 2122e691072e7423eb08a7eb02b1012dec594494 Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Fri, 17 Apr 2026 15:50:53 +0200 Subject: [PATCH 12/20] update config --- configs/smhtt_ul/2018/corrections_mt.yaml.classic | 8 ++++---- ff_corrections.py | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml.classic b/configs/smhtt_ul/2018/corrections_mt.yaml.classic index 6c7c82e..59aceb9 100644 --- a/configs/smhtt_ul/2018/corrections_mt.yaml.classic +++ b/configs/smhtt_ul/2018/corrections_mt.yaml.classic @@ -415,8 +415,8 @@ target_processes: DR_SR: use_embedding: false - compute_different_set_of_fake_factors: true - compute_different_set_of_fake_factors_using_data: true + use_orthogonal_fake_factors: true + compute_orthogonal_fake_factors_using_data: true <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_1__eq_bin_opt, *QCD_var_dependence_n_bins] @@ -626,8 +626,8 @@ target_processes: DR_SR: use_embedding: true - compute_different_set_of_fake_factors: true - compute_different_set_of_fake_factors_using_data: false + use_orthogonal_fake_factors: true + compute_orthogonal_fake_factors_using_data: false <<: [*mt_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: <<: [*mt_1__eq_bin_opt, *Wjets_var_dependence_n_bins] diff --git a/ff_corrections.py b/ff_corrections.py index 46023f3..57ea3bb 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -334,7 +334,10 @@ def run_ff_calculation_for_DRtoSR( process=process, to_AR_SR=False, ) - + if not corr_config["target_processes"][process]["DR_SR"].get("use_orthogonal_fake_factors", True): + log.info(f"DR to SR correction for {process} process is configured to not use orthogonal fake factors. Skipping fake factor calculation for DR to SR correction.") + return None + use_data_flag = corr_config["target_processes"][process]["DR_SR"].get("compute_orthogonal_fake_factors_using_data", True) if process.startswith("QCD") and not use_data_flag: raise NotImplementedError("compute_orthogonal_fake_factors_using_data=False is not currently implemented for QCD.") From b9c64c7315d1e3a1a3ff88f30bbc020949bd57b7 Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Mon, 20 Apr 2026 15:26:34 +0200 Subject: [PATCH 13/20] fix some bugs --- FF_calculation/FF_Wjets.py | 6 +++--- ff_corrections.py | 6 ++++++ helper/correctionlib_json.py | 3 +++ helper/ff_functions.py | 8 ++++---- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/FF_calculation/FF_Wjets.py b/FF_calculation/FF_Wjets.py index 604c0a1..a29f8cc 100644 --- a/FF_calculation/FF_Wjets.py +++ b/FF_calculation/FF_Wjets.py @@ -236,9 +236,9 @@ def calculation_Wjets_FFs(args: Tuple[Any, ...]) -> Dict[str, Union[Dict[str, st correction_option=splitting.fit_option, bandwidth=splitting.bandwidth, mc_shifted_hist={ - "MCShiftUp": FF_hist_up.Clone(), - "MCShiftDown": FF_hist_down.Clone(), - }, + "MCShiftUp": ff_hists_to_fit[1].Clone(), + "MCShiftDown": ff_hists_to_fit[2].Clone(), + } if use_data else None, stat_sigma=config["stat_sigma"] if "stat_sigma" in config else 1.0, ) unc_draw_obj = results["default"] diff --git a/ff_corrections.py b/ff_corrections.py index 57ea3bb..c49861b 100644 --- a/ff_corrections.py +++ b/ff_corrections.py @@ -643,6 +643,12 @@ def run_correction( # setting default systematic variations if not present in the config if "correction_variations" not in corr_config: corr_config["correction_variations"] = gd.default_correction_variations + else: + if isinstance(corr_config["correction_variations"], str): + corr_config["correction_variations"] = [corr_config["correction_variations"]] + for var in corr_config["correction_variations"]: + if var not in gd.VARIATIONS: + raise ValueError(f"Variation {var} is not defined in the general definitions! Please choose from {gd.VARIATIONS} or add the variation to the general definitions if it is missing.") # ########## needed precalculations for DR to SR corrections ########## # diff --git a/helper/correctionlib_json.py b/helper/correctionlib_json.py index bba4b25..31c4497 100644 --- a/helper/correctionlib_json.py +++ b/helper/correctionlib_json.py @@ -669,6 +669,9 @@ def unique_append(self, item): binning = correction_conf["var_bins"] correction_variations = correction_conf.get("correction_variations", gd.default_correction_variations) + for var in correction_variations: + if var not in gd.VARIATIONS: + raise ValueError(f"Variation {var} is not defined in the general definitions! Please choose from {gd.VARIATIONS} or add the variation to the general definitions if it is missing.") correction_variations = ["".join(it) for it in product(correction_variations, ["Up", "Down"])] if is_2D: diff --git a/helper/ff_functions.py b/helper/ff_functions.py index b47056e..a0e763d 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -1424,13 +1424,13 @@ def statistical_check( corr_dict["default"]["variations"][key] = np.full_like(corr_dict["default"]["variations"][key], 1.0 - stat_sigma * stat_unct_inclusive) if mc_shifted_hist is None: - corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC_SHIFT + "Up"] = np.ones_like(corr_dict["default"]["nominal"]) - corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC_SHIFT + "Down"] = np.ones_like(corr_dict["default"]["nominal"]) + corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC + "Up"] = np.ones_like(corr_dict["default"]["nominal"]) + corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC + "Down"] = np.ones_like(corr_dict["default"]["nominal"]) else: mc_up_val, _ = fit_to_constant(mc_shifted_hist["MCShiftUp"]) mc_dn_val, _ = fit_to_constant(mc_shifted_hist["MCShiftDown"]) - corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC_SHIFT + "Up"] = np.full_like(corr_dict["default"]["nominal"], mc_up_val) - corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC_SHIFT + "Down"] = np.full_like(corr_dict["default"]["nominal"], mc_dn_val) + corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC + "Up"] = np.full_like(corr_dict["default"]["nominal"], mc_up_val) + corr_dict["default"]["variations"][gd.VARIATIONS.SYST_MC + "Down"] = np.full_like(corr_dict["default"]["nominal"], mc_dn_val) else: corr_dict["default"]["_auto_skipped"] = False From 4f2437bbd4245b60e97633a7c25d987b0dcb199e Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Mon, 20 Apr 2026 15:28:05 +0200 Subject: [PATCH 14/20] update documentation --- docs/corrections.md | 26 +++++++++++++++++++++++++- docs/fakefactors.md | 4 +++- docs/preselection.md | 5 ++++- mkdocs.yml | 4 +++- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/corrections.md b/docs/corrections.md index f2a051c..6282a52 100644 --- a/docs/corrections.md +++ b/docs/corrections.md @@ -1,6 +1,7 @@ # Fake Factor corrections In this step the corrections for the fake factors are calculated. This should be run after the FF calculation step. +### Configuration Currently two different correction types are implemented: 1. non closure correction depending on a specific variable @@ -39,7 +40,30 @@ Each correction has following specifications: `ARlike_cuts` | `dict` | event selections for the application-like region of the target process that should be replaced compared to the selection used in the previous FF calculation step `AR_SR_cuts` | `dict` | event selections for a switch from the determination region to the signal/application region, this is only relevant for `DR_SR` corrections `non_closure` | `dict` | this is only relevant for `DR_SR` corrections, since for this corrections additional fake factors are calculated. It's possible to calculated and apply non closure corrections to these fake factors before calculating the actual DR to SR correction. - + +### Statistical check +As an option it is possible to check using a sliding-window compatibility test whether a computed correction is statistically consistent with 1.0 (i.e., a flat correction, meaning no genuine fake factor bias). The test works as follows: + +1. **Error selection**: Per-bin uncertainties are taken either as the fully propagated errors (data + MC statistical, added in quadrature) or as the data-only "MC-suppressed" errors — depending on the parameter `use_suppressed_mc_errors_for_correction_selection`. +2. **Sliding-window scan**: Pulls $(y_i - 1)/\sigma_i$ are computed for each bin. The test scans all contiguous windows of 1 to $N$ bins and finds the most significant deviation (minimum p-value): + +$$z_\text{window} = \frac{\left|\sum_{i} \text{pull}_i\right|}{\sqrt{N_\text{window}}}$$ + +3. **Look-elsewhere correction**: A Bonferroni-style correction is applied to account for the scan over multiple windows: + +$$p_\text{shape} = 1 - (1 - p_\text{min})^{N_\text{bins}}$$ + +4. **Auto-skipping**: If `p_shape > skip_corrections_p_value` (correction is compatible with 1) **and** `skip_corrections_compatible_to_one` is `true`, the correction is replaced with a flat 1.0. Bandwidth/shape variations are also set to 1.0. Statistical variations are collapsed to a single inclusive uncertainty. MC-shift variations are either fit to a constant or also set to 1.0. + +Three parameter can be set to define this check: + + parameter | type | description + ---|---|--- + `skip_corrections_compatible_to_one` | `bool` | Master switch for automatic skipping of corrections compatible with 1.0. If `True` and a correction passes the p-value threshold (see below), it is replaced by a flat 1.0 correction and all shape/bandwidth uncertainties are also flattened. Statistical uncertainties are collapsed into a single inclusive value. Defaults to `false`. + `skip_corrections_p_value` | `float` | P-value threshold for the compatibility-with-1 test. A correction is considered compatible with 1.0 (and thus auto-skipped) if its shape p-value is above this threshold. Higher values are more aggressive (skip more corrections). Only has an effect when `skip_corrections_compatible_to_one` is set to `true`. Defaults to `0.05`. + `use_suppressed_mc_errors_for_correction_selection` | `bool` | Controls which per-bin uncertainties are used in the compatibility test. If `True`, only the data statistical uncertainties are used — MC statistical errors from the MC subtraction step are ignored ("suppressed"). If `False`, the fully propagated errors (data + MC statistical uncertainties added in quadrature) are used. Using the suppressed errors avoids MC-dominated samples from artificially increasing the uncertainty and causing genuine corrections to be auto-skipped. Defaults to `true`. + +### Running calculations To run the FF correction step, execute the python script and specify the config file (relative path possible): ```bash python ff_corrections.py --config-file PATH/CONFIG.yaml diff --git a/docs/fakefactors.md b/docs/fakefactors.md index 184dff4..feb634e 100644 --- a/docs/fakefactors.md +++ b/docs/fakefactors.md @@ -1,6 +1,7 @@ # Fake Factor calculation In this step the fake factors are calculated. This should be run after the preselection step. +### Configuration All information for the FF calculation step is defined in a configuration file in the `configs/ANALYSIS/ERA/` folder using the `common_settings.yaml` and a more specific config file. The `common_settings.yaml` has to be named like that and is used for all steps of the fake factor estimation (`preselection`, `FF calculation`, `FF corrections`).
The FF calculation config has the following parameters: @@ -41,7 +42,8 @@ In `process_fractions` specifications for the calculation of the process fractio `SR_cuts` | `list` | see `target_processes`, (optional) not needed for the fraction calculation **Note:** When using split binning for process fraction calculations, the `var_bins` parameter can also be defined in the same manner as for `target_processes`. - + +### Running calculations To run the FF calculation step, execute the python script and specify the config file (relative path possible): ```bash python ff_calculation.py --config-file PATH/CONFIG.yaml diff --git a/docs/preselection.md b/docs/preselection.md index 9bda137..3b3597a 100644 --- a/docs/preselection.md +++ b/docs/preselection.md @@ -1,5 +1,7 @@ # Event preselection -This framework is designed for n-tuples (and friend trees) produced with CROWN as input. +This framework is designed for n-tuples (and friend trees) produced with CROWN as input. + +### Configuration All information for the preselection step should be defined in configuration files in the `configs/ANALYSIS/ERA/` folder using the `common_settings.yaml` file and a more specific config file. The `common_settings.yaml` has to be named like that and is used for all steps of the fake factor estimation (`preselection`, `FF calculation`, `FF corrections`). The preselection config has the following parameters: @@ -83,6 +85,7 @@ There are two types of weights. Scale factors for b-tagging and tau ID vs jet are applied on the fly during the FF calculation step. +### Running preselection To run the preselection step, execute the python script and specify the config file (relative path possible): ```bash python preselection.py --config-file configs/PATH/CONFIG.yaml diff --git a/mkdocs.yml b/mkdocs.yml index c85ba66..83fa311 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,7 +10,7 @@ repo_name: KIT-CMS/TauFakeFactors repo_url: https://github.com/KIT-CMS/TauFakeFactors/ # Copyright -copyright: Copyright © 2025 Nikita Shadskiy, Artur Monsch +copyright: Copyright © 2026 Nikita Shadskiy, Artur Monsch # Theme theme: @@ -58,3 +58,5 @@ markdown_extensions: - pymdownx.keys - pymdownx.tabbed: alternate_style: true + - pymdownx.arithmatex: + generic: true From 73049fea6c071109f3148f6153dd10ddd866cdfa Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Mon, 20 Apr 2026 15:31:30 +0200 Subject: [PATCH 15/20] config updates --- configs/smhtt_ul/2018/common_settings.yaml | 2 ++ configs/smhtt_ul/2018/corrections_mt.yaml.classic | 10 +++++----- configs/smhtt_ul/2018/corrections_mt.yaml.ml | 10 +++++----- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/configs/smhtt_ul/2018/common_settings.yaml b/configs/smhtt_ul/2018/common_settings.yaml index 71fe319..0e6b9e6 100644 --- a/configs/smhtt_ul/2018/common_settings.yaml +++ b/configs/smhtt_ul/2018/common_settings.yaml @@ -25,6 +25,8 @@ tau_vs_jet_wgt_wps: use_embedding: true use_center_of_mass_bins: true +stat_sigma: 1.0 + skip_corrections_compatible_to_one: false skip_corrections_p_value: 0.05 use_suppressed_mc_errors_for_correction_selection: true diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml.classic b/configs/smhtt_ul/2018/corrections_mt.yaml.classic index 59aceb9..6af3500 100644 --- a/configs/smhtt_ul/2018/corrections_mt.yaml.classic +++ b/configs/smhtt_ul/2018/corrections_mt.yaml.classic @@ -44,12 +44,12 @@ templates: ">=2": 15 correction_variations__with_mc_subtraction_shift: &correction_variations__with_mc_subtraction_shift correction_variations: - - Stat1Sigma + - StatShift - SystMCShift - SystBandAsym correction_variations__without_mc_subtraction_shift: &correction_variations__without_mc_subtraction_shift correction_variations: - - Stat1Sigma + - StatShift - SystBandAsym variables: eta_1: &eta_1 @@ -244,7 +244,7 @@ target_processes: non_closure: tau_decaymode_2: <<: [*tau_decaymode_2, *3j_split] - correction_variations: ["Stat1Sigma", "SystMCShift"] + correction_variations: ["StatShift", "SystMCShift"] eta_1: <<: [*eta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -456,7 +456,7 @@ target_processes: non_closure: tau_decaymode_2: <<: [*tau_decaymode_2, *3j_split] - correction_variations: ["Stat1Sigma", "SystMCShift"] + correction_variations: ["StatShift", "SystMCShift"] eta_1: <<: [*eta_1, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -660,7 +660,7 @@ target_processes: non_closure: tau_decaymode_2: <<: [*tau_decaymode_2, *2j_split] - correction_variations: ["Stat1Sigma"] + correction_variations: ["StatShift"] eta_1: <<: [*eta_1, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: diff --git a/configs/smhtt_ul/2018/corrections_mt.yaml.ml b/configs/smhtt_ul/2018/corrections_mt.yaml.ml index f6eee93..48ff21c 100644 --- a/configs/smhtt_ul/2018/corrections_mt.yaml.ml +++ b/configs/smhtt_ul/2018/corrections_mt.yaml.ml @@ -44,12 +44,12 @@ templates: ">=2": 15 correction_variations__with_mc_subtraction_shift: &correction_variations__with_mc_subtraction_shift correction_variations: - - Stat1Sigma + - StatShift - SystMCShift - SystBandAsym correction_variations__without_mc_subtraction_shift: &correction_variations__without_mc_subtraction_shift correction_variations: - - Stat1Sigma + - StatShift - SystBandAsym variables: eta_1: @@ -249,7 +249,7 @@ target_processes: non_closure: tau_decaymode_2: <<: [*tau_decaymode_2, *3j_split] - correction_variations: ["Stat1Sigma", "SystMCShift"] + correction_variations: ["StatShift", "SystMCShift"] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -318,7 +318,7 @@ target_processes: non_closure: tau_decaymode_2: <<: [*tau_decaymode_2, *3j_split] - correction_variations: ["Stat1Sigma", "SystMCShift"] + correction_variations: ["StatShift", "SystMCShift"] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *3j_split, *correction_variations__with_mc_subtraction_shift] equipopulated_binning_options: @@ -380,7 +380,7 @@ target_processes: non_closure: tau_decaymode_2: <<: [*tau_decaymode_2, *2j_split] - correction_variations: ["Stat1Sigma"] + correction_variations: ["StatShift"] deltaEta_ditaupair: <<: [*deltaEta_ditaupair, *2j_split, *correction_variations__without_mc_subtraction_shift] equipopulated_binning_options: From 513519cc2458b2fb16c0c7c22477918a13f2064d Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Tue, 21 Apr 2026 13:07:58 +0200 Subject: [PATCH 16/20] update documentation --- docs/fakefactors.md | 3 ++- docs/ml_fakefactors.md | 41 +++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 4 ++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 docs/ml_fakefactors.md diff --git a/docs/fakefactors.md b/docs/fakefactors.md index feb634e..e39fb33 100644 --- a/docs/fakefactors.md +++ b/docs/fakefactors.md @@ -10,8 +10,9 @@ General options for the calculation: parameter | type | description ---|---|--- `channel` | `string` | tau pair decay channels ("et", "mt", "tt") - `use_embedding` | `bool` | True if embedded sample should be used, False if only MC sample should be used + `use_embedding` | `bool` | `true` if embedded sample should be used, `false` if only MC sample should be used `use_center_of_mass_bins` | `bool` | Changes the x-data that is entering FF and correction calculation. If set then a center of mass value is used for the x-data, calculated from events entering the corresponding bin. If not set, the bin centers are used. Default is set to True.

This will not affect FF and correction calculation that are set to `"binwise"` (the x-data values although displayed in plots are not used) + `stat_sigma` | `float` | This parameter defines the number of standard deviations to be considered when determining the uncertainties for fit or smoothing parameters, which are then stored in the correctionlib files. Default is `1.0`. In `target_processes` the processes for which FFs should be calculated (normally for QCD, Wjets, ttbar) are defined.
Each target process needs some specifications: diff --git a/docs/ml_fakefactors.md b/docs/ml_fakefactors.md new file mode 100644 index 0000000..7fd193f --- /dev/null +++ b/docs/ml_fakefactors.md @@ -0,0 +1,41 @@ +# ML-Based Fake Factor Evaluation + +The framework supports the evaluation of fake factors based on machine learning models in the ONNX format instead of the classic approach of measuring them (see [Fake Factor Calculation](fakefactors.md)). ONNXRuntime is utilized to to evaluate the models within ROOT RDataFrames. + +## ML Training + +Not include yet. Files/models have to be provided externally. + +## Configuration + +To use ML-based fake factors, the configuration must specify the ONNX model details for each process. These details are defined in a YAML configuration file, which should be located in the `workdir/TAG` directory. The configuration includes: + +- **Model Path**: The path to the ONNX model file. +- **Model Inputs**: A list of input variable names required by the model. +- **Define Columns**: Optional expressions to define missing columns dynamically. + +Example YAML configuration: +```yaml +target_processes: + QCD: + model_path: "models/qcd_fake_factors.onnx" + model_input: + - "event_parity" + - "pt_1" + - "njets" + ... + define_columns: + event_parity: event % 2 + ... + Wjets: + model_path: "models/wjets_fake_factors.onnx" + model_input: + - "pt_2" + - "nbtag" + ... + ... +``` + +## Notes + +- Ensure that the ONNX model is compatible with ONNXRuntime and that the input variable names match those in the configuration. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 83fa311..661d238 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -38,6 +38,7 @@ nav: - Automated Binning: binning.md - Fake Factor Calculation: fakefactors.md - Fake Factor Corrections: corrections.md + - Fake Factor with ML (in development): ml_fakefactors.md - Documentation: documentation.md # Extensions @@ -60,3 +61,6 @@ markdown_extensions: alternate_style: true - pymdownx.arithmatex: generic: true + +extra_javascript: + - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js From 9c8a8dc55e00fe6b759fb3fe381b19e602cf1a9d Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Tue, 21 Apr 2026 13:08:24 +0200 Subject: [PATCH 17/20] update conda environment --- environment.yml | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/environment.yml b/environment.yml index 2f77e1b..2cf305b 100644 --- a/environment.yml +++ b/environment.yml @@ -33,22 +33,29 @@ dependencies: - bzip2=1.0.8=h4bc722e_7 - c-ares=1.34.5=hb9d3cd8_0 - c-compiler=1.11.0=h4d9bdce_0 - - ca-certificates=2025.8.3=hbd8a1cb_0 + - ca-certificates=2026.2.25=hbd8a1cb_0 - cached-property=1.5.2=hd8ed1ab_1 - cached_property=1.5.2=pyha770c72_1 - cairo=1.18.4=h3394656_0 - - certifi=2025.8.3=pyhd8ed1ab_0 + - certifi=2026.2.25=pyhd8ed1ab_0 - cffi=1.17.1=py312h06ac9bb_0 - cfitsio=4.6.2=ha0b56bc_1 - charset-normalizer=3.4.3=pyhd8ed1ab_0 - click=8.2.1=pyh707e725_0 - colorama=0.4.6=pyhd8ed1ab_1 + - coloredlogs=15.0.1=pyhd8ed1ab_4 - comm=0.2.3=pyhe01879c_0 - compilers=1.11.0=ha770c72_0 - conda-gcc-specs=14.3.0=hb991d5c_4 - contourpy=1.3.3=py312hd9148b4_1 - correctionlib=2.7.0=py312ha04a795_0 + - cpython=3.12.13=py312hd8ed1ab_0 - cramjam=2.11.0=py312h848b54d_0 + - cuda-cudart=12.9.79=h5888daf_0 + - cuda-cudart_linux-64=12.9.79=h3f2d84a_0 + - cuda-nvrtc=12.9.86=hecca717_1 + - cuda-version=12.9=h4f385c5_3 + - cudnn=9.10.2.21=hbcb9cd8_0 - cxx-compiler=1.11.0=hfcd1e18_0 - cycler=0.12.1=pyhd8ed1ab_1 - cyrus-sasl=2.1.28=hd9c7081_0 @@ -91,6 +98,8 @@ dependencies: - gl2ps=1.4.2=hae5d5c5_1 - glew=2.1.0=h9c3ff4c_2 - glib-tools=2.84.3=hf516916_0 + - gmp=6.3.0=hac33072_2 + - gmpy2=2.3.0=py312hcaba1f9_1 - graphite2=1.3.14=hecca717_1 - graphviz=13.1.2=h87b6fe6_0 - gsl=2.7=he838d99_0 @@ -108,12 +117,14 @@ dependencies: - hpack=4.1.0=pyhd8ed1ab_0 - httpcore=1.0.9=pyh29332c3_0 - httpx=0.28.1=pyhd8ed1ab_0 + - humanfriendly=10.0=pyh707e725_8 - hyperframe=6.1.0=pyhd8ed1ab_0 - icu=75.1=he02047a_0 - idna=3.10=pyhd8ed1ab_1 - importlib-metadata=8.7.0=pyhe01879c_1 - importlib-resources=6.5.2=pyhd8ed1ab_0 - importlib_resources=6.5.2=pyhd8ed1ab_0 + - ipdb=0.13.13=pyhd8ed1ab_1 - ipykernel=6.30.1=pyh82676e8_0 - ipyparallel=9.0.1=pyh29332c3_0 - ipython=9.4.0=pyhfa0c392_0 @@ -143,6 +154,7 @@ dependencies: - lcms2=2.17=h717163a_0 - ld_impl_linux-64=2.44=h1423503_1 - lerc=4.0.0=h0aef613_1 + - libabseil=20260107.1=cxx17_h7b12aa8_0 - libasprintf=0.25.1=h3f43e3d_1 - libasprintf-devel=0.25.1=h3f43e3d_1 - libblas=3.9.0=34_h59b9bed_openblas @@ -152,8 +164,14 @@ dependencies: - libcblas=3.9.0=34_he106b2a_openblas - libclang-cpp20.1=20.1.8=default_hddf928d_0 - libclang13=20.1.8=default_ha444ac7_0 + - libcublas=12.9.1.4=h676940d_1 + - libcudnn=9.10.2.21=hf7e9902_0 + - libcudnn-dev=9.10.2.21=h58dd1b1_0 + - libcufft=11.4.1.4=hecca717_1 - libcups=2.3.3=hb8b1518_5 + - libcurand=10.3.10.19=h676940d_1 - libcurl=8.14.1=h332b0f4_0 + - libcusparse=12.5.10.65=hecca717_2 - libdeflate=1.24=h86f0d12_0 - libdrm=2.4.125=hb9d3cd8_0 - libedit=3.1.20250104=pl5321h7949ede_0 @@ -188,6 +206,7 @@ dependencies: - libnghttp2=1.64.0=h161d5f1_0 - libnsl=2.0.1=hb9d3cd8_1 - libntlm=1.8=hb9d3cd8_0 + - libnvjitlink=12.9.86=hecca717_2 - libopenblas=0.3.30=pthreads_h94d23a6_1 - libopengl=1.7.0=ha4b6fd6_2 - libpciaccess=0.18=hb9d3cd8_0 @@ -225,10 +244,13 @@ dependencies: - mistune=3.1.3=pyh29332c3_0 - mkdocs=1.6.1=pyhd8ed1ab_1 - mkdocs-get-deps=0.2.0=pyhd8ed1ab_1 - - mkdocs-material=9.6.16=pyhd8ed1ab_0 + - mkdocs-material=9.7.6=pyhcf101f3_1 - mkdocs-material-extensions=1.3.1=pyhd8ed1ab_1 + - mpc=1.4.0=he0a73b1_0 + - mpfr=4.2.2=he0a73b1_0 - mplhep=0.4.0=pyhd8ed1ab_0 - mplhep_data=0.0.4=pyhd8ed1ab_2 + - mpmath=1.4.1=pyhd8ed1ab_0 - munkres=1.1.4=pyhd8ed1ab_1 - mypy_extensions=1.1.0=pyha770c72_0 - nbclient=0.10.2=pyhd8ed1ab_0 @@ -241,9 +263,10 @@ dependencies: - notebook-shim=0.2.4=pyhd8ed1ab_1 - numba=0.61.2=py312h7bcfee6_1 - numpy=2.2.6=py312h72c5963_0 + - onnxruntime=1.24.2=py312h5fe9fb3_200_cuda129 - openjpeg=2.5.3=h55fea9a_1 - openldap=2.6.10=he970967_0 - - openssl=3.5.2=h26f9b46_0 + - openssl=3.6.2=h35e630c_0 - overrides=7.7.0=pyhd8ed1ab_1 - packaging=25.0=pyh29332c3_1 - paginate=0.5.7=pyhd8ed1ab_1 @@ -263,6 +286,7 @@ dependencies: - portalocker=3.2.0=py312h7900ff3_0 - prometheus_client=0.22.1=pyhd8ed1ab_0 - prompt-toolkit=3.0.51=pyha770c72_0 + - protobuf=6.33.5=py312ha7b3241_2 - psutil=7.0.0=py312h66e93f0_0 - pthread-stubs=0.4=hb9d3cd8_1002 - ptyprocess=0.7.0=pyhd8ed1ab_1 @@ -271,7 +295,7 @@ dependencies: - pydantic=2.11.7=pyh3cfb1c2_0 - pydantic-core=2.33.2=py312h680f630_0 - pygments=2.19.2=pyhd8ed1ab_0 - - pymdown-extensions=10.16.1=pyhd8ed1ab_0 + - pymdown-extensions=10.21.2=pyhd8ed1ab_0 - pyparsing=3.2.3=pyhe01879c_2 - pyside6=6.9.1=py312hdb827e4_0 - pysocks=1.7.1=pyha55dd90_7 @@ -279,6 +303,7 @@ dependencies: - python=3.12.11=h9e4cc4f_0_cpython - python-dateutil=2.9.0.post0=pyhe01879c_2 - python-fastjsonschema=2.21.1=pyhd8ed1ab_0 + - python-flatbuffers=25.9.23=pyh1e1bc0e_0 - python-json-logger=2.0.7=pyhd8ed1ab_0 - python-tzdata=2025.2=pyhd8ed1ab_0 - python-xxhash=3.5.0=py312h66e93f0_2 @@ -301,6 +326,7 @@ dependencies: - rpds-py=0.27.0=py312h868fb18_0 - ruamel.yaml=0.18.14=py312h66e93f0_0 - ruamel.yaml.clib=0.2.8=py312h66e93f0_1 + - scipy=1.17.1=py312h54fa4ab_0 - scitokens-cpp=1.1.3=h6ac2c77_0 - send2trash=1.8.3=pyh0d859eb_1 - setuptools=80.9.0=pyhff2d567_0 @@ -309,11 +335,13 @@ dependencies: - sniffio=1.3.1=pyhd8ed1ab_1 - soupsieve=2.7=pyhd8ed1ab_0 - stack_data=0.6.3=pyhd8ed1ab_1 + - sympy=1.14.0=pyh2585a3b_106 - sysroot_linux-64=2.17=h0157908_18 - tbb=2022.2.0=hb60516a_0 - terminado=0.18.1=pyh0d859eb_0 - tinycss2=1.4.0=pyhd8ed1ab_0 - tk=8.6.13=noxft_hd72426e_102 + - toml=0.10.2=pyhcf101f3_3 - tomli=2.2.1=pyhe01879c_2 - tornado=6.5.2=py312h4c3975b_0 - tqdm=4.67.1=pyhd8ed1ab_1 From abe22c8fe218d8168a029c5f50cfe73743635134 Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Mon, 27 Apr 2026 11:16:05 +0200 Subject: [PATCH 18/20] fix 2D FF write out to correctionlib --- helper/correctionlib_json.py | 38 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/helper/correctionlib_json.py b/helper/correctionlib_json.py index 31c4497..3263b7c 100644 --- a/helper/correctionlib_json.py +++ b/helper/correctionlib_json.py @@ -195,12 +195,12 @@ def generate_ff_corrlib_json( return cset -def get_ff_content(category: str, variable_info: Tuple[str, List[float]], ff_info: Dict, variation: str) -> cs.Category: +def get_ff_content(categories: Tuple[str], variable_info: Tuple[str, List[float]], ff_info: Dict, variation: str) -> cs.Category: """ Function which produces a correctionlib Category with Binning as content based on the measured fake factors for a specific category and variation. Args: - category: Name of the category for which the content is produced + categories: Tuple with category names for which the content is produced variable_info: Tuple with information (name and binning) about the variable the fake factors depends on ff_info: Dictionary of fake factor functions as strings, e.g. ff_function[PROCESS][CATEGORY_1][VARIATION] variation: Name of the variation for which the content is produced @@ -209,18 +209,18 @@ def get_ff_content(category: str, variable_info: Tuple[str, List[float]], ff_inf Category object from correctionlib with Binning as content """ # this is the case if smoothing is used to estimate the fake factor function - if "default" in ff_info[category].keys(): - ff_version = "default" if "downsampled" not in ff_info[category] else "downsampled" - unc_list = list(ff_info[category][ff_version]["variations"].keys()) + if "default" in ff_info[categories[-1]].keys(): + ff_version = "default" if "downsampled" not in ff_info[categories[-1]] else "downsampled" + unc_list = list(ff_info[categories[-1]][ff_version]["variations"].keys()) if variation not in unc_list and variation != "nominal": return cs.Binning( nodetype="binning", input=variable_info[0], - edges=list(ff_info[category][ff_version]["nominal"]["edges"]), - content=list(ff_info[category][ff_version]["nominal"]["content"]), + edges=list(ff_info[categories[-1]][ff_version]["nominal"]["edges"]), + content=list(ff_info[categories[-1]][ff_version]["nominal"]["content"]), flow="clamp", ) - ff_bin_info = ff_info[category][ff_version]["variations"][variation] if variation != "nominal" else ff_info[category][ff_version]["nominal"] + ff_bin_info = ff_info[categories[-1]][ff_version]["variations"][variation] if variation != "nominal" else ff_info[categories[-1]][ff_version]["nominal"] return cs.Binning( nodetype="binning", input=variable_info[0], @@ -229,16 +229,16 @@ def get_ff_content(category: str, variable_info: Tuple[str, List[float]], ff_inf flow="clamp", ) # this is the case if a polynomial fit is used to estimate the fake factor function - elif "nominal" in ff_info[category].keys(): - unc_list = list(ff_info[category]["variations"].keys()) + elif "nominal" in ff_info[categories[-1]].keys(): + unc_list = list(ff_info[categories[-1]]["variations"].keys()) if variation not in unc_list and variation != "nominal": return cs.Binning( nodetype="binning", input=variable_info[0], **get_edges_and_content( - ff_info[category]["nominal"], + ff_info[categories[-1]]["nominal"], variable_info[0], - variable_info[1][category], + variable_info[1][categories[0]] if len(categories) == 1 else variable_info[1][categories[0]][categories[1]], ), flow="clamp", ) @@ -246,14 +246,14 @@ def get_ff_content(category: str, variable_info: Tuple[str, List[float]], ff_inf nodetype="binning", input=variable_info[0], **get_edges_and_content( - ff_info[category]["variations"][variation] if variation != "nominal" else ff_info[category]["nominal"], + ff_info[categories[-1]]["variations"][variation] if variation != "nominal" else ff_info[categories[-1]]["nominal"], variable_info[0], - variable_info[1][category], + variable_info[1][categories[0]] if len(categories) == 1 else variable_info[1][categories[0]][categories[1]], ), flow="clamp", ) else: - raise ValueError(f"The provided fake factor information for category {category} is not valid. Please check the ff_functions dictionary.") + raise ValueError(f"The provided fake factor information for category {categories} is not valid. Please check the ff_functions dictionary.") def make_1D_ff( @@ -327,7 +327,7 @@ def make_1D_ff( input=cat_inputs[0], edges=process_conf["split_categories_binedges"][cat_inputs[0]], content=[ - get_ff_content(cat1, variable_info, ff_functions, unc_name) for cat1 in ff_functions + get_ff_content((cat1,), variable_info, ff_functions, unc_name) for cat1 in ff_functions ], flow="clamp", ), @@ -339,7 +339,7 @@ def make_1D_ff( input=cat_inputs[0], edges=process_conf["split_categories_binedges"][cat_inputs[0]], content=[ - get_ff_content(cat1, variable_info, ff_functions, "nominal") for cat1 in ff_functions + get_ff_content((cat1,), variable_info, ff_functions, "nominal") for cat1 in ff_functions ], flow="clamp", ), @@ -445,7 +445,7 @@ def make_2D_ff( else binedges_conf[cat_inputs[1]] ), content=[ - get_ff_content(cat2, variable_info, ff_functions[cat1], unc_name) for cat2 in ff_functions[cat1] + get_ff_content((cat1, cat2), variable_info, ff_functions[cat1], unc_name) for cat2 in ff_functions[cat1] ], flow="clamp", ) @@ -470,7 +470,7 @@ def make_2D_ff( else binedges_conf[cat_inputs[1]] ), content=[ - get_ff_content(cat2, variable_info, ff_functions[cat1], "nominal") for cat2 in ff_functions[cat1] + get_ff_content((cat1, cat2), variable_info, ff_functions[cat1], "nominal") for cat2 in ff_functions[cat1] ], flow="clamp", ) From f4d42b98ab5021152a5fe5281657bbf0b086cf10 Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Mon, 27 Apr 2026 16:52:39 +0200 Subject: [PATCH 19/20] fix cornor case of fit_function --- FF_calculation/FF_ttbar.py | 2 +- helper/ff_functions.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FF_calculation/FF_ttbar.py b/FF_calculation/FF_ttbar.py index 3b38795..7e313a3 100644 --- a/FF_calculation/FF_ttbar.py +++ b/FF_calculation/FF_ttbar.py @@ -117,7 +117,7 @@ def calculation_ttbar_FFs( # performing the fit and calculating the uncertainties if isinstance(splitting.fit_option, list): nominal_draw_obj, unc_draw_obj, results, used_fit = ff_func.fit_function( - ff_hists=FF_hist.Clone(), + ff_hists=[FF_hist.Clone()], bin_edges=splitting.var_bins, logger=logger, fit_option=splitting.fit_option, diff --git a/helper/ff_functions.py b/helper/ff_functions.py index a0e763d..c221b20 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -1097,7 +1097,7 @@ def build_TGraph( def fit_function( - ff_hists: Union[List[Any], Any], + ff_hists: Union[List[Any]], bin_edges: List[int], logger: str, fit_option: Union[str, List[str]], @@ -1115,7 +1115,7 @@ def fit_function( the fitted function variations are generated which are later used for plotting purposes. Args: - ff_hists: Either a list of nominal and MC varied ratio histograms or only the nominal ratio histogram + ff_hists: A list of either nominal and MC varied ratio histograms or only the nominal ratio histogram bin_edges: Bins edges of the fitted variable, needed for the graphs for plotting logger: Name of the logger that should be used fit_option: List[str] correspond to a list of poly_n fits to be performed @@ -1135,7 +1135,7 @@ def fit_function( fit_option = [fit_option] do_mc_subtr_unc, ff_hist_up, ff_hist_down = False, None, None - if isinstance(ff_hists, list): + if isinstance(ff_hists, list) and len(ff_hists) == 3: ff_hist, ff_hist_up, ff_hist_down = ff_hists do_mc_subtr_unc = True else: From 80223a53e217eb773c1611d06583ab20c02c01fd Mon Sep 17 00:00:00 2001 From: nshadskiy Date: Mon, 27 Apr 2026 17:16:01 +0200 Subject: [PATCH 20/20] fix index --- helper/ff_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/ff_functions.py b/helper/ff_functions.py index c221b20..8124425 100644 --- a/helper/ff_functions.py +++ b/helper/ff_functions.py @@ -1139,7 +1139,7 @@ def fit_function( ff_hist, ff_hist_up, ff_hist_down = ff_hists do_mc_subtr_unc = True else: - ff_hist = ff_hists + ff_hist = ff_hists[0] retrival_function, convert = fitting_helper.get_wrapped_functions_from_fits, True if fit_option == "binwise":