xarpes 0.2.3__tar.gz → 0.2.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: xarpes
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Extraction from angle resolved photoemission spectra
5
5
  Author: xARPES Developers
6
6
  Requires-Python: >=3.7.0
@@ -15,6 +15,7 @@ Requires-Dist: numpy
15
15
  Requires-Dist: scipy
16
16
  Requires-Dist: lmfit
17
17
  Requires-Dist: xarray
18
+ Requires-Dist: pyqt5
18
19
  Project-URL: Documentation, https://xarpes.github.io
19
20
 
20
21
  ![xARPES](https://xarpes.github.io/_images/xarpes.svg)
@@ -24,4 +24,5 @@ dependencies = [
24
24
  "scipy",
25
25
  "lmfit",
26
26
  "xarray",
27
+ "pyqt5",
27
28
  ]
@@ -1,4 +1,4 @@
1
- __version__ = '0.2.3'
1
+ __version__ = '0.2.4'
2
2
 
3
3
  from . import plotting
4
4
 
@@ -17,7 +17,6 @@ from .plotting import get_ax_fig_plt, add_fig_kwargs
17
17
  from .functions import fit_leastsq
18
18
  from .distributions import fermi_dirac
19
19
 
20
-
21
20
  class MDCs():
22
21
  r"""
23
22
  """
@@ -33,14 +32,12 @@ class MDCs():
33
32
  # """
34
33
  # return 0
35
34
 
36
-
37
35
  # @add_fig_kwargs
38
36
  # def fit_fermi_edge(self, hnuminphi_guess, background_guess=0.0,
39
- # integrated_weight_guess=1.0, angle_min=-np.infty,
40
- # angle_max=np.infty, ekin_min=-np.infty,
41
- # ekin_max=np.infty, ax=None, **kwargs):
42
-
43
-
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
+
44
41
  @add_fig_kwargs
45
42
  def plot(self, ax=None, **kwargs):
46
43
  r"""
@@ -48,12 +45,11 @@ class MDCs():
48
45
  ax, fig, plt = get_ax_fig_plt(ax=ax)
49
46
 
50
47
  ax.scatter(self.angles, self.intensities)
51
-
52
- ax.set_xlabel("Angle ($\degree$)")
48
+
49
+ ax.set_xlabel('Angle ($\degree$)')
53
50
  ax.set_ylabel('Counts (-)')
54
-
51
+
55
52
  return fig
56
-
57
53
 
58
54
  class band_map():
59
55
  r"""Class for the band map from the ARPES experiment.
@@ -158,7 +154,6 @@ class band_map():
158
154
  Minimum angle of integration interval [degrees]
159
155
  angle_max : float
160
156
  Maximum angle of integration interval [degrees]
161
-
162
157
 
163
158
  Returns
164
159
  -------
@@ -166,25 +161,25 @@ class band_map():
166
161
  Array of size n containing the angular values
167
162
  energy_range : ndarray
168
163
  Array of size m containing the energy values
169
- mdcs :
164
+ mdcs :
170
165
  Array of size nxm containing the MDC intensities
171
166
  """
172
-
173
- energy_index = np.abs(self.ekin-energy_value).argmin()
174
- angle_min_index = np.abs(self.angles-angle_min).argmin()
175
- angle_max_index = np.abs(self.angles-angle_max).argmin()
176
-
177
- angle_range = self.angles[angle_min_index:angle_max_index+1]
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]
178
173
  energy_range = self.ekin[energy_index]
179
- mdcs = self.intensities[energy_index, angle_min_index:angle_max_index+1]
174
+ mdcs = self.intensities[energy_index,
175
+ angle_min_index:angle_max_index + 1]
180
176
 
181
177
  return mdcs, angle_range, energy_range, self.angular_resolution
182
178
 
183
-
184
179
  @add_fig_kwargs
185
180
  def plot_band_map(self, ax=None, **kwargs):
186
181
  r"""Plots the band map.
187
-
182
+
188
183
  Parameters
189
184
  ----------
190
185
 
@@ -192,29 +187,30 @@ class band_map():
192
187
  ----------------
193
188
  **kwargs : dict, optional
194
189
  Additional arguments passed on to add_fig_kwargs. See the keyword
195
- table below.
190
+ table below.
196
191
 
197
192
  Returns
198
193
  -------
199
194
  fig : Matplotlib-Figure
200
195
  Figure containing the Fermi edge fit
201
- """
196
+ """
202
197
  ax, fig, plt = get_ax_fig_plt(ax=ax)
203
198
 
204
199
  Angl, Ekin = np.meshgrid(self.angles, self.ekin)
205
- mesh = ax.pcolormesh(Angl, Ekin, self.intensities, shading="auto", cmap=plt.get_cmap("bone").reversed())
200
+ mesh = ax.pcolormesh(Angl, Ekin, self.intensities, shading='auto',
201
+ cmap=plt.get_cmap('bone').reversed())
206
202
  cbar = plt.colorbar(mesh, ax=ax)
207
-
208
- ax.set_xlabel("Angle ($\degree$)")
209
- ax.set_ylabel("$E_{\mathrm{kin}}$ (eV)")
210
-
203
+
204
+ ax.set_xlabel('Angle ($\degree$)')
205
+ ax.set_ylabel('$E_{\mathrm{kin}}$ (eV)')
206
+
211
207
  return fig
212
-
208
+
213
209
  @add_fig_kwargs
214
210
  def fit_fermi_edge(self, hnuminphi_guess, background_guess=0.0,
215
- integrated_weight_guess=1.0, angle_min=-np.infty,
216
- angle_max=np.infty, ekin_min=-np.infty,
217
- ekin_max=np.infty, ax=None, **kwargs):
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):
218
214
  r"""Fits the Fermi edge of the band map and plots the result.
219
215
  Also sets hnuminphi, the kinetic energy minus the work function in eV.
220
216
  The fitting includes an energy convolution with an abscissa range
@@ -303,4 +299,4 @@ class band_map():
303
299
 
304
300
  ax.legend()
305
301
 
306
- return fig
302
+ return fig
@@ -29,7 +29,6 @@ class distribution:
29
29
  """
