Commit 307095af authored by Marcel Rieger's avatar Marcel Rieger
Browse files

Make best fit calculation in exclusion plots optional.

parent 6ed5ba79
......@@ -159,22 +159,28 @@ def plot_exclusion_and_bestfit_1d(
legend_entries.append((h_dummy, " ", ""))
# best fit values
scans = [
evaluate_likelihood_scan_1d(d["nll_values"][scan_parameter], d["nll_values"]["dnll2"],
poi_min=d.get("scan_min"))
for d in data
]
g_bestfit = create_tgraph(n,
[scan.num_min() for scan in scans],
[n - i - 0.5 for i in range(n)],
[scan.num_min.u(direction="down", default=0.) for scan in scans],
[scan.num_min.u(direction="up", default=0.,) for scan in scans],
0,
0,
)
r.setup_graph(g_bestfit, props={"MarkerStyle": 20, "MarkerSize": 1.2, "LineWidth": 1})
draw_objs.append((g_bestfit, "PEZ"))
legend_entries.append((g_bestfit, "Best fit value"))
scans = []
for d in data:
scan = None
if "nll_values" in d:
scan = evaluate_likelihood_scan_1d(
d["nll_values"][scan_parameter],
d["nll_values"]["dnll2"],
poi_min=d.get("scan_min"),
)
scans.append(scan)
if any(scans):
g_bestfit = create_tgraph(n,
[(scan.num_min() if scan else -1e5) for scan in scans],
[n - i - 0.5 for i in range(n)],
[(scan.num_min.u(direction="down", default=0.) if scan else 0) for scan in scans],
[(scan.num_min.u(direction="up", default=0.,) if scan else 0) for scan in scans],
0,
0,
)
r.setup_graph(g_bestfit, props={"MarkerStyle": 20, "MarkerSize": 1.2, "LineWidth": 1})
draw_objs.append((g_bestfit, "PEZ"))
legend_entries.append((g_bestfit, "Best fit value"))
# theory prediction
if x_min < 1:
......
......@@ -232,7 +232,7 @@ def plot_gofs(
y_offset = n - 1 - i
# stats label
mean, stddev = scipy.stats.norm.fit(d["toys"])
mean, stddev = scipy.stats.norm.fit(d["central_toys"])
stats_label_x = r.get_x(84, pad, anchor="right")
stats_label_y = r.get_y(bottom_margin + int((n - i - 1.3) * entry_height), pad)
stats_label = stats_label_tmpl % (len(d["toys"]), mean, stddev)
......
......@@ -16,6 +16,11 @@ from dhi.config import br_hh
class PlotExclusionAndBestFit(POIScanTask, MultiDatacardTask, POIPlotTask):
best_fit = luigi.BoolParameter(
default=True,
description="when True, the POI's best fit value from likelihood profiling is computed and "
"shown as well; default: True",
)
h_lines = law.CSVParameter(
cls=luigi.IntParameter,
default=tuple(),
......@@ -46,14 +51,15 @@ class PlotExclusionAndBestFit(POIScanTask, MultiDatacardTask, POIPlotTask):
for scan_parameters in self.get_scan_parameters_product()
]
return [
{
"limits": merge_tasks(MergeUpperLimits, datacards=datacards),
"likelihoods": merge_tasks(MergeLikelihoodScan, datacards=datacards,
pois=tuple(self.scan_parameter_names)),
}
for datacards in self.multi_datacards
]
reqs = []
for datacards in self.multi_datacards:
req = {"limits": merge_tasks(MergeUpperLimits, datacards=datacards)}
if self.best_fit:
req["likelihoods"] = merge_tasks(MergeLikelihoodScan, datacards=datacards,
pois=tuple(self.scan_parameter_names))
reqs.append(req)
return reqs
def output(self):
name = self.create_plot_name(["exclusionbestfit", self.get_output_postfix()])
......@@ -77,9 +83,11 @@ class PlotExclusionAndBestFit(POIScanTask, MultiDatacardTask, POIPlotTask):
limits = PlotUpperLimits._load_scan_data(inp["limits"], self.scan_parameter_names)
# load likelihoods
nll_values, scan_min = PlotLikelihoodScan._load_scan_data(inp["likelihoods"],
self.scan_parameter_names, self.get_scan_parameters_product())
scan_min = None if np.isnan(scan_min[0]) else float(scan_min[0])
nll_values, scan_min = None, None
if "likelihoods" in inp:
nll_values, scan_min = PlotLikelihoodScan._load_scan_data(inp["likelihoods"],
self.scan_parameter_names, self.get_scan_parameters_product())
scan_min = None if np.isnan(scan_min[0]) else float(scan_min[0])
# store data
entry = dict(
......@@ -122,6 +130,7 @@ class PlotExclusionAndBestFit(POIScanTask, MultiDatacardTask, POIPlotTask):
class PlotExclusionAndBestFit2D(POIScanTask, POIPlotTask):
best_fit = PlotExclusionAndBestFit.best_fit
xsec_contours = law.CSVParameter(
default=("auto",),
significant=False,
......@@ -170,10 +179,12 @@ class PlotExclusionAndBestFit2D(POIScanTask, POIPlotTask):
for scan_parameters in self.get_scan_parameters_product()
]
return {
"limits": merge_tasks(MergeUpperLimits),
"likelihoods": merge_tasks(MergeLikelihoodScan, pois=tuple(self.scan_parameter_names)),
}
reqs = {"limits": merge_tasks(MergeUpperLimits)}
if self.best_fit:
reqs["likelihoods"] = merge_tasks(MergeLikelihoodScan,
pois=tuple(self.scan_parameter_names))
return reqs
def output(self):
name = self.create_plot_name(["exclusionbestfit2d", self.get_output_postfix()])
......@@ -236,9 +247,11 @@ class PlotExclusionAndBestFit2D(POIScanTask, POIPlotTask):
xsec_levels = [float(l) for l in self.xsec_contours]
# load likelihood scan data
nll_values, scan_mins = PlotLikelihoodScan._load_scan_data(inputs["likelihoods"],
self.scan_parameter_names, self.get_scan_parameters_product())
scan_mins = [(None if np.isnan(v) else float(v)) for v in scan_mins]
nll_values, scan_mins = None, None
if "likelihoods" in inputs:
nll_values, scan_mins = PlotLikelihoodScan._load_scan_data(inputs["likelihoods"],
self.scan_parameter_names, self.get_scan_parameters_product())
scan_mins = [(None if np.isnan(v) else float(v)) for v in scan_mins]
# call the plot function
self.call_plot_func(
......
......@@ -52,3 +52,4 @@
| `--page` | The number of the page to print (starting at 0) when `--parameters-per-page` is set. Prints all pages when negative. Defaults to `-1`. |
| `--postfit-toys` | Create frequentist postfit toys, which depend on observed data. Defaults to `False`. |
| `--scan-parameters` | Colon-separated parameters to scan, each in the format `name[,start,stop[,points]]`. When the same scan parameter name is used multiple times, the corresponding scan ranges are joined and the order of first occurrence is preserved. Defaults to `kl,-30,30,61`. |
| `--best-fit` | When `True`, the POIs best fit value is computed via likelihood profiling and shown as well. Defaults to `True`. |
......@@ -2,6 +2,6 @@ The `PlotExclusionAndBestFit2D` task collects the fit results from the `MergeUpp
<div class="dhi_parameter_table">
--8<-- "content/snippets/parameters.md@-2,20,19,16,54,14,12,48,17,18,12,39,40,11,3,4,5,6,7,8"
--8<-- "content/snippets/parameters.md@-2,20,19,16,54,14,12,55,48,17,18,12,39,40,11,3,4,5,6,7,8"
</div>
......@@ -2,6 +2,6 @@ The `PlotExclusionAndBestFit` task collects the fit results from the `MergeUpper
<div class="dhi_parameter_table">
--8<-- "content/snippets/parameters.md@-2,21,19,16,54,14,12,48,17,18,3,4,22,23,12,5,6"
--8<-- "content/snippets/parameters.md@-2,21,19,16,54,14,12,55,48,17,18,3,4,22,23,12,5,6"
</div>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment