nxs-analysis-tools 0.0.31__py3-none-any.whl → 0.0.33__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 nxs-analysis-tools might be problematic. Click here for more details.
- _meta/__init__.py +1 -1
- nxs_analysis_tools/__init__.py +2 -2
- nxs_analysis_tools/chess.py +413 -363
- nxs_analysis_tools/datareduction.py +989 -887
- nxs_analysis_tools/fitting.py +258 -262
- nxs_analysis_tools/pairdistribution.py +585 -515
- {nxs_analysis_tools-0.0.31.dist-info → nxs_analysis_tools-0.0.33.dist-info}/METADATA +1 -1
- nxs_analysis_tools-0.0.33.dist-info/RECORD +11 -0
- {nxs_analysis_tools-0.0.31.dist-info → nxs_analysis_tools-0.0.33.dist-info}/WHEEL +1 -1
- nxs_analysis_tools-0.0.31.dist-info/RECORD +0 -11
- {nxs_analysis_tools-0.0.31.dist-info → nxs_analysis_tools-0.0.33.dist-info}/LICENSE +0 -0
- {nxs_analysis_tools-0.0.31.dist-info → nxs_analysis_tools-0.0.33.dist-info}/top_level.txt +0 -0
nxs_analysis_tools/chess.py
CHANGED
|
@@ -1,363 +1,413 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module provides classes and functions for analyzing scattering datasets collected at CHESS
|
|
3
|
-
(ID4B) with temperature dependence. It includes functions for loading data, cutting data, and
|
|
4
|
-
plotting linecuts.
|
|
5
|
-
"""
|
|
6
|
-
import os
|
|
7
|
-
import matplotlib.pyplot as plt
|
|
8
|
-
import matplotlib as mpl
|
|
9
|
-
|
|
10
|
-
from
|
|
11
|
-
from
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
self.
|
|
27
|
-
self.
|
|
28
|
-
self.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
Parameters
|
|
254
|
-
----------
|
|
255
|
-
|
|
256
|
-
The
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
1
|
+
"""
|
|
2
|
+
This module provides classes and functions for analyzing scattering datasets collected at CHESS
|
|
3
|
+
(ID4B) with temperature dependence. It includes functions for loading data, cutting data, and
|
|
4
|
+
plotting linecuts.
|
|
5
|
+
"""
|
|
6
|
+
import os
|
|
7
|
+
import matplotlib.pyplot as plt
|
|
8
|
+
import matplotlib as mpl
|
|
9
|
+
import numpy as np
|
|
10
|
+
from IPython.display import display, Markdown
|
|
11
|
+
from nexusformat.nexus import nxload
|
|
12
|
+
from nxs_analysis_tools import load_data, Scissors
|
|
13
|
+
from nxs_analysis_tools.fitting import LinecutModel
|
|
14
|
+
from nxs_analysis_tools.datareduction import load_transform, reciprocal_lattice_params
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TempDependence:
|
|
18
|
+
"""
|
|
19
|
+
Class for analyzing scattering datasets collected at CHESS (ID4B) with temperature dependence.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
"""
|
|
24
|
+
Initialize TempDependence class.
|
|
25
|
+
"""
|
|
26
|
+
self.nxs_files_list = []
|
|
27
|
+
self.sample_directory = ''
|
|
28
|
+
self.xlabel = ''
|
|
29
|
+
self.datasets = {}
|
|
30
|
+
self.temperatures = []
|
|
31
|
+
self.scissors = {}
|
|
32
|
+
self.linecuts = {}
|
|
33
|
+
self.linecutmodels = {}
|
|
34
|
+
|
|
35
|
+
def set_temperatures(self, temperatures):
|
|
36
|
+
self.temperatures = temperatures
|
|
37
|
+
|
|
38
|
+
def set_sample_directory(self, path):
|
|
39
|
+
self.sample_directory = os.path.normpath(path)
|
|
40
|
+
|
|
41
|
+
def initialize(self):
|
|
42
|
+
for temperature in self.temperatures:
|
|
43
|
+
self.scissors[temperature] = Scissors()
|
|
44
|
+
self.scissors[temperature] = LinecutModel()
|
|
45
|
+
|
|
46
|
+
def set_data(self, temperature, data):
|
|
47
|
+
self.datasets[temperature] = data
|
|
48
|
+
|
|
49
|
+
def load_transforms(self, temperatures_list=None):
|
|
50
|
+
# Convert all temperatures to strings
|
|
51
|
+
if temperatures_list:
|
|
52
|
+
temperatures_list = [str(t) for t in temperatures_list]
|
|
53
|
+
|
|
54
|
+
# Search all files in the sample directory
|
|
55
|
+
for item in os.listdir(self.sample_directory):
|
|
56
|
+
|
|
57
|
+
# Find the nxs files
|
|
58
|
+
if item.endswith('.nxs'):
|
|
59
|
+
|
|
60
|
+
# Load the nxs files
|
|
61
|
+
path = os.path.join(self.sample_directory, item)
|
|
62
|
+
g = nxload(path)
|
|
63
|
+
|
|
64
|
+
# Extract the sample temperature
|
|
65
|
+
temperature = str(int(np.round(g.entry.sample.temperature.nxdata)))
|
|
66
|
+
|
|
67
|
+
# Load all samples (or a subset if temperatures_list is provided)
|
|
68
|
+
if (temperatures_list is None) or (temperature in temperatures_list):
|
|
69
|
+
self.temperatures.append(temperature)
|
|
70
|
+
self.datasets[temperature] = load_transform(path)
|
|
71
|
+
# Initialize scissors object at each temperature
|
|
72
|
+
self.scissors[temperature] = Scissors()
|
|
73
|
+
self.scissors[temperature].set_data(self.datasets[temperature])
|
|
74
|
+
|
|
75
|
+
# Initialize linecutmodel object at each temperature
|
|
76
|
+
self.linecutmodels[temperature] = LinecutModel()
|
|
77
|
+
|
|
78
|
+
def load_datasets(self, file_ending='hkli.nxs', temperatures_list=None):
|
|
79
|
+
"""
|
|
80
|
+
Load scattering datasets from the specified folder.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
folder : str
|
|
85
|
+
The path to the folder where the datasets are located.
|
|
86
|
+
file_ending : str, optional
|
|
87
|
+
The file extension of the datasets to be loaded. The default is 'hkli.nxs'.
|
|
88
|
+
temperatures_list : list of int or None, optional
|
|
89
|
+
The list of specific temperatures to load. If None, all available temperatures are
|
|
90
|
+
loaded. The default is None.
|
|
91
|
+
"""
|
|
92
|
+
temperature_folders = [] # Empty list to store temperature folder names
|
|
93
|
+
for item in os.listdir(self.sample_directory):
|
|
94
|
+
try:
|
|
95
|
+
temperature_folders.append(int(item)) # If folder name can be int, add it
|
|
96
|
+
except ValueError:
|
|
97
|
+
pass # Otherwise don't add it
|
|
98
|
+
temperature_folders.sort() # Sort from low to high T
|
|
99
|
+
temperature_folders = [str(i) for i in temperature_folders] # Convert to strings
|
|
100
|
+
|
|
101
|
+
print('Found temperature folders:')
|
|
102
|
+
[print('[' + str(i) + '] ' + folder) for i, folder in enumerate(temperature_folders)]
|
|
103
|
+
|
|
104
|
+
self.temperatures = temperature_folders
|
|
105
|
+
|
|
106
|
+
if temperatures_list is not None:
|
|
107
|
+
self.temperatures = [str(t) for t in temperatures_list]
|
|
108
|
+
|
|
109
|
+
# Load .nxs files
|
|
110
|
+
for T in self.temperatures:
|
|
111
|
+
for file in os.listdir(os.path.join(self.sample_directory, T)):
|
|
112
|
+
if file.endswith(file_ending):
|
|
113
|
+
filepath = os.path.join(self.sample_directory, T, file)
|
|
114
|
+
print('-----------------------------------------------')
|
|
115
|
+
print('Loading ' + T + ' K indexed .nxs files...')
|
|
116
|
+
print('Found ' + filepath)
|
|
117
|
+
|
|
118
|
+
# Load dataset at each temperature
|
|
119
|
+
self.datasets[T] = load_data(filepath)
|
|
120
|
+
|
|
121
|
+
# Initialize scissors object at each temperature
|
|
122
|
+
self.scissors[T] = Scissors()
|
|
123
|
+
self.scissors[T].set_data(self.datasets[T])
|
|
124
|
+
|
|
125
|
+
# Initialize linecutmodel object at each temperature
|
|
126
|
+
self.linecutmodels[T] = LinecutModel()
|
|
127
|
+
|
|
128
|
+
def get_sample_directory(self):
|
|
129
|
+
"""
|
|
130
|
+
Get the folder path where the datasets are located.
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
str:
|
|
135
|
+
The folder path.
|
|
136
|
+
"""
|
|
137
|
+
return self.sample_directory
|
|
138
|
+
|
|
139
|
+
def clear_datasets(self):
|
|
140
|
+
"""
|
|
141
|
+
Clear the datasets stored in the TempDependence instance.
|
|
142
|
+
"""
|
|
143
|
+
self.datasets = {}
|
|
144
|
+
|
|
145
|
+
def set_Lattice_params(self, lattice_params):
|
|
146
|
+
self.a, self.b, self.c, self.al, self.be, self.ga = lattice_params
|
|
147
|
+
self.a_star, self.b_star, self.c_star, self.al_star, self.be_star, self.ga_star = reciprocal_lattice_params(lattice_params)
|
|
148
|
+
def set_window(self, window):
|
|
149
|
+
"""
|
|
150
|
+
Set the extents of the integration window.
|
|
151
|
+
|
|
152
|
+
Parameters
|
|
153
|
+
----------
|
|
154
|
+
window : tuple
|
|
155
|
+
Extents of the window for integration along each axis.
|
|
156
|
+
"""
|
|
157
|
+
for T in self.temperatures:
|
|
158
|
+
print("----------------------------------")
|
|
159
|
+
print("T = " + T + " K")
|
|
160
|
+
self.scissors[T].set_window(window)
|
|
161
|
+
|
|
162
|
+
def set_center(self, center):
|
|
163
|
+
"""
|
|
164
|
+
Set the central coordinate for the linecut.
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
center : tuple
|
|
169
|
+
Central coordinate around which to perform the linecut.
|
|
170
|
+
"""
|
|
171
|
+
for T in self.temperatures:
|
|
172
|
+
self.scissors[T].set_center(center)
|
|
173
|
+
|
|
174
|
+
def cut_data(self, center=None, window=None, axis=None):
|
|
175
|
+
"""
|
|
176
|
+
Perform data cutting for each temperature dataset.
|
|
177
|
+
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
center : tuple
|
|
181
|
+
The center point for cutting the data.
|
|
182
|
+
window : tuple
|
|
183
|
+
The window size for cutting the data.
|
|
184
|
+
axis : int or None, optional
|
|
185
|
+
The axis along which to perform the cutting. If None, cutting is performed along the
|
|
186
|
+
longest axis in `window`. The default is None.
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
list
|
|
191
|
+
A list of linecuts obtained from the cutting operation.
|
|
192
|
+
"""
|
|
193
|
+
|
|
194
|
+
center = center if center is not None else self.scissors[self.temperatures[0]].center
|
|
195
|
+
window = window if window is not None else self.scissors[self.temperatures[0]].window
|
|
196
|
+
|
|
197
|
+
for T in self.temperatures:
|
|
198
|
+
print("-------------------------------")
|
|
199
|
+
print("Cutting T = " + T + " K data...")
|
|
200
|
+
self.scissors[T].cut_data(center, window, axis)
|
|
201
|
+
self.linecuts[T] = self.scissors[T].linecut
|
|
202
|
+
self.linecutmodels[T].set_data(self.linecuts[T])
|
|
203
|
+
|
|
204
|
+
xlabel_components = [self.linecuts[self.temperatures[0]].axes
|
|
205
|
+
if i == self.scissors[self.temperatures[0]].axis
|
|
206
|
+
else str(c) for i, c in enumerate(self.scissors[self.temperatures[0]].center)]
|
|
207
|
+
self.xlabel = ' '.join(xlabel_components)
|
|
208
|
+
|
|
209
|
+
return self.linecuts
|
|
210
|
+
|
|
211
|
+
def plot_linecuts(self, vertical_offset=0, **kwargs):
|
|
212
|
+
"""
|
|
213
|
+
Plot the linecuts obtained from data cutting.
|
|
214
|
+
|
|
215
|
+
Parameters
|
|
216
|
+
----------
|
|
217
|
+
vertical_offset : float, optional
|
|
218
|
+
The vertical offset between linecuts on the plot. The default is 0.
|
|
219
|
+
**kwargs
|
|
220
|
+
Additional keyword arguments to be passed to the plot function.
|
|
221
|
+
"""
|
|
222
|
+
fig, ax = plt.subplots()
|
|
223
|
+
|
|
224
|
+
# Get the Viridis colormap
|
|
225
|
+
cmap = mpl.colormaps.get_cmap('viridis')
|
|
226
|
+
|
|
227
|
+
for i, linecut in enumerate(self.linecuts.values()):
|
|
228
|
+
x_data = linecut[linecut.axes].nxdata
|
|
229
|
+
y_data = linecut[linecut.signal].nxdata + i * vertical_offset
|
|
230
|
+
ax.plot(x_data, y_data, color=cmap(i / len(self.linecuts)), label=self.temperatures[i],
|
|
231
|
+
**kwargs)
|
|
232
|
+
|
|
233
|
+
ax.set(xlabel=self.xlabel,
|
|
234
|
+
ylabel=self.linecuts[self.temperatures[0]].signal)
|
|
235
|
+
|
|
236
|
+
# Get the current legend handles and labels
|
|
237
|
+
handles, labels = plt.gca().get_legend_handles_labels()
|
|
238
|
+
|
|
239
|
+
# Reverse the order of handles and labels
|
|
240
|
+
handles = handles[::-1]
|
|
241
|
+
labels = labels[::-1]
|
|
242
|
+
|
|
243
|
+
# Create a new legend with reversed order
|
|
244
|
+
plt.legend(handles, labels)
|
|
245
|
+
|
|
246
|
+
return fig, ax
|
|
247
|
+
|
|
248
|
+
def highlight_integration_window(self, temperature=None, **kwargs):
|
|
249
|
+
"""
|
|
250
|
+
Displays the integration window plot for a specific temperature, or for the first temperature if
|
|
251
|
+
none is provided.
|
|
252
|
+
|
|
253
|
+
Parameters
|
|
254
|
+
----------
|
|
255
|
+
temperature : str, optional
|
|
256
|
+
The temperature at which to display the integration window plot. If provided, the plot
|
|
257
|
+
will be generated using the dataset corresponding to the specified temperature. If not
|
|
258
|
+
provided, the integration window plots will be generated for the first temperature.
|
|
259
|
+
**kwargs : keyword arguments, optional
|
|
260
|
+
Additional keyword arguments to customize the plot.
|
|
261
|
+
"""
|
|
262
|
+
|
|
263
|
+
if temperature is not None:
|
|
264
|
+
p = self.scissors[self.temperatures[0]].highlight_integration_window(data=self.datasets[temperature],
|
|
265
|
+
**kwargs)
|
|
266
|
+
else:
|
|
267
|
+
p = self.scissors[self.temperatures[0]].highlight_integration_window(
|
|
268
|
+
data=self.datasets[self.temperatures[0]], **kwargs
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
return p
|
|
272
|
+
|
|
273
|
+
def plot_integration_window(self, temperature=None, **kwargs):
|
|
274
|
+
"""
|
|
275
|
+
Plots the three principal cross-sections of the integration volume on a single figure for a specific
|
|
276
|
+
temperature, or for the first temperature if none is provided.
|
|
277
|
+
|
|
278
|
+
Parameters
|
|
279
|
+
----------
|
|
280
|
+
temperature : str, optional
|
|
281
|
+
The temperature at which to plot the integration volume. If provided, the plot
|
|
282
|
+
will be generated using the dataset corresponding to the specified temperature. If not
|
|
283
|
+
provided, the integration window plots will be generated for the first temperature.
|
|
284
|
+
**kwargs : keyword arguments, optional
|
|
285
|
+
Additional keyword arguments to customize the plot.
|
|
286
|
+
"""
|
|
287
|
+
|
|
288
|
+
if temperature is not None:
|
|
289
|
+
p = self.scissors[self.temperatures[0]].plot_integration_window(**kwargs)
|
|
290
|
+
else:
|
|
291
|
+
p = self.scissors[self.temperatures[0]].plot_integration_window(**kwargs)
|
|
292
|
+
|
|
293
|
+
return p
|
|
294
|
+
|
|
295
|
+
def set_model_components(self, model_components):
|
|
296
|
+
"""
|
|
297
|
+
Set the model components for all line cut models.
|
|
298
|
+
|
|
299
|
+
This method sets the same model components for all line cut models in the analysis.
|
|
300
|
+
It iterates over each line cut model and calls their respective `set_model_components` method
|
|
301
|
+
with the provided `model_components`.
|
|
302
|
+
|
|
303
|
+
Parameters
|
|
304
|
+
----------
|
|
305
|
+
model_components : Model or iterable of Model
|
|
306
|
+
The model components to set for all line cut models.
|
|
307
|
+
|
|
308
|
+
"""
|
|
309
|
+
[linecutmodel.set_model_components(model_components) for linecutmodel in self.linecutmodels.values()]
|
|
310
|
+
|
|
311
|
+
def set_param_hint(self, *args, **kwargs):
|
|
312
|
+
"""
|
|
313
|
+
Set parameter hints for all line cut models.
|
|
314
|
+
|
|
315
|
+
This method sets the parameter hints for all line cut models in the analysis.
|
|
316
|
+
It iterates over each line cut model and calls their respective `set_param_hint` method
|
|
317
|
+
with the provided arguments and keyword arguments.
|
|
318
|
+
|
|
319
|
+
Parameters
|
|
320
|
+
----------
|
|
321
|
+
*args
|
|
322
|
+
Variable length argument list.
|
|
323
|
+
**kwargs
|
|
324
|
+
Arbitrary keyword arguments.
|
|
325
|
+
|
|
326
|
+
"""
|
|
327
|
+
[linecutmodel.set_param_hint(*args, **kwargs) for linecutmodel in self.linecutmodels.values()]
|
|
328
|
+
|
|
329
|
+
def make_params(self):
|
|
330
|
+
"""
|
|
331
|
+
Make parameters for all line cut models.
|
|
332
|
+
|
|
333
|
+
This method creates the parameters for all line cut models in the analysis.
|
|
334
|
+
It iterates over each line cut model and calls their respective `make_params` method.
|
|
335
|
+
"""
|
|
336
|
+
[linecutmodel.make_params() for linecutmodel in self.linecutmodels.values()]
|
|
337
|
+
|
|
338
|
+
def guess(self):
|
|
339
|
+
"""
|
|
340
|
+
Make initial parameter guesses for all line cut models.
|
|
341
|
+
|
|
342
|
+
This method generates initial parameter guesses for all line cut models in the analysis.
|
|
343
|
+
It iterates over each line cut model and calls their respective `guess` method.
|
|
344
|
+
|
|
345
|
+
"""
|
|
346
|
+
[linecutmodel.guess() for linecutmodel in self.linecutmodels.values()]
|
|
347
|
+
|
|
348
|
+
def print_initial_params(self):
|
|
349
|
+
"""
|
|
350
|
+
Print the initial parameter values for all line cut models.
|
|
351
|
+
|
|
352
|
+
This method prints the initial parameter values for all line cut models in the analysis.
|
|
353
|
+
It iterates over each line cut model and calls their respective `print_initial_params` method.
|
|
354
|
+
|
|
355
|
+
"""
|
|
356
|
+
[linecutmodel.print_initial_params() for linecutmodel in self.linecutmodels.values()]
|
|
357
|
+
|
|
358
|
+
def plot_initial_guess(self):
|
|
359
|
+
"""
|
|
360
|
+
Plot the initial guess for all line cut models.
|
|
361
|
+
|
|
362
|
+
This method plots the initial guess for all line cut models in the analysis.
|
|
363
|
+
It iterates over each line cut model and calls their respective `plot_initial_guess` method.
|
|
364
|
+
|
|
365
|
+
"""
|
|
366
|
+
for T, linecutmodel in self.linecutmodels.items():
|
|
367
|
+
fig, ax = plt.subplots()
|
|
368
|
+
ax.set(title=T + ' K')
|
|
369
|
+
linecutmodel.plot_initial_guess()
|
|
370
|
+
|
|
371
|
+
def fit(self):
|
|
372
|
+
"""
|
|
373
|
+
Fit the line cut models.
|
|
374
|
+
|
|
375
|
+
This method fits the line cut models for each temperature in the analysis.
|
|
376
|
+
It iterates over each line cut model, performs the fit, and prints the fitting progress.
|
|
377
|
+
|
|
378
|
+
"""
|
|
379
|
+
for T, linecutmodel in self.linecutmodels.items():
|
|
380
|
+
print(f"Fitting {T} K data...")
|
|
381
|
+
linecutmodel.fit()
|
|
382
|
+
print("Done.")
|
|
383
|
+
print("Fits completed.")
|
|
384
|
+
|
|
385
|
+
def plot_fit(self, mdheadings=False, **kwargs):
|
|
386
|
+
"""
|
|
387
|
+
Plot the fit results.
|
|
388
|
+
|
|
389
|
+
This method plots the fit results for each temperature in the analysis.
|
|
390
|
+
It iterates over each line cut model, calls their respective `plot_fit` method,
|
|
391
|
+
and sets the xlabel, ylabel, and title for the plot.
|
|
392
|
+
|
|
393
|
+
"""
|
|
394
|
+
for T, linecutmodel in self.linecutmodels.items():
|
|
395
|
+
# Create a markdown heading for the plot
|
|
396
|
+
if mdheadings:
|
|
397
|
+
display(Markdown(f"### {T} K Fit Results"))
|
|
398
|
+
# Plot fit
|
|
399
|
+
linecutmodel.plot_fit(xlabel=self.xlabel, ylabel=self.datasets[self.temperatures[0]].signal, title=f"{T} K",
|
|
400
|
+
**kwargs)
|
|
401
|
+
|
|
402
|
+
def print_fit_report(self):
|
|
403
|
+
"""
|
|
404
|
+
Plot the fit results.
|
|
405
|
+
|
|
406
|
+
This method plots the fit results for each temperature in the analysis.
|
|
407
|
+
It iterates over each line cut model, calls their respective `plot_fit` method,
|
|
408
|
+
and sets the xlabel, ylabel, and title for the plot.
|
|
409
|
+
|
|
410
|
+
"""
|
|
411
|
+
for T, linecutmodel in self.linecutmodels.items():
|
|
412
|
+
print(f"[[[{T} K Fit Report]]]")
|
|
413
|
+
linecutmodel.print_fit_report()
|