reflectorch 1.4.0__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.
Potentially problematic release.
This version of reflectorch might be problematic. Click here for more details.
- reflectorch/__init__.py +17 -17
- reflectorch/data_generation/__init__.py +128 -128
- reflectorch/data_generation/dataset.py +210 -210
- reflectorch/data_generation/likelihoods.py +80 -80
- reflectorch/data_generation/noise.py +470 -470
- reflectorch/data_generation/priors/__init__.py +60 -60
- reflectorch/data_generation/priors/base.py +55 -55
- reflectorch/data_generation/priors/exp_subprior_sampler.py +298 -298
- reflectorch/data_generation/priors/independent_priors.py +195 -195
- reflectorch/data_generation/priors/multilayer_models.py +311 -311
- reflectorch/data_generation/priors/multilayer_structures.py +104 -104
- reflectorch/data_generation/priors/no_constraints.py +206 -206
- reflectorch/data_generation/priors/parametric_models.py +841 -841
- reflectorch/data_generation/priors/parametric_subpriors.py +369 -369
- reflectorch/data_generation/priors/params.py +252 -252
- reflectorch/data_generation/priors/sampler_strategies.py +369 -369
- reflectorch/data_generation/priors/scaler_mixin.py +65 -65
- reflectorch/data_generation/priors/subprior_sampler.py +371 -371
- reflectorch/data_generation/priors/utils.py +118 -118
- reflectorch/data_generation/process_data.py +41 -41
- reflectorch/data_generation/q_generator.py +280 -280
- reflectorch/data_generation/reflectivity/__init__.py +102 -102
- reflectorch/data_generation/reflectivity/abeles.py +97 -97
- reflectorch/data_generation/reflectivity/kinematical.py +70 -70
- reflectorch/data_generation/reflectivity/memory_eff.py +105 -105
- reflectorch/data_generation/reflectivity/numpy_implementations.py +120 -120
- reflectorch/data_generation/reflectivity/smearing.py +138 -138
- reflectorch/data_generation/reflectivity/smearing_pointwise.py +109 -109
- reflectorch/data_generation/scale_curves.py +112 -112
- reflectorch/data_generation/smearing.py +98 -98
- reflectorch/data_generation/utils.py +223 -223
- reflectorch/extensions/jupyter/__init__.py +11 -6
- reflectorch/extensions/jupyter/api.py +85 -0
- reflectorch/extensions/jupyter/callbacks.py +34 -34
- reflectorch/extensions/jupyter/components.py +758 -0
- reflectorch/extensions/jupyter/custom_select.py +268 -0
- reflectorch/extensions/jupyter/log_widget.py +241 -0
- reflectorch/extensions/jupyter/model_selection.py +495 -0
- reflectorch/extensions/jupyter/plotly_plot_manager.py +329 -0
- reflectorch/extensions/jupyter/widget.py +625 -0
- reflectorch/extensions/matplotlib/__init__.py +5 -5
- reflectorch/extensions/matplotlib/losses.py +32 -32
- reflectorch/extensions/refnx/refnx_conversion.py +76 -76
- reflectorch/inference/__init__.py +28 -24
- reflectorch/inference/inference_model.py +847 -1374
- reflectorch/inference/input_interface.py +239 -0
- reflectorch/inference/loading_data.py +36 -36
- reflectorch/inference/multilayer_fitter.py +171 -171
- reflectorch/inference/multilayer_inference_model.py +193 -193
- reflectorch/inference/plotting.py +523 -516
- reflectorch/inference/preprocess_exp/__init__.py +6 -6
- reflectorch/inference/preprocess_exp/attenuation.py +36 -36
- reflectorch/inference/preprocess_exp/cut_with_q_ratio.py +31 -31
- reflectorch/inference/preprocess_exp/footprint.py +81 -81
- reflectorch/inference/preprocess_exp/interpolation.py +19 -19
- reflectorch/inference/preprocess_exp/normalize.py +21 -21
- reflectorch/inference/preprocess_exp/preprocess.py +121 -121
- reflectorch/inference/query_matcher.py +81 -81
- reflectorch/inference/record_time.py +43 -43
- reflectorch/inference/sampler_solution.py +56 -56
- reflectorch/inference/scipy_fitter.py +272 -262
- reflectorch/inference/torch_fitter.py +87 -87
- reflectorch/ml/__init__.py +32 -32
- reflectorch/ml/basic_trainer.py +292 -292
- reflectorch/ml/callbacks.py +80 -80
- reflectorch/ml/dataloaders.py +26 -26
- reflectorch/ml/loggers.py +55 -55
- reflectorch/ml/schedulers.py +355 -355
- reflectorch/ml/trainers.py +200 -200
- reflectorch/ml/utils.py +2 -2
- reflectorch/models/__init__.py +15 -15
- reflectorch/models/activations.py +50 -50
- reflectorch/models/encoders/__init__.py +19 -19
- reflectorch/models/encoders/conv_encoder.py +218 -218
- reflectorch/models/encoders/conv_res_net.py +115 -115
- reflectorch/models/encoders/fno.py +133 -133
- reflectorch/models/encoders/integral_kernel_embedding.py +389 -389
- reflectorch/models/networks/__init__.py +14 -14
- reflectorch/models/networks/mlp_networks.py +434 -434
- reflectorch/models/networks/residual_net.py +156 -156
- reflectorch/paths.py +29 -27
- reflectorch/runs/__init__.py +31 -31
- reflectorch/runs/config.py +25 -25
- reflectorch/runs/slurm_utils.py +93 -93
- reflectorch/runs/train.py +78 -78
- reflectorch/runs/utils.py +404 -404
- reflectorch/test_config.py +4 -4
- reflectorch/train.py +4 -4
- reflectorch/train_on_cluster.py +4 -4
- reflectorch/utils.py +97 -97
- {reflectorch-1.4.0.dist-info → reflectorch-1.5.0.dist-info}/METADATA +129 -126
- reflectorch-1.5.0.dist-info/RECORD +96 -0
- {reflectorch-1.4.0.dist-info → reflectorch-1.5.0.dist-info}/licenses/LICENSE.txt +20 -20
- reflectorch-1.4.0.dist-info/RECORD +0 -88
- {reflectorch-1.4.0.dist-info → reflectorch-1.5.0.dist-info}/WHEEL +0 -0
- {reflectorch-1.4.0.dist-info → reflectorch-1.5.0.dist-info}/top_level.txt +0 -0
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
from typing import Tuple
|
|
2
|
-
|
|
3
|
-
import torch
|
|
4
|
-
from torch import Tensor
|
|
5
|
-
|
|
6
|
-
from reflectorch.data_generation.utils import (
|
|
7
|
-
get_d_rhos,
|
|
8
|
-
uniform_sampler,
|
|
9
|
-
)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def get_max_allowed_roughness(thicknesses: Tensor, mask: Tensor = None, coef: float = 0.5):
|
|
13
|
-
"""gets the maximum allowed interlayer roughnesses such that they do not exceed a fraction of the thickness of either layers meeting at that interface"""
|
|
14
|
-
batch_size, layers_num = thicknesses.shape
|
|
15
|
-
max_roughness = torch.ones(
|
|
16
|
-
batch_size, layers_num + 1, device=thicknesses.device, dtype=thicknesses.dtype
|
|
17
|
-
) * float('inf')
|
|
18
|
-
|
|
19
|
-
boundary = thicknesses * coef
|
|
20
|
-
if mask is not None:
|
|
21
|
-
boundary[get_thickness_mask_from_sld_mask(mask)] = float('inf')
|
|
22
|
-
|
|
23
|
-
max_roughness[:, :-1] = boundary
|
|
24
|
-
max_roughness[:, 1:] = torch.minimum(max_roughness[:, 1:], boundary)
|
|
25
|
-
return max_roughness
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def get_allowed_contrast_indices(slds: Tensor, min_contrast: float, mask: Tensor = None) -> Tensor:
|
|
29
|
-
d_rhos = get_d_rhos(slds)
|
|
30
|
-
indices = d_rhos.abs() >= min_contrast
|
|
31
|
-
if mask is not None:
|
|
32
|
-
indices = indices | mask
|
|
33
|
-
indices = torch.all(indices, -1)
|
|
34
|
-
return indices
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def params_within_bounds(params_t: Tensor, min_t: Tensor, max_t: Tensor, mask: Tensor = None) -> Tensor:
|
|
38
|
-
indices = (params_t >= min_t[None]) & (params_t <= max_t[None])
|
|
39
|
-
if mask is not None:
|
|
40
|
-
indices = indices | mask
|
|
41
|
-
indices = torch.all(indices, -1)
|
|
42
|
-
return indices
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def get_allowed_roughness_indices(thicknesses: Tensor, roughnesses: Tensor, mask: Tensor = None) -> Tensor:
|
|
46
|
-
max_roughness = get_max_allowed_roughness(thicknesses, mask)
|
|
47
|
-
indices = roughnesses <= max_roughness
|
|
48
|
-
if mask is not None:
|
|
49
|
-
indices = indices | mask
|
|
50
|
-
indices = torch.all(indices, -1)
|
|
51
|
-
return indices
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def get_thickness_mask_from_sld_mask(mask: Tensor):
|
|
55
|
-
return mask[:, :-1]
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def generate_roughnesses(thicknesses: Tensor, roughness_range: Tuple[float, float], mask: Tensor = None):
|
|
59
|
-
batch_size, layers_num = thicknesses.shape
|
|
60
|
-
max_roughness = get_max_allowed_roughness(thicknesses, mask)
|
|
61
|
-
max_roughness = torch.clamp_(max_roughness, max=roughness_range[1])
|
|
62
|
-
|
|
63
|
-
roughnesses = uniform_sampler(
|
|
64
|
-
roughness_range[0], max_roughness, batch_size, layers_num + 1,
|
|
65
|
-
device=thicknesses.device, dtype=thicknesses.dtype
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
if mask is not None:
|
|
69
|
-
roughnesses[mask] = 0.
|
|
70
|
-
|
|
71
|
-
return roughnesses
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def generate_thicknesses(
|
|
75
|
-
thickness_range: Tuple[float, float],
|
|
76
|
-
batch_size: int,
|
|
77
|
-
layers_num: int,
|
|
78
|
-
device: torch.device,
|
|
79
|
-
dtype: torch.dtype,
|
|
80
|
-
mask: Tensor = None
|
|
81
|
-
):
|
|
82
|
-
thicknesses = uniform_sampler(
|
|
83
|
-
*thickness_range, batch_size, layers_num, device=device, dtype=dtype
|
|
84
|
-
)
|
|
85
|
-
if mask is not None:
|
|
86
|
-
thicknesses[get_thickness_mask_from_sld_mask(mask)] = 0.
|
|
87
|
-
return thicknesses
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def generate_slds_with_min_contrast(
|
|
91
|
-
sld_range: Tuple[float, float],
|
|
92
|
-
batch_size: int,
|
|
93
|
-
layers_num: int,
|
|
94
|
-
min_contrast: float,
|
|
95
|
-
device: torch.device,
|
|
96
|
-
dtype: torch.dtype,
|
|
97
|
-
mask: Tensor = None,
|
|
98
|
-
*,
|
|
99
|
-
_depth: int = 0
|
|
100
|
-
):
|
|
101
|
-
# rejection sampling
|
|
102
|
-
slds = uniform_sampler(
|
|
103
|
-
*sld_range, batch_size, layers_num + 1, device=device, dtype=dtype
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
if mask is not None:
|
|
107
|
-
slds[mask] = 0.
|
|
108
|
-
|
|
109
|
-
rejected_indices = ~get_allowed_contrast_indices(slds, min_contrast, mask)
|
|
110
|
-
rejected_num = rejected_indices.sum(0).item()
|
|
111
|
-
|
|
112
|
-
if rejected_num:
|
|
113
|
-
if mask is not None:
|
|
114
|
-
mask = mask[rejected_indices]
|
|
115
|
-
slds[rejected_indices] = generate_slds_with_min_contrast(
|
|
116
|
-
sld_range, rejected_num, layers_num, min_contrast, device, dtype, mask, _depth=_depth+1
|
|
117
|
-
)
|
|
118
|
-
return slds
|
|
1
|
+
from typing import Tuple
|
|
2
|
+
|
|
3
|
+
import torch
|
|
4
|
+
from torch import Tensor
|
|
5
|
+
|
|
6
|
+
from reflectorch.data_generation.utils import (
|
|
7
|
+
get_d_rhos,
|
|
8
|
+
uniform_sampler,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_max_allowed_roughness(thicknesses: Tensor, mask: Tensor = None, coef: float = 0.5):
|
|
13
|
+
"""gets the maximum allowed interlayer roughnesses such that they do not exceed a fraction of the thickness of either layers meeting at that interface"""
|
|
14
|
+
batch_size, layers_num = thicknesses.shape
|
|
15
|
+
max_roughness = torch.ones(
|
|
16
|
+
batch_size, layers_num + 1, device=thicknesses.device, dtype=thicknesses.dtype
|
|
17
|
+
) * float('inf')
|
|
18
|
+
|
|
19
|
+
boundary = thicknesses * coef
|
|
20
|
+
if mask is not None:
|
|
21
|
+
boundary[get_thickness_mask_from_sld_mask(mask)] = float('inf')
|
|
22
|
+
|
|
23
|
+
max_roughness[:, :-1] = boundary
|
|
24
|
+
max_roughness[:, 1:] = torch.minimum(max_roughness[:, 1:], boundary)
|
|
25
|
+
return max_roughness
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_allowed_contrast_indices(slds: Tensor, min_contrast: float, mask: Tensor = None) -> Tensor:
|
|
29
|
+
d_rhos = get_d_rhos(slds)
|
|
30
|
+
indices = d_rhos.abs() >= min_contrast
|
|
31
|
+
if mask is not None:
|
|
32
|
+
indices = indices | mask
|
|
33
|
+
indices = torch.all(indices, -1)
|
|
34
|
+
return indices
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def params_within_bounds(params_t: Tensor, min_t: Tensor, max_t: Tensor, mask: Tensor = None) -> Tensor:
|
|
38
|
+
indices = (params_t >= min_t[None]) & (params_t <= max_t[None])
|
|
39
|
+
if mask is not None:
|
|
40
|
+
indices = indices | mask
|
|
41
|
+
indices = torch.all(indices, -1)
|
|
42
|
+
return indices
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_allowed_roughness_indices(thicknesses: Tensor, roughnesses: Tensor, mask: Tensor = None) -> Tensor:
|
|
46
|
+
max_roughness = get_max_allowed_roughness(thicknesses, mask)
|
|
47
|
+
indices = roughnesses <= max_roughness
|
|
48
|
+
if mask is not None:
|
|
49
|
+
indices = indices | mask
|
|
50
|
+
indices = torch.all(indices, -1)
|
|
51
|
+
return indices
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_thickness_mask_from_sld_mask(mask: Tensor):
|
|
55
|
+
return mask[:, :-1]
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def generate_roughnesses(thicknesses: Tensor, roughness_range: Tuple[float, float], mask: Tensor = None):
|
|
59
|
+
batch_size, layers_num = thicknesses.shape
|
|
60
|
+
max_roughness = get_max_allowed_roughness(thicknesses, mask)
|
|
61
|
+
max_roughness = torch.clamp_(max_roughness, max=roughness_range[1])
|
|
62
|
+
|
|
63
|
+
roughnesses = uniform_sampler(
|
|
64
|
+
roughness_range[0], max_roughness, batch_size, layers_num + 1,
|
|
65
|
+
device=thicknesses.device, dtype=thicknesses.dtype
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if mask is not None:
|
|
69
|
+
roughnesses[mask] = 0.
|
|
70
|
+
|
|
71
|
+
return roughnesses
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def generate_thicknesses(
|
|
75
|
+
thickness_range: Tuple[float, float],
|
|
76
|
+
batch_size: int,
|
|
77
|
+
layers_num: int,
|
|
78
|
+
device: torch.device,
|
|
79
|
+
dtype: torch.dtype,
|
|
80
|
+
mask: Tensor = None
|
|
81
|
+
):
|
|
82
|
+
thicknesses = uniform_sampler(
|
|
83
|
+
*thickness_range, batch_size, layers_num, device=device, dtype=dtype
|
|
84
|
+
)
|
|
85
|
+
if mask is not None:
|
|
86
|
+
thicknesses[get_thickness_mask_from_sld_mask(mask)] = 0.
|
|
87
|
+
return thicknesses
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def generate_slds_with_min_contrast(
|
|
91
|
+
sld_range: Tuple[float, float],
|
|
92
|
+
batch_size: int,
|
|
93
|
+
layers_num: int,
|
|
94
|
+
min_contrast: float,
|
|
95
|
+
device: torch.device,
|
|
96
|
+
dtype: torch.dtype,
|
|
97
|
+
mask: Tensor = None,
|
|
98
|
+
*,
|
|
99
|
+
_depth: int = 0
|
|
100
|
+
):
|
|
101
|
+
# rejection sampling
|
|
102
|
+
slds = uniform_sampler(
|
|
103
|
+
*sld_range, batch_size, layers_num + 1, device=device, dtype=dtype
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
if mask is not None:
|
|
107
|
+
slds[mask] = 0.
|
|
108
|
+
|
|
109
|
+
rejected_indices = ~get_allowed_contrast_indices(slds, min_contrast, mask)
|
|
110
|
+
rejected_num = rejected_indices.sum(0).item()
|
|
111
|
+
|
|
112
|
+
if rejected_num:
|
|
113
|
+
if mask is not None:
|
|
114
|
+
mask = mask[rejected_indices]
|
|
115
|
+
slds[rejected_indices] = generate_slds_with_min_contrast(
|
|
116
|
+
sld_range, rejected_num, layers_num, min_contrast, device, dtype, mask, _depth=_depth+1
|
|
117
|
+
)
|
|
118
|
+
return slds
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
from typing import Any
|
|
2
|
-
|
|
3
|
-
__all__ = [
|
|
4
|
-
"ProcessData",
|
|
5
|
-
"ProcessPipeline",
|
|
6
|
-
]
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class ProcessData(object):
|
|
10
|
-
def __add__(self, other):
|
|
11
|
-
if isinstance(other, ProcessData):
|
|
12
|
-
return ProcessPipeline(self, other)
|
|
13
|
-
|
|
14
|
-
def apply(self, args: Any, context: dict = None):
|
|
15
|
-
return args
|
|
16
|
-
|
|
17
|
-
def __call__(self, args: Any, context: dict = None):
|
|
18
|
-
return self.apply(args, context)
|
|
19
|
-
|
|
20
|
-
def __repr__(self):
|
|
21
|
-
return f'{self.__class__.__name__}()'
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class ProcessPipeline(ProcessData):
|
|
25
|
-
def __init__(self, *processes):
|
|
26
|
-
self._processes = list(processes)
|
|
27
|
-
|
|
28
|
-
def apply(self, args: Any, context: dict = None):
|
|
29
|
-
for process in self._processes:
|
|
30
|
-
args = process(args, context)
|
|
31
|
-
return args
|
|
32
|
-
|
|
33
|
-
def __add__(self, other):
|
|
34
|
-
if isinstance(other, ProcessPipeline):
|
|
35
|
-
return ProcessPipeline(*self._processes, *other._processes)
|
|
36
|
-
elif isinstance(other, ProcessData):
|
|
37
|
-
return ProcessPipeline(*self._processes, other)
|
|
38
|
-
|
|
39
|
-
def __repr__(self):
|
|
40
|
-
processes = ", ".join(repr(p) for p in self._processes)
|
|
41
|
-
return f'ProcessPipeline({processes})'
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
"ProcessData",
|
|
5
|
+
"ProcessPipeline",
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ProcessData(object):
|
|
10
|
+
def __add__(self, other):
|
|
11
|
+
if isinstance(other, ProcessData):
|
|
12
|
+
return ProcessPipeline(self, other)
|
|
13
|
+
|
|
14
|
+
def apply(self, args: Any, context: dict = None):
|
|
15
|
+
return args
|
|
16
|
+
|
|
17
|
+
def __call__(self, args: Any, context: dict = None):
|
|
18
|
+
return self.apply(args, context)
|
|
19
|
+
|
|
20
|
+
def __repr__(self):
|
|
21
|
+
return f'{self.__class__.__name__}()'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ProcessPipeline(ProcessData):
|
|
25
|
+
def __init__(self, *processes):
|
|
26
|
+
self._processes = list(processes)
|
|
27
|
+
|
|
28
|
+
def apply(self, args: Any, context: dict = None):
|
|
29
|
+
for process in self._processes:
|
|
30
|
+
args = process(args, context)
|
|
31
|
+
return args
|
|
32
|
+
|
|
33
|
+
def __add__(self, other):
|
|
34
|
+
if isinstance(other, ProcessPipeline):
|
|
35
|
+
return ProcessPipeline(*self._processes, *other._processes)
|
|
36
|
+
elif isinstance(other, ProcessData):
|
|
37
|
+
return ProcessPipeline(*self._processes, other)
|
|
38
|
+
|
|
39
|
+
def __repr__(self):
|
|
40
|
+
processes = ", ".join(repr(p) for p in self._processes)
|
|
41
|
+
return f'ProcessPipeline({processes})'
|