nxs-analysis-tools 0.0.29__py3-none-any.whl → 0.0.31__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.
@@ -1,363 +1,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
- 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[0]].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
+ 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()