xarpes 0.1.0__py3-none-any.whl → 0.2.0__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.
- xarpes/.ipynb_checkpoints/__init__-checkpoint.py +13 -0
- xarpes/.ipynb_checkpoints/band_map-checkpoint.py +205 -0
- xarpes/.ipynb_checkpoints/distributions-checkpoint.py +430 -0
- xarpes/.ipynb_checkpoints/functions-checkpoint.py +133 -0
- xarpes/.ipynb_checkpoints/plotting-checkpoint.py +157 -0
- xarpes/__init__.py +1 -1
- xarpes/band_map.py +48 -11
- xarpes/distributions.py +366 -40
- xarpes/functions.py +102 -7
- xarpes/plotting.py +30 -18
- xarpes-0.2.0.dist-info/LICENSE +674 -0
- {xarpes-0.1.0.dist-info → xarpes-0.2.0.dist-info}/METADATA +8 -1
- xarpes-0.2.0.dist-info/RECORD +14 -0
- xarpes-0.1.0.dist-info/LICENSE +0 -339
- xarpes-0.1.0.dist-info/RECORD +0 -9
- {xarpes-0.1.0.dist-info → xarpes-0.2.0.dist-info}/WHEEL +0 -0
xarpes/distributions.py
CHANGED
|
@@ -1,38 +1,361 @@
|
|
|
1
1
|
# Copyright (C) 2024 xARPES Developers
|
|
2
|
-
# This program is free software under the terms of the GNU
|
|
2
|
+
# This program is free software under the terms of the GNU GPLv3 license.
|
|
3
3
|
|
|
4
4
|
"""The distributions used throughout the code."""
|
|
5
5
|
|
|
6
6
|
class distribution:
|
|
7
|
+
r"""Parent class for distributions. The class cannot be used on its own,
|
|
8
|
+
but is used to instantiate unique and non-unique distributions.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
name : str
|
|
13
|
+
Non-unique name for instances, not to be modified after instantiation.
|
|
14
|
+
"""
|
|
7
15
|
def __init__(self, name):
|
|
8
|
-
self.
|
|
16
|
+
self._name = name
|
|
9
17
|
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
@property
|
|
19
|
+
def name(self):
|
|
20
|
+
r"""Returns the name of the class instance.
|
|
12
21
|
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
name : str
|
|
25
|
+
Non-unique name for instances, not to be modified after
|
|
26
|
+
instantiation.
|
|
27
|
+
"""
|
|
28
|
+
return self._name
|
|
13
29
|
|
|
14
30
|
class unique_distribution(distribution):
|
|
31
|
+
r"""Parent class for unique distributions, to be used one at a time, e.g.,
|
|
32
|
+
during the background of an MDC fit or the Fermi-Dirac distribution.
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
label : str
|
|
37
|
+
Unique label for instances, identical to the name for unique
|
|
38
|
+
distributions. Not to be modified after instantiation.
|
|
39
|
+
"""
|
|
15
40
|
def __init__(self, name):
|
|
16
41
|
super().__init__(name)
|
|
17
42
|
self._label = name
|
|
18
43
|
|
|
44
|
+
@property
|
|
19
45
|
def label(self):
|
|
46
|
+
r"""Returns the unique class label.
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
label : str
|
|
51
|
+
Unique label for instances, identical to the name for unique
|
|
52
|
+
distributions. Not to be modified after instantiation.
|
|
53
|
+
"""
|
|
20
54
|
return self._label
|
|
21
55
|
|
|
56
|
+
class constant(unique_distribution):
|
|
57
|
+
r"""Child class for constant distributions, used e.g., during MDC fitting.
|
|
58
|
+
The constant class is unique, only one instance should be used per task.
|
|
59
|
+
|
|
60
|
+
Parameters
|
|
61
|
+
----------
|
|
62
|
+
offset : float
|
|
63
|
+
The value of the distribution for the abscissa equal to 0.
|
|
64
|
+
"""
|
|
65
|
+
def __init__(self, offset):
|
|
66
|
+
super().__init__(name='constant')
|
|
67
|
+
self._offset = offset
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def offset(self):
|
|
71
|
+
r"""Returns the offset of the constant distribution.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
offset : float
|
|
76
|
+
The value of the distribution for the abscissa equal to 0.
|
|
77
|
+
"""
|
|
78
|
+
return self._offset
|
|
79
|
+
|
|
80
|
+
@offset.setter
|
|
81
|
+
def set_offset(self, x):
|
|
82
|
+
r"""Sets the offset of the constant distribution.
|
|
83
|
+
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
offset : float
|
|
87
|
+
The value of the distribution for the abscissa equal to 0.
|
|
88
|
+
"""
|
|
89
|
+
self._offset = x
|
|
90
|
+
|
|
91
|
+
class linear(unique_distribution):
|
|
92
|
+
r"""Child cass for for linear distributions, used e.g., during MDC fitting.
|
|
93
|
+
The constant class is unique, only one instance should be used per task.
|
|
94
|
+
|
|
95
|
+
Parameters
|
|
96
|
+
----------
|
|
97
|
+
offset : float
|
|
98
|
+
The value of the distribution for the abscissa equal to 0.
|
|
99
|
+
slope : float
|
|
100
|
+
The linear slope of the distribution w.r.t. the abscissa.
|
|
101
|
+
"""
|
|
102
|
+
def __init__(self, slope, offset):
|
|
103
|
+
super().__init__(name='linear')
|
|
104
|
+
self._offset = offset
|
|
105
|
+
self._slope = slope
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
def offset(self):
|
|
109
|
+
r"""Returns the offset of the linear distribution.
|
|
110
|
+
|
|
111
|
+
Returns
|
|
112
|
+
-------
|
|
113
|
+
offset : float
|
|
114
|
+
The value of the distribution for the abscissa equal to 0.
|
|
115
|
+
"""
|
|
116
|
+
return self._offset
|
|
117
|
+
|
|
118
|
+
@offset.setter
|
|
119
|
+
def set_offset(self, x):
|
|
120
|
+
r"""Sets the offset of the linear distribution.
|
|
121
|
+
|
|
122
|
+
Parameters
|
|
123
|
+
----------
|
|
124
|
+
offset : float
|
|
125
|
+
The value of the distribution for the abscissa equal to 0.
|
|
126
|
+
"""
|
|
127
|
+
self._offset = x
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def slope(self):
|
|
131
|
+
r"""Returns the slope of the linear distribution.
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
slope : float
|
|
136
|
+
The linear slope of the distribution w.r.t. the abscissa.
|
|
137
|
+
"""
|
|
138
|
+
return self._slope
|
|
139
|
+
|
|
140
|
+
@slope.setter
|
|
141
|
+
def set_slope(self, x):
|
|
142
|
+
r"""Sets the slope of the linear distribution.
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
slope : float
|
|
147
|
+
The linear slope of the distribution w.r.t. the abscissa.
|
|
148
|
+
"""
|
|
149
|
+
self._slope = x
|
|
150
|
+
|
|
151
|
+
class linear(unique_distribution):
|
|
152
|
+
r"""Child cass for for linear distributions, used e.g., during MDC fitting.
|
|
153
|
+
The constant class is unique, only one instance should be used per task.
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
offset : float
|
|
158
|
+
The value of the distribution for the abscissa equal to 0.
|
|
159
|
+
slope : float
|
|
160
|
+
The linear slope of the distribution w.r.t. the abscissa.
|
|
161
|
+
"""
|
|
162
|
+
def __init__(self, slope, offset):
|
|
163
|
+
|
|
164
|
+
super().__init__(name='linear')
|
|
165
|
+
self._offset = offset
|
|
166
|
+
self._slope = slope
|
|
167
|
+
|
|
168
|
+
@property
|
|
169
|
+
def offset(self):
|
|
170
|
+
r"""Returns the offset of the linear distribution.
|
|
171
|
+
|
|
172
|
+
Returns
|
|
173
|
+
-------
|
|
174
|
+
offset : float
|
|
175
|
+
The value of the distribution for the abscissa equal to 0.
|
|
176
|
+
"""
|
|
177
|
+
return self._offset
|
|
178
|
+
|
|
179
|
+
@offset.setter
|
|
180
|
+
def set_offset(self, x):
|
|
181
|
+
r"""Sets the offset of the linear distribution.
|
|
182
|
+
|
|
183
|
+
Parameters
|
|
184
|
+
----------
|
|
185
|
+
offset : float
|
|
186
|
+
The value of the distribution for the abscissa equal to 0.
|
|
187
|
+
"""
|
|
188
|
+
self._offset = x
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def slope(self):
|
|
192
|
+
r"""Returns the slope of the linear distribution.
|
|
193
|
+
|
|
194
|
+
Returns
|
|
195
|
+
-------
|
|
196
|
+
slope : float
|
|
197
|
+
The linear slope of the distribution w.r.t. the abscissa.
|
|
198
|
+
"""
|
|
199
|
+
return self._slope
|
|
200
|
+
|
|
201
|
+
@slope.setter
|
|
202
|
+
def set_slope(self, x):
|
|
203
|
+
r"""Sets the slope of the linear distribution.
|
|
204
|
+
|
|
205
|
+
Parameters
|
|
206
|
+
----------
|
|
207
|
+
slope : float
|
|
208
|
+
The linear slope of the distribution w.r.t. the abscissa.
|
|
209
|
+
"""
|
|
210
|
+
self._slope = x
|
|
22
211
|
|
|
23
212
|
class fermi_dirac(unique_distribution):
|
|
213
|
+
r"""Child class for Fermi-Dirac (FD) distributions, used e.g., during Fermi
|
|
214
|
+
edge fitting. The FD class is unique, only one instance should be used
|
|
215
|
+
per task.
|
|
216
|
+
|
|
217
|
+
The Fermi-Dirac distribution is described by the following formula:
|
|
218
|
+
|
|
219
|
+
.. math::
|
|
220
|
+
|
|
221
|
+
\frac{A}{\rm{e}^{\beta(E_{\rm{kin}}-(h\nu-\Phi))}+1} + B
|
|
222
|
+
|
|
223
|
+
with :math:`A` as :attr:`integrated_weight`, :math:`B` as
|
|
224
|
+
:attr:`background`, :math:`h\nu-\Phi` as :attr:`hnuminphi`, and
|
|
225
|
+
:math:`\beta=1/(k_{\rm{B}}T)` with :math:`T` as :attr:`temperature`.
|
|
226
|
+
|
|
227
|
+
Parameters
|
|
228
|
+
----------
|
|
229
|
+
temperature : float
|
|
230
|
+
Temperature of the sample [K]
|
|
231
|
+
hnuminphi : float
|
|
232
|
+
Kinetic energy minus the work function [eV]
|
|
233
|
+
background : float
|
|
234
|
+
Background spectral weight [counts]
|
|
235
|
+
integrated_weight : float
|
|
236
|
+
Integrated weight on top of the background [counts]
|
|
237
|
+
"""
|
|
24
238
|
def __init__(self, temperature, hnuminphi, background=0,
|
|
25
239
|
integrated_weight=1, name='fermi_dirac'):
|
|
26
|
-
|
|
27
240
|
super().__init__(name)
|
|
28
241
|
self.temperature = temperature
|
|
29
242
|
self.hnuminphi = hnuminphi
|
|
30
243
|
self.background = background
|
|
31
244
|
self.integrated_weight = integrated_weight
|
|
32
|
-
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def temperature(self):
|
|
248
|
+
r"""Returns the temperature of the sample.
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
-------
|
|
252
|
+
temperature : float
|
|
253
|
+
Temperature of the sample [K]
|
|
254
|
+
"""
|
|
255
|
+
return self._temperature
|
|
256
|
+
|
|
257
|
+
@temperature.setter
|
|
258
|
+
def set_temperature(self, x):
|
|
259
|
+
r"""Sets the temperature of the FD distribution.
|
|
260
|
+
|
|
261
|
+
Parameters
|
|
262
|
+
----------
|
|
263
|
+
temperature : float
|
|
264
|
+
Temperature of the sample [K]
|
|
265
|
+
"""
|
|
266
|
+
self._temperature = x
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
def hnuminphi(self):
|
|
270
|
+
r"""Returns the photon energy minus the work function of the FD
|
|
271
|
+
distribution.
|
|
272
|
+
|
|
273
|
+
Returns
|
|
274
|
+
-------
|
|
275
|
+
hnuminphi: float
|
|
276
|
+
Kinetic energy minus the work function [eV]
|
|
277
|
+
"""
|
|
278
|
+
return self._hnuminphi
|
|
279
|
+
|
|
280
|
+
@hnuminphi.setter
|
|
281
|
+
def set_hnuminphi(self, x):
|
|
282
|
+
r"""Sets the photon energy minus the work function of the FD
|
|
283
|
+
distribution.
|
|
284
|
+
|
|
285
|
+
Parameters
|
|
286
|
+
----------
|
|
287
|
+
hnuminphi : float
|
|
288
|
+
Kinetic energy minus the work function [eV]
|
|
289
|
+
"""
|
|
290
|
+
self._hnuminphi = x
|
|
291
|
+
|
|
292
|
+
@property
|
|
293
|
+
def background(self):
|
|
294
|
+
r"""Returns the background intensity of the FD distribution.
|
|
295
|
+
|
|
296
|
+
Returns
|
|
297
|
+
-------
|
|
298
|
+
background : float
|
|
299
|
+
Background spectral weight [counts]
|
|
300
|
+
"""
|
|
301
|
+
return self._background
|
|
302
|
+
|
|
303
|
+
@background.setter
|
|
304
|
+
def set_background(self, x):
|
|
305
|
+
r"""Sets the background intensity of the FD distribution.
|
|
306
|
+
|
|
307
|
+
Parameters
|
|
308
|
+
----------
|
|
309
|
+
background : float
|
|
310
|
+
Background spectral weight [counts]
|
|
311
|
+
"""
|
|
312
|
+
self._background = x
|
|
313
|
+
|
|
314
|
+
@property
|
|
315
|
+
def integrated_weight(self):
|
|
316
|
+
r"""Returns the integrated weight of the FD distribution.
|
|
317
|
+
|
|
318
|
+
Returns
|
|
319
|
+
-------
|
|
320
|
+
integrated_weight: float
|
|
321
|
+
Integrated weight on top of the background [counts]
|
|
322
|
+
"""
|
|
323
|
+
return self._integrated_weight
|
|
324
|
+
|
|
325
|
+
@integrated_weight.setter
|
|
326
|
+
def set_integrated_weight(self, x):
|
|
327
|
+
r"""Sets the integrated weight of the FD distribution.
|
|
328
|
+
|
|
329
|
+
Parameters
|
|
330
|
+
----------
|
|
331
|
+
integrated_weight : float
|
|
332
|
+
Integrated weight on top of the background [counts]
|
|
333
|
+
"""
|
|
334
|
+
self._integrated_weight = x
|
|
33
335
|
|
|
34
336
|
def __call__(self, energy_range, hnuminphi, background, integrated_weight,
|
|
35
337
|
energy_resolution):
|
|
338
|
+
"""Call method to directly evaluate a FD distribution without having to
|
|
339
|
+
instantiate a class instance.
|
|
340
|
+
|
|
341
|
+
Parameters
|
|
342
|
+
----------
|
|
343
|
+
energy_range : ndarray
|
|
344
|
+
1D array on which to evaluate the FD distribution [eV]
|
|
345
|
+
hnuminphi : float
|
|
346
|
+
Kinetic energy minus the work function [eV]
|
|
347
|
+
background : float
|
|
348
|
+
Background spectral weight [counts]
|
|
349
|
+
integrated_weight : float
|
|
350
|
+
Integrated weight on top of the background [counts]
|
|
351
|
+
energy_resolution : float
|
|
352
|
+
Energy resolution of the detector for the convolution [eV]
|
|
353
|
+
|
|
354
|
+
Returns
|
|
355
|
+
-------
|
|
356
|
+
evalf : ndarray
|
|
357
|
+
1D array of the energy-convolved FD distribution [counts]
|
|
358
|
+
"""
|
|
36
359
|
from scipy.ndimage import gaussian_filter
|
|
37
360
|
import numpy as np
|
|
38
361
|
sigma_extend = 5 # Extend data range by "5 sigma"
|
|
@@ -48,17 +371,49 @@ class fermi_dirac(unique_distribution):
|
|
|
48
371
|
len(energy_range) + 2 * enumb)
|
|
49
372
|
result = (integrated_weight / (1 + np.exp((extend - hnuminphi) / k_BT))
|
|
50
373
|
+ background)
|
|
51
|
-
|
|
374
|
+
evalf = gaussian_filter(result, sigma=estep)[enumb:-enumb]
|
|
375
|
+
return evalf
|
|
52
376
|
|
|
53
377
|
def evaluate(self, energy_range):
|
|
378
|
+
r"""Evaluates the FD distribution for a given class instance.
|
|
379
|
+
No energy convolution is performed with evaluate.
|
|
380
|
+
|
|
381
|
+
Parameters
|
|
382
|
+
----------
|
|
383
|
+
energy_range : ndarray
|
|
384
|
+
1D array on which to evaluate the FD distribution [eV]
|
|
385
|
+
|
|
386
|
+
Returns
|
|
387
|
+
-------
|
|
388
|
+
evalf : ndarray
|
|
389
|
+
1D array of the evaluated FD distribution [counts]
|
|
390
|
+
"""
|
|
54
391
|
import numpy as np
|
|
55
392
|
k_B = 8.617e-5 # Boltzmann constant [eV/K]
|
|
56
393
|
k_BT = self.temperature * k_B
|
|
57
|
-
|
|
394
|
+
evalf = (self.integrated_weight
|
|
58
395
|
/ (1 + np.exp((energy_range - self.hnuminphi) / k_BT))
|
|
59
396
|
+ self.background)
|
|
397
|
+
return evalf
|
|
60
398
|
|
|
61
399
|
def convolve(self, energy_range, energy_resolution):
|
|
400
|
+
r"""Evaluates the FD distribution for a given class instance and
|
|
401
|
+
performs the energy convolution with the given resolution. The
|
|
402
|
+
convolution is performed with an expanded abscissa range of 5
|
|
403
|
+
times the standard deviation.
|
|
404
|
+
|
|
405
|
+
Parameters
|
|
406
|
+
----------
|
|
407
|
+
energy_range : ndarray
|
|
408
|
+
1D array on which to evaluate and convolve FD distribution [eV]
|
|
409
|
+
energy_resolution : float
|
|
410
|
+
Energy resolution of the detector for the convolution [eV]
|
|
411
|
+
|
|
412
|
+
Returns
|
|
413
|
+
-------
|
|
414
|
+
evalf : ndarray
|
|
415
|
+
1D array of the energy-convolved FD distribution [counts]
|
|
416
|
+
"""
|
|
62
417
|
import numpy as np
|
|
63
418
|
from scipy.ndimage import gaussian_filter
|
|
64
419
|
sigma_extend = 5 # Extend data range by "5 sigma"
|
|
@@ -70,35 +425,6 @@ class fermi_dirac(unique_distribution):
|
|
|
70
425
|
extend = np.linspace(energy_range[0] - enumb * step_size,
|
|
71
426
|
energy_range[-1] + enumb * step_size,
|
|
72
427
|
len(energy_range) + 2 * enumb)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class constant(unique_distribution):
|
|
77
|
-
def __init__(self, offset):
|
|
78
|
-
super().__init__(name='constant')
|
|
79
|
-
self._offset = offset
|
|
80
|
-
|
|
81
|
-
def offset(self):
|
|
82
|
-
return self._offset
|
|
83
|
-
|
|
84
|
-
def set_offset(self, x):
|
|
85
|
-
self._offset = x
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class linear(unique_distribution):
|
|
89
|
-
def __init__(self, slope, offset):
|
|
90
|
-
super().__init__(name='linear')
|
|
91
|
-
self._offset = offset
|
|
92
|
-
self._slope = slope
|
|
93
|
-
|
|
94
|
-
def offset(self):
|
|
95
|
-
return self._offset
|
|
96
|
-
|
|
97
|
-
def set_offset(self, x):
|
|
98
|
-
self._offset = x
|
|
99
|
-
|
|
100
|
-
def slope(self):
|
|
101
|
-
return self._slope
|
|
102
|
-
|
|
103
|
-
def set_slope(self, x):
|
|
104
|
-
self._slope = x
|
|
428
|
+
evalf = gaussian_filter(self.evaluate(extend),
|
|
429
|
+
sigma=estep)[enumb:-enumb]
|
|
430
|
+
return evalf
|
xarpes/functions.py
CHANGED
|
@@ -1,20 +1,115 @@
|
|
|
1
1
|
# Copyright (C) 2024 xARPES Developers
|
|
2
|
-
# This program is free software under the terms of the GNU
|
|
2
|
+
# This program is free software under the terms of the GNU GPLv3 license.
|
|
3
3
|
|
|
4
|
-
"""Separate functions used in conjunction with various classes."""
|
|
4
|
+
"""Separate functions mostly used in conjunction with various classes."""
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
from
|
|
6
|
+
def download_examples():
|
|
7
|
+
"""Downloads the examples folder from the xARPES code only if it does not
|
|
8
|
+
already exist. Prints executed steps and a final cleanup/failure message.
|
|
9
|
+
|
|
10
|
+
Returns
|
|
11
|
+
-------
|
|
12
|
+
0, 1 : int
|
|
13
|
+
Returns 0 if the execution succeeds, 1 if it fails.
|
|
14
|
+
"""
|
|
15
|
+
import requests
|
|
16
|
+
import zipfile
|
|
17
|
+
import os
|
|
18
|
+
import shutil
|
|
19
|
+
import io
|
|
20
|
+
|
|
21
|
+
repo_url = 'https://github.com/xARPES/xARPES_examples'
|
|
22
|
+
output_dir = '.' # Directory from which the function is called
|
|
23
|
+
|
|
24
|
+
# Check if 'examples' directory already exists
|
|
25
|
+
final_examples_path = os.path.join(output_dir, 'examples')
|
|
26
|
+
if os.path.exists(final_examples_path):
|
|
27
|
+
print("Warning: 'examples' folder already exists. No download will be performed.")
|
|
28
|
+
return 1 # Exit the function if 'examples' directory exists
|
|
29
|
+
|
|
30
|
+
# Proceed with download if 'examples' directory does not exist
|
|
31
|
+
repo_parts = repo_url.replace("https://github.com/", "").rstrip('/')
|
|
32
|
+
zip_url = f"https://github.com/{repo_parts}/archive/refs/heads/main.zip"
|
|
33
|
+
|
|
34
|
+
# Make the HTTP request to download the zip file
|
|
35
|
+
print(f"Downloading {zip_url}")
|
|
36
|
+
response = requests.get(zip_url)
|
|
37
|
+
if response.status_code == 200:
|
|
38
|
+
zip_file_bytes = io.BytesIO(response.content)
|
|
39
|
+
|
|
40
|
+
with zipfile.ZipFile(zip_file_bytes, 'r') as zip_ref:
|
|
41
|
+
zip_ref.extractall(output_dir)
|
|
8
42
|
|
|
9
|
-
|
|
43
|
+
# Path to the extracted main folder
|
|
44
|
+
main_folder_path = os.path.join(output_dir, repo_parts.split('/')[-1] + '-main')
|
|
45
|
+
examples_path = os.path.join(main_folder_path, 'examples')
|
|
46
|
+
|
|
47
|
+
# Move the 'examples' directory to the target location if it was extracted
|
|
48
|
+
if os.path.exists(examples_path):
|
|
49
|
+
shutil.move(examples_path, final_examples_path)
|
|
50
|
+
print(f"'examples' subdirectory moved to {final_examples_path}")
|
|
51
|
+
else:
|
|
52
|
+
print("'examples' subdirectory not found in the repository.")
|
|
53
|
+
|
|
54
|
+
# Remove the rest of the extracted content
|
|
55
|
+
shutil.rmtree(main_folder_path)
|
|
56
|
+
print(f"Cleaned up temporary files in {main_folder_path}")
|
|
57
|
+
return 0
|
|
58
|
+
else:
|
|
59
|
+
print(f"Failed to download the repository. Status code: {response.status_code}")
|
|
60
|
+
return 1
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def error_function(p, xdata, ydata, function, extra_args):
|
|
10
64
|
r"""The error function used inside the fit_leastsq function.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
----------
|
|
68
|
+
p : ndarray
|
|
69
|
+
Array of parameters during the optimization
|
|
70
|
+
xdata : ndarray
|
|
71
|
+
Array of abscissa values the function is evaluated on
|
|
72
|
+
ydata : ndarray
|
|
73
|
+
Outcomes on ordinate the evaluated function is compared to
|
|
74
|
+
function : function
|
|
75
|
+
Function or class with call method to be evaluated
|
|
76
|
+
extra_args :
|
|
77
|
+
Arguments provided to function that should not be optimized
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
residual :
|
|
82
|
+
Residual between evaluated function and ydata
|
|
11
83
|
"""
|
|
12
|
-
|
|
84
|
+
residual = function(xdata, *p, extra_args) - ydata
|
|
85
|
+
return residual
|
|
13
86
|
|
|
14
87
|
|
|
15
88
|
def fit_leastsq(p0, xdata, ydata, function, extra_args):
|
|
16
89
|
r"""Wrapper arround scipy.optimize.leastsq.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
p0 : ndarray
|
|
94
|
+
Initial guess for parameters to be optimized
|
|
95
|
+
xdata : ndarray
|
|
96
|
+
Array of abscissa values the function is evaluated on
|
|
97
|
+
ydata : ndarray
|
|
98
|
+
Outcomes on ordinate the evaluated function is compared to
|
|
99
|
+
function : function
|
|
100
|
+
Function or class with call method to be evaluated
|
|
101
|
+
extra_args :
|
|
102
|
+
Arguments provided to function that should not be optimized
|
|
103
|
+
|
|
104
|
+
Returns
|
|
105
|
+
-------
|
|
106
|
+
pfit_leastsq : ndarray
|
|
107
|
+
Array containing the optimized parameters
|
|
108
|
+
perr_leastsq : ndarray
|
|
109
|
+
Covariance matrix of the optimized parameters
|
|
17
110
|
"""
|
|
111
|
+
import numpy as np
|
|
112
|
+
from scipy.optimize import leastsq
|
|
18
113
|
pfit, pcov, infodict, errmsg, success = leastsq(
|
|
19
114
|
error_function, p0, args=(xdata, ydata, function, extra_args),
|
|
20
115
|
full_output=1)
|
|
@@ -35,4 +130,4 @@ def fit_leastsq(p0, xdata, ydata, function, extra_args):
|
|
|
35
130
|
pfit_leastsq = pfit
|
|
36
131
|
perr_leastsq = np.array(error)
|
|
37
132
|
|
|
38
|
-
return pfit_leastsq, perr_leastsq
|
|
133
|
+
return pfit_leastsq, perr_leastsq
|
xarpes/plotting.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Copyright (C) 2024 xARPES Developers
|
|
2
|
-
# This program is free software under the terms of the GNU
|
|
2
|
+
# This program is free software under the terms of the GNU GPLv3 license.
|
|
3
3
|
|
|
4
4
|
# get_ax_fig_plt and add_fig_kwargs originate from pymatgen/util/plotting.py.
|
|
5
5
|
# Copyright (C) 2011-2024 Shyue Ping Ong and the pymatgen Development Team
|
|
@@ -15,7 +15,7 @@ from functools import wraps
|
|
|
15
15
|
import matplotlib.pyplot as plt
|
|
16
16
|
import matplotlib as mpl
|
|
17
17
|
|
|
18
|
-
def
|
|
18
|
+
def plot_settings(name='default'):
|
|
19
19
|
mpl.rc('xtick', labelsize=10, direction='in')
|
|
20
20
|
mpl.rc('ytick', labelsize=10, direction='in')
|
|
21
21
|
lw = dict(default=2.0, large=4.0)[name]
|
|
@@ -26,20 +26,28 @@ def my_plot_settings(name='default'):
|
|
|
26
26
|
mpl.rcParams['xtick.major.width'] = 0.8
|
|
27
27
|
mpl.rcParams.update({'font.size': 16})
|
|
28
28
|
|
|
29
|
-
|
|
30
29
|
def get_ax_fig_plt(ax=None, **kwargs):
|
|
31
|
-
r"""Helper function used in plot functions supporting an optional Axes
|
|
32
|
-
argument.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
plt
|
|
30
|
+
r"""Helper function used in plot functions supporting an optional `Axes`
|
|
31
|
+
argument.
|
|
32
|
+
|
|
33
|
+
If `ax` is `None`, we build the `matplotlib` figure and create the `Axes`.
|
|
34
|
+
Else we return the current active figure.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
ax : object
|
|
39
|
+
`Axes` object. Defaults to `None`.
|
|
40
|
+
**kwargs
|
|
41
|
+
Keyword arguments are passed to `plt.figure` if `ax` is not `None`.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
ax : object
|
|
46
|
+
`Axes` object.
|
|
47
|
+
figure : object
|
|
48
|
+
`matplotlib` figure.
|
|
49
|
+
plt : object
|
|
50
|
+
`matplotlib.pyplot` module.
|
|
43
51
|
"""
|
|
44
52
|
if ax is None:
|
|
45
53
|
fig = plt.figure(**kwargs)
|
|
@@ -49,7 +57,6 @@ def get_ax_fig_plt(ax=None, **kwargs):
|
|
|
49
57
|
|
|
50
58
|
return ax, fig, plt
|
|
51
59
|
|
|
52
|
-
|
|
53
60
|
def add_fig_kwargs(func):
|
|
54
61
|
"""Decorator that adds keyword arguments for functions returning matplotlib
|
|
55
62
|
figures.
|
|
@@ -115,6 +122,10 @@ def add_fig_kwargs(func):
|
|
|
115
122
|
|
|
116
123
|
# Add docstring to the decorated method.
|
|
117
124
|
doc_str = """\n\n
|
|
125
|
+
|
|
126
|
+
notes
|
|
127
|
+
-----
|
|
128
|
+
|
|
118
129
|
Keyword arguments controlling the display of the figure:
|
|
119
130
|
|
|
120
131
|
================ ====================================================
|
|
@@ -126,7 +137,8 @@ def add_fig_kwargs(func):
|
|
|
126
137
|
size_kwargs Dictionary with options passed to fig.set_size_inches
|
|
127
138
|
e.g. size_kwargs=dict(w=3, h=4)
|
|
128
139
|
tight_layout True to call fig.tight_layout (default: False)
|
|
129
|
-
ax_grid True (False) to add (remove) grid from all axes in
|
|
140
|
+
ax_grid True (False) to add (remove) grid from all axes in
|
|
141
|
+
fig.
|
|
130
142
|
Default: None i.e. fig is left unchanged.
|
|
131
143
|
ax_annotate Add labels to subplots e.g. (a), (b).
|
|
132
144
|
Default: False
|
|
@@ -142,4 +154,4 @@ def add_fig_kwargs(func):
|
|
|
142
154
|
# Use s
|
|
143
155
|
wrapper.__doc__ = doc_str
|
|
144
156
|
|
|
145
|
-
return wrapper
|
|
157
|
+
return wrapper
|