pyhf icon indicating copy to clipboard operation
pyhf copied to clipboard

`Workspace.build` does not propagate all relevant information from measurement config

Open alexander-held opened this issue 3 years ago • 1 comments

Summary

Workspace.build does not propagate auxdata / sigmas from the measurement config to the new workspace.

This is caused by the measurement config only taking into account a few of the possible settings: https://github.com/scikit-hep/pyhf/blob/e3d879f3e4982ac629bec7bf92d78b00025e52dc/src/pyhf/workspace.py#L820-L831

The current behavior can result in a crash when lumi modifiers are present (related: #1516).

Instead of hardcoding all possibilities, I was wondering about the usefulness of a model.config.spec, similar to model.spec. It would presumably simplify the code here, and may also be useful for hashing if the measurement config is important (#1762).

OS / Environment

n/a

Steps to Reproduce

import pyhf

spec = {
    "channels": [
        {
            "name": "Signal Region",
            "samples": [
                {
                    "data": [35],
                    "modifiers": [
                        {
                            "data": None,
                            "name": "Signal strength",
                            "type": "normfactor",
                        },
                        {"data": None, "name": "lumi", "type": "lumi"},
                    ],
                    "name": "Signal",
                }
            ],
        }
    ],
    "measurements": [
        {
            "config": {
                "parameters": [
                    {
                        "auxdata": [1.0],
                        "bounds": [[0.9, 1.1]],
                        "inits": [1.0],
                        "name": "lumi",
                        "sigmas": [0.02],
                    },
                ],
                "poi": "Signal strength",
            },
            "name": "lumi",
        },
    ],
    "observations": [{"data": [35], "name": "Signal Region"}],
    "version": "1.0.0",
}

ws = pyhf.Workspace(spec)
print(ws["measurements"][0]["config"]["parameters"][0])  # contains auxdata / sigmas
model = ws.model()
data = ws.data(model)

new_ws = pyhf.Workspace.build(model, data)
print(new_ws["measurements"][0]["config"]["parameters"][1])  # auxdata / sigmas now missing
new_ws.model()  # fails due to mising lumi auxdata

File Upload (optional)

No response

Expected Results

The new workspace should match the old one, and model creation from the new workspace should work.

Actual Results

{'auxdata': [1.0], 'bounds': [[0.9, 1.1]], 'inits': [1.0], 'name': 'lumi', 'sigmas': [0.02]}
{'bounds': [[0, 10]], 'inits': [1.0], 'fixed': False, 'name': 'Signal strength'}
Traceback (most recent call last):
  File "[...]/lumi_bug.py", line 51, in <module>
    new_ws.model()  # fails due to mising lumi auxdata
  File "[...]/pyhf/src/pyhf/workspace.py", line 442, in model
    return Model(modelspec, **config_kwargs)
  File "[...]/pyhf/src/pyhf/pdf.py", line 674, in __init__
    modifiers, _nominal_rates = _nominal_and_modifiers_from_spec(
  File "[...]/pyhf/src/pyhf/pdf.py", line 164, in _nominal_and_modifiers_from_spec
    _prameter_objects, _auxdata, _auxdata_order = _create_parameters_from_spec(
  File "[...]/pyhf/src/pyhf/pdf.py", line 52, in _create_parameters_from_spec
    auxdata += paramset.auxdata
TypeError: 'NoneType' object is not iterable

pyhf Version

master (e3d879f)

Code of Conduct

  • [X] I agree to follow the Code of Conduct

alexander-held avatar Feb 07 '22 13:02 alexander-held

Another thing getting lost is the measurement config name field, which is replaced by a generic "measurement".

alexander-held avatar Mar 07 '23 14:03 alexander-held