-
Notifications
You must be signed in to change notification settings - Fork 8
Btag v2 #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Btag v2 #97
Changes from all commits
511b749
77e8939
1e290fa
00ab14a
94eafe8
66f6ff5
9127aa1
111e1ed
8f2d4e2
466ad72
8c24e76
862267b
0a90d03
9ba9374
97a4605
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |
| from .CorrectionsCore import * | ||
| from FLAF.Common.Utilities import WorkingPointsbTag | ||
| import yaml | ||
| import json | ||
|
|
||
| # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BTagShapeCalibration | ||
| # https://twiki.cern.ch/twiki/bin/view/CMS/BTagCalibration | ||
|
|
@@ -254,3 +255,95 @@ def getBTagShapeSF(self, df, src_name, scale_name, isCentral, return_variations) | |
| ) | ||
| SF_branches.append(branch_name_final) | ||
| return df, SF_branches | ||
|
|
||
|
|
||
| ROOT.gInterpreter.Declare(r""" | ||
| #include <map> | ||
| #include <string> | ||
|
|
||
| struct BTagMapApplier { | ||
| std::map<std::string,float> corr; | ||
|
|
||
| float operator()(float w, const std::string &key) const { | ||
| auto it = corr.find(key); | ||
| const float r = (it != corr.end()) ? it->second : 1.0; | ||
| return w * r; | ||
| } | ||
| }; | ||
| """) | ||
|
|
||
|
|
||
| class btagShapeWeightCorrector: | ||
| def __init__(self, *, norm_file_path, bins): | ||
| self.norm_file_path = norm_file_path | ||
| with open(norm_file_path, "r") as norm_file: | ||
| self.shape_weight_corr_dict = json.load(norm_file) | ||
| self.bins = bins | ||
| self._appliers = [] | ||
|
|
||
| def _define_key_column(self, df, keycol, syst): | ||
| # key = norm_<syst>_<bin_name> | ||
| pieces = [] | ||
| for bin_name, cut in self.bins.items(): | ||
| pieces.append(f'({cut}) ? std::string("norm_{syst}_{bin_name}") : ') | ||
| key_expr = "".join(pieces) + 'std::string("__default__")' | ||
|
|
||
| cols = set(df.GetColumnNames()) | ||
| return ( | ||
| df.Redefine(keycol, key_expr) | ||
| if keycol in cols | ||
| else df.Define(keycol, key_expr) | ||
| ) | ||
|
|
||
| def UpdateBtagWeight(self, *, df, unc_src, unc_scale, sf_branches): | ||
| unc_src_scale = f"{unc_src}_{unc_scale}" if unc_src != unc_scale else unc_src | ||
| if unc_src_scale not in self.shape_weight_corr_dict: | ||
| raise KeyError( | ||
| f"Key `{unc_src_scale}` not found in `{self.norm_file_path}`." | ||
| ) | ||
|
|
||
| # btag branches have format weight_bTagShape_{syst}_rel | ||
| # need to extract syst => need token #2 | ||
| systs = [b.split("_")[2] for b in sf_branches] | ||
|
|
||
| applier = ROOT.BTagMapApplier() | ||
| applier.corr["__default__"] = 1.0 | ||
| for k, v in self.shape_weight_corr_dict[unc_src_scale].items(): | ||
| applier.corr[k] = float(v) | ||
| self._appliers.append(applier) | ||
|
|
||
| # only correct weights for uncertainty variations | ||
| # branches are defined as relative, i.e. branch/central | ||
| # to correct, need to first multiply by central | ||
| # after this loop _rel branches will have the full value | ||
| # => will have to divide them by central after it is corrected | ||
| for syst in systs: | ||
| if syst == "Central": | ||
| continue | ||
| keycol = f"btag_shape_norm_key_{syst}" | ||
| df = self._define_key_column(df, keycol, syst) | ||
|
|
||
| branch_name = f"weight_bTagShape_{syst}_rel" | ||
| # rel := rel * central * corr(norm_<syst>_<bin>) | ||
| df = df.Redefine( | ||
| branch_name, f"(float){branch_name} * weight_bTagShape_Central" | ||
| ).Redefine(branch_name, applier, [branch_name, keycol]) | ||
|
|
||
| # correct central separately after everything else was corrected and central is not needed | ||
| df = self._define_key_column(df, "btag_shape_norm_key_Central", "Central") | ||
| df = df.Redefine( | ||
| "weight_bTagShape_Central", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should correct all btag-related up/down uncertainties, not only the central one |
||
| applier, | ||
| ["weight_bTagShape_Central", "btag_shape_norm_key_Central"], | ||
| ) | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We expect |
||
| # redefine all _rel branches by dividing them by updated Central to make them contain relative value | ||
| for syst in systs: | ||
| if syst == "Central": | ||
| continue | ||
| branch_name = f"weight_bTagShape_{syst}_rel" | ||
| df = df.Redefine( | ||
| branch_name, f"(float){branch_name} / weight_bTagShape_Central" | ||
| ) | ||
|
|
||
| return df | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid possible confusions with WP-based btag SFs that directly correct "normalization" instead of the btag discriminator shape.