Skip to content

Commit c125bd1

Browse files
test: Add test of independence of pyhf.infer from pyhf details (#768)
* Add test that pyhf.infer.hypotest is independent of pyhf to ensure that inference is decoupled
1 parent 5951c5a commit c125bd1

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

tests/test_infer.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22
import pyhf
3+
import numpy as np
34

45

56
@pytest.fixture(scope='module')
@@ -85,3 +86,65 @@ def test_hypotest_return_expected_set(tmpdir, hypotest_args):
8586
assert isinstance(result[2], type(tb.astensor(result[2])))
8687
assert len(result[3]) == 5
8788
assert check_uniform_type(result[3])
89+
90+
91+
def test_inferapi_pyhf_independence():
92+
'''
93+
pyhf.infer should eventually be factored out so it should be
94+
infependent from pyhf internals. This is testing that
95+
a much simpler model still can run through pyhf.infer.hypotest
96+
'''
97+
from pyhf import get_backend
98+
99+
class _NonPyhfConfig(object):
100+
def __init__(self):
101+
self.poi_index = 0
102+
self.npars = 2
103+
104+
def suggested_init(self):
105+
return [1.0, 1.0]
106+
107+
def suggested_bounds(self):
108+
return [[0.0, 10.0], [0.0, 10.0]]
109+
110+
class NonPyhfModel(object):
111+
def __init__(self, spec):
112+
self.sig, self.nominal, self.uncert = spec
113+
self.factor = (self.nominal / self.uncert) ** 2
114+
self.aux = 1.0 * self.factor
115+
self.config = _NonPyhfConfig()
116+
117+
def _make_main_pdf(self, pars):
118+
mu, gamma = pars
119+
expected_main = gamma * self.nominal + mu * self.sig
120+
return pyhf.probability.Poisson(expected_main)
121+
122+
def _make_constraint_pdf(self, pars):
123+
mu, gamma = pars
124+
return pyhf.probability.Poisson(gamma * self.factor)
125+
126+
def expected_data(self, pars, include_auxdata=True):
127+
tensorlib, _ = get_backend()
128+
expected_main = tensorlib.astensor(
129+
[self._make_main_pdf(pars).expected_data()]
130+
)
131+
aux_data = tensorlib.astensor(
132+
[self._make_constraint_pdf(pars).expected_data()]
133+
)
134+
if not include_auxdata:
135+
return expected_main
136+
return tensorlib.concatenate([expected_main, aux_data])
137+
138+
def logpdf(self, pars, data):
139+
tensorlib, _ = get_backend()
140+
maindata, auxdata = data
141+
main = self._make_main_pdf(pars).log_prob(maindata)
142+
constraint = self._make_constraint_pdf(pars).log_prob(auxdata)
143+
return tensorlib.astensor([main + constraint])
144+
145+
model = NonPyhfModel([5, 50, 7])
146+
cls = pyhf.infer.hypotest(
147+
1.0, model.expected_data(model.config.suggested_init()), model
148+
)
149+
150+
assert np.isclose(cls[0], 0.7267836451638846)

0 commit comments

Comments
 (0)