-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathwrapper.py
More file actions
240 lines (195 loc) · 6.92 KB
/
Copy pathwrapper.py
File metadata and controls
240 lines (195 loc) · 6.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# SPDX-FileCopyrightText: 2026 EasyScience contributors <https://github.com/easyscience>
# SPDX-License-Identifier: BSD-3-Clause
from typing import Tuple
import numpy as np
from refnx import reflect
from easyreflectometry.model import PercentageFwhm
from easyreflectometry.model.resolution_functions import SIGMA_TO_FWHM
from ..wrapper_base import WrapperBase
class RefnxWrapper(WrapperBase):
@property
def include_magnetism(self) -> bool:
"""Include magnetism."""
return self._magnetism
@include_magnetism.setter
def include_magnetism(self, magnetism: bool) -> None:
"""Set the magnetism flag.
Parameters
----------
magnetism : bool
The magnetism flag.
"""
raise NotImplementedError('Magnetism is not supported by refnx')
def create_material(self, name: str):
"""Create a material using SLD.
Parameters
----------
name : str
The name of the material.
"""
self.storage['material'][name] = reflect.SLD(0, name=name)
def create_layer(self, name: str):
"""Create a layer using Slab.
Parameters
----------
name : str
The name of the layer.
"""
self.storage['layer'][name] = reflect.Slab(0, 0, 0, name=name)
def create_item(self, name: str):
"""Create an item using Stack.
Parameters
----------
name : str
The name of the item.
"""
self.storage['item'][name] = reflect.Stack(name=name)
def create_model(self, name: str):
"""Create a model for analysis.
Parameters
----------
name : str
Name for the model.
"""
self.storage['model'][name] = reflect.ReflectModel(reflect.Structure())
def update_model(self, name: str, **kwargs):
"""Update the non-structural parameters of the model.
Parameters
----------
**kwargs :
name : str
Name for the model.
"""
model = self.storage['model'][name]
for key in kwargs.keys():
item = getattr(model, key)
setattr(item, 'value', kwargs[key])
def get_model_value(self, name: str, key: str) -> float:
"""A function to get a given model value.
Parameters
----------
name : str
Name for the model.
key : str
The given value keys.
Returns
-------
float
The desired value.
"""
model = self.storage['model'][name]
item = getattr(model, key)
return getattr(item, 'value')
def assign_material_to_layer(self, material_name: str, layer_name: str):
"""Assign a material to a layer.
Parameters
----------
material_name : str
The material name.
layer_name : str
The layer name.
"""
self.storage['layer'][layer_name].sld = self.storage['material'][material_name]
def add_layer_to_item(self, layer_name: str, item_name: str):
"""Create a layer from the material of the same name, in a given item.
Parameters
----------
layer_name : str
The layer name.
item_name : str
The item name.
"""
item = self.storage['item'][item_name]
item.append(self.storage['layer'][layer_name])
def add_item(self, item_name: str, model_name: str):
"""Add an item to the model.
Parameters
----------
item_name : str
Items to add to model.
model_name : str
Name for the model.
"""
self.storage['model'][model_name].structure.components.append(self.storage['item'][item_name])
def remove_layer_from_item(self, layer_name: str, item_name: str):
"""Remove a layer in a given item.
Parameters
----------
layer_name : str
The layer name.
item_name : str
The item name.
"""
layer_idx = self.storage['item'][item_name].components.index(self.storage['layer'][layer_name])
del self.storage['item'][item_name].components[layer_idx]
def remove_item(self, item_name: str, model_name: str):
"""Remove a given item.
Parameters
----------
item_name : str
The item name.
model_name : str
Name of the model.
"""
item_idx = self.storage['model'][model_name].structure.components.index(self.storage['item'][item_name])
del self.storage['model'][model_name].structure.components[item_idx]
del self.storage['item'][item_name]
def calculate(self, q_array: np.ndarray, model_name: str) -> np.ndarray:
"""For a given q array calculate the corresponding reflectivity.
Parameters
----------
q_array : np.ndarray
Array of data points to be calculated.
model_name : str
The model name.
Returns
-------
np.ndarray
Reflectivity calculated at q.
"""
structure = _remove_unecessary_stacks(self.storage['model'][model_name].structure)
model = reflect.ReflectModel(
structure,
scale=self.storage['model'][model_name].scale.value,
bkg=self.storage['model'][model_name].bkg.value,
dq_type='pointwise',
)
dq_vector = self._resolution_function.smearing(q_array)
if isinstance(self._resolution_function, PercentageFwhm):
# refnx interprets a scalar x_err as a constant dq/q (FWHM percentage),
# so pass the percentage directly rather than a per-point vector.
dq_vector = self._resolution_function.constant
else:
# smearing() returns sigma; refnx expects the FWHM at each point.
dq_vector = dq_vector * SIGMA_TO_FWHM
return model(x=q_array, x_err=dq_vector)
def sld_profile(self, model_name: str) -> Tuple[np.ndarray, np.ndarray]:
"""Return the scattering length density profile.
Parameters
----------
model_name : str
Name for the model.
Returns
-------
Z and sld(z).
"""
return _remove_unecessary_stacks(self.storage['model'][model_name].structure).sld_profile()
def _remove_unecessary_stacks(current_structure: reflect.Structure) -> reflect.Structure:
"""Removed unnecessary reflect.Stack objects from the structure.
Parameters
----------
current_structure : reflect.Structure
The current structure.
Returns
-------
reflect.structure
The structre without the unnecessary Stacks.
"""
structure = []
for i in current_structure.components:
if i.repeats.value == 1:
for j in i.components:
structure.append(j)
else:
structure.append(i)
return reflect.Structure(structure)