xarpes 0.3.4__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/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
- kilo = 1e3 # 1000 [-]
6
- uncr = 1.95996398 # Standard deviation to 95 % confidence [-]
7
- k_B = 8.617333e-5 # Boltzmann constant [eV / K]
8
- pref = 3.80998211616 # hbar^2 / (2 m_e) [eV Angstrom^2]
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 k_B, pref, dtor
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
- hnuminphi=None, matrix_element=None, matrix_args=None, ax=None,
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 hnuminphi is None):
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 hnuminphi.')
124
+ 'a kinetic energy and hnuminPhi.')
125
125
  extended_result = dist.evaluate(extend,
126
- kinetic_energy, hnuminphi)
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
- hnuminphi=None, matrix_element=None, matrix_args=None,
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, hnuminphi)
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:`hnuminphi`, and
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
- hnuminphi : float
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, hnuminphi, background=0,
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.hnuminphi = hnuminphi
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 hnuminphi(self):
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
- hnuminphi: float
296
+ hnuminPhi: float
297
297
  Kinetic energy minus the work function [eV]
298
298
  """
299
- return self._hnuminphi
299
+ return self._hnuminPhi
300
300
 
301
- @hnuminphi.setter
302
- def hnuminphi(self, x):
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
- hnuminphi : float
308
+ hnuminPhi : float
309
309
  Kinetic energy minus the work function [eV]
310
310
  """
311
- self._hnuminphi = x
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, hnuminphi, background, integrated_weight,
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
- hnuminphi : float
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 * k_B
380
+ k_BT = temperature * K_B
381
381
 
382
- return (integrated_weight / (1 + np.exp((energy_range - hnuminphi)
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 * k_B
399
+ k_BT = self.temperature * K_B
400
400
 
401
401
  return (self.integrated_weight
402
- / (1 + np.exp((energy_range - self.hnuminphi) / k_BT))
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 / ((np.sin(angle_range * dtor)
645
- - np.sin(peak * dtor)) ** 2 + broadening ** 2)
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 * dtor) - np.sin(self.peak * dtor)) ** 2 +
653
- self.broadening ** 2)
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, hnuminphi, center_wavevector=None,
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(pref / kinetic_energy)
715
- * center_wavevector) / dtor
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(hnuminphi /
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 * dtor)
722
- - np.sin(binding_angle * dtor)) ** 2 - np.sin(peak * dtor) ** 2)
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, hnuminphi):
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(pref / kinetic_energy)
730
- * self.center_wavevector) / dtor
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(hnuminphi /
734
+ binding_angle = self.center_angle * np.sqrt(hnuminPhi /
734
735
  kinetic_energy)
735
736
 
736
- return self.amplitude / np.pi * self.broadening / (((np.sin(
737
- angle_range * dtor) - np.sin(binding_angle * dtor)) ** 2 - np.sin(
738
- self.peak * dtor) ** 2) ** 2 + self.broadening ** 2)
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, hnuminphi,
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, hnuminphi)
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, hnuminphi, matrix_element=None,
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__) == 'SpectralQuadratic':
124
- part = dist.evaluate(extend, kinetic_energy, hnuminphi)
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 * fwhm_to_std)
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