Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Bookkeep fixed parameters #989

Merged
merged 36 commits into from
Aug 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0271fe6
update pdf to correctly bookkeep fixed parameters
kratsg Jul 26, 2020
410fa11
update tests to check for fixed parameters
kratsg Jul 26, 2020
7616a5c
update our schema sadly
kratsg Jul 26, 2020
4f7dfd3
single list item for now
kratsg Jul 26, 2020
e8eb3c8
missing slots
kratsg Jul 26, 2020
2765a88
be more specific in this test
kratsg Jul 26, 2020
3311abe
fix test
kratsg Jul 26, 2020
79929cf
single list item for now for overall
kratsg Jul 26, 2020
2d6d30d
black
kratsg Jul 26, 2020
b272f0f
fix up import test
kratsg Jul 26, 2020
12f39aa
get patchset tests working
kratsg Jul 26, 2020
ac4d795
fix pdf test
kratsg Jul 26, 2020
1aaefa5
add python code block to pass doctest
kratsg Jul 26, 2020
ada4dc9
get the scripts working
kratsg Jul 26, 2020
d2d6e85
Revert "get patchset tests working"
kratsg Jul 30, 2020
a6248c4
Revert "fix up import test"
kratsg Jul 30, 2020
72d26af
Revert "single list item for now for overall"
kratsg Jul 30, 2020
1ef7520
no list
kratsg Jul 30, 2020
d36baed
no list here too
kratsg Jul 30, 2020
a8c30c3
Revert "single list item for now"
kratsg Jul 30, 2020
220c9c5
Revert "update our schema sadly"
kratsg Jul 30, 2020
e712fb9
fix up test
kratsg Jul 30, 2020
2ad18d7
fix modifiers
kratsg Jul 30, 2020
82a5819
remove breakpoint
kratsg Jul 30, 2020
6ea7306
clean up fixed_pars
kratsg Jul 30, 2020
5fea7a5
codefactor
kratsg Jul 30, 2020
7e126d6
Revert "get the scripts working"
kratsg Jul 30, 2020
f45b455
fix schema test
kratsg Jul 30, 2020
9c56529
need to scale out by number of pars
kratsg Jul 30, 2020
3bc4519
add test to check
kratsg Jul 30, 2020
c027822
add docstring
kratsg Jul 30, 2020
44bb785
Apply suggestions from code review
kratsg Jul 30, 2020
d9f0e4c
update the test with more physical inits
kratsg Jul 30, 2020
34bb9a3
fixed_pars->suggested_fixed
kratsg Jul 30, 2020
b6e338e
remove slots
kratsg Aug 1, 2020
ada372a
remove more slots
kratsg Aug 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/pyhf/modifiers/histosys.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def required_parset(cls, sample_data, modifier_data):
'is_shared': True,
'inits': (0.0,),
'bounds': ((-5.0, 5.0),),
'fixed': False,
'auxdata': (0.0,),
}

Expand Down
1 change: 1 addition & 0 deletions src/pyhf/modifiers/lumi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def required_parset(cls, sample_data, modifier_data):
'op_code': cls.op_code,
'inits': None, # lumi
'bounds': None, # (0, 10*lumi)
'fixed': False,
'auxdata': None, # lumi
'sigmas': None, # lumi * lumirelerror
}
Expand Down
1 change: 1 addition & 0 deletions src/pyhf/modifiers/normfactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def required_parset(cls, sample_data, modifier_data):
'is_shared': True,
'inits': (1.0,),
'bounds': ((0, 10),),
'fixed': False,
}


Expand Down
1 change: 1 addition & 0 deletions src/pyhf/modifiers/normsys.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def required_parset(cls, sample_data, modifier_data):
'is_shared': True,
'inits': (0.0,),
'bounds': ((-5.0, 5.0),),
'fixed': False,
'auxdata': (0.0,),
}

Expand Down
1 change: 1 addition & 0 deletions src/pyhf/modifiers/shapefactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def required_parset(cls, sample_data, modifier_data):
'is_shared': True,
'inits': (1.0,) * len(sample_data),
'bounds': ((0.0, 10.0),) * len(sample_data),
'fixed': False,
}


Expand Down
1 change: 1 addition & 0 deletions src/pyhf/modifiers/shapesys.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def required_parset(cls, sample_data, modifier_data):
'is_shared': False,
'inits': (1.0,) * n_parameters,
'bounds': ((1e-10, 10.0),) * n_parameters,
'fixed': False,
# nb: auxdata/factors set by finalize. Set to non-numeric to crash
# if we fail to set auxdata/factors correctly
'auxdata': (None,) * n_parameters,
Expand Down
1 change: 1 addition & 0 deletions src/pyhf/modifiers/staterror.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def required_parset(cls, sample_data, modifier_data):
'is_shared': True,
'inits': (1.0,) * len(sample_data),
'bounds': ((1e-10, 10.0),) * len(sample_data),
'fixed': False,
'auxdata': (1.0,) * len(sample_data),
}