30
30
  return self._name
31
31
 
32
-
33
32
  class unique_distribution(distribution):
34
33
  r"""Parent class for unique distributions, to be used one at a time, e.g.,
35
34
  during the background of an MDC fit or the Fermi-Dirac distribution.
@@ -56,7 +55,6 @@ class unique_distribution(distribution):
56
55
  """
57
56
  return self._label
58
57
 
59
-
60
58
  class constant(unique_distribution):
61
59
  r"""Child class for constant distributions, used e.g., during MDC fitting.
62
60
  The constant class is unique, only one instance should be used per task.
@@ -92,7 +90,6 @@ class constant(unique_distribution):
92
90
  """
93
91
  self._offset = x
94
92
 
95
-
96
93
  class linear(unique_distribution):
97
94
  r"""Child cass for for linear distributions, used e.g., during MDC fitting.
98
95
  The constant class is unique, only one instance should be used per task.
@@ -153,7 +150,6 @@ class linear(unique_distribution):
153
150
  """
154
151
  self._slope = x
155
152
 
156
-
157
153
  class fermi_dirac(unique_distribution):
158
154
  r"""Child class for Fermi-Dirac (FD) distributions, used e.g., during Fermi
159
155
  edge fitting. The FD class is unique, only one instance should be used
@@ -302,7 +298,7 @@ class fermi_dirac(unique_distribution):
302
298
  1D array of the energy-convolved FD distribution [counts]
303
299
  """
304
300
  from scipy.ndimage import gaussian_filter
305
-
301
+
306
302
  sigma_extend = 5 # Extend data range by "5 sigma"
307
303
  # Conversion from FWHM to standard deviation [-]
308
304
  fwhm_to_std = np.sqrt(8 * np.log(2))
@@ -332,7 +328,7 @@ class fermi_dirac(unique_distribution):
332
328
  -------
