jelli 0.0.1__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.
- jelli/__init__.py +5 -0
- jelli/_version.py +1 -0
- jelli/core/__init__.py +0 -0
- jelli/core/custom_basis.py +177 -0
- jelli/core/experimental_correlations.py +100 -0
- jelli/core/global_likelihood.py +923 -0
- jelli/core/global_likelihood_point.py +34 -0
- jelli/core/measurement.py +489 -0
- jelli/core/observable_sector.py +1063 -0
- jelli/core/theory_correlations.py +93 -0
- jelli/utils/__init__.py +0 -0
- jelli/utils/data_io.py +53 -0
- jelli/utils/distributions.py +197 -0
- jelli/utils/jax_helpers.py +17 -0
- jelli/utils/par_helpers.py +103 -0
- jelli/utils/probability.py +439 -0
- jelli-0.0.1.dist-info/METADATA +20 -0
- jelli-0.0.1.dist-info/RECORD +21 -0
- jelli-0.0.1.dist-info/WHEEL +5 -0
- jelli-0.0.1.dist-info/licenses/LICENSE +21 -0
- jelli-0.0.1.dist-info/top_level.txt +1 -0
jelli/__init__.py
ADDED
jelli/_version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.0.1'
|
jelli/core/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
from typing import List, Dict, Union
|
|
2
|
+
|
|
3
|
+
class CustomBasis:
|
|
4
|
+
'''
|
|
5
|
+
A class to represent a custom parameter basis.
|
|
6
|
+
|
|
7
|
+
Parameters
|
|
8
|
+
----------
|
|
9
|
+
name : str
|
|
10
|
+
The name of the custom basis.
|
|
11
|
+
parameters : list or dict
|
|
12
|
+
The parameters in the custom basis. If a list is provided, all parameters are assumed to be real. If a dict is provided, the keys are the parameter names and the values are the types (e.g., 'R' for real, 'C' for complex).
|
|
13
|
+
|
|
14
|
+
Attributes
|
|
15
|
+
----------
|
|
16
|
+
name : str
|
|
17
|
+
The name of the custom basis.
|
|
18
|
+
parameters : dict
|
|
19
|
+
The parameters in the custom basis. The keys are the parameter names and the values are the types (e.g., 'R' for real, 'C' for complex).
|
|
20
|
+
|
|
21
|
+
Methods
|
|
22
|
+
-------
|
|
23
|
+
get_all_names() -> List[str]
|
|
24
|
+
Get all custom basis names.
|
|
25
|
+
get(name: str) -> 'CustomBasis'
|
|
26
|
+
Get a custom basis by name.
|
|
27
|
+
get_all() -> List['CustomBasis']
|
|
28
|
+
Get all custom basis objects.
|
|
29
|
+
get_parameter_basis() -> List
|
|
30
|
+
Get the parameter basis.
|
|
31
|
+
|
|
32
|
+
Examples
|
|
33
|
+
--------
|
|
34
|
+
Initialize a custom basis with real parameters:
|
|
35
|
+
|
|
36
|
+
>>> custom_basis = CustomBasis('example_basis', ['param1', 'param2'])
|
|
37
|
+
|
|
38
|
+
Initialize a custom basis with mixed parameters:
|
|
39
|
+
|
|
40
|
+
>>> custom_basis = CustomBasis('example_basis', {'param1': 'R', 'param2': 'C'})
|
|
41
|
+
|
|
42
|
+
Get all custom basis names:
|
|
43
|
+
|
|
44
|
+
>>> CustomBasis.get_all_names()
|
|
45
|
+
|
|
46
|
+
Get a custom basis by name:
|
|
47
|
+
|
|
48
|
+
>>> custom_basis = CustomBasis.get('example_basis')
|
|
49
|
+
|
|
50
|
+
Get all custom basis objects:
|
|
51
|
+
|
|
52
|
+
>>> custom_bases = CustomBasis.get_all()
|
|
53
|
+
|
|
54
|
+
Get the parameter basis:
|
|
55
|
+
|
|
56
|
+
>>> parameter_basis = custom_basis.get_parameter_basis()
|
|
57
|
+
|
|
58
|
+
'''
|
|
59
|
+
|
|
60
|
+
_custom_bases: Dict[str, 'CustomBasis'] = {} # Class attribute to store all custom bases
|
|
61
|
+
|
|
62
|
+
def __init__(self, name: str, parameters: Union[List[str], Dict[str, str]]):
|
|
63
|
+
"""
|
|
64
|
+
Initialize the CustomBasis class.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
name : str
|
|
69
|
+
The name of the custom basis.
|
|
70
|
+
parameters : list or dict
|
|
71
|
+
The parameters in the custom basis. If a list is provided, all parameters are assumed to be real. If a dict is provided, the keys are the parameter names and the values are the types (e.g., 'R' for real, 'C' for complex).
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
--------
|
|
75
|
+
None
|
|
76
|
+
|
|
77
|
+
Examples
|
|
78
|
+
--------
|
|
79
|
+
Initialize a custom basis with real parameters:
|
|
80
|
+
|
|
81
|
+
>>> custom_basis = CustomBasis('example_basis', ['param1', 'param2'])
|
|
82
|
+
|
|
83
|
+
Initialize a custom basis with mixed parameters:
|
|
84
|
+
|
|
85
|
+
>>> custom_basis = CustomBasis('example_basis', {'param1': 'R', 'param2': 'C'})
|
|
86
|
+
"""
|
|
87
|
+
self.name = name
|
|
88
|
+
if isinstance(parameters, list):
|
|
89
|
+
self.parameters = {param: 'R' for param in parameters}
|
|
90
|
+
elif isinstance(parameters, dict):
|
|
91
|
+
if not all(value in ['R', 'C'] for value in parameters.values()):
|
|
92
|
+
raise ValueError("All parameter types must be either 'R' or 'C'.")
|
|
93
|
+
self.parameters = parameters
|
|
94
|
+
else:
|
|
95
|
+
raise ValueError("Parameters must be a list or a dictionary.")
|
|
96
|
+
self._custom_bases[self.name] = self
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def get_all_names(cls) -> List[str]:
|
|
100
|
+
"""
|
|
101
|
+
Get all custom basis names.
|
|
102
|
+
|
|
103
|
+
Returns
|
|
104
|
+
--------
|
|
105
|
+
list
|
|
106
|
+
A list of all custom basis names.
|
|
107
|
+
|
|
108
|
+
Examples
|
|
109
|
+
--------
|
|
110
|
+
>>> CustomBasis.get_all_names()
|
|
111
|
+
"""
|
|
112
|
+
return sorted(cls._custom_bases.keys())
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def get(cls, name: str) -> 'CustomBasis':
|
|
116
|
+
"""
|
|
117
|
+
Get a custom basis by name.
|
|
118
|
+
|
|
119
|
+
Parameters
|
|
120
|
+
----------
|
|
121
|
+
name : str
|
|
122
|
+
The name of the custom basis.
|
|
123
|
+
Returns
|
|
124
|
+
--------
|
|
125
|
+
CustomBasis
|
|
126
|
+
The custom basis object.
|
|
127
|
+
|
|
128
|
+
Examples
|
|
129
|
+
--------
|
|
130
|
+
>>> CustomBasis.get('example_basis')
|
|
131
|
+
"""
|
|
132
|
+
return cls._custom_bases.get(name)
|
|
133
|
+
|
|
134
|
+
@classmethod
|
|
135
|
+
def get_all(cls) -> List['CustomBasis']:
|
|
136
|
+
"""
|
|
137
|
+
Get all custom basis objects.
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
--------
|
|
141
|
+
list
|
|
142
|
+
A list of all custom basis objects.
|
|
143
|
+
|
|
144
|
+
Examples
|
|
145
|
+
--------
|
|
146
|
+
>>> CustomBasis.get_all()
|
|
147
|
+
"""
|
|
148
|
+
return list(cls._custom_bases.values())
|
|
149
|
+
|
|
150
|
+
def get_parameter_basis(self, split_re_im=True) -> List:
|
|
151
|
+
"""
|
|
152
|
+
Get the parameter basis.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
split_re_im : bool, optional
|
|
157
|
+
If True, split parameters into real and imaginary parts, otherwise return the parameters directly. Default is True.
|
|
158
|
+
|
|
159
|
+
Returns
|
|
160
|
+
--------
|
|
161
|
+
list
|
|
162
|
+
A list containing the parameter basis.
|
|
163
|
+
|
|
164
|
+
Examples
|
|
165
|
+
--------
|
|
166
|
+
>>> custom_basis = CustomBasis('example_basis', ['param1', 'param2'])
|
|
167
|
+
>>> custom_basis.get_parameter_basis('example_basis')
|
|
168
|
+
"""
|
|
169
|
+
if split_re_im:
|
|
170
|
+
parameter_basis = []
|
|
171
|
+
for parameter, parameter_type in self.parameters.items():
|
|
172
|
+
parameter_basis.append((parameter, 'R'))
|
|
173
|
+
if parameter_type == 'C':
|
|
174
|
+
parameter_basis.append((parameter, 'I'))
|
|
175
|
+
else:
|
|
176
|
+
parameter_basis = self.parameters.keys()
|
|
177
|
+
return sorted(parameter_basis)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from typing import Dict, Optional, Iterable
|
|
2
|
+
import h5py
|
|
3
|
+
import numpy as np
|
|
4
|
+
from jax import numpy as jnp
|
|
5
|
+
import os
|
|
6
|
+
from ..utils.data_io import get_json_schema, hash_observable_names
|
|
7
|
+
|
|
8
|
+
class ExperimentalCorrelations:
|
|
9
|
+
|
|
10
|
+
_instances: Dict[str, Dict[str, 'ExperimentalCorrelations']] = {
|
|
11
|
+
'correlations': {},
|
|
12
|
+
'central': {},
|
|
13
|
+
'uncertainties': {}
|
|
14
|
+
} # Dictionary to hold instances of ExperimentalCorrelations
|
|
15
|
+
_covariance_scaled: Dict[str, jnp.ndarray] = {}
|
|
16
|
+
_pdfxf_h5_versions = {'1.0'} # Set of supported versions of the pdfxf-h5 JSON schema
|
|
17
|
+
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
hash_val: str,
|
|
21
|
+
data_type: str,
|
|
22
|
+
data: np.ndarray,
|
|
23
|
+
row_names: Dict[str, int],
|
|
24
|
+
col_names: Dict[str, int]
|
|
25
|
+
) -> None:
|
|
26
|
+
self.hash_val = hash_val
|
|
27
|
+
self.data_type = data_type
|
|
28
|
+
self.data = data
|
|
29
|
+
self.row_names = row_names
|
|
30
|
+
self.col_names = col_names
|
|
31
|
+
self._instances[data_type][hash_val] = self
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
def _load_file(cls, path: str) -> None:
|
|
35
|
+
with h5py.File(path, 'r') as f:
|
|
36
|
+
schema_name, schema_version = get_json_schema(dict(f.attrs))
|
|
37
|
+
if schema_name == 'pdfxf-h5' and schema_version in cls._pdfxf_h5_versions:
|
|
38
|
+
for hash_val in f['correlations']:
|
|
39
|
+
cls.from_hdf5_group(hash_val, 'correlations', f['correlations'][hash_val])
|
|
40
|
+
for hash_val in f['central']:
|
|
41
|
+
cls.from_hdf5_group(hash_val, 'central', f['central'][hash_val])
|
|
42
|
+
for hash_val in f['uncertainties']:
|
|
43
|
+
cls.from_hdf5_group(hash_val, 'uncertainties', f['uncertainties'][hash_val])
|
|
44
|
+
|
|
45
|
+
@classmethod
|
|
46
|
+
def load(cls, path: str) -> None:
|
|
47
|
+
# load all hdf5 files in the directory
|
|
48
|
+
if os.path.isdir(path):
|
|
49
|
+
for file in os.listdir(path):
|
|
50
|
+
if file.endswith('.hdf5'):
|
|
51
|
+
cls._load_file(os.path.join(path, file))
|
|
52
|
+
# load single hdf5 file
|
|
53
|
+
else:
|
|
54
|
+
cls._load_file(path)
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def from_hdf5_group(cls, hash_val: str, data_type: str, hdf5_group: h5py.Group) -> None:
|
|
58
|
+
data = hdf5_group['data']
|
|
59
|
+
data = np.array(data[()], dtype=np.float64) * data.attrs.get('scale', 1.0)
|
|
60
|
+
row_names = {name: i for i, name in enumerate(hdf5_group['row_names'][()].astype(str))}
|
|
61
|
+
col_names = {name: i for i, name in enumerate(hdf5_group.get('col_names', np.array([]))[()].astype(str))}
|
|
62
|
+
cls(hash_val, data_type, data, row_names, col_names)
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def get_data(
|
|
66
|
+
cls,
|
|
67
|
+
data_type: str,
|
|
68
|
+
row_names: Iterable[str],
|
|
69
|
+
col_names: Optional[Iterable[str]] = []
|
|
70
|
+
):
|
|
71
|
+
hash_val = hash_observable_names(row_names, col_names)
|
|
72
|
+
if hash_val in cls._instances[data_type]:
|
|
73
|
+
data = cls._instances[data_type][hash_val].data
|
|
74
|
+
else:
|
|
75
|
+
hash_val = hash_observable_names(col_names, row_names)
|
|
76
|
+
if hash_val in cls._instances[data_type]:
|
|
77
|
+
data = cls._instances[data_type][hash_val].data.T
|
|
78
|
+
else:
|
|
79
|
+
data = None
|
|
80
|
+
return data
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def get_cov_scaled(
|
|
84
|
+
cls,
|
|
85
|
+
row_names: Iterable[str],
|
|
86
|
+
col_names: Iterable[str],
|
|
87
|
+
std_exp_scaled_row: np.ndarray,
|
|
88
|
+
std_exp_scaled_col: np.ndarray,
|
|
89
|
+
):
|
|
90
|
+
hash_val = hash_observable_names(row_names, col_names)
|
|
91
|
+
if hash_val in cls._covariance_scaled:
|
|
92
|
+
cov_scaled = cls._covariance_scaled[hash_val]
|
|
93
|
+
else:
|
|
94
|
+
corr = cls.get_data('correlations', row_names, col_names)
|
|
95
|
+
if corr is None:
|
|
96
|
+
raise ValueError(f"Correlation data for {row_names} and {col_names} not found.")
|
|
97
|
+
cov_scaled = corr * np.outer(std_exp_scaled_row, std_exp_scaled_col)
|
|
98
|
+
cov_scaled = jnp.array(cov_scaled, dtype=jnp.float64)
|
|
99
|
+
cls._covariance_scaled[hash_val] = cov_scaled
|
|
100
|
+
return cov_scaled
|