Skip to content

Commit 6a3ab96

Browse files
committed
fix: satisfy precommit
1 parent 9ed8358 commit 6a3ab96

11 files changed

+139
-41
lines changed

src/cabinetry/fit/__init__.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import pyhf
99
import scipy.optimize
1010
import scipy.stats
11-
import re
1211

1312
from cabinetry import model_utils
1413
from cabinetry.fit.results_containers import (
@@ -87,10 +86,7 @@ def _fit_model_pyhf(
8786

8887
bestfit = pyhf.tensorlib.to_numpy(result[:, 0])
8988
uncertainty = pyhf.tensorlib.to_numpy(result[:, 1])
90-
labels = model.config.par_names()
91-
_mod_dict = dict(model.config.modifiers)
92-
_clean_labels = [re.sub(r"\[.*\]", "", label) for label in labels]
93-
types = [_mod_dict[n] if n in _mod_dict else None for n in _clean_labels]
89+
labels, types = model_utils._labels_modifiers(model)
9490
corr_mat = pyhf.tensorlib.to_numpy(corr_mat)
9591
best_twice_nll = float(best_twice_nll) # convert 0-dim np.ndarray to float
9692

@@ -150,7 +146,7 @@ def _fit_model_custom(
150146
fix_pars = fix_pars or model.config.suggested_fixed()
151147
par_bounds = par_bounds or model.config.suggested_bounds()
152148

153-
labels = model.config.par_names()
149+
labels, types = model_utils._labels_modifiers(model)
154150

155151
# set initial step size to 0 for fixed parameters
156152
# this will cause the associated parameter uncertainties to be 0 post-fit
@@ -195,6 +191,7 @@ def twice_nll_func(pars: np.ndarray) -> Any:
195191
bestfit,
196192
uncertainty,
197193
labels,
194+
types,
198195
corr_mat,
199196
best_twice_nll,
200197
minos_uncertainty=minos_results,

src/cabinetry/fit/results_containers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Provides containers for inference results."""
22

3-
from typing import Dict, List, NamedTuple, Tuple
3+
from typing import Dict, List, NamedTuple, Optional, Tuple
44

55
import numpy as np
66

@@ -24,7 +24,7 @@ class FitResults(NamedTuple):
2424
bestfit: np.ndarray
2525
uncertainty: np.ndarray
2626
labels: List[str]
27-
types: List[str]
27+
types: List[Optional[str]]
2828
corr_mat: np.ndarray
2929
best_twice_nll: float
3030
goodness_of_fit: float = -1

src/cabinetry/model_utils.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import json
44
import logging
5+
import re
56
from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union
67

78
import awkward as ak
@@ -516,6 +517,17 @@ def _filter_channels(
516517
return filtered_channels
517518

518519

520+
def _labels_modifiers(
521+
model: pyhf.pdf.Model,
522+
) -> Tuple[List[str], List[Optional[str]]]:
523+
""" """
524+
labels = model.config.par_names()
525+
_mod_dict = dict(model.config.modifiers)
526+
_clean_labels = [re.sub(r"\[.*\]", "", label) for label in labels]
527+
types = [_mod_dict[n] if n in _mod_dict else None for n in _clean_labels]
528+
return labels, types
529+
530+
519531
def match_fit_results(model: pyhf.pdf.Model, fit_results: FitResults) -> FitResults:
520532
"""Matches results from a fit to a model by adding or removing parameters as needed.
521533
@@ -543,7 +555,7 @@ def match_fit_results(model: pyhf.pdf.Model, fit_results: FitResults) -> FitResu
543555

544556
bestfit = asimov_parameters(model) # Asimov parameter values for target model
545557
uncertainty = prefit_uncertainties(model) # pre-fit uncertainties for target model
546-
labels = model.config.par_names() # labels for target model
558+
labels, types = _labels_modifiers(model)
547559

548560
# indices of parameters in current fit results, or None if they are missing
549561
indices_for_corr: List[Optional[int]] = [None] * len(labels)
@@ -577,6 +589,7 @@ def match_fit_results(model: pyhf.pdf.Model, fit_results: FitResults) -> FitResu
577589
np.asarray(bestfit),
578590
np.asarray(uncertainty),
579591
labels,
592+
types,
580593
corr_mat,
581594
fit_results.best_twice_nll,
582595
fit_results.goodness_of_fit,

src/cabinetry/visualize/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""High-level entry point for visualizing fit models and inference results."""
22

3+
import fnmatch
34
import glob
45
import logging
56
import pathlib
6-
import fnmatch
77
from typing import Any, Dict, List, Optional, Tuple, Union
88

99
import matplotlib as mpl
@@ -442,7 +442,7 @@ def pulls(
442442
*,
443443
figure_folder: Union[str, pathlib.Path] = "figures",
444444
exclude: Optional[Union[str, List[str], Tuple[str, ...]]] = None,
445-
exclude_by_type: Optional[Union[str, List[str]]] = ["staterror"],
445+
exclude_by_type: Optional[List[str]] = None,
446446
close_figure: bool = True,
447447
save_figure: bool = True,
448448
) -> mpl.figure.Figure:
@@ -489,6 +489,8 @@ def pulls(
489489
)
490490

491491
# exclude by type
492+
if exclude_by_type is None:
493+
exclude_by_type = ["staterror"]
492494
exclude_set.update(
493495
[
494496
label

src/cabinetry/visualize/plot_result.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def pulls(
9191
matplotlib.figure.Figure: the pull figure
9292
"""
9393
num_pars = len(bestfit)
94-
numeric = np.zeros(num_pars, dtype=bool) if numeric is None else numeric
94+
numeric = np.zeros(num_pars, dtype=bool) if numeric is None else np.asarray(numeric)
9595
y_positions = np.arange(num_pars)[::-1]
9696

9797
fig, ax = plt.subplots(figsize=(6, 1 + num_pars / 4), dpi=100)

tests/cli/test_cli.py

+28-6
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,12 @@ def test_workspace(mock_validate, mock_build, cli_helpers, tmp_path):
9595
@mock.patch(
9696
"cabinetry.fit.fit",
9797
return_value=fit.FitResults(
98-
np.asarray([1.0]), np.asarray([0.1]), ["label"], np.asarray([[1.0]]), 1.0
98+
np.asarray([1.0]),
99+
np.asarray([0.1]),
100+
["label"],
101+
["type"],
102+
np.asarray([[1.0]]),
103+
1.0,
99104
),
100105
autospec=True,
101106
)
@@ -109,8 +114,9 @@ def test_fit(mock_utils, mock_fit, mock_pulls, mock_corrmat, tmp_path):
109114
bestfit = np.asarray([1.0])
110115
uncertainty = np.asarray([0.1])
111116
labels = ["label"]
117+
types = ["type"]
112118
corr_mat = np.asarray([[1.0]])
113-
fit_results = fit.FitResults(bestfit, uncertainty, labels, corr_mat, 1.0)
119+
fit_results = fit.FitResults(bestfit, uncertainty, labels, types, corr_mat, 1.0)
114120

115121
workspace_path = str(tmp_path / "workspace.json")
116122

@@ -204,7 +210,12 @@ def test_fit(mock_utils, mock_fit, mock_pulls, mock_corrmat, tmp_path):
204210
@mock.patch(
205211
"cabinetry.fit.fit",
206212
return_value=fit.FitResults(
207-
np.asarray([1.0]), np.asarray([0.1]), ["label"], np.asarray([[1.0]]), 1.0
213+
np.asarray([1.0]),
214+
np.asarray([0.1]),
215+
["label"],
216+
["type"],
217+
np.asarray([[1.0]]),
218+
1.0,
208219
),
209220
autospec=True,
210221
)
@@ -218,8 +229,9 @@ def test_ranking(mock_utils, mock_fit, mock_rank, mock_vis, tmp_path):
218229
bestfit = np.asarray([1.0])
219230
uncertainty = np.asarray([0.1])
220231
labels = ["label"]
232+
types = ["type"]
221233
corr_mat = np.asarray([[1.0]])
222-
fit_results = fit.FitResults(bestfit, uncertainty, labels, corr_mat, 1.0)
234+
fit_results = fit.FitResults(bestfit, uncertainty, labels, types, corr_mat, 1.0)
223235

224236
workspace_path = str(tmp_path / "workspace.json")
225237

@@ -467,7 +479,12 @@ def test_significance(mock_utils, mock_sig, tmp_path):
467479
@mock.patch(
468480
"cabinetry.fit.fit",
469481
return_value=fit.FitResults(
470-
np.asarray([1.0]), np.asarray([0.1]), ["label"], np.asarray([[1.0]]), 1.0
482+
np.asarray([1.0]),
483+
np.asarray([0.1]),
484+
["label"],
485+
["type"],
486+
np.asarray([[1.0]]),
487+
1.0,
471488
),
472489
autospec=True,
473490
)
@@ -508,7 +525,12 @@ def test_data_mc(
508525
config_path = str(tmp_path / "config.yml")
509526
cli_helpers.write_config(config_path, config)
510527
fit_results = fit.FitResults(
511-
np.asarray([1.0]), np.asarray([0.1]), ["label"], np.asarray([[1.0]]), 1.0
528+
np.asarray([1.0]),
529+
np.asarray([0.1]),
530+
["label"],
531+
["type"],
532+
np.asarray([[1.0]]),
533+
1.0,
512534
)
513535

514536
result = runner.invoke(

tests/fit/test_fit.py

+64-17
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ def test_print_results(caplog):
1616
bestfit = np.asarray([1.0, 2.0])
1717
uncertainty = np.asarray([0.1, 0.3])
1818
labels = ["param_A", "param_B"]
19-
fit_results = fit.FitResults(bestfit, uncertainty, labels, np.empty(0), 0.0)
19+
types = ["normsys", "shapesys"]
20+
fit_results = fit.FitResults(bestfit, uncertainty, labels, types, np.empty(0), 0.0)
2021

2122
fit.print_results(fit_results)
2223
assert "param_A = 1.0000 +/- 0.1000" in [rec.message for rec in caplog.records]
@@ -143,13 +144,13 @@ def test__fit_model_custom(mock_minos, example_spec, example_spec_multibin):
143144
@mock.patch(
144145
"cabinetry.fit._fit_model_custom",
145146
return_value=fit.FitResults(
146-
np.asarray([1.2]), np.asarray([0.2]), ["par"], np.empty(0), 2.0
147+
np.asarray([1.2]), np.asarray([0.2]), ["par"], ["normsys"], np.empty(0), 2.0
147148
),
148149
)
149150
@mock.patch(
150151
"cabinetry.fit._fit_model_pyhf",
151152
return_value=fit.FitResults(
152-
np.asarray([1.1]), np.asarray([0.2]), ["par"], np.empty(0), 2.0
153+
np.asarray([1.1]), np.asarray([0.2]), ["par"], ["normsys"], np.empty(0), 2.0
153154
),
154155
)
155156
def test__fit_model(mock_pyhf, mock_custom, example_spec):
@@ -295,7 +296,7 @@ def test__goodness_of_fit(
295296
@mock.patch(
296297
"cabinetry.fit._fit_model",
297298
return_value=fit.FitResults(
298-
np.asarray([1.0]), np.asarray([0.1]), ["par"], np.empty(0), 2.0
299+
np.asarray([1.0]), np.asarray([0.1]), ["par"], ["normsys"], np.empty(0), 2.0
299300
),
300301
)
301302
def test_fit(mock_fit, mock_print, mock_gof):
@@ -382,33 +383,78 @@ def test_fit(mock_fit, mock_print, mock_gof):
382383
"cabinetry.fit._fit_model",
383384
side_effect=[
384385
fit.FitResults(
385-
np.asarray([0.9, 1.3]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
386+
np.asarray([0.9, 1.3]),
387+
np.asarray([0.1, 0.1]),
388+
["a", "b"],
389+
["normsys", "normsys"],
390+
np.empty(0),
391+
0.0,
386392
),
387393
fit.FitResults(
388-
np.asarray([0.9, 0.7]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
394+
np.asarray([0.9, 0.7]),
395+
np.asarray([0.1, 0.1]),
396+
["a", "b"],
397+
["normsys", "normsys"],
398+
np.empty(0),
399+
0.0,
389400
),
390401
fit.FitResults(
391-
np.asarray([0.9, 1.2]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
402+
np.asarray([0.9, 1.2]),
403+
np.asarray([0.1, 0.1]),
404+
["a", "b"],
405+
["normsys", "normsys"],
406+
np.empty(0),
407+
0.0,
392408
),
393409
fit.FitResults(
394-
np.asarray([0.9, 0.8]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
410+
np.asarray([0.9, 0.8]),
411+
np.asarray([0.1, 0.1]),
412+
["a", "b"],
413+
["normsys", "normsys"],
414+
np.empty(0),
415+
0.0,
395416
),
396417
# for second ranking call with fixed parameter
397418
fit.FitResults(
398-
np.asarray([0.9, 1.2]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
419+
np.asarray([0.9, 1.2]),
420+
np.asarray([0.1, 0.1]),
421+
["a", "b"],
422+
["normsys", "normsys"],
423+
np.empty(0),
424+
0.0,
399425
),
400426
fit.FitResults(
401-
np.asarray([0.9, 0.8]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
427+
np.asarray([0.9, 0.8]),
428+
np.asarray([0.1, 0.1]),
429+
["a", "b"],
430+
["normsys", "normsys"],
431+
np.empty(0),
432+
0.0,
402433
),
403434
# for third ranking call without reference results
404435
fit.FitResults(
405-
np.asarray([0.9, 1.0]), np.asarray([0.3, 0.3]), ["a", "b"], np.empty(0), 0.0
436+
np.asarray([0.9, 1.0]),
437+
np.asarray([0.3, 0.3]),
438+
["a", "b"],
439+
["normsys", "normsys"],
440+
np.empty(0),
441+
0.0,
406442
),
407443
fit.FitResults(
408-
np.asarray([0.9, 1.3]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
444+
np.asarray([0.9, 1.3]),
445+
np.asarray([0.1, 0.1]),
446+
["a", "b"],
447+
["normsys", "normsys"],
448+
np.empty(0),
449+
0.0,
409450
),
410451
fit.FitResults(
411-
np.asarray([0.9, 0.7]), np.asarray([0.1, 0.1]), ["a", "b"], np.empty(0), 0.0
452+
np.asarray([0.9, 0.7]),
453+
np.asarray([0.1, 0.1]),
454+
["a", "b"],
455+
["normsys", "normsys"],
456+
np.empty(0),
457+
0.0,
412458
),
413459
],
414460
)
@@ -417,7 +463,8 @@ def test_ranking(mock_fit, example_spec):
417463
bestfit = np.asarray([0.9, 1.0])
418464
uncertainty = np.asarray([0.02, 0.1])
419465
labels = ["staterror", "mu"]
420-
fit_results = fit.FitResults(bestfit, uncertainty, labels, np.empty(0), 0.0)
466+
types = ["staterror", "normfactor"]
467+
fit_results = fit.FitResults(bestfit, uncertainty, labels, types, np.empty(0), 0.0)
421468
model, data = model_utils.model_and_data(example_spec)
422469
ranking_results = fit.ranking(model, data, fit_results=fit_results)
423470

@@ -500,16 +547,16 @@ def test_ranking(mock_fit, example_spec):
500547
"cabinetry.fit._fit_model",
501548
side_effect=[
502549
fit.FitResults(
503-
np.asarray([0.9, 1.3]), np.asarray([0.1, 0.1]), [], np.empty(0), 8.0
550+
np.asarray([0.9, 1.3]), np.asarray([0.1, 0.1]), [], [], np.empty(0), 8.0
504551
)
505552
] # nominal fit
506553
+ [
507-
fit.FitResults(np.empty(0), np.empty(0), [], np.empty(0), abs(i) + 8)
554+
fit.FitResults(np.empty(0), np.empty(0), [], [], np.empty(0), abs(i) + 8)
508555
for i in np.linspace(-5, 5, 11)
509556
] # fits in scan
510557
+ [
511558
fit.FitResults(
512-
np.asarray([0.9, 1.3]), np.asarray([0.1, 0.1]), [], np.empty(0), 2.0
559+
np.asarray([0.9, 1.3]), np.asarray([0.1, 0.1]), [], [], np.empty(0), 2.0
513560
)
514561
]
515562
* 6, # fits for custom parameter range

0 commit comments

Comments
 (0)