Expand Down
1 change: 1 addition & 0 deletions src/pyhf/parameters/paramsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ def __init__(self, **kwargs):
self.n_parameters = kwargs.pop('n_parameters')
self.suggested_init = kwargs.pop('inits')
self.suggested_bounds = kwargs.pop('bounds')
self.fixed = kwargs.pop('fixed')


class unconstrained(paramset):
Expand Down
2 changes: 2 additions & 0 deletions src/pyhf/parameters/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def reduce_paramsets_requirements(paramsets_requirements, paramsets_user_configs
'auxdata',
'factors',
'sigmas',
'fixed',
]

# - process all defined paramsets
Expand All @@ -27,6 +28,7 @@ def reduce_paramsets_requirements(paramsets_requirements, paramsets_user_configs
combined_paramset = {}
for k in paramset_keys:
for paramset_requirement in paramset_requirements:
# undefined: the modifier does not support configuring that property
v = paramset_requirement.get(k, 'undefined')
combined_paramset.setdefault(k, set([])).add(v)

Expand Down
30 changes: 28 additions & 2 deletions src/pyhf/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def _paramset_requirements_from_modelspec(spec, channel_nbins):
paramset_type = paramset_requirements.get('paramset_type')
paramset = paramset_type(**paramset_requirements)
_sets[param_name] = paramset

return _sets


Expand Down Expand Up @@ -229,8 +230,8 @@ def __init__(self, spec, **config_kwargs):
)

