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.

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