xarpes 0.2.2__py3-none-any.whl → 0.2.4__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 +2 -7
- xarpes/__init__.py +1 -1
- xarpes/band_map.py +107 -10
- xarpes/distributions.py +136 -69
- xarpes/functions.py +63 -59
- xarpes/plotting.py +1 -0
- {xarpes-0.2.2.dist-info → xarpes-0.2.4.dist-info}/METADATA +4 -2
- xarpes-0.2.4.dist-info/RECORD +10 -0
- xarpes/.ipynb_checkpoints/band_map-checkpoint.py +0 -205
- xarpes/.ipynb_checkpoints/distributions-checkpoint.py +0 -430
- xarpes/.ipynb_checkpoints/functions-checkpoint.py +0 -133
- xarpes/.ipynb_checkpoints/plotting-checkpoint.py +0 -157
- xarpes-0.2.2.dist-info/RECORD +0 -14
- {xarpes-0.2.2.dist-info → xarpes-0.2.4.dist-info}/LICENSE +0 -0
- {xarpes-0.2.2.dist-info → xarpes-0.2.4.dist-info}/WHEEL +0 -0
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
__version__ = '0.
|
|
1
|
+
__version__ = '0.2.2'
|
|
2
2
|
|
|
3
3
|
from . import plotting
|
|
4
4
|
|
|
5
5
|
from .band_map import *
|
|
6
6
|
from .distributions import *
|
|
7
7
|
from .functions import *
|
|
8
|
-
from .plotting import *
|
|
9
|
-
|
|
10
|
-
# from . import plotting
|
|
11
|
-
# from xarpes.plotting import *
|
|
12
|
-
# from xarpes.distributions import *
|
|
13
|
-
# from xarpes.distributions import fermi_dirac
|
|
8
|
+
from .plotting import *
|
xarpes/__init__.py
CHANGED
xarpes/band_map.py
CHANGED
|
@@ -12,9 +12,45 @@
|
|
|
12
12
|
"""The band map class and allowed operations on it."""
|
|
13
13
|
|
|
14
14
|
import numpy as np
|
|
15
|
+
|
|
15
16
|
from .plotting import get_ax_fig_plt, add_fig_kwargs
|
|
17
|
+
from .functions import fit_leastsq
|
|
16
18
|
from .distributions import fermi_dirac
|
|
17
19
|
|
|
20
|
+
class MDCs():
|
|
21
|
+
r"""
|
|
22
|
+
"""
|
|
23
|
+
def __init__(self, intensities, angles, ekin, angular_resolution):
|
|
24
|
+
self.intensities = intensities
|
|
25
|
+
self.angles = angles
|
|
26
|
+
self.ekin = ekin
|
|
27
|
+
self.angular_resolution = angular_resolution
|
|
28
|
+
|
|
29
|
+
# @add_fig_kwargs
|
|
30
|
+
# def fit(self):
|
|
31
|
+
# r"""
|
|
32
|
+
# """
|
|
33
|
+
# return 0
|
|
34
|
+
|
|
35
|
+
# @add_fig_kwargs
|
|
36
|
+
# def fit_fermi_edge(self, hnuminphi_guess, background_guess=0.0,
|
|
37
|
+
# integrated_weight_guess=1.0, angle_min=-np.inf,
|
|
38
|
+
# angle_max=np.inf, ekin_min=-np.inf,
|
|
39
|
+
# ekin_max=np.inf, ax=None, **kwargs):
|
|
40
|
+
|
|
41
|
+
@add_fig_kwargs
|
|
42
|
+
def plot(self, ax=None, **kwargs):
|
|
43
|
+
r"""
|
|
44
|
+
"""
|
|
45
|
+
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
46
|
+
|
|
47
|
+
ax.scatter(self.angles, self.intensities)
|
|
48
|
+
|
|
49
|
+
ax.set_xlabel('Angle ($\degree$)')
|
|
50
|
+
ax.set_ylabel('Counts (-)')
|
|
51
|
+
|
|
52
|
+
return fig
|
|
53
|
+
|
|
18
54
|
class band_map():
|
|
19
55
|
r"""Class for the band map from the ARPES experiment.
|
|
20
56
|
|
|
@@ -26,7 +62,9 @@ class band_map():
|
|
|
26
62
|
1D array of angular values for the abscissa [degrees]
|
|
27
63
|
ekin : ndarray
|
|
28
64
|
1D array of kinetic energy values for the ordinate [eV]
|
|
29
|
-
|
|
65
|
+
angular_resolution : float, None
|
|
66
|
+
Angular resolution of the detector [degrees]
|
|
67
|
+
energy_resolution : float, None
|
|
30
68
|
Energy resolution of the detector [eV]
|
|
31
69
|
temperature : float, None
|
|
32
70
|
Temperature of the sample [K]
|
|
@@ -36,11 +74,13 @@ class band_map():
|
|
|
36
74
|
Standard deviation of kinetic energy minus work function [eV]
|
|
37
75
|
"""
|
|
38
76
|
def __init__(self, intensities, angles, ekin, energy_resolution=None,
|
|
39
|
-
|
|
77
|
+
angular_resolution=None, temperature=None, hnuminphi=None,
|
|
78
|
+
hnuminphi_std=None):
|
|
40
79
|
self.intensities = intensities
|
|
41
80
|
self.angles = angles
|
|
42
81
|
self.ekin = ekin
|
|
43
82
|
self.energy_resolution = energy_resolution
|
|
83
|
+
self.angular_resolution = angular_resolution
|
|
44
84
|
self.temperature = temperature
|
|
45
85
|
self.hnuminphi = hnuminphi
|
|
46
86
|
self.hnuminphi_std = hnuminphi_std
|
|
@@ -106,13 +146,72 @@ class band_map():
|
|
|
106
146
|
"""
|
|
107
147
|
self.angles = self.angles + shift
|
|
108
148
|
|
|
149
|
+
def slice(self, angle_min, angle_max, energy_value):
|
|
150
|
+
r"""
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
angle_min : float
|
|
154
|
+
Minimum angle of integration interval [degrees]
|
|
155
|
+
angle_max : float
|
|
156
|
+
Maximum angle of integration interval [degrees]
|
|
157
|
+
|
|
158
|
+
Returns
|
|
159
|
+
-------
|
|
160
|
+
angle_range : ndarray
|
|
161
|
+
Array of size n containing the angular values
|
|
162
|
+
energy_range : ndarray
|
|
163
|
+
Array of size m containing the energy values
|
|
164
|
+
mdcs :
|
|
165
|
+
Array of size nxm containing the MDC intensities
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
energy_index = np.abs(self.ekin - energy_value).argmin()
|
|
169
|
+
angle_min_index = np.abs(self.angles - angle_min).argmin()
|
|
170
|
+
angle_max_index = np.abs(self.angles - angle_max).argmin()
|
|
171
|
+
|
|
172
|
+
angle_range = self.angles[angle_min_index:angle_max_index + 1]
|
|
173
|
+
energy_range = self.ekin[energy_index]
|
|
174
|
+
mdcs = self.intensities[energy_index,
|
|
175
|
+
angle_min_index:angle_max_index + 1]
|
|
176
|
+
|
|
177
|
+
return mdcs, angle_range, energy_range, self.angular_resolution
|
|
178
|
+
|
|
179
|
+
@add_fig_kwargs
|
|
180
|
+
def plot_band_map(self, ax=None, **kwargs):
|
|
181
|
+
r"""Plots the band map.
|
|
182
|
+
|
|
183
|
+
Parameters
|
|
184
|
+
----------
|
|
185
|
+
|
|
186
|
+
Other parameters
|
|
187
|
+
----------------
|
|
188
|
+
**kwargs : dict, optional
|
|
189
|
+
Additional arguments passed on to add_fig_kwargs. See the keyword
|
|
190
|
+
table below.
|
|
191
|
+
|
|
192
|
+
Returns
|
|
193
|
+
-------
|
|
194
|
+
fig : Matplotlib-Figure
|
|
195
|
+
Figure containing the Fermi edge fit
|
|
196
|
+
"""
|
|
197
|
+
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
198
|
+
|
|
199
|
+
Angl, Ekin = np.meshgrid(self.angles, self.ekin)
|
|
200
|
+
mesh = ax.pcolormesh(Angl, Ekin, self.intensities, shading='auto',
|
|
201
|
+
cmap=plt.get_cmap('bone').reversed())
|
|
202
|
+
cbar = plt.colorbar(mesh, ax=ax)
|
|
203
|
+
|
|
204
|
+
ax.set_xlabel('Angle ($\degree$)')
|
|
205
|
+
ax.set_ylabel('$E_{\mathrm{kin}}$ (eV)')
|
|
206
|
+
|
|
207
|
+
return fig
|
|
208
|
+
|
|
109
209
|
@add_fig_kwargs
|
|
110
210
|
def fit_fermi_edge(self, hnuminphi_guess, background_guess=0.0,
|
|
111
|
-
integrated_weight_guess=1.0, angle_min=-np.
|
|
112
|
-
angle_max=np.
|
|
113
|
-
ekin_max=np.
|
|
114
|
-
r"""
|
|
115
|
-
Fits the Fermi edge of the band map and plots the result.
|
|
211
|
+
integrated_weight_guess=1.0, angle_min=-np.inf,
|
|
212
|
+
angle_max=np.inf, ekin_min=-np.inf,
|
|
213
|
+
ekin_max=np.inf, ax=None, **kwargs):
|
|
214
|
+
r"""Fits the Fermi edge of the band map and plots the result.
|
|
116
215
|
Also sets hnuminphi, the kinetic energy minus the work function in eV.
|
|
117
216
|
The fitting includes an energy convolution with an abscissa range
|
|
118
217
|
expanded by 5 times the energy resolution standard deviation.
|
|
@@ -148,8 +247,6 @@ class band_map():
|
|
|
148
247
|
fig : Matplotlib-Figure
|
|
149
248
|
Figure containing the Fermi edge fit
|
|
150
249
|
"""
|
|
151
|
-
from xarpes.functions import fit_leastsq
|
|
152
|
-
|
|
153
250
|
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
154
251
|
|
|
155
252
|
min_angle_index = np.argmin(np.abs(self.angles - angle_min))
|
|
@@ -202,4 +299,4 @@ class band_map():
|
|
|
202
299
|
|
|
203
300
|
ax.legend()
|
|
204
301
|
|
|
205
|
-
return fig
|
|
302
|
+
return fig
|
xarpes/distributions.py
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
"""The distributions used throughout the code."""
|
|
5
5
|
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
6
8
|
class distribution:
|
|
7
9
|
r"""Parent class for distributions. The class cannot be used on its own,
|
|
8
10
|
but is used to instantiate unique and non-unique distributions.
|
|
@@ -62,8 +64,8 @@ class constant(unique_distribution):
|
|
|
62
64
|
offset : float
|
|
63
65
|
The value of the distribution for the abscissa equal to 0.
|
|
64
66
|
"""
|
|
65
|
-
def __init__(self, offset):
|
|
66
|
-
super().__init__(name
|
|
67
|
+
def __init__(self, offset, name='constant'):
|
|
68
|
+
super().__init__(name)
|
|
67
69
|
self._offset = offset
|
|
68
70
|
|
|
69
71
|
@property
|
|
@@ -99,69 +101,8 @@ class linear(unique_distribution):
|
|
|
99
101
|
slope : float
|
|
100
102
|
The linear slope of the distribution w.r.t. the abscissa.
|
|
101
103
|
"""
|
|
102
|
-
def __init__(self, slope, offset):
|
|
103
|
-
super().__init__(name
|
|
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')
|
|
104
|
+
def __init__(self, slope, offset, name='linear'):
|
|
105
|
+
super().__init__(name)
|
|
165
106
|
self._offset = offset
|
|
166
107
|
self._slope = slope
|
|
167
108
|
|
|
@@ -357,7 +298,7 @@ class fermi_dirac(unique_distribution):
|
|
|
357
298
|
1D array of the energy-convolved FD distribution [counts]
|
|
358
299
|
"""
|
|
359
300
|
from scipy.ndimage import gaussian_filter
|
|
360
|
-
|
|
301
|
+
|
|
361
302
|
sigma_extend = 5 # Extend data range by "5 sigma"
|
|
362
303
|
# Conversion from FWHM to standard deviation [-]
|
|
363
304
|
fwhm_to_std = np.sqrt(8 * np.log(2))
|
|
@@ -388,7 +329,6 @@ class fermi_dirac(unique_distribution):
|
|
|
388
329
|
evalf : ndarray
|
|
389
330
|
1D array of the evaluated FD distribution [counts]
|
|
390
331
|
"""
|
|
391
|
-
import numpy as np
|
|
392
332
|
k_B = 8.617e-5 # Boltzmann constant [eV/K]
|
|
393
333
|
k_BT = self.temperature * k_B
|
|
394
334
|
evalf = (self.integrated_weight
|
|
@@ -414,8 +354,8 @@ class fermi_dirac(unique_distribution):
|
|
|
414
354
|
evalf : ndarray
|
|
415
355
|
1D array of the energy-convolved FD distribution [counts]
|
|
416
356
|
"""
|
|
417
|
-
import numpy as np
|
|
418
357
|
from scipy.ndimage import gaussian_filter
|
|
358
|
+
|
|
419
359
|
sigma_extend = 5 # Extend data range by "5 sigma"
|
|
420
360
|
# Conversion from FWHM to standard deviation [-]
|
|
421
361
|
fwhm_to_std = np.sqrt(8 * np.log(2))
|
|
@@ -427,4 +367,131 @@ class fermi_dirac(unique_distribution):
|
|
|
427
367
|
len(energy_range) + 2 * enumb)
|
|
428
368
|
evalf = gaussian_filter(self.evaluate(extend),
|
|
429
369
|
sigma=estep)[enumb:-enumb]
|
|
430
|
-
return evalf
|
|
370
|
+
return evalf
|
|
371
|
+
|
|
372
|
+
class non_unique_distribution(distribution):
|
|
373
|
+
r"""Parent class for unique distributions, to be used one at a time, e.g.,
|
|
374
|
+
during the background of an MDC fit or the Fermi-Dirac distribution.
|
|
375
|
+
|
|
376
|
+
Parameters
|
|
377
|
+
----------
|
|
378
|
+
label : str
|
|
379
|
+
Unique label for instances, identical to the name for unique
|
|
380
|
+
distributions. Not to be modified after instantiation.
|
|
381
|
+
"""
|
|
382
|
+
def __init__(self, name, index):
|
|
383
|
+
super().__init__(name)
|
|
384
|
+
self._label = name + index
|
|
385
|
+
|
|
386
|
+
@property
|
|
387
|
+
def label(self):
|
|
388
|
+
r"""Returns the unique class label.
|
|
389
|
+
|
|
390
|
+
Returns
|
|
391
|
+
-------
|
|
392
|
+
label : str
|
|
393
|
+
Unique label for instances, identical to the name for unique
|
|
394
|
+
distributions. Not to be modified after instantiation.
|
|
395
|
+
"""
|
|
396
|
+
return self._label
|
|
397
|
+
|
|
398
|
+
class dispersion(distribution):
|
|
399
|
+
r"""Dispersions are assumed to be unique, so they need an index.
|
|
400
|
+
"""
|
|
401
|
+
def __init__(self, amplitude, center, broadening, name, index):
|
|
402
|
+
super().__init__(name)
|
|
403
|
+
self._amplitude = amplitude
|
|
404
|
+
self._center = center
|
|
405
|
+
self._broadening = broadening
|
|
406
|
+
self._label = name + index
|
|
407
|
+
|
|
408
|
+
@property
|
|
409
|
+
def label(self):
|
|
410
|
+
r"""
|
|
411
|
+
"""
|
|
412
|
+
return self._label
|
|
413
|
+
|
|
414
|
+
@property
|
|
415
|
+
def amplitude(self):
|
|
416
|
+
r"""
|
|
417
|
+
"""
|
|
418
|
+
return self._amplitude
|
|
419
|
+
|
|
420
|
+
@amplitude.setter
|
|
421
|
+
def set_amplitude(self, x):
|
|
422
|
+
r"""
|
|
423
|
+
"""
|
|
424
|
+
self._amplitude = x
|
|
425
|
+
|
|
426
|
+
@property
|
|
427
|
+
def center(self):
|
|
428
|
+
r"""
|
|
429
|
+
"""
|
|
430
|
+
return self._center
|
|
431
|
+
|
|
432
|
+
@amplitude.setter
|
|
433
|
+
def set_center(self, x):
|
|
434
|
+
r"""
|
|
435
|
+
"""
|
|
436
|
+
self._center = x
|
|
437
|
+
|
|
438
|
+
@property
|
|
439
|
+
def broadening(self):
|
|
440
|
+
r"""
|
|
441
|
+
"""
|
|
442
|
+
return self._broadening
|
|
443
|
+
|
|
444
|
+
@broadening.setter
|
|
445
|
+
def set_broadening(self, x):
|
|
446
|
+
r"""
|
|
447
|
+
"""
|
|
448
|
+
self._broadening = x
|
|
449
|
+
|
|
450
|
+
# class spectral_linear(dispersion):
|
|
451
|
+
# r"""Class for the linear dispersion spectral function"""
|
|
452
|
+
# def __init__(self, amplitude, center, broadening, name, index):
|
|
453
|
+
# super().__init__(amplitude=amplitude, center=center,
|
|
454
|
+
# broadening=broadening, name=name, index=index)
|
|
455
|
+
|
|
456
|
+
# def result(self, x):
|
|
457
|
+
# r"""
|
|
458
|
+
# """
|
|
459
|
+
# dtor = np.pi/180
|
|
460
|
+
# evalf = self.amplitude / np.pi * self.broadening / ((np.sin(x*dtor)
|
|
461
|
+
# - np.sin(self.center*dtor))**2 + self.broadening**2)
|
|
462
|
+
# return evalf
|
|
463
|
+
|
|
464
|
+
# class spectral_linear(dispersion):
|
|
465
|
+
# r"""Class for the linear dispersion spectral function"""
|
|
466
|
+
# def __init__(self, amplitude, center, broadening, bottom, side, name,
|
|
467
|
+
# index):
|
|
468
|
+
# super()__init__(amplitude=amplitude, center=center,
|
|
469
|
+
# broadening=broadening, name=name, index=index)
|
|
470
|
+
# self._bottom = bottom
|
|
471
|
+
# self._side = side
|
|
472
|
+
|
|
473
|
+
# @property
|
|
474
|
+
# def bottom(self):
|
|
475
|
+
# r"""
|
|
476
|
+
# """
|
|
477
|
+
# return self._bottom
|
|
478
|
+
|
|
479
|
+
# @bottom.setter
|
|
480
|
+
# def set_bottom(self, x):
|
|
481
|
+
# r"""
|
|
482
|
+
# """
|
|
483
|
+
# self._bottom = x
|
|
484
|
+
|
|
485
|
+
# @property
|
|
486
|
+
# def side(self):
|
|
487
|
+
# r"""
|
|
488
|
+
# """
|
|
489
|
+
# return self._side
|
|
490
|
+
|
|
491
|
+
# def result(self, x):
|
|
492
|
+
# r"""
|
|
493
|
+
# """
|
|
494
|
+
# dtor = np.pi/180
|
|
495
|
+
# evalf = self.amplitude / np.pi * self.broadening / (((np.sin(x*dtor)
|
|
496
|
+
# - np.sin(self.bottom*dtor))**2 - np.sin(self.center*dtor)**2)**2
|
|
497
|
+
# + self.broadening**2)
|
xarpes/functions.py
CHANGED
|
@@ -3,62 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
"""Separate functions mostly used in conjunction with various classes."""
|
|
5
5
|
|
|
6
|
-
|
|
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)
|
|
42
|
-
|
|
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
|
-
|
|
6
|
+
import numpy as np
|
|
62
7
|
|
|
63
8
|
def error_function(p, xdata, ydata, function, extra_args):
|
|
64
9
|
r"""The error function used inside the fit_leastsq function.
|
|
@@ -84,7 +29,6 @@ def error_function(p, xdata, ydata, function, extra_args):
|
|
|
84
29
|
residual = function(xdata, *p, extra_args) - ydata
|
|
85
30
|
return residual
|
|
86
31
|
|
|
87
|
-
|
|
88
32
|
def fit_leastsq(p0, xdata, ydata, function, extra_args):
|
|
89
33
|
r"""Wrapper arround scipy.optimize.leastsq.
|
|
90
34
|
|
|
@@ -108,8 +52,8 @@ def fit_leastsq(p0, xdata, ydata, function, extra_args):
|
|
|
108
52
|
perr_leastsq : ndarray
|
|
109
53
|
Covariance matrix of the optimized parameters
|
|
110
54
|
"""
|
|
111
|
-
import numpy as np
|
|
112
55
|
from scipy.optimize import leastsq
|
|
56
|
+
|
|
113
57
|
pfit, pcov, infodict, errmsg, success = leastsq(
|
|
114
58
|
error_function, p0, args=(xdata, ydata, function, extra_args),
|
|
115
59
|
full_output=1)
|
|
@@ -130,4 +74,64 @@ def fit_leastsq(p0, xdata, ydata, function, extra_args):
|
|
|
130
74
|
pfit_leastsq = pfit
|
|
131
75
|
perr_leastsq = np.array(error)
|
|
132
76
|
|
|
133
|
-
return pfit_leastsq, perr_leastsq
|
|
77
|
+
return pfit_leastsq, perr_leastsq
|
|
78
|
+
|
|
79
|
+
def download_examples():
|
|
80
|
+
"""Downloads the examples folder from the xARPES code only if it does not
|
|
81
|
+
already exist. Prints executed steps and a final cleanup/failure message.
|
|
82
|
+
|
|
83
|
+
Returns
|
|
84
|
+
-------
|
|
85
|
+
0, 1 : int
|
|
86
|
+
Returns 0 if the execution succeeds, 1 if it fails.
|
|
87
|
+
"""
|
|
88
|
+
import requests
|
|
89
|
+
import zipfile
|
|
90
|
+
import os
|
|
91
|
+
import shutil
|
|
92
|
+
import io
|
|
93
|
+
|
|
94
|
+
repo_url = 'https://github.com/xARPES/xARPES_examples'
|
|
95
|
+
output_dir = '.' # Directory from which the function is called
|
|
96
|
+
|
|
97
|
+
# Check if 'examples' directory already exists
|
|
98
|
+
final_examples_path = os.path.join(output_dir, 'examples')
|
|
99
|
+
if os.path.exists(final_examples_path):
|
|
100
|
+
print("Warning: 'examples' folder already exists. \
|
|
101
|
+
No download will be performed.")
|
|
102
|
+
return 1 # Exit the function if 'examples' directory exists
|
|
103
|
+
|
|
104
|
+
# Proceed with download if 'examples' directory does not exist
|
|
105
|
+
repo_parts = repo_url.replace('https://github.com/', '').rstrip('/')
|
|
106
|
+
zip_url = f'https://github.com/{repo_parts}/archive/refs/heads/main.zip'
|
|
107
|
+
|
|
108
|
+
# Make the HTTP request to download the zip file
|
|
109
|
+
print(f'Downloading {zip_url}')
|
|
110
|
+
response = requests.get(zip_url)
|
|
111
|
+
if response.status_code == 200:
|
|
112
|
+
zip_file_bytes = io.BytesIO(response.content)
|
|
113
|
+
|
|
114
|
+
with zipfile.ZipFile(zip_file_bytes, 'r') as zip_ref:
|
|
115
|
+
zip_ref.extractall(output_dir)
|
|
116
|
+
|
|
117
|
+
# Path to the extracted main folder
|
|
118
|
+
main_folder_path = os.path.join(output_dir,
|
|
119
|
+
repo_parts.split('/')[-1]
|
|
120
|
+
+ '-main')
|
|
121
|
+
examples_path = os.path.join(main_folder_path, 'examples')
|
|
122
|
+
|
|
123
|
+
# Move the 'examples' directory to the target location
|
|
124
|
+
if os.path.exists(examples_path):
|
|
125
|
+
shutil.move(examples_path, final_examples_path)
|
|
126
|
+
print(f"'examples' subdirectory moved to {final_examples_path}")
|
|
127
|
+
else:
|
|
128
|
+
print("'examples' subdirectory not found in the repository.")
|
|
129
|
+
|
|
130
|
+
# Remove the rest of the extracted content
|
|
131
|
+
shutil.rmtree(main_folder_path)
|
|
132
|
+
print(f'Cleaned up temporary files in {main_folder_path}')
|
|
133
|
+
return 0
|
|
134
|
+
else:
|
|
135
|
+
print(f'Failed to download the repository. Status code: \
|
|
136
|
+
{response.status_code}')
|
|
137
|
+
return 1
|
xarpes/plotting.py
CHANGED
|
@@ -25,6 +25,7 @@ def plot_settings(name='default'):
|
|
|
25
25
|
mpl.rcParams['xtick.minor.size'] = 2
|
|
26
26
|
mpl.rcParams['xtick.major.width'] = 0.8
|
|
27
27
|
mpl.rcParams.update({'font.size': 16})
|
|
28
|
+
mpl.use('Qt5Agg') # Backend for showing plots in terminal
|
|
28
29
|
|
|
29
30
|
def get_ax_fig_plt(ax=None, **kwargs):
|
|
30
31
|
r"""Helper function used in plot functions supporting an optional `Axes`
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: xarpes
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Extraction from angle resolved photoemission spectra
|
|
5
5
|
Author: xARPES Developers
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.7.0
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
8
|
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -14,6 +14,8 @@ Requires-Dist: matplotlib
|
|
|
14
14
|
Requires-Dist: numpy
|
|
15
15
|
Requires-Dist: scipy
|
|
16
16
|
Requires-Dist: lmfit
|
|
17
|
+
Requires-Dist: xarray
|
|
18
|
+
Requires-Dist: pyqt5
|
|
17
19
|
Project-URL: Documentation, https://xarpes.github.io
|
|
18
20
|
|
|
19
21
|

|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
xarpes/__init__.py,sha256=WD-CqxsgBL8lK0Cv_uMuRSprM2iV0mwJxclRvmgNxbU,149
|
|
2
|
+
xarpes/band_map.py,sha256=jLmGJe7WmDGP7nV2ekEua5mzDZ6JuobZ9-XG7WM48YA,10402
|
|
3
|
+
xarpes/distributions.py,sha256=mfh_OJPFXq1H1_SYtB3qLyxe4CJCl-aKhdNQkjIHBrE,15148
|
|
4
|
+
xarpes/functions.py,sha256=mQxOh2CEPSDcjGxStBnpQXe3aJOdLkgrjsQacv1wXJs,4624
|
|
5
|
+
xarpes/plotting.py,sha256=vGCF9-v1YzxdSRYMAkl0HwsZiG3eG_CWpf4WdZ4s3hU,5405
|
|
6
|
+
xarpes/.ipynb_checkpoints/__init__-checkpoint.py,sha256=Xi1H3Jn5vt_8WQhSTRqb9hSBhv12fTXEnQrKVdkFGcw,148
|
|
7
|
+
xarpes-0.2.4.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
8
|
+
xarpes-0.2.4.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
|
9
|
+
xarpes-0.2.4.dist-info/METADATA,sha256=WoXPKwGrRLQUMOskZv2QMx0vIcThcjl6J6yFKGBqck8,3910
|
|
10
|
+
xarpes-0.2.4.dist-info/RECORD,,
|