if config_kwargs:
raise KeyError(
f"""Unexpected keyword argument(s): '{"', '".join(config_kwargs.keys())}'"""
raise exceptions.Unsupported(
f"Unsupported options were passed in: {list(config_kwargs.keys())}."
)

self.par_map = {}
Expand Down Expand Up @@ -265,6 +266,31 @@ def par_slice(self, name):
def param_set(self, name):
return self.par_map[name]['paramset']

def suggested_fixed(self):
"""
Identify the fixed parameters in the model.

Returns:
List: A list of booleans, ``True`` for fixed and ``False`` for not fixed.

Something like the following to build fixed_vals appropriately:

.. code:: python

fixed_pars = pdf.config.suggested_fixed()
inits = pdf.config.suggested_init()
fixed_vals = [
(index, init)
for index, (init, is_fixed) in enumerate(zip(inits, fixed_pars))
if is_fixed
]
"""
fixed = []
for name in self.par_order:
paramset = self.par_map[name]['paramset']
fixed = fixed + [paramset.fixed] * paramset.n_parameters
return fixed

def set_poi(self, name):
if name not in [x for x, _ in self.modifiers]:
raise exceptions.InvalidModel(
Expand Down
131 changes: 107 additions & 24 deletions tests/test_combined_modifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
from pyhf.modifiers.shapesys import shapesys_combined
from pyhf.modifiers.normfactor import normfactor_combined
from pyhf.modifiers.shapefactor import shapefactor_combined
from pyhf.parameters import paramset
from pyhf.parameters import (
paramset,
unconstrained,
constrained_by_normal,
constrained_by_poisson,
)
import numpy as np
import pyhf

Expand Down Expand Up @@ -42,11 +47,23 @@ def test_histosys(backend):
mc = MockConfig(
par_map={
'hello': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[-5, 5]]),
'paramset': constrained_by_normal(
n_parameters=1,
inits=[0],
bounds=[[-5, 5]],
fixed=False,
auxdata=[0.0],
),
'slice': slice(0, 1),
},
'world': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[-5, 5]]),
'paramset': constrained_by_normal(
n_parameters=1,
inits=[0],
bounds=[[-5, 5]],
fixed=False,
auxdata=[0.0],
),
'slice': slice(1, 2),
},
},
Expand Down Expand Up @@ -131,11 +148,23 @@ def test_normsys(backend):
mc = MockConfig(
par_map={
'hello': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[-5, 5]]),
'paramset': constrained_by_normal(
n_parameters=1,
inits=[0],
bounds=[[-5, 5]],
fixed=False,
auxdata=[0.0],
),
'slice': slice(0, 1),
},
'world': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[-5, 5]]),
'paramset': constrained_by_normal(
n_parameters=1,
inits=[0],
bounds=[[-5, 5]],
fixed=False,
auxdata=[0.0],
),
'slice': slice(1, 2),
},
},
Expand Down Expand Up @@ -222,7 +251,14 @@ def test_lumi(backend):
mc = MockConfig(
par_map={
'lumi': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[-5, 5]]),
'paramset': constrained_by_normal(
n_parameters=1,
inits=[0],
bounds=[[-5, 5]],
fixed=False,
auxdata=[None],
sigmas=[None],
),
'slice': slice(0, 1),
}
},
Expand Down Expand Up @@ -272,12 +308,22 @@ def test_stat(backend):
mc = MockConfig(
par_map={
'staterror_chan1': {
'paramset': paramset(n_parameters=1, inits=[1], bounds=[[0, 10]]),
'paramset': constrained_by_normal(
n_parameters=1,
inits=[1],
bounds=[[0, 10]],
fixed=False,
auxdata=[1],
),
'slice': slice(0, 1),
},
'staterror_chan2': {
'paramset': paramset(
n_parameters=2, inits=[1, 1], bounds=[[0, 10], [0, 10]]
'paramset': constrained_by_normal(
n_parameters=2,
inits=[1, 1],
bounds=[[0, 10], [0, 10]],
fixed=False,
auxdata=[1, 1],
),
'slice': slice(1, 3),
},
Expand Down Expand Up @@ -349,21 +395,37 @@ def test_shapesys(backend):
mc = MockConfig(
par_map={
'dummy1': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[0, 10]]),
'paramset': paramset(
n_parameters=1, inits=[0], bounds=[[0, 10]], fixed=False,
),
'slice': slice(0, 1),
},
'shapesys1': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[0, 10]]),
'paramset': constrained_by_poisson(
n_parameters=1,
inits=[0],
bounds=[[0, 10]],
fixed=False,
auxdata=[None],
factors=[None],
),
'slice': slice(1, 2),
},
'shapesys2': {
'paramset': paramset(
n_parameters=2, inits=[0, 0], bounds=[[0, 10], [0, 10]]
'paramset': constrained_by_poisson(
n_parameters=2,
inits=[0, 0],
bounds=[[0, 10], [0, 10]],
fixed=False,
auxdata=[None, None],
factors=[None, None],
),
'slice': slice(2, 4),
},
'dummy2': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[0, 10]]),
'paramset': paramset(
n_parameters=1, inits=[0], bounds=[[0, 10]], fixed=False,
),
'slice': slice(4, 5),
},
},
Expand Down Expand Up @@ -432,11 +494,15 @@ def test_normfactor(backend):
mc = MockConfig(
par_map={
'mu1': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[0, 10]]),
'paramset': unconstrained(
n_parameters=1, inits=[0], bounds=[[0, 10]], fixed=False,
),
'slice': slice(0, 1),
},
'mu2': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[0, 10]]),
'paramset': unconstrained(
n_parameters=1, inits=[0], bounds=[[0, 10]], fixed=False,
),
'slice': slice(1, 2),
},
},
Expand Down Expand Up @@ -508,18 +574,30 @@ def test_shapesys_zero(backend):
mc = MockConfig(
par_map={
'SigXsecOverSM': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[0, 10]]),
'paramset': paramset(
n_parameters=1, inits=[0], bounds=[[0, 10]], fixed=False,
),
'slice': slice(0, 1),
},
'syst': {
'paramset': paramset(
n_parameters=5, inits=[0] * 5, bounds=[[0, 10]] * 5
'paramset': constrained_by_poisson(
n_parameters=5,
inits=[0] * 5,
bounds=[[0, 10]] * 5,
fixed=False,
auxdata=[None] * 5,
factors=[None] * 5,
),
'slice': slice(1, 6),
},
'syst_lowstats': {
'paramset': paramset(
n_parameters=0, inits=[0] * 0, bounds=[[0, 10]] * 0
'paramset': constrained_by_poisson(
n_parameters=0,
inits=[0] * 0,
bounds=[[0, 10]] * 0,
fixed=False,
auxdata=[None] * 0,
factors=[None] * 0,
),
'slice': slice(6, 6),
},
Expand Down Expand Up @@ -590,12 +668,17 @@ def test_shapefactor(backend):
mc = MockConfig(
par_map={
'shapefac1': {
'paramset': paramset(n_parameters=1, inits=[0], bounds=[[0, 10]]),
'paramset': unconstrained(
n_parameters=1, inits=[0], bounds=[[0, 10]], fixed=False,
),
'slice': slice(0, 1),
},
'shapefac2': {
'paramset': paramset(
n_parameters=2, inits=[0, 0], bounds=[[0, 10], [0, 10]]
'paramset': unconstrained(
n_parameters=2,
inits=[0, 0],
bounds=[[0, 10], [0, 10]],
fixed=False,
),
'slice': slice(1, 3),
},
Expand Down
4 changes: 4 additions & 0 deletions tests/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ def test_batched_constraints(backend):
bounds=[[0, 10]],
auxdata=[12],
factors=[12],
fixed=False,
),
'slice': slice(0, 1),
'auxdata': [1],
Expand All @@ -152,6 +153,7 @@ def test_batched_constraints(backend):
bounds=[[0, 10]] * 2,
auxdata=[13, 14],
factors=[13, 14],
fixed=False,
),
'slice': slice(1, 3),
},
Expand All @@ -162,6 +164,7 @@ def test_batched_constraints(backend):
bounds=[[0, 10]] * 2,
auxdata=[0, 0],
sigmas=[1.5, 2.0],
fixed=False,
),
'slice': slice(3, 5),
},
Expand All @@ -171,6 +174,7 @@ def test_batched_constraints(backend):
inits=[0] * 3,
bounds=[[0, 10]] * 3,
auxdata=[0, 0, 0],
fixed=False,
),
'slice': slice(5, 8),
},
Expand Down
Loading