From 87b84f7b421bb2c14813ff7737b93dfbcccd2ab7 Mon Sep 17 00:00:00 2001 From: Matthew Feickert Date: Mon, 18 Sep 2023 13:04:12 -0500 Subject: [PATCH] feat: Don't specify a default POI name (#2328) * Set the default model poi_name to None to avoid making assumptions for users. * To maintain the pyhf.simplemodels users experience add poi_name="mu" as a default argument to be passed to the returned pyhf.pdf.Model object. * Add poi_name="mu" to all pyhf.Model construction in the tests. --- src/pyhf/pdf.py | 4 +++- src/pyhf/simplemodels.py | 15 +++++++++++---- tests/test_backend_consistency.py | 2 +- tests/test_optim.py | 8 ++++---- tests/test_validation.py | 4 +++- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/pyhf/pdf.py b/src/pyhf/pdf.py index 3b55f2369a..2b03da9020 100644 --- a/src/pyhf/pdf.py +++ b/src/pyhf/pdf.py @@ -768,7 +768,9 @@ def __init__( log.info(f"Validating spec against schema: {self.schema:s}") schema.validate(self.spec, self.schema, version=self.version) # build up our representation of the specification - poi_name = config_kwargs.pop('poi_name', 'mu') + # Default to no POI name + # https://github.com/scikit-hep/pyhf/issues/2327 + poi_name = config_kwargs.pop("poi_name", None) self._config = _ModelConfig(self.spec, **config_kwargs) modifiers, _nominal_rates = _nominal_and_modifiers_from_spec( diff --git a/src/pyhf/simplemodels.py b/src/pyhf/simplemodels.py index 299d3176c1..805bb0ffd9 100644 --- a/src/pyhf/simplemodels.py +++ b/src/pyhf/simplemodels.py @@ -10,7 +10,7 @@ def __dir__(): def correlated_background( - signal, bkg, bkg_up, bkg_down, batch_size=None, validate=True + signal, bkg, bkg_up, bkg_down, batch_size=None, validate=True, poi_name="mu" ): r""" Construct a simple single channel :class:`~pyhf.pdf.Model` with a @@ -27,10 +27,14 @@ def correlated_background( batch_size (:obj:`None` or :obj:`int`): Number of simultaneous (batched) Models to compute. validate (:obj:`bool`): If :obj:`True`, validate the model before returning. Only set this to :obj:`False` if you have an experimental use case and know what you're doing. + poi_name (:obj:`str`): The :class:`~pyhf.pdf.Model` parameter of interest name. + Defaults to ``"mu"``. Returns: ~pyhf.pdf.Model: The statistical model adhering to the :obj:`model.json` schema. + .. versionchanged:: 0.8.0 Added ``poi_name`` argument. + Example: >>> import pyhf >>> pyhf.set_backend("numpy") @@ -79,11 +83,11 @@ def correlated_background( } ] } - return Model(spec, batch_size=batch_size, validate=validate) + return Model(spec, batch_size=batch_size, validate=validate, poi_name=poi_name) def uncorrelated_background( - signal, bkg, bkg_uncertainty, batch_size=None, validate=True + signal, bkg, bkg_uncertainty, batch_size=None, validate=True, poi_name="mu" ): """ Construct a simple single channel :class:`~pyhf.pdf.Model` with a @@ -114,10 +118,13 @@ def uncorrelated_background( batch_size (:obj:`None` or :obj:`int`): Number of simultaneous (batched) Models to compute validate (:obj:`bool`): If :obj:`True`, validate the model before returning. Only set this to :obj:`False` if you have an experimental use case and know what you're doing. + poi_name (:obj:`str`): The :class:`~pyhf.pdf.Model` parameter of interest name. + Defaults to ``"mu"``. Returns: ~pyhf.pdf.Model: The statistical model adhering to the :obj:`model.json` schema + .. versionchanged:: 0.8.0 Added ``poi_name`` argument. """ spec = { 'channels': [ @@ -146,7 +153,7 @@ def uncorrelated_background( } ] } - return Model(spec, batch_size=batch_size, validate=validate) + return Model(spec, batch_size=batch_size, validate=validate, poi_name=poi_name) # Deprecated APIs diff --git a/tests/test_backend_consistency.py b/tests/test_backend_consistency.py index 3a2bca22f3..512b06b707 100644 --- a/tests/test_backend_consistency.py +++ b/tests/test_backend_consistency.py @@ -99,7 +99,7 @@ def test_hypotest_qmu_tilde( else [signal_sample, background_sample] ) spec = {'channels': [{'name': 'singlechannel', 'samples': samples}]} - pdf = pyhf.Model(spec) + pdf = pyhf.Model(spec, poi_name="mu") data = source['bindata']['data'] + pdf.config.auxdata diff --git a/tests/test_optim.py b/tests/test_optim.py index e4c5409076..b94b722cf8 100644 --- a/tests/test_optim.py +++ b/tests/test_optim.py @@ -312,7 +312,7 @@ def spec(source): @pytest.mark.parametrize('mu', [1.0], ids=['mu=1']) def test_optim(backend, source, spec, mu): - pdf = pyhf.Model(spec) + pdf = pyhf.Model(spec, poi_name="mu") data = source['bindata']['data'] + pdf.config.auxdata init_pars = pdf.config.suggested_init() @@ -336,7 +336,7 @@ def test_optim(backend, source, spec, mu): @pytest.mark.parametrize('mu', [1.0], ids=['mu=1']) def test_optim_with_value(backend, source, spec, mu): - pdf = pyhf.Model(spec) + pdf = pyhf.Model(spec, poi_name="mu") data = source['bindata']['data'] + pdf.config.auxdata init_pars = pdf.config.suggested_init() @@ -364,7 +364,7 @@ def test_optim_with_value(backend, source, spec, mu): @pytest.mark.parametrize('mu', [1.0], ids=['mu=1']) @pytest.mark.only_numpy_minuit def test_optim_uncerts(backend, source, spec, mu): - pdf = pyhf.Model(spec) + pdf = pyhf.Model(spec, poi_name="mu") data = source['bindata']['data'] + pdf.config.auxdata init_pars = pdf.config.suggested_init() @@ -391,7 +391,7 @@ def test_optim_uncerts(backend, source, spec, mu): @pytest.mark.parametrize('mu', [1.0], ids=['mu=1']) @pytest.mark.only_numpy_minuit def test_optim_correlations(backend, source, spec, mu): - pdf = pyhf.Model(spec) + pdf = pyhf.Model(spec, poi_name="mu") data = source['bindata']['data'] + pdf.config.auxdata init_pars = pdf.config.suggested_init() diff --git a/tests/test_validation.py b/tests/test_validation.py index 37d7500de1..1e3b54392b 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -788,7 +788,9 @@ def test_validation(setup): source = setup['source'] pdf = pyhf.Model( - setup['spec'], modifier_settings={'normsys': {'interpcode': 'code1'}} + setup["spec"], + modifier_settings={"normsys": {"interpcode": "code1"}}, + poi_name="mu", ) if 'channels' in source: