nxs-analysis-tools 0.0.32__py3-none-any.whl → 0.0.34__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,262 +1,258 @@
1
- """
2
- Module for fitting of linecuts using the lmfit package.
3
- """
4
-
5
- import operator
6
- from lmfit.model import Model
7
- from lmfit.model import CompositeModel
8
- import matplotlib.pyplot as plt
9
- import numpy as np
10
-
11
-
12
- class LinecutModel:
13
- """
14
- A class representing a linecut model for data analysis and fitting.
15
-
16
- Attributes
17
- ----------
18
- y : array-like or None
19
- The dependent variable data.
20
- x : array-like or None
21
- The independent variable data.
22
- y_eval : array-like or None
23
- The evaluated y-values of the fitted model.
24
- x_eval : array-like or None
25
- The x-values used for evaluation.
26
- y_eval_components : dict or None
27
- The evaluated y-values of the model components.
28
- y_fit_components : dict or None
29
- The fitted y-values of the model components.
30
- y_fit : array-like or None
31
- The fitted y-values of the model.
32
- x_fit : array-like or None
33
- The x-values used for fitting.
34
- y_init_fit : array-like or None
35
- The initial guess of the y-values.
36
- params : Parameters or None
37
- The parameters of the model.
38
- model_components : Model or list of Models or None
39
- The model component(s) used for fitting.
40
- model : Model or None
41
- The composite model used for fitting.
42
- modelresult : ModelResult or None
43
- The result of the model fitting.
44
- data : NXdata or None
45
- The 1D linecut data used for analysis.
46
-
47
- Methods
48
- -------
49
- __init__(self, data=None)
50
- Initialize the LinecutModel.
51
- set_data(self, data)
52
- Set the data for analysis.
53
- set_model_components(self, model_components)
54
- Set the model components.
55
- set_param_hint(self, *args, **kwargs)
56
- Set parameter hints for the model.
57
- make_params(self)
58
- Create and initialize the parameters for the model.
59
- guess(self)
60
- Perform initial guesses for each model component.
61
- print_initial_params(self)
62
- Print out initial guesses for each parameter of the model.
63
- plot_initial_guess(self, numpoints=None)
64
- Plot the initial guess.
65
- fit(self)
66
- Fit the model to the data.
67
- plot_fit(self, numpoints=None, fit_report=True, **kwargs)
68
- Plot the fitted model.
69
- print_fit_report(self)
70
- Print the fit report.
71
- """
72
- def __init__(self, data=None):
73
- """
74
- Initialize the LinecutModel.
75
- """
76
- self.y = None
77
- self.x = None
78
- self.y_eval = None
79
- self.x_eval = None
80
- self.y_eval_components = None
81
- self.y_fit_components = None
82
- self.y_fit = None
83
- self.x_fit = None
84
- self.y_init_fit = None
85
- self.params = None
86
- self.model_components = None
87
- self.model = None
88
- self.modelresult = None
89
- self.data = data if data is not None else None
90
- if self.data is not None:
91
- self.x = data[data.axes].nxdata
92
- self.y = data[data.signal].nxdata
93
-
94
- def set_data(self, data):
95
- """
96
- Set the data for analysis.
97
-
98
- Parameters
99
- ----------
100
- data : NXdata
101
- The 1D linecut data to be used for analysis.
102
- """
103
- self.data = data
104
- self.x = data[data.axes].nxdata
105
- self.y = data[data.signal].nxdata
106
-
107
- def set_model_components(self, model_components):
108
- """
109
- Set the model components
110
-
111
- Parameters
112
- ----------
113
- model_components : Model or list of Models
114
- The model component(s) to be used for fitting, which will be combined into a CompositeModel.
115
- """
116
-
117
- # If the model only has one component, then use it as the model
118
- if isinstance(model_components, Model):
119
- self.model = model_components
120
- # Else, combine the components into a composite model and use that as the
121
- else:
122
- self.model_components = model_components
123
- self.model = model_components[0]
124
-
125
- # Combine remaining components into the composite model
126
- for component in model_components[1:]:
127
- self.model = CompositeModel(self.model, component, operator.add)
128
-
129
- def set_param_hint(self, *args, **kwargs):
130
- """
131
- Set parameter hints for the model.
132
-
133
- Parameters
134
- ----------
135
- *args : positional arguments
136
- Positional arguments passed to the `set_param_hint` method of the underlying model.
137
-
138
- **kwargs : keyword arguments
139
- Keyword arguments passed to the `set_param_hint` method of the underlying model.
140
- """
141
-
142
- self.model.set_param_hint(*args, **kwargs)
143
-
144
- def make_params(self):
145
- """
146
- Create and initialize the parameters for the model.
147
-
148
- Returns
149
- -------
150
- Parameters
151
- The initialized parameters for the model.
152
- """
153
- # Intialize empty parameters (in function)
154
- params = self.model.make_params()
155
- self.params = params
156
- fwhm_params = {key: value for key, value in params.items() if 'fwhm' in key}
157
- for key, value in fwhm_params.items():
158
- pi_str = str(np.pi)
159
- params.add(key.replace('fwhm', 'corrlength'), expr='(2 * ' + pi_str + ') / ' + key)
160
-
161
- return params
162
-
163
- def guess(self):
164
- """
165
- Perform initial guesses for each model component.
166
- """
167
- for model_component in list(self.model_components):
168
- self.params.update(model_component.guess(self.y, x=self.x))
169
-
170
- def print_initial_params(self):
171
- """
172
- Print out initial guesses for each parameter of the model.
173
- """
174
- model = self.model
175
- for param, hint in model.param_hints.items():
176
- print(f'{param}')
177
- for key, value in hint.items():
178
- print(f'\t{key}: {value}')
179
-
180
- def plot_initial_guess(self, numpoints=None):
181
- """
182
- Plot initial guess.
183
- """
184
- model = self.model
185
- params = self.params
186
- x = self.x
187
- y = self.y
188
- y_init_fit = model.eval(params=params, x=x)
189
- self.y_init_fit = y_init_fit
190
- plt.plot(x, y, 'o', label='data')
191
- plt.plot(x, y_init_fit, '--', label='guess')
192
-
193
- # Plot the components of the model
194
- if numpoints is None:
195
- numpoints = len(self.x)
196
- self.x_eval = np.linspace(self.x.min(), self.x.max(), numpoints)
197
- y_init_fit_components = model.eval_components(params=params, x=self.x_eval)
198
- ax = plt.gca()
199
- for model_component, value in y_init_fit_components.items():
200
- ax.fill_between(self.x_eval, value, alpha=0.3, label=model_component)
201
- plt.legend()
202
- plt.show()
203
-
204
- def fit(self):
205
- """
206
- Fit the model to the data.
207
-
208
- This method fits the model to the data using the specified parameters and the x-values.
209
- It updates the model result, fitted y-values, and the evaluated components.
210
-
211
- """
212
- self.modelresult = self.model.fit(self.y, self.params, x=self.x)
213
- self.y_fit = self.modelresult.eval(x=self.x)
214
- self.y_fit_components = self.modelresult.eval_components(x=self.x)
215
-
216
- def plot_fit(self, numpoints=None, fit_report=True, **kwargs):
217
- """
218
- Plot the fitted model.
219
-
220
- This method plots the fitted model along with the original data.
221
- It evaluates the model and its components at the specified number of points (numpoints)
222
- and plots the results.
223
-
224
- Parameters
225
- ----------
226
- numpoints : int, optional
227
- Number of points to evaluate the model and its components. If not provided,
228
- it defaults to the length of the x-values.
229
-
230
- fit_report : bool, optional
231
- Whether to print the fit report. Default is True.
232
-
233
- **kwargs : dict, optional
234
- Additional keyword arguments to be passed to the `plot` method.
235
-
236
- Returns
237
- -------
238
- ax : matplotlib.axes.Axes
239
- The Axes object containing the plot.
240
-
241
- """
242
- if numpoints is None:
243
- numpoints = len(self.x)
244
- self.x_eval = np.linspace(self.x.min(), self.x.max(), numpoints)
245
- self.y_eval = self.modelresult.eval(x=self.x_eval)
246
- self.y_eval_components = self.modelresult.eval_components(x=self.x_eval)
247
- self.modelresult.plot(numpoints=numpoints, **kwargs)
248
- ax = plt.gca()
249
- for model_component, value in self.y_eval_components.items():
250
- ax.fill_between(self.x_eval, value, alpha=0.3, label=model_component)
251
- # ax.plot(self.x_eval, value, label=model_component)
252
- plt.legend()
253
- plt.show()
254
- if fit_report:
255
- print(self.modelresult.fit_report())
256
- return ax
257
-
258
- def print_fit_report(self):
259
- """
260
- Show fit report.
261
- """
262
- print(self.modelresult.fit_report())
1
+ """
2
+ Module for fitting of linecuts using the lmfit package.
3
+ """
4
+
5
+ import operator
6
+ from lmfit.model import Model
7
+ from lmfit.model import CompositeModel
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+
11
+
12
+ class LinecutModel:
13
+ """
14
+ A class representing a linecut model for data analysis and fitting.
15
+
16
+ Attributes
17
+ ----------
18
+ y : array-like or None
19
+ The dependent variable data.
20
+ x : array-like or None
21
+ The independent variable data.
22
+ y_eval : array-like or None
23
+ The evaluated y-values of the fitted model.
24
+ x_eval : array-like or None
25
+ The x-values used for evaluation.
26
+ y_eval_components : dict or None
27
+ The evaluated y-values of the model components.
28
+ y_fit_components : dict or None
29
+ The fitted y-values of the model components.
30
+ y_fit : array-like or None
31
+ The fitted y-values of the model.
32
+ x_fit : array-like or None
33
+ The x-values used for fitting.
34
+ y_init_fit : array-like or None
35
+ The initial guess of the y-values.
36
+ params : Parameters or None
37
+ The parameters of the model.
38
+ model_components : Model or list of Models or None
39
+ The model component(s) used for fitting.
40
+ model : Model or None
41
+ The composite model used for fitting.
42
+ modelresult : ModelResult or None
43
+ The result of the model fitting.
44
+ data : NXdata or None
45
+ The 1D linecut data used for analysis.
46
+
47
+ Methods
48
+ -------
49
+ __init__(self, data=None)
50
+ Initialize the LinecutModel.
51
+ set_data(self, data)
52
+ Set the data for analysis.
53
+ set_model_components(self, model_components)
54
+ Set the model components.
55
+ set_param_hint(self, *args, **kwargs)
56
+ Set parameter hints for the model.
57
+ make_params(self)
58
+ Create and initialize the parameters for the model.
59
+ guess(self)
60
+ Perform initial guesses for each model component.
61
+ print_initial_params(self)
62
+ Print out initial guesses for each parameter of the model.
63
+ plot_initial_guess(self, numpoints=None)
64
+ Plot the initial guess.
65
+ fit(self)
66
+ Fit the model to the data.
67
+ plot_fit(self, numpoints=None, fit_report=True, **kwargs)
68
+ Plot the fitted model.
69
+ print_fit_report(self)
70
+ Print the fit report.
71
+ """
72
+ def __init__(self, data=None):
73
+ """
74
+ Initialize the LinecutModel.
75
+ """
76
+ self.y = None
77
+ self.x = None
78
+ self.y_eval = None
79
+ self.x_eval = None
80
+ self.y_eval_components = None
81
+ self.y_fit_components = None
82
+ self.y_fit = None
83
+ self.x_fit = None
84
+ self.y_init_fit = None
85
+ self.params = None
86
+ self.model_components = None
87
+ self.model = None
88
+ self.modelresult = None
89
+ self.data = data if data is not None else None
90
+ if self.data is not None:
91
+ self.x = data[data.axes].nxdata
92
+ self.y = data[data.signal].nxdata
93
+
94
+ def set_data(self, data):
95
+ """
96
+ Set the data for analysis.
97
+
98
+ Parameters
99
+ ----------
100
+ data : NXdata
101
+ The 1D linecut data to be used for analysis.
102
+ """
103
+ self.data = data
104
+ self.x = data[data.axes].nxdata
105
+ self.y = data[data.signal].nxdata
106
+
107
+ def set_model_components(self, model_components):
108
+ """
109
+ Set the model components
110
+
111
+ Parameters
112
+ ----------
113
+ model_components : Model or list of Models
114
+ The model component(s) to be used for fitting, which will be combined into a CompositeModel.
115
+ """
116
+
117
+ # If the model only has one component, then use it as the model
118
+ if isinstance(model_components, Model):
119
+ self.model = model_components
120
+ # Else, combine the components into a composite model and use that as the
121
+ else:
122
+ self.model_components = model_components
123
+ self.model = model_components[0]
124
+
125
+ # Combine remaining components into the composite model
126
+ for component in model_components[1:]:
127
+ self.model = CompositeModel(self.model, component, operator.add)
128
+
129
+ def set_param_hint(self, *args, **kwargs):
130
+ """
131
+ Set parameter hints for the model.
132
+
133
+ Parameters
134
+ ----------
135
+ *args : positional arguments
136
+ Positional arguments passed to the `set_param_hint` method of the underlying model.
137
+
138
+ **kwargs : keyword arguments
139
+ Keyword arguments passed to the `set_param_hint` method of the underlying model.
140
+ """
141
+
142
+ self.model.set_param_hint(*args, **kwargs)
143
+
144
+ def make_params(self):
145
+ """
146
+ Create and initialize the parameters for the model.
147
+
148
+ Returns
149
+ -------
150
+ Parameters
151
+ The initialized parameters for the model.
152
+ """
153
+ # Intialize empty parameters (in function)
154
+ params = self.model.make_params()
155
+ self.params = params
156
+
157
+ return params
158
+
159
+ def guess(self):
160
+ """
161
+ Perform initial guesses for each model component.
162
+ """
163
+ for model_component in list(self.model_components):
164
+ self.params.update(model_component.guess(self.y, x=self.x))
165
+
166
+ def print_initial_params(self):
167
+ """
168
+ Print out initial guesses for each parameter of the model.
169
+ """
170
+ model = self.model
171
+ for param, hint in model.param_hints.items():
172
+ print(f'{param}')
173
+ for key, value in hint.items():
174
+ print(f'\t{key}: {value}')
175
+
176
+ def plot_initial_guess(self, numpoints=None):
177
+ """
178
+ Plot initial guess.
179
+ """
180
+ model = self.model
181
+ params = self.params
182
+ x = self.x
183
+ y = self.y
184
+ y_init_fit = model.eval(params=params, x=x)
185
+ self.y_init_fit = y_init_fit
186
+ plt.plot(x, y, 'o', label='data')
187
+ plt.plot(x, y_init_fit, '--', label='guess')
188
+
189
+ # Plot the components of the model
190
+ if numpoints is None:
191
+ numpoints = len(self.x)
192
+ self.x_eval = np.linspace(self.x.min(), self.x.max(), numpoints)
193
+ y_init_fit_components = model.eval_components(params=params, x=self.x_eval)
194
+ ax = plt.gca()
195
+ for model_component, value in y_init_fit_components.items():
196
+ ax.fill_between(self.x_eval, value, alpha=0.3, label=model_component)
197
+ plt.legend()
198
+ plt.show()
199
+
200
+ def fit(self):
201
+ """
202
+ Fit the model to the data.
203
+
204
+ This method fits the model to the data using the specified parameters and the x-values.
205
+ It updates the model result, fitted y-values, and the evaluated components.
206
+
207
+ """
208
+ self.modelresult = self.model.fit(self.y, self.params, x=self.x)
209
+ self.y_fit = self.modelresult.eval(x=self.x)
210
+ self.y_fit_components = self.modelresult.eval_components(x=self.x)
211
+
212
+ def plot_fit(self, numpoints=None, fit_report=True, **kwargs):
213
+ """
214
+ Plot the fitted model.
215
+
216
+ This method plots the fitted model along with the original data.
217
+ It evaluates the model and its components at the specified number of points (numpoints)
218
+ and plots the results.
219
+
220
+ Parameters
221
+ ----------
222
+ numpoints : int, optional
223
+ Number of points to evaluate the model and its components. If not provided,
224
+ it defaults to the length of the x-values.
225
+
226
+ fit_report : bool, optional
227
+ Whether to print the fit report. Default is True.
228
+
229
+ **kwargs : dict, optional
230
+ Additional keyword arguments to be passed to the `plot` method.
231
+
232
+ Returns
233
+ -------
234
+ ax : matplotlib.axes.Axes
235
+ The Axes object containing the plot.
236
+
237
+ """
238
+ if numpoints is None:
239
+ numpoints = len(self.x)
240
+ self.x_eval = np.linspace(self.x.min(), self.x.max(), numpoints)
241
+ self.y_eval = self.modelresult.eval(x=self.x_eval)
242
+ self.y_eval_components = self.modelresult.eval_components(x=self.x_eval)
243
+ self.modelresult.plot(numpoints=numpoints, **kwargs)
244
+ ax = plt.gca()
245
+ for model_component, value in self.y_eval_components.items():
246
+ ax.fill_between(self.x_eval, value, alpha=0.3, label=model_component)
247
+ # ax.plot(self.x_eval, value, label=model_component)
248
+ plt.legend()
249
+ plt.show()
250
+ if fit_report:
251
+ print(self.modelresult.fit_report())
252
+ return ax
253
+
254
+ def print_fit_report(self):
255
+ """
256
+ Show fit report.
257
+ """
258
+ print(self.modelresult.fit_report())