333
329
  evalf : ndarray
334
330
  1D array of the evaluated FD distribution [counts]
335
- """
331
+ """
336
332
  k_B = 8.617e-5 # Boltzmann constant [eV/K]
337
333
  k_BT = self.temperature * k_B
338
334
  evalf = (self.integrated_weight
@@ -359,7 +355,7 @@ class fermi_dirac(unique_distribution):
359
355
  1D array of the energy-convolved FD distribution [counts]
360
356
  """
361
357
  from scipy.ndimage import gaussian_filter
362
-
358
+
363
359
  sigma_extend = 5 # Extend data range by "5 sigma"
364
360
  # Conversion from FWHM to standard deviation [-]
365
361
  fwhm_to_std = np.sqrt(8 * np.log(2))
@@ -373,7 +369,6 @@ class fermi_dirac(unique_distribution):
373
369
  sigma=estep)[enumb:-enumb]
374
370
  return evalf
375
371
 
376
-
377
372
  class non_unique_distribution(distribution):
378
373
  r"""Parent class for unique distributions, to be used one at a time, e.g.,
379
374
  during the background of an MDC fit or the Fermi-Dirac distribution.
@@ -400,7 +395,6 @@ class non_unique_distribution(distribution):
400
395
  """
401
396
  return self._label
402
397
 
403
-
404
398
  class dispersion(distribution):
405
399
  r"""Dispersions are assumed to be unique, so they need an index.
406
400
  """
@@ -453,13 +447,12 @@ class dispersion(distribution):
453
447
  """
454
448
  self._broadening = x
455
449
 
456
-
457
450
  # class spectral_linear(dispersion):
458
451
  # r"""Class for the linear dispersion spectral function"""
459
452
  # def __init__(self, amplitude, center, broadening, name, index):
460
453
  # super().__init__(amplitude=amplitude, center=center,
461
454
  # broadening=broadening, name=name, index=index)
462
-
455
+
463
456
  # def result(self, x):
464
457
  # r"""
465
458
  # """
@@ -468,10 +461,9 @@ class dispersion(distribution):
468
461
  # - np.sin(self.center*dtor))**2 + self.broadening**2)
469
462
  # return evalf
470
463
 
471
-
472
464
  # class spectral_linear(dispersion):
473
465
  # r"""Class for the linear dispersion spectral function"""
474
- # def __init__(self, amplitude, center, broadening, bottom, side, name,
466
+ # def __init__(self, amplitude, center, broadening, bottom, side, name,
475
467
  # index):
476
468
  # super()__init__(amplitude=amplitude, center=center,
477
469
  # broadening=broadening, name=name, index=index)
@@ -495,11 +487,11 @@ class dispersion(distribution):
495
487
  # r"""
496
488
  # """
497
489
  # return self._side
498
-
490
+
499
491
  # def result(self, x):
500
492
  # r"""
501
493
  # """
502
494
  # dtor = np.pi/180
503
495
  # evalf = self.amplitude / np.pi * self.broadening / (((np.sin(x*dtor)
504
496
  # - np.sin(self.bottom*dtor))**2 - np.sin(self.center*dtor)**2)**2
505
- # + self.broadening**2)
497
+ # + self.broadening**2)
@@ -29,7 +29,6 @@ def error_function(p, xdata, ydata, function, extra_args):
29
29
  residual = function(xdata, *p, extra_args) - ydata
30
30
  return residual
31
31
 
32
-
33
32
  def fit_leastsq(p0, xdata, ydata, function, extra_args):
34
33
  r"""Wrapper arround scipy.optimize.leastsq.
35
34
 
@@ -54,7 +53,7 @@ def fit_leastsq(p0, xdata, ydata, function, extra_args):
54
53
  Covariance matrix of the optimized parameters
55
54
  """
56
55
  from scipy.optimize import leastsq
57
-
56
+
58
57
  pfit, pcov, infodict, errmsg, success = leastsq(
59
58
  error_function, p0, args=(xdata, ydata, function, extra_args),
60
59
  full_output=1)
@@ -76,12 +75,11 @@ def fit_leastsq(p0, xdata, ydata, function, extra_args):
76
75
  perr_leastsq = np.array(error)
77
76
 
78
77
  return pfit_leastsq, perr_leastsq
79
-
80
78
 
81
79
  def download_examples():
82
80
  """Downloads the examples folder from the xARPES code only if it does not
83
81
  already exist. Prints executed steps and a final cleanup/failure message.
84
-
82
+
85
83
  Returns
86
84
  -------
87
85
  0, 1 : int
@@ -92,22 +90,23 @@ def download_examples():
92
90
  import os
93
91
  import shutil
94
92
  import io
95
-
93
+
96
94
  repo_url = 'https://github.com/xARPES/xARPES_examples'
97
- output_dir = '.' # Directory from which the function is called
98
-
95
+ output_dir = '.' # Directory from which the function is called
96
+
99
97
  # Check if 'examples' directory already exists
100
98
  final_examples_path = os.path.join(output_dir, 'examples')
101
99
  if os.path.exists(final_examples_path):
102
- print("Warning: 'examples' folder already exists. No download will be performed.")
100
+ print("Warning: 'examples' folder already exists. \
101
+ No download will be performed.")
103
102
  return 1 # Exit the function if 'examples' directory exists
104
103
 
105
104
  # Proceed with download if 'examples' directory does not exist
106
- repo_parts = repo_url.replace("https://github.com/", "").rstrip('/')
107
- zip_url = f"https://github.com/{repo_parts}/archive/refs/heads/main.zip"
105
+ repo_parts = repo_url.replace('https://github.com/', '').rstrip('/')
106
+ zip_url = f'https://github.com/{repo_parts}/archive/refs/heads/main.zip'
108
107
 
109
108
  # Make the HTTP request to download the zip file
110
- print(f"Downloading {zip_url}")
109
+ print(f'Downloading {zip_url}')
111
110
  response = requests.get(zip_url)
112
111
  if response.status_code == 200:
113
112
  zip_file_bytes = io.BytesIO(response.content)
@@ -116,10 +115,12 @@ def download_examples():
116
115
  zip_ref.extractall(output_dir)
117
116
 
118
117
  # Path to the extracted main folder
119
- main_folder_path = os.path.join(output_dir, repo_parts.split('/')[-1] + '-main')
118
+ main_folder_path = os.path.join(output_dir,
119
+ repo_parts.split('/')[-1]
120
+ + '-main')
120
121
  examples_path = os.path.join(main_folder_path, 'examples')
121
122
 
122
- # Move the 'examples' directory to the target location if it was extracted
123
+ # Move the 'examples' directory to the target location
123
124
  if os.path.exists(examples_path):
124
125
  shutil.move(examples_path, final_examples_path)
125
126
  print(f"'examples' subdirectory moved to {final_examples_path}")
@@ -128,8 +129,9 @@ def download_examples():
128
129
 
129
130
  # Remove the rest of the extracted content
130
131
  shutil.rmtree(main_folder_path)
131
- print(f"Cleaned up temporary files in {main_folder_path}")
132
+ print(f'Cleaned up temporary files in {main_folder_path}')
132
133
  return 0
133
134
  else:
134
- print(f"Failed to download the repository. Status code: {response.status_code}")
135
- return 1
135
+ print(f'Failed to download the repository. Status code: \
136
+ {response.status_code}')
137
+ return 1
@@ -26,7 +26,6 @@ def plot_settings(name='default'):
26
26
  mpl.rcParams['xtick.major.width'] = 0.8
27
27
  mpl.rcParams.update({'font.size': 16})
28
28
  mpl.use('Qt5Agg') # Backend for showing plots in terminal
29
-
30
29
 
31
30
  def get_ax_fig_plt(ax=None, **kwargs):
32
31
  r"""Helper function used in plot functions supporting an optional `Axes`
File without changes
File without changes