|
1 | 1 | import pytest
|
2 | 2 | import pyhf
|
| 3 | +import numpy as np |
3 | 4 |
|
4 | 5 |
|
5 | 6 | @pytest.fixture(scope='module')
|
@@ -85,3 +86,65 @@ def test_hypotest_return_expected_set(tmpdir, hypotest_args):
|
85 | 86 | assert isinstance(result[2], type(tb.astensor(result[2])))
|
86 | 87 | assert len(result[3]) == 5
|
87 | 88 | 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