xarpes 0.4.0__py3-none-any.whl → 0.5.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/__init__.py +35 -5
- xarpes/bandmap.py +829 -0
- xarpes/constants.py +9 -8
- xarpes/distributions.py +45 -43
- xarpes/functions.py +18 -6
- xarpes/mdcs.py +1035 -0
- xarpes/plotting.py +1 -47
- xarpes/selfenergies.py +621 -0
- xarpes/settings_parameters.py +30 -0
- xarpes/settings_plots.py +54 -0
- {xarpes-0.4.0.dist-info → xarpes-0.5.0.dist-info}/METADATA +5 -4
- xarpes-0.5.0.dist-info/RECORD +15 -0
- {xarpes-0.4.0.dist-info → xarpes-0.5.0.dist-info}/WHEEL +1 -1
- xarpes/spectral.py +0 -2476
- xarpes-0.4.0.dist-info/RECORD +0 -11
- {xarpes-0.4.0.dist-info/licenses → xarpes-0.5.0.dist-info}/LICENSE +0 -0
- {xarpes-0.4.0.dist-info → xarpes-0.5.0.dist-info}/entry_points.txt +0 -0
xarpes/constants.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# Copyright (C) 2025 xARPES Developers
|
|
2
2
|
# This program is free software under the terms of the GNU GPLv3 license.
|
|
3
3
|
|
|
4
|
+
"""Constants used elsewhere in xARPES."""
|
|
5
|
+
|
|
6
|
+
from scipy.constants import Boltzmann, elementary_charge, hbar, m_e
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
4
9
|
# Physical constants
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
dtor = 0.01745329252 # Degrees to radians - pi / 180 [rad / deg]
|
|
10
|
-
fwhm_to_std = 2.35482004503 # Convert FWHM to std, sqrt[8 \times ln(2)] [-]
|
|
11
|
-
sigma_extend = 5 # Extend data range by "5 sigma"
|
|
12
|
-
stdv = 1.959963984 # "2 sigma" Gaussian STD - scipy.stats.norm.ppf(0.975)
|
|
10
|
+
KILO = 1e3 # 1000 [-]
|
|
11
|
+
FWHM2STD = np.sqrt(8 * np.log(2)) # Convert FWHM to std [-]
|
|
12
|
+
K_B = Boltzmann / elementary_charge # Boltzmann constant [eV / K]
|
|
13
|
+
PREF = (hbar**2 / (2 * m_e)) / elementary_charge * 1e20 # hbar^2 / (2 m_e) [eV Angstrom^2]
|
xarpes/distributions.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
from .functions import extend_function
|
|
8
8
|
from .plotting import get_ax_fig_plt, add_fig_kwargs
|
|
9
|
-
from .constants import
|
|
9
|
+
from .constants import K_B, PREF
|
|
10
10
|
|
|
11
11
|
class CreateDistributions:
|
|
12
12
|
r"""
|
|
@@ -95,7 +95,7 @@ class CreateDistributions:
|
|
|
95
95
|
|
|
96
96
|
@add_fig_kwargs
|
|
97
97
|
def plot(self, angle_range, angle_resolution, kinetic_energy=None,
|
|
98
|
-
|
|
98
|
+
hnuminPhi=None, matrix_element=None, matrix_args=None, ax=None,
|
|
99
99
|
**kwargs):
|
|
100
100
|
r"""
|
|
101
101
|
"""
|
|
@@ -118,12 +118,12 @@ class CreateDistributions:
|
|
|
118
118
|
for dist in self.distributions:
|
|
119
119
|
if dist.class_name == 'SpectralQuadratic':
|
|
120
120
|
if (dist.center_angle is not None) and (kinetic_energy is
|
|
121
|
-
None or
|
|
121
|
+
None or hnuminPhi is None):
|
|
122
122
|
raise ValueError('Spectral quadratic function is '
|
|
123
123
|
'defined in terms of a center angle. Please provide '
|
|
124
|
-
'a kinetic energy and
|
|
124
|
+
'a kinetic energy and hnuminPhi.')
|
|
125
125
|
extended_result = dist.evaluate(extend,
|
|
126
|
-
kinetic_energy,
|
|
126
|
+
kinetic_energy, hnuminPhi)
|
|
127
127
|
else:
|
|
128
128
|
extended_result = dist.evaluate(extend)
|
|
129
129
|
|
|
@@ -171,7 +171,7 @@ class Distribution:
|
|
|
171
171
|
|
|
172
172
|
@add_fig_kwargs
|
|
173
173
|
def plot(self, angle_range, angle_resolution, kinetic_energy=None,
|
|
174
|
-
|
|
174
|
+
hnuminPhi=None, matrix_element=None, matrix_args=None,
|
|
175
175
|
ax=None, **kwargs):
|
|
176
176
|
r"""Overwritten for FermiDirac distribution.
|
|
177
177
|
"""
|
|
@@ -188,7 +188,7 @@ class Distribution:
|
|
|
188
188
|
extend, step, numb = extend_function(angle_range, angle_resolution)
|
|
189
189
|
|
|
190
190
|
if self.class_name == 'SpectralQuadratic':
|
|
191
|
-
extended_result = self.evaluate(extend, kinetic_energy,
|
|
191
|
+
extended_result = self.evaluate(extend, kinetic_energy, hnuminPhi)
|
|
192
192
|
else:
|
|
193
193
|
extended_result = self.evaluate(extend)
|
|
194
194
|
|
|
@@ -242,25 +242,25 @@ class FermiDirac(UniqueDistribution):
|
|
|
242
242
|
\frac{A}{\rm{e}^{\beta(E_{\rm{kin}}-(h\nu-\Phi))}+1} + B
|
|
243
243
|
|
|
244
244
|
with :math:`A` as :attr:`integrated_weight`, :math:`B` as
|
|
245
|
-
:attr:`background`, :math:`h\nu-\Phi` as :attr:`
|
|
245
|
+
:attr:`background`, :math:`h\nu-\Phi` as :attr:`hnuminPhi`, and
|
|
246
246
|
:math:`\beta=1/(k_{\rm{B}}T)` with :math:`T` as :attr:`temperature`.
|
|
247
247
|
|
|
248
248
|
Parameters
|
|
249
249
|
----------
|
|
250
250
|
temperature : float
|
|
251
251
|
Temperature of the sample [K]
|
|
252
|
-
|
|
252
|
+
hnuminPhi : float
|
|
253
253
|
Kinetic energy minus the work function [eV]
|
|
254
254
|
background : float
|
|
255
255
|
Background spectral weight [counts]
|
|
256
256
|
integrated_weight : float
|
|
257
257
|
Integrated weight on top of the background [counts]
|
|
258
258
|
"""
|
|
259
|
-
def __init__(self, temperature,
|
|
259
|
+
def __init__(self, temperature, hnuminPhi, background=0,
|
|
260
260
|
integrated_weight=1, name='FermiDirac'):
|
|
261
261
|
super().__init__(name)
|
|
262
262
|
self.temperature = temperature
|
|
263
|
-
self.
|
|
263
|
+
self.hnuminPhi = hnuminPhi
|
|
264
264
|
self.background = background
|
|
265
265
|
self.integrated_weight = integrated_weight
|
|
266
266
|
|
|
@@ -287,28 +287,28 @@ class FermiDirac(UniqueDistribution):
|
|
|
287
287
|
self._temperature = x
|
|
288
288
|
|
|
289
289
|
@property
|
|
290
|
-
def
|
|
290
|
+
def hnuminPhi(self):
|
|
291
291
|
r"""Returns the photon energy minus the work function of the FD
|
|
292
292
|
distribution.
|
|
293
293
|
|
|
294
294
|
Returns
|
|
295
295
|
-------
|
|
296
|
-
|
|
296
|
+
hnuminPhi: float
|
|
297
297
|
Kinetic energy minus the work function [eV]
|
|
298
298
|
"""
|
|
299
|
-
return self.
|
|
299
|
+
return self._hnuminPhi
|
|
300
300
|
|
|
301
|
-
@
|
|
302
|
-
def
|
|
301
|
+
@hnuminPhi.setter
|
|
302
|
+
def hnuminPhi(self, x):
|
|
303
303
|
r"""Sets the photon energy minus the work function of the FD
|
|
304
304
|
distribution.
|
|
305
305
|
|
|
306
306
|
Parameters
|
|
307
307
|
----------
|
|
308
|
-
|
|
308
|
+
hnuminPhi : float
|
|
309
309
|
Kinetic energy minus the work function [eV]
|
|
310
310
|
"""
|
|
311
|
-
self.
|
|
311
|
+
self._hnuminPhi = x
|
|
312
312
|
|
|
313
313
|
@property
|
|
314
314
|
def background(self):
|
|
@@ -354,7 +354,7 @@ class FermiDirac(UniqueDistribution):
|
|
|
354
354
|
"""
|
|
355
355
|
self._integrated_weight = x
|
|
356
356
|
|
|
357
|
-
def __call__(self, energy_range,
|
|
357
|
+
def __call__(self, energy_range, hnuminPhi, background, integrated_weight,
|
|
358
358
|
temperature):
|
|
359
359
|
"""Call method to directly evaluate a FD distribution without having to
|
|
360
360
|
instantiate a class instance.
|
|
@@ -363,7 +363,7 @@ class FermiDirac(UniqueDistribution):
|
|
|
363
363
|
----------
|
|
364
364
|
energy_range : ndarray
|
|
365
365
|
1D array on which to evaluate the FD distribution [eV]
|
|
366
|
-
|
|
366
|
+
hnuminPhi : float
|
|
367
367
|
Kinetic energy minus the work function [eV]
|
|
368
368
|
background : float
|
|
369
369
|
Background spectral weight [counts]
|
|
@@ -377,9 +377,9 @@ class FermiDirac(UniqueDistribution):
|
|
|
377
377
|
evalf : ndarray
|
|
378
378
|
1D array of the energy-convolved FD distribution [counts]
|
|
379
379
|
"""
|
|
380
|
-
k_BT = temperature *
|
|
380
|
+
k_BT = temperature * K_B
|
|
381
381
|
|
|
382
|
-
return (integrated_weight / (1 + np.exp((energy_range -
|
|
382
|
+
return (integrated_weight / (1 + np.exp((energy_range - hnuminPhi)
|
|
383
383
|
/ k_BT)) + background)
|
|
384
384
|
|
|
385
385
|
def evaluate(self, energy_range):
|
|
@@ -396,10 +396,10 @@ class FermiDirac(UniqueDistribution):
|
|
|
396
396
|
evalf : ndarray
|
|
397
397
|
1D array of the evaluated FD distribution [counts]
|
|
398
398
|
"""
|
|
399
|
-
k_BT = self.temperature *
|
|
399
|
+
k_BT = self.temperature * K_B
|
|
400
400
|
|
|
401
401
|
return (self.integrated_weight
|
|
402
|
-
/ (1 + np.exp((energy_range - self.
|
|
402
|
+
/ (1 + np.exp((energy_range - self.hnuminPhi) / k_BT))
|
|
403
403
|
+ self.background)
|
|
404
404
|
|
|
405
405
|
@add_fig_kwargs
|
|
@@ -641,16 +641,17 @@ class SpectralLinear(Dispersion):
|
|
|
641
641
|
peak):
|
|
642
642
|
r"""
|
|
643
643
|
"""
|
|
644
|
-
result = amplitude / np.pi * broadening /
|
|
645
|
-
|
|
644
|
+
result = amplitude / np.pi * broadening / \
|
|
645
|
+
((np.sin(np.deg2rad(angle_range)) - np.sin(np.deg2rad(peak)))**2 \
|
|
646
|
+
+ broadening ** 2)
|
|
646
647
|
return result
|
|
647
648
|
|
|
648
649
|
def evaluate(self, angle_range):
|
|
649
650
|
r"""
|
|
650
651
|
"""
|
|
651
652
|
return self.amplitude / np.pi * self.broadening / ((np.sin(
|
|
652
|
-
angle_range
|
|
653
|
-
self.broadening
|
|
653
|
+
np.deg2rad(angle_range)) - np.sin(np.deg2rad(self.peak)))** 2 +
|
|
654
|
+
self.broadening** 2)
|
|
654
655
|
|
|
655
656
|
|
|
656
657
|
class SpectralQuadratic(Dispersion):
|
|
@@ -704,41 +705,42 @@ class SpectralQuadratic(Dispersion):
|
|
|
704
705
|
'energies. Please check again.')
|
|
705
706
|
|
|
706
707
|
def __call__(self, angle_range, amplitude, broadening,
|
|
707
|
-
peak, kinetic_energy,
|
|
708
|
+
peak, kinetic_energy, hnuminPhi, center_wavevector=None,
|
|
708
709
|
center_angle=None):
|
|
709
710
|
r"""TBD
|
|
710
711
|
"""
|
|
711
712
|
self.check_center_coordinates(center_wavevector, center_angle)
|
|
712
713
|
|
|
713
714
|
if center_wavevector is not None:
|
|
714
|
-
binding_angle = np.arcsin(np.sqrt(
|
|
715
|
-
* center_wavevector)
|
|
715
|
+
binding_angle = np.rad2deg(np.arcsin(np.sqrt(PREF / kinetic_energy)
|
|
716
|
+
* center_wavevector))
|
|
716
717
|
self.check_binding_angle(binding_angle)
|
|
717
718
|
elif center_angle is not None:
|
|
718
|
-
binding_angle = self.center_angle * np.sqrt(
|
|
719
|
+
binding_angle = self.center_angle * np.sqrt(hnuminPhi /
|
|
719
720
|
kinetic_energy)
|
|
720
721
|
|
|
721
|
-
return amplitude / np.pi * broadening / (((np.sin(angle_range
|
|
722
|
-
- np.sin(binding_angle
|
|
722
|
+
return amplitude / np.pi * broadening / (((np.sin(np.deg2rad(angle_range))
|
|
723
|
+
- np.sin(np.deg2rad(binding_angle)))** 2 - np.sin(np.deg2rad(peak))** 2)
|
|
723
724
|
** 2 + broadening ** 2)
|
|
724
725
|
|
|
725
|
-
def evaluate(self, angle_range, kinetic_energy,
|
|
726
|
+
def evaluate(self, angle_range, kinetic_energy, hnuminPhi):
|
|
726
727
|
r"""TBD
|
|
727
728
|
"""
|
|
728
729
|
if self.center_wavevector is not None:
|
|
729
|
-
binding_angle = np.arcsin(np.sqrt(
|
|
730
|
-
* self.center_wavevector)
|
|
730
|
+
binding_angle = np.rad2deg(np.arcsin(np.sqrt(PREF / kinetic_energy)
|
|
731
|
+
* self.center_wavevector))
|
|
731
732
|
self.check_binding_angle(binding_angle)
|
|
732
733
|
elif self.center_angle is not None:
|
|
733
|
-
binding_angle = self.center_angle * np.sqrt(
|
|
734
|
+
binding_angle = self.center_angle * np.sqrt(hnuminPhi /
|
|
734
735
|
kinetic_energy)
|
|
735
736
|
|
|
736
|
-
return self.amplitude / np.pi * self.broadening /
|
|
737
|
-
|
|
738
|
-
|
|
737
|
+
return self.amplitude / np.pi * self.broadening / \
|
|
738
|
+
(((np.sin(np.deg2rad(angle_range)) - \
|
|
739
|
+
np.sin(np.deg2rad(binding_angle)))**2 - \
|
|
740
|
+
np.sin(np.deg2rad(self.peak))**2)**2 + self.broadening**2)
|
|
739
741
|
|
|
740
742
|
@add_fig_kwargs
|
|
741
|
-
def plot(self, angle_range, angle_resolution, kinetic_energy,
|
|
743
|
+
def plot(self, angle_range, angle_resolution, kinetic_energy, hnuminPhi,
|
|
742
744
|
matrix_element=None, matrix_args=None, ax=None, **kwargs):
|
|
743
745
|
r"""Overwrites generic class plotting method.
|
|
744
746
|
"""
|
|
@@ -751,7 +753,7 @@ class SpectralQuadratic(Dispersion):
|
|
|
751
753
|
|
|
752
754
|
extend, step, numb = extend_function(angle_range, angle_resolution)
|
|
753
755
|
|
|
754
|
-
extended_result = self.evaluate(extend, kinetic_energy,
|
|
756
|
+
extended_result = self.evaluate(extend, kinetic_energy, hnuminPhi)
|
|
755
757
|
|
|
756
758
|
if matrix_element is not None:
|
|
757
759
|
extended_result *= matrix_element(extend, **matrix_args)
|
xarpes/functions.py
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
"""Separate functions mostly used in conjunction with various classes."""
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
|
-
from .constants import fwhm_to_std, sigma_extend
|
|
8
7
|
|
|
9
8
|
def resolve_param_name(params, label, pname):
|
|
10
9
|
"""
|
|
@@ -100,7 +99,7 @@ def construct_parameters(distribution_list, matrix_args=None):
|
|
|
100
99
|
|
|
101
100
|
|
|
102
101
|
def residual(parameters, xdata, ydata, angle_resolution, new_distributions,
|
|
103
|
-
kinetic_energy,
|
|
102
|
+
kinetic_energy, hnuminPhi, matrix_element=None,
|
|
104
103
|
element_names=None):
|
|
105
104
|
r"""
|
|
106
105
|
"""
|
|
@@ -120,8 +119,9 @@ def residual(parameters, xdata, ydata, angle_resolution, new_distributions,
|
|
|
120
119
|
model = np.zeros_like(extend)
|
|
121
120
|
|
|
122
121
|
for dist in new_distributions:
|
|
123
|
-
if getattr(dist, 'class_name', type(dist).__name__) ==
|
|
124
|
-
|
|
122
|
+
if getattr(dist, 'class_name', type(dist).__name__) == \
|
|
123
|
+
'SpectralQuadratic':
|
|
124
|
+
part = dist.evaluate(extend, kinetic_energy, hnuminPhi)
|
|
125
125
|
else:
|
|
126
126
|
part = dist.evaluate(extend)
|
|
127
127
|
|
|
@@ -137,9 +137,11 @@ def residual(parameters, xdata, ydata, angle_resolution, new_distributions,
|
|
|
137
137
|
def extend_function(abscissa_range, abscissa_resolution):
|
|
138
138
|
r"""TBD
|
|
139
139
|
"""
|
|
140
|
+
from .constants import FWHM2STD
|
|
141
|
+
from . import settings_parameters as xprs
|
|
140
142
|
step_size = np.abs(abscissa_range[1] - abscissa_range[0])
|
|
141
|
-
step = abscissa_resolution / (step_size *
|
|
142
|
-
numb = int(sigma_extend * step)
|
|
143
|
+
step = abscissa_resolution / (step_size * FWHM2STD)
|
|
144
|
+
numb = int(xprs.sigma_extend * step)
|
|
143
145
|
extend = np.linspace(abscissa_range[0] - numb * step_size,
|
|
144
146
|
abscissa_range[-1] + numb * step_size,
|
|
145
147
|
len(abscissa_range) + 2 * numb)
|
|
@@ -238,6 +240,16 @@ def fit_leastsq(p0, xdata, ydata, function, resolution=None,
|
|
|
238
240
|
return pfit, pcov
|
|
239
241
|
|
|
240
242
|
|
|
243
|
+
def MEM_core():
|
|
244
|
+
r"""
|
|
245
|
+
Extracts the unscaled Eliashberg function for a given value of the Lagrange
|
|
246
|
+
multiplier alpha. It also returns the reconstruction F.
|
|
247
|
+
In essence, this function applies the Newton method to solve
|
|
248
|
+
"""
|
|
249
|
+
return 0
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
241
253
|
def download_examples():
|
|
242
254
|
"""Downloads the examples folder from the main xARPES repository only if it
|
|
243
255
|
does not already exist in the current directory. Prints executed steps and a
|