Skip to content

Conversation

@lukasheinrich
Copy link
Contributor

@lukasheinrich lukasheinrich commented Oct 14, 2021

Description

this is just a commit on top of #1625 that cleans up parameter handling and will a lot of nice things (user-configurable constraint terms, dropping constraints, etc)

Checklist Before Requesting Reviewer

  • Tests are passing
  • "WIP" removed from the title of the pull request
  • Selected an Assignee for the PR to be responsible for the log summary

Before Merging

For the PR Assignees:

  • Summarize commit messages into a comprehensive review of the PR
* Remove parameter pruning due to non-defined constraints (will
move all parameter allocation to modifier_builders
* Remove dead code in src/pyhf/constraints.py
* Refactor pyhf.pdf._nominal_builder
* Add tests for modifier holes and fixed sets

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@matthewfeickert matthewfeickert marked this pull request as draft October 15, 2021 07:14
@matthewfeickert matthewfeickert added API Changes the public API feat/enhancement New feature or request labels Oct 15, 2021
@matthewfeickert matthewfeickert changed the title [WIP] Simplied parameters feat: Simplified parameters Oct 15, 2021
@matthewfeickert
Copy link
Member

@lukasheinrich This has now been rebased off of master now that PR #1625 has been merged.

@lukasheinrich lukasheinrich force-pushed the simplied_parameters branch 2 times, most recently from dae1fab to 00d70d3 Compare October 17, 2021 23:11
@codecov
Copy link

codecov bot commented Oct 17, 2021

Codecov Report

Merging #1639 (6c66796) into master (5ea4e0a) will increase coverage by 0.00%.
The diff coverage is 98.86%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1639   +/-   ##
=======================================
  Coverage   98.07%   98.07%           
=======================================
  Files          64       64           
  Lines        4199     4216   +17     
  Branches      578      585    +7     
=======================================
+ Hits         4118     4135   +17     
  Misses         48       48           
  Partials       33       33           
Flag Coverage Δ
contrib 25.30% <12.50%> (+0.06%) ⬆️
doctest 61.05% <52.27%> (-0.11%) ⬇️
unittests 96.39% <98.86%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/pyhf/cli/spec.py 100.00% <ø> (ø)
src/pyhf/parameters/paramview.py 95.12% <ø> (ø)
src/pyhf/readxml.py 94.40% <ø> (ø)
src/pyhf/workspace.py 100.00% <ø> (ø)
src/pyhf/pdf.py 97.79% <96.29%> (+0.07%) ⬆️
src/pyhf/cli/infer.py 97.61% <100.00%> (ø)
src/pyhf/constraints.py 97.01% <100.00%> (-0.07%) ⬇️
src/pyhf/modifiers/shapesys.py 100.00% <100.00%> (ø)
src/pyhf/modifiers/staterror.py 97.95% <100.00%> (+0.23%) ⬆️
src/pyhf/parameters/paramsets.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5ea4e0a...6c66796. Read the comment docs.

@lukasheinrich lukasheinrich marked this pull request as ready for review October 17, 2021 23:32
@lukasheinrich
Copy link
Contributor Author



def test_staterror_holes():
spec = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When fitting this to Asimov:

pyhf.set_backend(pyhf.tensorlib, pyhf.optimize.minuit_optimizer(verbose=2))
res = pyhf.infer.mle.fit(
    [50.0, 60.0, 0.0, 70.0, 50.0, 60.0, 10.0, 70.0] + model.config.auxdata,
    model,
    return_uncertainties=True,
)
for i, parname in enumerate(model.config.par_names()):
    print(f"{parname} = {res[i][0]} +/- {res[i][1]}")

it looks like things do not work as expected yet. When making all staterrors non-zero, the fit will still fail if the prediction for the third bin of channel1 is 0 (this is probably independent of this PR).

When making the model prediction non-zero everywhere, but making one staterror bin zero again, the fit will fail as the pdf is NaN, but the parameter for the bin with zero staterror is still a free parameter in the fit. I would have expected it to be held constant or pruned instead.

Copy link
Contributor Author

@lukasheinrich lukasheinrich Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a good catch - I need to add something like reindex_access_field to staterror.. I have removed the test for now.

So I guess the logic we want is that the NP is removed if the sum of the nominals across all sampples is zero

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For staterror it could be removed in two cases:

  • nominal is zero (then the modifier has no effect anyway, though the parameter may act on other samples still)
  • auxdata is zero (again, the parameter may act on other samples still)
    If the parameter does not modify any samples at all, then I think it should be pruned.

I was also looking at the naming: it may be nice to change the parameter component names such that the index corresponds to the bin. For three parameters ["par[0]", "par[1]", "par[2]"] acting on three bins, I would expect the parameter names to be ["par[0]", "par[2]"] when removing the parameter acting on the central bin, instead of the ["par[0]", "par[1]"] that seems to be used now (which may make it difficult to track which parameters still exist).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import pyhf
import matplotlib.pyplot as plt

spec = {
        'channels': [
            {
                'name': 'channel1',
                'samples': [
                    {
                        'name': 'another_sample',
                        'data': [50,60,0,70],
                        'modifiers': [
                            {'name': 'mu', 'type': 'normfactor', 'data': None},
                            {'name': 'staterror_1', 'type': 'staterror', 'data': [5,0,5,5]}
                        ],
                    },
                ],
            },
            {
                'name': 'channel2',
                'samples': [
                    {
                        'name': 'another_sample',
                        'data': [50,0,0,70],
                        'modifiers': [
                            {'name': 'staterror_2', 'type': 'staterror', 'data': [5,0,5,5]}
                        ],
                    },
                ],
            }
        ],
    }

model = pyhf.Model(spec, poi_name = '')
assert model.config.npars == 6
a,b = model._modifications(pyhf.tensorlib.astensor([10,2.,3.,4.,5.,6.]))
assert (b[1][0,0,0,:] == [2.,3.,1.,4.,1.,1.,1.,1.]).all()
assert (b[1][1,0,0,:] == [1.,1.,1.,1.,5.,1.,1.,6.]).all()
plt.imshow(b[1][:,0,0,:])

gives:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok re-added the test @alexander-held

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disucssion here: #1650

@lukasheinrich lukasheinrich force-pushed the simplied_parameters branch 4 times, most recently from f3647d2 to a98d946 Compare October 18, 2021 17:21
@kratsg kratsg force-pushed the simplied_parameters branch from d03c741 to 1e07e2b Compare October 19, 2021 18:21
@matthewfeickert matthewfeickert added tests pytest refactor A code change that neither fixes a bug nor adds a feature labels Oct 22, 2021
Copy link
Member

@matthewfeickert matthewfeickert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 👍 Thanks @lukasheinrich!

Once the CI finishes I'll merge this in. 🚀

@matthewfeickert matthewfeickert changed the title feat: Simplified parameters refactor: Simplified parameters Oct 22, 2021
@matthewfeickert matthewfeickert added the fix A bug fix label Oct 22, 2021
@matthewfeickert matthewfeickert merged commit 9fbbbf9 into master Oct 22, 2021
@matthewfeickert matthewfeickert deleted the simplied_parameters branch October 22, 2021 18:10
@alexander-held
Copy link
Member

For future reference, this changed the behavior of paramset.suggested_fixed, and the old behavior is now achieved via paramset.suggested_fixed_as_bool.

kratsg pushed a commit that referenced this pull request Jan 5, 2022
… of 0 (#1740)

* Update warning note for shapesys modifier, and add similar warning for
staterror modifier, that bins that have a modifier data value of 0 will
result in a nuisance parameter being allocated resulting in a fixed modifier
of 1.
   - These changes occurred in PR #1639
* Move descriptions of modifier examples before example is given for clarity.
@kratsg kratsg added the bug Something isn't working label Aug 27, 2022
matthewfeickert pushed a commit that referenced this pull request Aug 28, 2022
* Fix staterror bug introduced after v0.6.3 where staterror erroneously affected
  multiple samples.
   - Amends PR #1639 which introduced regression.
   - c.f. Issue #1720
* Remove staterror_combined.__staterror_uncrt as it is unused by the codebase.
* Add test to verify that staterror does not affect more samples than shapesys equivalently.

Co-authored-by: Giordon Stark <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API Changes the public API bug Something isn't working feat/enhancement New feature or request fix A bug fix refactor A code change that neither fixes a bug nor adds a feature tests pytest

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor shapesys Remove StatError NPs when zero-valued like ShapeSys clarify dead code situation in constraints.py

4 participants