plothist 1.3.2__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plothist/__init__.py +66 -74
- plothist/_version.py +21 -0
- plothist/_version.pyi +2 -0
- plothist/comparison.py +115 -106
- plothist/examples/1d_hist/1d_comparison_asymmetry.py +37 -0
- plothist/examples/1d_hist/1d_comparison_difference.py +40 -0
- plothist/examples/1d_hist/1d_comparison_efficiency.py +37 -0
- plothist/examples/1d_hist/1d_comparison_only_efficiency.py +33 -0
- plothist/examples/1d_hist/1d_comparison_pull.py +37 -0
- plothist/examples/1d_hist/1d_comparison_ratio.py +37 -0
- plothist/examples/1d_hist/1d_comparison_relative_difference.py +37 -0
- plothist/examples/1d_hist/1d_comparison_split_ratio.py +37 -0
- plothist/examples/1d_hist/1d_elt1.py +38 -0
- plothist/examples/1d_hist/1d_elt1_stacked.py +45 -0
- plothist/examples/1d_hist/1d_elt2.py +33 -0
- plothist/examples/1d_hist/1d_hist_simple.py +28 -0
- plothist/examples/1d_hist/1d_int_category.py +41 -0
- plothist/examples/1d_hist/1d_profile.py +33 -0
- plothist/examples/1d_hist/1d_side_by_side.py +58 -0
- plothist/examples/1d_hist/1d_str_category.py +41 -0
- plothist/examples/1d_hist/README.rst +4 -0
- plothist/examples/2d_hist/2d_hist_correlations.py +65 -0
- plothist/examples/2d_hist/2d_hist_simple.py +28 -0
- plothist/examples/2d_hist/2d_hist_simple_discrete_colormap.py +42 -0
- plothist/examples/2d_hist/2d_hist_uneven.py +28 -0
- plothist/examples/2d_hist/2d_hist_with_projections.py +36 -0
- plothist/examples/2d_hist/README.rst +4 -0
- plothist/examples/README.rst +7 -0
- plothist/examples/advanced/1d_comparison_advanced.py +87 -0
- plothist/examples/advanced/1d_side_by_side_with_numbers.py +81 -0
- plothist/examples/advanced/README.rst +4 -0
- plothist/examples/advanced/asymmetry_comparison_advanced.py +133 -0
- plothist/examples/advanced/model_examples_flatten2D.py +86 -0
- plothist/examples/func_1d/README.rst +4 -0
- plothist/examples/func_1d/fct_1d.py +27 -0
- plothist/examples/func_1d/fct_1d_stacked.py +42 -0
- plothist/examples/model_ex/README.rst +4 -0
- plothist/examples/model_ex/model_all_comparisons.py +103 -0
- plothist/examples/model_ex/model_all_comparisons_no_model_unc.py +115 -0
- plothist/examples/model_ex/model_examples_pull.py +56 -0
- plothist/examples/model_ex/model_examples_pull_no_model_unc.py +59 -0
- plothist/examples/model_ex/model_examples_stacked.py +74 -0
- plothist/examples/model_ex/model_examples_stacked_unstacked.py +60 -0
- plothist/examples/model_ex/model_examples_unstacked.py +57 -0
- plothist/examples/model_ex/model_with_stacked_and_unstacked_function_components.py +50 -0
- plothist/examples/model_ex/model_with_stacked_and_unstacked_histograms_components.py +69 -0
- plothist/examples/model_ex/ratio_data_vs_model_with_stacked_and_unstacked_function_components.py +61 -0
- plothist/examples/utility/README.rst +4 -0
- plothist/examples/utility/add_text_example.py +39 -0
- plothist/examples/utility/color_palette_hists.py +94 -0
- plothist/examples/utility/color_palette_squares.py +100 -0
- plothist/examples/utility/matplotlib_vs_plothist_style.py +63 -0
- plothist/histogramming.py +77 -48
- plothist/plothist_style.py +61 -62
- plothist/plotters.py +280 -233
- plothist/test_helpers.py +43 -0
- plothist/variable_registry.py +62 -43
- {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/METADATA +20 -12
- plothist-1.5.0.dist-info/RECORD +63 -0
- {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/licenses/LICENSE +1 -1
- plothist/dummy_data.csv +0 -100001
- plothist/get_dummy_data.py +0 -17
- plothist/scripts/__init__.py +0 -2
- plothist/scripts/install_latin_modern_fonts.py +0 -145
- plothist/scripts/make_examples.py +0 -210
- plothist-1.3.2.dist-info/RECORD +0 -18
- plothist-1.3.2.dist-info/entry_points.txt +0 -3
- {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/WHEEL +0 -0
- {plothist-1.3.2.dist-info → plothist-1.5.0.dist-info}/licenses/AUTHORS.md +0 -0
plothist/__init__.py
CHANGED
|
@@ -1,115 +1,107 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ._version import version as __version__
|
|
4
|
+
from .comparison import (
|
|
5
|
+
get_asymmetrical_uncertainties,
|
|
6
|
+
get_comparison,
|
|
7
|
+
get_difference,
|
|
8
|
+
get_pull,
|
|
9
|
+
get_ratio,
|
|
10
|
+
get_ratio_variances,
|
|
11
|
+
)
|
|
12
|
+
from .histogramming import (
|
|
13
|
+
create_axis,
|
|
14
|
+
flatten_2d_hist,
|
|
15
|
+
make_2d_hist,
|
|
16
|
+
make_hist,
|
|
17
|
+
)
|
|
18
|
+
from .plothist_style import (
|
|
19
|
+
add_luminosity,
|
|
20
|
+
add_text,
|
|
21
|
+
cubehelix_palette,
|
|
22
|
+
get_color_palette,
|
|
23
|
+
plot_reordered_legend,
|
|
24
|
+
set_fitting_ylabel_fontsize,
|
|
25
|
+
set_style,
|
|
26
|
+
)
|
|
1
27
|
from .plotters import (
|
|
2
28
|
create_comparison_figure,
|
|
3
|
-
plot_hist,
|
|
4
29
|
plot_2d_hist,
|
|
5
30
|
plot_2d_hist_with_projections,
|
|
31
|
+
plot_comparison,
|
|
32
|
+
plot_data_model_comparison,
|
|
6
33
|
plot_error_hist,
|
|
34
|
+
plot_function,
|
|
35
|
+
plot_hist,
|
|
7
36
|
plot_hist_uncertainties,
|
|
37
|
+
plot_model,
|
|
8
38
|
plot_two_hist_comparison,
|
|
9
|
-
plot_comparison,
|
|
10
39
|
savefig,
|
|
11
|
-
plot_data_model_comparison,
|
|
12
|
-
plot_model,
|
|
13
|
-
plot_function,
|
|
14
40
|
)
|
|
15
|
-
|
|
16
|
-
from .histogramming import (
|
|
17
|
-
create_axis,
|
|
18
|
-
make_hist,
|
|
19
|
-
make_2d_hist,
|
|
20
|
-
flatten_2d_hist,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
41
|
from .variable_registry import (
|
|
24
42
|
create_variable_registry,
|
|
25
43
|
get_variable_from_registry,
|
|
26
|
-
update_variable_registry,
|
|
27
44
|
remove_variable_registry_parameters,
|
|
45
|
+
update_variable_registry,
|
|
28
46
|
update_variable_registry_ranges,
|
|
29
47
|
)
|
|
30
48
|
|
|
31
|
-
from .comparison import (
|
|
32
|
-
get_asymmetrical_uncertainties,
|
|
33
|
-
get_comparison,
|
|
34
|
-
get_pull,
|
|
35
|
-
get_difference,
|
|
36
|
-
get_ratio,
|
|
37
|
-
get_ratio_variances,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
from .plothist_style import (
|
|
41
|
-
set_style,
|
|
42
|
-
cubehelix_palette,
|
|
43
|
-
get_color_palette,
|
|
44
|
-
set_fitting_ylabel_fontsize,
|
|
45
|
-
add_text,
|
|
46
|
-
add_luminosity,
|
|
47
|
-
plot_reordered_legend,
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
from .get_dummy_data import get_dummy_data
|
|
51
|
-
|
|
52
49
|
__all__ = [
|
|
53
50
|
"__version__",
|
|
51
|
+
"add_luminosity",
|
|
52
|
+
"add_text",
|
|
53
|
+
"create_axis",
|
|
54
|
+
"create_comparison_figure",
|
|
54
55
|
"create_variable_registry",
|
|
56
|
+
"cubehelix_palette",
|
|
57
|
+
"flatten_2d_hist",
|
|
58
|
+
"get_asymmetrical_uncertainties",
|
|
59
|
+
"get_color_palette",
|
|
60
|
+
"get_comparison",
|
|
61
|
+
"get_difference",
|
|
62
|
+
"get_pull",
|
|
63
|
+
"get_ratio",
|
|
64
|
+
"get_ratio_variances",
|
|
55
65
|
"get_variable_from_registry",
|
|
56
|
-
"update_variable_registry",
|
|
57
|
-
"remove_variable_registry_parameters",
|
|
58
|
-
"update_variable_registry_ranges",
|
|
59
|
-
"create_comparison_figure",
|
|
60
|
-
"create_axis",
|
|
61
|
-
"make_hist",
|
|
62
66
|
"make_2d_hist",
|
|
63
|
-
"
|
|
67
|
+
"make_hist",
|
|
64
68
|
"plot_2d_hist",
|
|
65
69
|
"plot_2d_hist_with_projections",
|
|
70
|
+
"plot_comparison",
|
|
71
|
+
"plot_data_model_comparison",
|
|
66
72
|
"plot_error_hist",
|
|
73
|
+
"plot_function",
|
|
74
|
+
"plot_hist",
|
|
67
75
|
"plot_hist_uncertainties",
|
|
76
|
+
"plot_model",
|
|
77
|
+
"plot_reordered_legend",
|
|
68
78
|
"plot_two_hist_comparison",
|
|
69
|
-
"
|
|
79
|
+
"remove_variable_registry_parameters",
|
|
70
80
|
"savefig",
|
|
71
|
-
"plot_data_model_comparison",
|
|
72
|
-
"plot_model",
|
|
73
|
-
"plot_function",
|
|
74
|
-
"add_luminosity",
|
|
75
|
-
"get_asymmetrical_uncertainties",
|
|
76
|
-
"set_style",
|
|
77
|
-
"cubehelix_palette",
|
|
78
|
-
"get_color_palette",
|
|
79
81
|
"set_fitting_ylabel_fontsize",
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"get_pull",
|
|
84
|
-
"get_difference",
|
|
85
|
-
"get_ratio",
|
|
86
|
-
"get_ratio_variances",
|
|
87
|
-
"flatten_2d_hist",
|
|
88
|
-
"plot_reordered_legend",
|
|
89
|
-
"get_dummy_data",
|
|
82
|
+
"set_style",
|
|
83
|
+
"update_variable_registry",
|
|
84
|
+
"update_variable_registry_ranges",
|
|
90
85
|
]
|
|
91
86
|
|
|
92
87
|
|
|
93
88
|
# Get style file and use it
|
|
94
|
-
import matplotlib.pyplot as plt
|
|
95
89
|
from importlib.resources import files
|
|
96
90
|
|
|
91
|
+
import matplotlib.pyplot as plt
|
|
92
|
+
|
|
97
93
|
style_file = files("plothist").joinpath("default_style.mplstyle")
|
|
98
94
|
plt.style.use(style_file)
|
|
99
95
|
|
|
100
|
-
#
|
|
101
|
-
from
|
|
102
|
-
|
|
96
|
+
# Install fonts
|
|
97
|
+
from importlib import resources
|
|
98
|
+
|
|
99
|
+
import matplotlib.font_manager as fm
|
|
103
100
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
warnings.warn(
|
|
109
|
-
"The recommended fonts to use plothist were not found. You can install them by typing 'install_latin_modern_fonts' in your terminal. If it still does not work, please check the documentation at https://plothist.readthedocs.io/en/latest/usage/font_installation.html",
|
|
110
|
-
stacklevel=3,
|
|
111
|
-
)
|
|
112
|
-
break
|
|
101
|
+
with resources.as_file(resources.files("plothist_utils") / "fonts") as font_path:
|
|
102
|
+
font_files = fm.findSystemFonts(fontpaths=[str(font_path)])
|
|
103
|
+
for font in font_files:
|
|
104
|
+
fm.fontManager.addfont(font)
|
|
113
105
|
|
|
114
106
|
# Check version of boost_histogram
|
|
115
107
|
import boost_histogram as bh
|
plothist/_version.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
6
|
+
TYPE_CHECKING = False
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
11
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
12
|
+
else:
|
|
13
|
+
VERSION_TUPLE = object
|
|
14
|
+
|
|
15
|
+
version: str
|
|
16
|
+
__version__: str
|
|
17
|
+
__version_tuple__: VERSION_TUPLE
|
|
18
|
+
version_tuple: VERSION_TUPLE
|
|
19
|
+
|
|
20
|
+
__version__ = version = '1.5.0'
|
|
21
|
+
__version_tuple__ = version_tuple = (1, 5, 0)
|
plothist/_version.pyi
ADDED
plothist/comparison.py
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import boost_histogram as bh
|
|
1
4
|
import numpy as np
|
|
2
|
-
|
|
5
|
+
from scipy import stats
|
|
6
|
+
|
|
3
7
|
from plothist.histogramming import _check_counting_histogram
|
|
4
8
|
|
|
5
9
|
|
|
6
|
-
def _check_uncertainty_type(uncertainty_type):
|
|
10
|
+
def _check_uncertainty_type(uncertainty_type: str) -> None:
|
|
7
11
|
"""
|
|
8
12
|
Check that the uncertainty type is valid.
|
|
9
13
|
|
|
@@ -24,13 +28,13 @@ def _check_uncertainty_type(uncertainty_type):
|
|
|
24
28
|
)
|
|
25
29
|
|
|
26
30
|
|
|
27
|
-
def _is_unweighted(hist):
|
|
31
|
+
def _is_unweighted(hist: bh.Histogram) -> bool:
|
|
28
32
|
"""
|
|
29
33
|
Check whether a histogram is unweighted.
|
|
30
34
|
|
|
31
35
|
Parameters
|
|
32
36
|
----------
|
|
33
|
-
hist :
|
|
37
|
+
hist : bh.Histogram
|
|
34
38
|
The histogram to check.
|
|
35
39
|
|
|
36
40
|
Returns
|
|
@@ -41,7 +45,9 @@ def _is_unweighted(hist):
|
|
|
41
45
|
return np.allclose(hist.variances(), hist.values())
|
|
42
46
|
|
|
43
47
|
|
|
44
|
-
def get_asymmetrical_uncertainties(
|
|
48
|
+
def get_asymmetrical_uncertainties(
|
|
49
|
+
hist: bh.Histogram,
|
|
50
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
45
51
|
"""
|
|
46
52
|
Get Poisson asymmetrical uncertainties for a histogram via a frequentist approach based on a confidence-interval computation.
|
|
47
53
|
Asymmetrical uncertainties can only be computed for an unweighted histogram, because the bin contents of a weighted histogram do not follow a Poisson distribution.
|
|
@@ -49,14 +55,14 @@ def get_asymmetrical_uncertainties(hist):
|
|
|
49
55
|
|
|
50
56
|
Parameters
|
|
51
57
|
----------
|
|
52
|
-
hist :
|
|
58
|
+
hist : bh.Histogram
|
|
53
59
|
The histogram.
|
|
54
60
|
|
|
55
61
|
Returns
|
|
56
62
|
-------
|
|
57
|
-
uncertainties_low :
|
|
63
|
+
uncertainties_low : np.ndarray
|
|
58
64
|
The lower uncertainties.
|
|
59
|
-
uncertainties_high :
|
|
65
|
+
uncertainties_high : np.ndarray
|
|
60
66
|
The upper uncertainties.
|
|
61
67
|
|
|
62
68
|
Raise
|
|
@@ -80,13 +86,13 @@ def get_asymmetrical_uncertainties(hist):
|
|
|
80
86
|
return uncertainties_low, uncertainties_high
|
|
81
87
|
|
|
82
88
|
|
|
83
|
-
def _check_binning_consistency(hist_list):
|
|
89
|
+
def _check_binning_consistency(hist_list: list[bh.Histogram]) -> None:
|
|
84
90
|
"""
|
|
85
91
|
Check that all the histograms in the provided list share the same definition of their bins.
|
|
86
92
|
|
|
87
93
|
Parameters
|
|
88
94
|
----------
|
|
89
|
-
hist_list : list
|
|
95
|
+
hist_list : list[bh.Histogram]
|
|
90
96
|
The list of histograms to check.
|
|
91
97
|
|
|
92
98
|
Raise
|
|
@@ -103,15 +109,15 @@ def _check_binning_consistency(hist_list):
|
|
|
103
109
|
raise ValueError("The bins of the histograms must be equal.")
|
|
104
110
|
|
|
105
111
|
|
|
106
|
-
def get_ratio_variances(h1, h2):
|
|
112
|
+
def get_ratio_variances(h1: bh.Histogram, h2: bh.Histogram) -> np.ndarray:
|
|
107
113
|
"""
|
|
108
114
|
Calculate the variances of the ratio of two uncorrelated histograms (h1/h2).
|
|
109
115
|
|
|
110
116
|
Parameters
|
|
111
117
|
----------
|
|
112
|
-
h1 :
|
|
118
|
+
h1 : bh.Histogram
|
|
113
119
|
The first histogram.
|
|
114
|
-
h2 :
|
|
120
|
+
h2 : bh.Histogram
|
|
115
121
|
The second histogram.
|
|
116
122
|
|
|
117
123
|
Returns
|
|
@@ -128,38 +134,39 @@ def get_ratio_variances(h1, h2):
|
|
|
128
134
|
_check_counting_histogram(h1)
|
|
129
135
|
_check_counting_histogram(h2)
|
|
130
136
|
|
|
131
|
-
np.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
np.seterr(divide="warn", invalid="warn")
|
|
139
|
-
|
|
140
|
-
return ratio_variances
|
|
137
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
138
|
+
return np.where(
|
|
139
|
+
h2.values() != 0,
|
|
140
|
+
h1.variances() / h2.values() ** 2
|
|
141
|
+
+ h2.variances() * h1.values() ** 2 / h2.values() ** 4,
|
|
142
|
+
np.nan,
|
|
143
|
+
)
|
|
141
144
|
|
|
142
145
|
|
|
143
|
-
def get_pull(
|
|
146
|
+
def get_pull(
|
|
147
|
+
h1: bh.Histogram,
|
|
148
|
+
h2: bh.Histogram,
|
|
149
|
+
h1_uncertainty_type: str = "symmetrical",
|
|
150
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
144
151
|
"""
|
|
145
152
|
Compute the pull between two histograms.
|
|
146
153
|
|
|
147
154
|
Parameters
|
|
148
155
|
----------
|
|
149
|
-
h1 :
|
|
156
|
+
h1 : bh.Histogram
|
|
150
157
|
The first histogram.
|
|
151
|
-
h2 :
|
|
158
|
+
h2 : bh.Histogram
|
|
152
159
|
The second histogram.
|
|
153
160
|
h1_uncertainty_type : str, optional
|
|
154
161
|
What kind of bin uncertainty to use for h1: "symmetrical" for the Poisson standard deviation derived from the variance stored in the histogram object, "asymmetrical" for asymmetrical uncertainties based on a Poisson confidence interval. Default is "symmetrical".
|
|
155
162
|
|
|
156
163
|
Returns
|
|
157
164
|
-------
|
|
158
|
-
pull_values :
|
|
165
|
+
pull_values : np.ndarray
|
|
159
166
|
The pull values.
|
|
160
|
-
pull_uncertainties_low :
|
|
167
|
+
pull_uncertainties_low : np.ndarray
|
|
161
168
|
The lower uncertainties on the pull. Always ones.
|
|
162
|
-
pull_uncertainties_high :
|
|
169
|
+
pull_uncertainties_high : np.ndarray
|
|
163
170
|
The upper uncertainties on the pull. Always ones.
|
|
164
171
|
"""
|
|
165
172
|
_check_uncertainty_type(h1_uncertainty_type)
|
|
@@ -192,26 +199,30 @@ def get_pull(h1, h2, h1_uncertainty_type="symmetrical"):
|
|
|
192
199
|
)
|
|
193
200
|
|
|
194
201
|
|
|
195
|
-
def get_difference(
|
|
202
|
+
def get_difference(
|
|
203
|
+
h1: bh.Histogram,
|
|
204
|
+
h2: bh.Histogram,
|
|
205
|
+
h1_uncertainty_type: str = "symmetrical",
|
|
206
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
196
207
|
"""
|
|
197
208
|
Compute the difference between two histograms.
|
|
198
209
|
|
|
199
210
|
Parameters
|
|
200
211
|
----------
|
|
201
|
-
h1 :
|
|
212
|
+
h1 : bh.Histogram
|
|
202
213
|
The first histogram.
|
|
203
|
-
h2 :
|
|
214
|
+
h2 : bh.Histogram
|
|
204
215
|
The second histogram.
|
|
205
216
|
h1_uncertainty_type : str, optional
|
|
206
217
|
What kind of bin uncertainty to use for h1: "symmetrical" for the Poisson standard deviation derived from the variance stored in the histogram object, "asymmetrical" for asymmetrical uncertainties based on a Poisson confidence interval. Default is "symmetrical".
|
|
207
218
|
|
|
208
219
|
Returns
|
|
209
220
|
-------
|
|
210
|
-
difference_values :
|
|
221
|
+
difference_values : np.ndarray
|
|
211
222
|
The difference values.
|
|
212
|
-
difference_uncertainties_low :
|
|
223
|
+
difference_uncertainties_low : np.ndarray
|
|
213
224
|
The lower uncertainties on the difference.
|
|
214
|
-
difference_uncertainties_high :
|
|
225
|
+
difference_uncertainties_high : np.ndarray
|
|
215
226
|
The upper uncertainties on the difference.
|
|
216
227
|
"""
|
|
217
228
|
_check_uncertainty_type(h1_uncertainty_type)
|
|
@@ -237,7 +248,7 @@ def get_difference(h1, h2, h1_uncertainty_type="symmetrical"):
|
|
|
237
248
|
)
|
|
238
249
|
|
|
239
250
|
|
|
240
|
-
def
|
|
251
|
+
def get_efficiency(h1: bh.Histogram, h2: bh.Histogram) -> tuple[np.ndarray, np.ndarray]:
|
|
241
252
|
"""
|
|
242
253
|
Calculate the ratio of two correlated histograms (h1/h2), in which the entries of h1 are a subsample of the entries of h2.
|
|
243
254
|
The variances are calculated according to the formula given in :ref:`documentation-statistics-label`.
|
|
@@ -250,16 +261,16 @@ def get_efficency(h1, h2):
|
|
|
250
261
|
|
|
251
262
|
Parameters
|
|
252
263
|
----------
|
|
253
|
-
h1 :
|
|
264
|
+
h1 : bh.Histogram
|
|
254
265
|
The first histogram.
|
|
255
|
-
h2 :
|
|
266
|
+
h2 : bh.Histogram
|
|
256
267
|
The second histogram.
|
|
257
268
|
|
|
258
269
|
Returns
|
|
259
270
|
-------
|
|
260
|
-
efficiency_values :
|
|
271
|
+
efficiency_values : np.ndarray
|
|
261
272
|
The efficiency values.
|
|
262
|
-
efficiency_uncertainties :
|
|
273
|
+
efficiency_uncertainties : np.ndarray
|
|
263
274
|
The uncertainties on the efficiency values.
|
|
264
275
|
|
|
265
276
|
Raises
|
|
@@ -300,23 +311,23 @@ def get_efficency(h1, h2):
|
|
|
300
311
|
return efficiency_values, np.sqrt(efficiency_variances)
|
|
301
312
|
|
|
302
313
|
|
|
303
|
-
def get_asymmetry(h1, h2):
|
|
314
|
+
def get_asymmetry(h1: bh.Histogram, h2: bh.Histogram) -> tuple[np.ndarray, np.ndarray]:
|
|
304
315
|
"""
|
|
305
316
|
Get the asymmetry between two histograms h1 and h2, defined as (h1 - h2) / (h1 + h2).
|
|
306
317
|
Only symmetrical uncertainties are supported.
|
|
307
318
|
|
|
308
319
|
Parameters
|
|
309
320
|
----------
|
|
310
|
-
h1 :
|
|
321
|
+
h1 : bh.Histogram
|
|
311
322
|
The first histogram.
|
|
312
|
-
h2 :
|
|
323
|
+
h2 : bh.Histogram
|
|
313
324
|
The second histogram.
|
|
314
325
|
|
|
315
326
|
Returns
|
|
316
327
|
-------
|
|
317
|
-
asymmetry_values :
|
|
328
|
+
asymmetry_values : np.ndarray
|
|
318
329
|
The asymmetry values.
|
|
319
|
-
asymmetry_uncertainties :
|
|
330
|
+
asymmetry_uncertainties : np.ndarray
|
|
320
331
|
The uncertainties on the asymmetry.
|
|
321
332
|
"""
|
|
322
333
|
_check_binning_consistency([h1, h2])
|
|
@@ -336,19 +347,19 @@ def get_asymmetry(h1, h2):
|
|
|
336
347
|
|
|
337
348
|
|
|
338
349
|
def get_ratio(
|
|
339
|
-
h1,
|
|
340
|
-
h2,
|
|
341
|
-
h1_uncertainty_type="symmetrical",
|
|
342
|
-
ratio_uncertainty_type="uncorrelated",
|
|
343
|
-
):
|
|
350
|
+
h1: bh.Histogram,
|
|
351
|
+
h2: bh.Histogram,
|
|
352
|
+
h1_uncertainty_type: str = "symmetrical",
|
|
353
|
+
ratio_uncertainty_type: str = "uncorrelated",
|
|
354
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
344
355
|
"""
|
|
345
356
|
Compute the ratio h1/h2 between two uncorrelated histograms h1 and h2.
|
|
346
357
|
|
|
347
358
|
Parameters
|
|
348
359
|
----------
|
|
349
|
-
h1 :
|
|
360
|
+
h1 : bh.Histogram
|
|
350
361
|
The numerator histogram.
|
|
351
|
-
h2 :
|
|
362
|
+
h2 : bh.Histogram
|
|
352
363
|
The denominator histogram.
|
|
353
364
|
h1_uncertainty_type : str, optional
|
|
354
365
|
What kind of bin uncertainty to use for h1: "symmetrical" for the Poisson standard deviation derived from the variance stored in the histogram object, "asymmetrical" for asymmetrical uncertainties based on a Poisson confidence interval. Default is "symmetrical".
|
|
@@ -360,11 +371,11 @@ def get_ratio(
|
|
|
360
371
|
|
|
361
372
|
Returns
|
|
362
373
|
-------
|
|
363
|
-
ratio_values :
|
|
374
|
+
ratio_values : np.ndarray
|
|
364
375
|
The ratio values.
|
|
365
|
-
ratio_uncertainties_low :
|
|
376
|
+
ratio_uncertainties_low : np.ndarray
|
|
366
377
|
The lower uncertainties on the ratio.
|
|
367
|
-
ratio_uncertainties_high :
|
|
378
|
+
ratio_uncertainties_high : np.ndarray
|
|
368
379
|
The upper uncertainties on the ratio.
|
|
369
380
|
|
|
370
381
|
Raises
|
|
@@ -416,19 +427,19 @@ def get_ratio(
|
|
|
416
427
|
|
|
417
428
|
|
|
418
429
|
def get_comparison(
|
|
419
|
-
h1,
|
|
420
|
-
h2,
|
|
421
|
-
comparison,
|
|
422
|
-
h1_uncertainty_type="symmetrical",
|
|
423
|
-
):
|
|
430
|
+
h1: bh.Histogram,
|
|
431
|
+
h2: bh.Histogram,
|
|
432
|
+
comparison: str,
|
|
433
|
+
h1_uncertainty_type: str = "symmetrical",
|
|
434
|
+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
|
|
424
435
|
"""
|
|
425
436
|
Compute the comparison between two histograms.
|
|
426
437
|
|
|
427
438
|
Parameters
|
|
428
439
|
----------
|
|
429
|
-
h1 :
|
|
440
|
+
h1 : bh.Histogram
|
|
430
441
|
The first histogram for comparison.
|
|
431
|
-
h2 :
|
|
442
|
+
h2 : bh.Histogram
|
|
432
443
|
The second histogram for comparison.
|
|
433
444
|
comparison : str
|
|
434
445
|
The type of comparison ("ratio", "split_ratio", "pull", "difference", "relative_difference", "efficiency", or "asymmetry").
|
|
@@ -440,11 +451,11 @@ def get_comparison(
|
|
|
440
451
|
|
|
441
452
|
Returns
|
|
442
453
|
-------
|
|
443
|
-
values :
|
|
454
|
+
values : np.ndarray
|
|
444
455
|
The comparison values.
|
|
445
|
-
lower_uncertainties :
|
|
456
|
+
lower_uncertainties : np.ndarray
|
|
446
457
|
The lower uncertainties on the comparison values.
|
|
447
|
-
upper_uncertainties :
|
|
458
|
+
upper_uncertainties : np.ndarray
|
|
448
459
|
The upper uncertainties on the comparison values.
|
|
449
460
|
|
|
450
461
|
Raises
|
|
@@ -459,49 +470,47 @@ def get_comparison(
|
|
|
459
470
|
_check_counting_histogram(h1)
|
|
460
471
|
_check_counting_histogram(h2)
|
|
461
472
|
|
|
462
|
-
np.
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
h1, h2, h1_uncertainty_type, "uncorrelated"
|
|
467
|
-
)
|
|
468
|
-
elif comparison == "split_ratio":
|
|
469
|
-
values, lower_uncertainties, upper_uncertainties = get_ratio(
|
|
470
|
-
h1, h2, h1_uncertainty_type, "split"
|
|
471
|
-
)
|
|
472
|
-
elif comparison == "relative_difference":
|
|
473
|
-
values, lower_uncertainties, upper_uncertainties = get_ratio(
|
|
474
|
-
h1, h2, h1_uncertainty_type, "uncorrelated"
|
|
475
|
-
)
|
|
476
|
-
values -= 1 # relative difference is ratio-1
|
|
477
|
-
elif comparison == "pull":
|
|
478
|
-
values, lower_uncertainties, upper_uncertainties = get_pull(
|
|
479
|
-
h1, h2, h1_uncertainty_type
|
|
480
|
-
)
|
|
481
|
-
elif comparison == "difference":
|
|
482
|
-
values, lower_uncertainties, upper_uncertainties = get_difference(
|
|
483
|
-
h1, h2, h1_uncertainty_type
|
|
484
|
-
)
|
|
485
|
-
elif comparison == "asymmetry":
|
|
486
|
-
if h1_uncertainty_type == "asymmetrical":
|
|
487
|
-
raise ValueError(
|
|
488
|
-
"Asymmetrical uncertainties are not supported for the asymmetry comparison."
|
|
473
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
474
|
+
if comparison == "ratio":
|
|
475
|
+
values, lower_uncertainties, upper_uncertainties = get_ratio(
|
|
476
|
+
h1, h2, h1_uncertainty_type, "uncorrelated"
|
|
489
477
|
)
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
478
|
+
elif comparison == "split_ratio":
|
|
479
|
+
values, lower_uncertainties, upper_uncertainties = get_ratio(
|
|
480
|
+
h1, h2, h1_uncertainty_type, "split"
|
|
481
|
+
)
|
|
482
|
+
elif comparison == "relative_difference":
|
|
483
|
+
values, lower_uncertainties, upper_uncertainties = get_ratio(
|
|
484
|
+
h1, h2, h1_uncertainty_type, "uncorrelated"
|
|
485
|
+
)
|
|
486
|
+
values -= 1 # relative difference is ratio-1
|
|
487
|
+
elif comparison == "pull":
|
|
488
|
+
values, lower_uncertainties, upper_uncertainties = get_pull(
|
|
489
|
+
h1, h2, h1_uncertainty_type
|
|
490
|
+
)
|
|
491
|
+
elif comparison == "difference":
|
|
492
|
+
values, lower_uncertainties, upper_uncertainties = get_difference(
|
|
493
|
+
h1, h2, h1_uncertainty_type
|
|
494
|
+
)
|
|
495
|
+
elif comparison == "asymmetry":
|
|
496
|
+
if h1_uncertainty_type == "asymmetrical":
|
|
497
|
+
raise ValueError(
|
|
498
|
+
"Asymmetrical uncertainties are not supported for the asymmetry comparison."
|
|
499
|
+
)
|
|
500
|
+
values, uncertainties = get_asymmetry(h1, h2)
|
|
501
|
+
lower_uncertainties = uncertainties
|
|
502
|
+
upper_uncertainties = uncertainties
|
|
503
|
+
elif comparison == "efficiency":
|
|
504
|
+
if h1_uncertainty_type == "asymmetrical":
|
|
505
|
+
raise ValueError(
|
|
506
|
+
"Asymmetrical uncertainties are not supported in an efficiency computation."
|
|
507
|
+
)
|
|
508
|
+
values, uncertainties = get_efficiency(h1, h2)
|
|
509
|
+
lower_uncertainties = uncertainties
|
|
510
|
+
upper_uncertainties = uncertainties
|
|
511
|
+
else:
|
|
495
512
|
raise ValueError(
|
|
496
|
-
"
|
|
513
|
+
f"{comparison} not available as a comparison ('ratio', 'split_ratio', 'pull', 'difference', 'relative_difference', 'asymmetry' or 'efficiency')."
|
|
497
514
|
)
|
|
498
|
-
values, uncertainties = get_efficency(h1, h2)
|
|
499
|
-
lower_uncertainties = uncertainties
|
|
500
|
-
upper_uncertainties = uncertainties
|
|
501
|
-
else:
|
|
502
|
-
raise ValueError(
|
|
503
|
-
f"{comparison} not available as a comparison ('ratio', 'split_ratio', 'pull', 'difference', 'relative_difference', 'asymmetry' or 'efficiency')."
|
|
504
|
-
)
|
|
505
|
-
np.seterr(divide="warn", invalid="warn")
|
|
506
515
|
|
|
507
516
|
return values, lower_uncertainties, upper_uncertainties
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Asymmetry
|
|
3
|
+
=========
|
|
4
|
+
|
|
5
|
+
Compare two 1D histograms using the asymmetry comparison [(h1-h2)/(h1+h2)].
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from plothist_utils import get_dummy_data
|
|
9
|
+
|
|
10
|
+
df = get_dummy_data()
|
|
11
|
+
|
|
12
|
+
name = "variable_1"
|
|
13
|
+
|
|
14
|
+
x1 = df[name][df["category"] == 2]
|
|
15
|
+
x2 = df[name][df["category"] == 3]
|
|
16
|
+
|
|
17
|
+
x_range = (min(*x1, *x2), max(*x1, *x2))
|
|
18
|
+
|
|
19
|
+
from plothist import make_hist
|
|
20
|
+
|
|
21
|
+
h1 = make_hist(x1, bins=50, range=x_range)
|
|
22
|
+
h2 = make_hist(x2, bins=50, range=x_range)
|
|
23
|
+
|
|
24
|
+
###
|
|
25
|
+
from plothist import plot_two_hist_comparison
|
|
26
|
+
|
|
27
|
+
fig, ax_main, ax_comparison = plot_two_hist_comparison(
|
|
28
|
+
h1,
|
|
29
|
+
h2,
|
|
30
|
+
xlabel=name,
|
|
31
|
+
ylabel="Entries",
|
|
32
|
+
h1_label=r"$\mathbfit{h}_1$",
|
|
33
|
+
h2_label=r"$\mathbfit{h}_2$",
|
|
34
|
+
comparison="asymmetry", # <--
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
fig.savefig("1d_comparison_asymmetry.svg", bbox_inches="tight")
|