From 9358f8591ce456ee1949bb867ea15f18231e8f26 Mon Sep 17 00:00:00 2001 From: Aryan Roy <50577809+aryan26roy@users.noreply.github.com> Date: Wed, 13 Oct 2021 05:17:26 +0530 Subject: [PATCH] feat: Add hypotest kwargs to pyhf.infer.intervals.upperlimit (#1613) * Add hypotest_kwargs to pyhf.infer.intervals.upperlimit to allow passing in configuration options to the underlying hypotest call * Add test for hypotest_kwargs use * Add Aryan Roy to contributor list --- docs/contributors.rst | 1 + src/pyhf/infer/intervals.py | 6 ++++-- tests/test_infer.py | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/contributors.rst b/docs/contributors.rst index 4333399065..264c4405fa 100644 --- a/docs/contributors.rst +++ b/docs/contributors.rst @@ -25,3 +25,4 @@ Contributors include: - Saransh Chopra - Sviatoslav Sydorenko - Mason Proffitt +- Aryan Roy diff --git a/src/pyhf/infer/intervals.py b/src/pyhf/infer/intervals.py index 10e51b6f56..0a967802c5 100644 --- a/src/pyhf/infer/intervals.py +++ b/src/pyhf/infer/intervals.py @@ -15,7 +15,7 @@ def _interp(x, xp, fp): return tb.astensor(np.interp(x, xp.tolist(), fp.tolist())) -def upperlimit(data, model, scan, level=0.05, return_results=False): +def upperlimit(data, model, scan, level=0.05, return_results=False, **hypotest_kwargs): """ Calculate an upper limit interval ``(0, poi_up)`` for a single Parameter of Interest (POI) using a fixed scan through POI-space. @@ -44,6 +44,8 @@ def upperlimit(data, model, scan, level=0.05, return_results=False): scan (:obj:`iterable`): Iterable of POI values. level (:obj:`float`): The threshold value to evaluate the interpolated results at. return_results (:obj:`bool`): Whether to return the per-point results. + hypotest_kwargs (:obj:`string`): Kwargs for the calls to + :class:`~pyhf.infer.hypotest` to configure the fits. Returns: Tuple of Tensors: @@ -56,7 +58,7 @@ def upperlimit(data, model, scan, level=0.05, return_results=False): """ tb, _ = get_backend() results = [ - hypotest(mu, data, model, test_stat="qtilde", return_expected_set=True) + hypotest(mu, data, model, return_expected_set=True, **hypotest_kwargs) for mu in scan ] obs = tb.astensor([[r[0]] for r in results]) diff --git a/tests/test_infer.py b/tests/test_infer.py index 3d4e62a66a..32f10277c4 100644 --- a/tests/test_infer.py +++ b/tests/test_infer.py @@ -34,6 +34,22 @@ def test_upperlimit(tmpdir, hypotest_args): ) +def test_upperlimit_with_kwargs(tmpdir, hypotest_args): + """ + Check that the default return structure of pyhf.infer.hypotest is as expected + """ + _, data, model = hypotest_args + results = pyhf.infer.intervals.upperlimit( + data, model, scan=np.linspace(0, 5, 11), test_stat="qtilde" + ) + assert len(results) == 2 + observed_limit, expected_limits = results + assert observed_limit == pytest.approx(1.0262704738584554) + assert expected_limits == pytest.approx( + [0.65765653, 0.87999725, 1.12453992, 1.50243428, 2.09232927] + ) + + def test_mle_fit_default(tmpdir, hypotest_args): """ Check that the default return structure of pyhf.infer.mle.fit is as expected