xarpes 0.3.4__py3-none-any.whl → 0.4.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 +2 -2
- xarpes/plotting.py +31 -1
- xarpes/spectral.py +360 -59
- {xarpes-0.3.4.dist-info → xarpes-0.4.0.dist-info}/METADATA +3 -3
- xarpes-0.4.0.dist-info/RECORD +11 -0
- xarpes-0.3.4.dist-info/RECORD +0 -11
- {xarpes-0.3.4.dist-info → xarpes-0.4.0.dist-info}/WHEEL +0 -0
- {xarpes-0.3.4.dist-info → xarpes-0.4.0.dist-info}/entry_points.txt +0 -0
- {xarpes-0.3.4.dist-info → xarpes-0.4.0.dist-info}/licenses/LICENSE +0 -0
xarpes/__init__.py
CHANGED
xarpes/plotting.py
CHANGED
|
@@ -12,14 +12,19 @@
|
|
|
12
12
|
"""Functions related to plotting."""
|
|
13
13
|
|
|
14
14
|
from functools import wraps
|
|
15
|
+
from IPython import get_ipython
|
|
15
16
|
import matplotlib.pyplot as plt
|
|
16
17
|
import matplotlib as mpl
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
|
|
20
|
+
def plot_settings(name='default', register_pre_run=True):
|
|
21
|
+
"""Configure default plotting style for xARPES."""
|
|
22
|
+
|
|
19
23
|
mpl.rc('xtick', labelsize=10, direction='in')
|
|
20
24
|
mpl.rc('ytick', labelsize=10, direction='in')
|
|
21
25
|
plt.rcParams['legend.frameon'] = False
|
|
22
26
|
lw = dict(default=2.0, large=4.0)[name]
|
|
27
|
+
|
|
23
28
|
mpl.rcParams.update({
|
|
24
29
|
'lines.linewidth': lw,
|
|
25
30
|
'lines.markersize': 3,
|
|
@@ -30,6 +35,31 @@ def plot_settings(name='default'):
|
|
|
30
35
|
'axes.ymargin': 0.15,
|
|
31
36
|
})
|
|
32
37
|
|
|
38
|
+
if register_pre_run:
|
|
39
|
+
_maybe_register_pre_run_close_all()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _maybe_register_pre_run_close_all():
|
|
43
|
+
"""Register a pre_run_cell hook once, and only inside Jupyter."""
|
|
44
|
+
|
|
45
|
+
# Create the function attribute on first call
|
|
46
|
+
if not hasattr(_maybe_register_pre_run_close_all, "_registered"):
|
|
47
|
+
_maybe_register_pre_run_close_all._registered = False
|
|
48
|
+
|
|
49
|
+
if _maybe_register_pre_run_close_all._registered:
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
ip = get_ipython()
|
|
53
|
+
if ip is None or ip.__class__.__name__ != "ZMQInteractiveShell":
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
def _close_all(_info):
|
|
57
|
+
plt.close('all')
|
|
58
|
+
|
|
59
|
+
ip.events.register('pre_run_cell', _close_all)
|
|
60
|
+
_maybe_register_pre_run_close_all._registered = True
|
|
61
|
+
|
|
62
|
+
|
|
33
63
|
def get_ax_fig_plt(ax=None, **kwargs):
|
|
34
64
|
r"""Helper function used in plot functions supporting an optional `Axes`
|
|
35
65
|
argument.
|
xarpes/spectral.py
CHANGED
|
@@ -346,20 +346,41 @@ class BandMap:
|
|
|
346
346
|
return mdcs, angle_range_out, self.angle_resolution, \
|
|
347
347
|
enel_range_out, self.hnuminphi
|
|
348
348
|
|
|
349
|
-
|
|
350
349
|
@add_fig_kwargs
|
|
351
350
|
def plot(self, abscissa='momentum', ordinate='electron_energy',
|
|
352
|
-
self_energies=None, ax=None, markersize=None,
|
|
351
|
+
self_energies=None, ax=None, markersize=None,
|
|
352
|
+
plot_dispersions='none', **kwargs):
|
|
353
353
|
r"""
|
|
354
|
-
Plot the band map. Optionally
|
|
354
|
+
Plot the band map. Optionally overlay a collection of self-energies,
|
|
355
355
|
e.g. a CreateSelfEnergies instance or any iterable of self-energy
|
|
356
|
-
objects.
|
|
356
|
+
objects. Self-energies are *not* stored internally; they are used
|
|
357
|
+
only for this plotting call.
|
|
357
358
|
|
|
358
359
|
When self-energies are present and ``abscissa='momentum'``, their
|
|
359
360
|
MDC maxima are overlaid with 95 % confidence intervals.
|
|
361
|
+
|
|
362
|
+
The `plot_dispersions` argument controls bare-band plotting:
|
|
363
|
+
|
|
364
|
+
- "full" : use the full momentum range of the map (default)
|
|
365
|
+
- "none" : do not plot bare dispersions
|
|
366
|
+
- "kink" : for each self-energy, use the min/max of its own
|
|
367
|
+
momentum range (typically its MDC maxima), with
|
|
368
|
+
`len(self.angles)` points.
|
|
369
|
+
- "domain" : for SpectralQuadratic, use only the left or right
|
|
370
|
+
domain relative to `center_wavevector`, based on the self-energy
|
|
371
|
+
attribute `side` ("left" / "right"); for other cases this behaves
|
|
372
|
+
as "full".
|
|
360
373
|
"""
|
|
361
374
|
import warnings
|
|
362
375
|
|
|
376
|
+
plot_disp_mode = plot_dispersions
|
|
377
|
+
valid_disp_modes = ('full', 'none', 'kink', 'domain')
|
|
378
|
+
if plot_disp_mode not in valid_disp_modes:
|
|
379
|
+
raise ValueError(
|
|
380
|
+
f"Invalid plot_dispersions '{plot_disp_mode}'. "
|
|
381
|
+
f"Valid options: {valid_disp_modes}."
|
|
382
|
+
)
|
|
383
|
+
|
|
363
384
|
valid_abscissa = ('angle', 'momentum')
|
|
364
385
|
valid_ordinate = ('kinetic_energy', 'electron_energy')
|
|
365
386
|
|
|
@@ -374,114 +395,247 @@ class BandMap:
|
|
|
374
395
|
f"Valid options: {valid_ordinate}"
|
|
375
396
|
)
|
|
376
397
|
|
|
377
|
-
# Optionally store self-energies on the instance
|
|
378
398
|
if self_energies is not None:
|
|
379
399
|
|
|
380
400
|
# MDC maxima are defined in momentum space, not angle space
|
|
381
|
-
if abscissa == 'angle'
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if not isinstance(self_energies, CreateSelfEnergies):
|
|
389
|
-
self_energies = CreateSelfEnergies(self_energies)
|
|
390
|
-
|
|
391
|
-
self._self_energies = self_energies
|
|
392
|
-
elif not hasattr(self, "_self_energies"):
|
|
393
|
-
self._self_energies = None
|
|
401
|
+
if abscissa == 'angle':
|
|
402
|
+
raise ValueError(
|
|
403
|
+
"MDC maxima cannot be plotted against angles; they are "
|
|
404
|
+
"defined in momentum space. Use abscissa='momentum' "
|
|
405
|
+
"when passing self-energies."
|
|
406
|
+
)
|
|
394
407
|
|
|
395
408
|
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
396
|
-
# Below, **kwargs is
|
|
397
409
|
|
|
398
410
|
Angl, Ekin = np.meshgrid(self.angles, self.ekin)
|
|
399
|
-
|
|
411
|
+
|
|
400
412
|
if abscissa == 'angle':
|
|
401
413
|
ax.set_xlabel('Angle ($\\degree$)')
|
|
402
414
|
if ordinate == 'kinetic_energy':
|
|
403
|
-
mesh = ax.pcolormesh(
|
|
404
|
-
|
|
405
|
-
|
|
415
|
+
mesh = ax.pcolormesh(
|
|
416
|
+
Angl, Ekin, self.intensities,
|
|
417
|
+
shading='auto',
|
|
418
|
+
cmap=plt.get_cmap('bone').reversed())
|
|
406
419
|
ax.set_ylabel('$E_{\\mathrm{kin}}$ (eV)')
|
|
407
420
|
elif ordinate == 'electron_energy':
|
|
408
421
|
Enel = Ekin - self.hnuminphi
|
|
409
|
-
mesh = ax.pcolormesh(
|
|
410
|
-
|
|
411
|
-
|
|
422
|
+
mesh = ax.pcolormesh(
|
|
423
|
+
Angl, Enel, self.intensities,
|
|
424
|
+
shading='auto',
|
|
425
|
+
cmap=plt.get_cmap('bone').reversed())
|
|
412
426
|
ax.set_ylabel('$E-\\mu$ (eV)')
|
|
413
427
|
|
|
414
428
|
elif abscissa == 'momentum':
|
|
415
429
|
ax.set_xlabel(r'$k_{//}$ ($\mathrm{\AA}^{-1}$)')
|
|
416
430
|
|
|
417
431
|
with warnings.catch_warnings(record=True) as wlist:
|
|
418
|
-
warnings.filterwarnings(
|
|
419
|
-
|
|
432
|
+
warnings.filterwarnings(
|
|
433
|
+
"always",
|
|
434
|
+
message=(
|
|
435
|
+
"The input coordinates to pcolormesh are "
|
|
420
436
|
"interpreted as cell centers, but are not "
|
|
421
|
-
"monotonically increasing or decreasing."
|
|
422
|
-
|
|
437
|
+
"monotonically increasing or decreasing."
|
|
438
|
+
),
|
|
439
|
+
category=UserWarning,
|
|
440
|
+
)
|
|
423
441
|
|
|
424
442
|
Mome = np.sqrt(Ekin / pref) * np.sin(Angl * dtor)
|
|
443
|
+
mome_min = np.min(Mome)
|
|
444
|
+
mome_max = np.max(Mome)
|
|
445
|
+
full_disp_momenta = np.linspace(
|
|
446
|
+
mome_min, mome_max, len(self.angles)
|
|
447
|
+
)
|
|
425
448
|
|
|
426
449
|
if ordinate == 'kinetic_energy':
|
|
427
|
-
mesh = ax.pcolormesh(
|
|
428
|
-
|
|
429
|
-
|
|
450
|
+
mesh = ax.pcolormesh(
|
|
451
|
+
Mome, Ekin, self.intensities,
|
|
452
|
+
shading='auto',
|
|
453
|
+
cmap=plt.get_cmap('bone').reversed())
|
|
430
454
|
ax.set_ylabel('$E_{\\mathrm{kin}}$ (eV)')
|
|
431
|
-
|
|
432
455
|
elif ordinate == 'electron_energy':
|
|
433
456
|
Enel = Ekin - self.hnuminphi
|
|
434
|
-
mesh = ax.pcolormesh(
|
|
435
|
-
|
|
436
|
-
|
|
457
|
+
mesh = ax.pcolormesh(
|
|
458
|
+
Mome, Enel, self.intensities,
|
|
459
|
+
shading='auto',
|
|
460
|
+
cmap=plt.get_cmap('bone').reversed())
|
|
437
461
|
ax.set_ylabel('$E-\\mu$ (eV)')
|
|
438
462
|
|
|
463
|
+
y_lims = ax.get_ylim()
|
|
464
|
+
|
|
439
465
|
if any("cell centers" in str(w.message) for w in wlist):
|
|
440
|
-
warnings.warn(
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
466
|
+
warnings.warn(
|
|
467
|
+
"Conversion from angle to momenta causes warping of the "
|
|
468
|
+
"cell centers. \n Cell edges of the mesh plot may look "
|
|
469
|
+
"irregular.",
|
|
470
|
+
UserWarning,
|
|
471
|
+
stacklevel=2,
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
if abscissa == 'momentum' and self_energies is not None:
|
|
475
|
+
for self_energy in self_energies:
|
|
444
476
|
|
|
445
|
-
if abscissa == 'momentum' and self._self_energies is not None:
|
|
446
|
-
for self_energy in self._self_energies:
|
|
447
477
|
mdc_maxima = getattr(self_energy, "mdc_maxima", None)
|
|
448
478
|
|
|
449
|
-
# If this self-energy doesn't contain maxima, don't plot
|
|
479
|
+
# If this self-energy doesn't contain maxima, don't plot
|
|
450
480
|
if mdc_maxima is None:
|
|
451
481
|
continue
|
|
452
482
|
|
|
453
|
-
|
|
454
|
-
|
|
483
|
+
# Reserve a colour from the axes cycle for this self-energy,
|
|
484
|
+
# and use it consistently for MDC maxima and dispersion.
|
|
485
|
+
line_color = ax._get_lines.get_next_color()
|
|
486
|
+
|
|
487
|
+
peak_sigma = getattr(
|
|
488
|
+
self_energy, "peak_positions_sigma", None
|
|
489
|
+
)
|
|
455
490
|
xerr = stdv * peak_sigma if peak_sigma is not None else None
|
|
456
491
|
|
|
457
492
|
if ordinate == 'kinetic_energy':
|
|
458
493
|
y_vals = self_energy.ekin_range
|
|
459
|
-
else:
|
|
494
|
+
else:
|
|
460
495
|
y_vals = self_energy.enel_range
|
|
461
496
|
|
|
462
497
|
x_vals = mdc_maxima
|
|
463
498
|
label = getattr(self_energy, "label", None)
|
|
464
499
|
|
|
500
|
+
# First plot the MDC maxima, using the reserved colour
|
|
465
501
|
if xerr is not None:
|
|
466
|
-
ax.errorbar(
|
|
467
|
-
|
|
468
|
-
|
|
502
|
+
ax.errorbar(
|
|
503
|
+
x_vals, y_vals, xerr=xerr, fmt='o',
|
|
504
|
+
linestyle='', label=label,
|
|
505
|
+
markersize=markersize,
|
|
506
|
+
color=line_color, ecolor=line_color,
|
|
507
|
+
)
|
|
469
508
|
else:
|
|
470
|
-
ax.plot(
|
|
471
|
-
|
|
509
|
+
ax.plot(
|
|
510
|
+
x_vals, y_vals, linestyle='',
|
|
511
|
+
marker='o', label=label,
|
|
512
|
+
markersize=markersize,
|
|
513
|
+
color=line_color,
|
|
514
|
+
)
|
|
472
515
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
516
|
+
# Bare-band dispersion for SpectralLinear / SpectralQuadratic
|
|
517
|
+
spec_class = getattr(
|
|
518
|
+
self_energy, "_class",
|
|
519
|
+
self_energy.__class__.__name__,
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
if (plot_disp_mode != 'none'
|
|
523
|
+
and spec_class in ("SpectralLinear",
|
|
524
|
+
"SpectralQuadratic")):
|
|
525
|
+
|
|
526
|
+
# Determine momentum grid for the dispersion
|
|
527
|
+
if plot_disp_mode == 'kink':
|
|
528
|
+
x_arr = np.asarray(x_vals)
|
|
529
|
+
mask = np.isfinite(x_arr)
|
|
530
|
+
if not np.any(mask):
|
|
531
|
+
# No valid k-points to define a range
|
|
532
|
+
continue
|
|
533
|
+
k_min = np.min(x_arr[mask])
|
|
534
|
+
k_max = np.max(x_arr[mask])
|
|
535
|
+
disp_momenta = np.linspace(
|
|
536
|
+
k_min, k_max, len(self.angles)
|
|
537
|
+
)
|
|
538
|
+
elif (plot_disp_mode == 'domain'
|
|
539
|
+
and spec_class == "SpectralQuadratic"):
|
|
540
|
+
side = getattr(self_energy, "side", None)
|
|
541
|
+
if side == 'left':
|
|
542
|
+
disp_momenta = np.linspace(
|
|
543
|
+
mome_min, self_energy.center_wavevector,
|
|
544
|
+
len(self.angles)
|
|
545
|
+
)
|
|
546
|
+
elif side == 'right':
|
|
547
|
+
disp_momenta = np.linspace(
|
|
548
|
+
self_energy.center_wavevector, mome_max,
|
|
549
|
+
len(self.angles)
|
|
550
|
+
)
|
|
551
|
+
else:
|
|
552
|
+
# Fallback: no valid side, use full range
|
|
553
|
+
disp_momenta = full_disp_momenta
|
|
554
|
+
else:
|
|
555
|
+
# 'full' or 'domain' for SpectralLinear
|
|
556
|
+
disp_momenta = full_disp_momenta
|
|
557
|
+
|
|
558
|
+
# --- Robust parameter checks before computing base_disp ---
|
|
559
|
+
if spec_class == "SpectralLinear":
|
|
560
|
+
fermi_vel = getattr(
|
|
561
|
+
self_energy, "fermi_velocity", None
|
|
562
|
+
)
|
|
563
|
+
fermi_k = getattr(
|
|
564
|
+
self_energy, "fermi_wavevector", None
|
|
565
|
+
)
|
|
566
|
+
if fermi_vel is None or fermi_k is None:
|
|
567
|
+
missing = []
|
|
568
|
+
if fermi_vel is None:
|
|
569
|
+
missing.append("fermi_velocity")
|
|
570
|
+
if fermi_k is None:
|
|
571
|
+
missing.append("fermi_wavevector")
|
|
572
|
+
raise TypeError(
|
|
573
|
+
"Cannot plot bare dispersion for "
|
|
574
|
+
"SpectralLinear: "
|
|
575
|
+
f"{', '.join(missing)} is None."
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
base_disp = (
|
|
579
|
+
fermi_vel * (disp_momenta - fermi_k)
|
|
580
|
+
)
|
|
581
|
+
|
|
582
|
+
else: # SpectralQuadratic
|
|
583
|
+
bare_mass = getattr(
|
|
584
|
+
self_energy, "bare_mass", None
|
|
585
|
+
)
|
|
586
|
+
center_k = getattr(
|
|
587
|
+
self_energy, "center_wavevector", None
|
|
588
|
+
)
|
|
589
|
+
fermi_k = getattr(
|
|
590
|
+
self_energy, "fermi_wavevector", None
|
|
591
|
+
)
|
|
592
|
+
|
|
593
|
+
missing = []
|
|
594
|
+
if bare_mass is None:
|
|
595
|
+
missing.append("bare_mass")
|
|
596
|
+
if center_k is None:
|
|
597
|
+
missing.append("center_wavevector")
|
|
598
|
+
if fermi_k is None:
|
|
599
|
+
missing.append("fermi_wavevector")
|
|
600
|
+
|
|
601
|
+
if missing:
|
|
602
|
+
raise TypeError(
|
|
603
|
+
"Cannot plot bare dispersion for "
|
|
604
|
+
"SpectralQuadratic: "
|
|
605
|
+
f"{', '.join(missing)} is None."
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
dk = disp_momenta - center_k
|
|
609
|
+
base_disp = (
|
|
610
|
+
pref * (dk ** 2 - fermi_k ** 2) / bare_mass
|
|
611
|
+
)
|
|
612
|
+
# --- end parameter checks and base_disp construction ---
|
|
613
|
+
|
|
614
|
+
if ordinate == 'electron_energy':
|
|
615
|
+
disp_vals = base_disp
|
|
616
|
+
else: # kinetic energy
|
|
617
|
+
disp_vals = base_disp + self.hnuminphi
|
|
618
|
+
|
|
619
|
+
band_label = getattr(self_energy, "label", None)
|
|
620
|
+
if band_label is not None:
|
|
621
|
+
band_label = f"{band_label} (bare)"
|
|
622
|
+
|
|
623
|
+
ax.plot(
|
|
624
|
+
disp_momenta, disp_vals,
|
|
625
|
+
label=band_label,
|
|
626
|
+
linestyle='--',
|
|
627
|
+
color=line_color,
|
|
628
|
+
)
|
|
476
629
|
|
|
477
630
|
handles, labels = ax.get_legend_handles_labels()
|
|
478
631
|
if any(labels):
|
|
479
632
|
ax.legend()
|
|
480
633
|
|
|
634
|
+
ax.set_ylim(y_lims)
|
|
635
|
+
|
|
481
636
|
plt.colorbar(mesh, ax=ax, label='counts (-)')
|
|
482
637
|
return fig
|
|
483
|
-
|
|
484
|
-
|
|
638
|
+
|
|
485
639
|
@add_fig_kwargs
|
|
486
640
|
def fit_fermi_edge(self, hnuminphi_guess, background_guess=0.0,
|
|
487
641
|
integrated_weight_guess=1.0, angle_min=-np.inf,
|
|
@@ -2094,6 +2248,154 @@ class SelfEnergy:
|
|
|
2094
2248
|
)
|
|
2095
2249
|
|
|
2096
2250
|
return self._mdc_maxima
|
|
2251
|
+
|
|
2252
|
+
def _se_legend_labels(self):
|
|
2253
|
+
"""Return (real_label, imag_label) for legend with safe subscripts."""
|
|
2254
|
+
se_label = getattr(self, "label", None)
|
|
2255
|
+
|
|
2256
|
+
if se_label is None:
|
|
2257
|
+
real_label = r"$\Sigma'(E)$"
|
|
2258
|
+
imag_label = r"$-\Sigma''(E)$"
|
|
2259
|
+
return real_label, imag_label
|
|
2260
|
+
|
|
2261
|
+
safe_label = str(se_label).replace("_", r"\_")
|
|
2262
|
+
|
|
2263
|
+
# If the label is empty after conversion, fall back
|
|
2264
|
+
if safe_label == "":
|
|
2265
|
+
real_label = r"$\Sigma'(E)$"
|
|
2266
|
+
imag_label = r"$-\Sigma''(E)$"
|
|
2267
|
+
return real_label, imag_label
|
|
2268
|
+
|
|
2269
|
+
real_label = rf"$\Sigma_{{\mathrm{{{safe_label}}}}}'(E)$"
|
|
2270
|
+
imag_label = rf"$-\Sigma_{{\mathrm{{{safe_label}}}}}''(E)$"
|
|
2271
|
+
|
|
2272
|
+
return real_label, imag_label
|
|
2273
|
+
|
|
2274
|
+
@add_fig_kwargs
|
|
2275
|
+
def plot_real(self, ax=None, **kwargs):
|
|
2276
|
+
r"""Plot the real part Σ' of the self-energy as a function of E-μ.
|
|
2277
|
+
|
|
2278
|
+
Parameters
|
|
2279
|
+
----------
|
|
2280
|
+
ax : Matplotlib-Axes or None
|
|
2281
|
+
Axis to plot on. Created if not provided by the user.
|
|
2282
|
+
**kwargs :
|
|
2283
|
+
Additional keyword arguments passed to ``ax.errorbar``.
|
|
2284
|
+
|
|
2285
|
+
Returns
|
|
2286
|
+
-------
|
|
2287
|
+
fig : Matplotlib-Figure
|
|
2288
|
+
Figure containing the Σ'(E) plot.
|
|
2289
|
+
"""
|
|
2290
|
+
|
|
2291
|
+
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
2292
|
+
|
|
2293
|
+
x = self.enel_range
|
|
2294
|
+
y = self.real
|
|
2295
|
+
y_sigma = self.real_sigma
|
|
2296
|
+
|
|
2297
|
+
real_label, _ = self._se_legend_labels()
|
|
2298
|
+
kwargs.setdefault("label", real_label)
|
|
2299
|
+
|
|
2300
|
+
if y_sigma is not None:
|
|
2301
|
+
if np.isnan(y_sigma).any():
|
|
2302
|
+
print(
|
|
2303
|
+
"Warning: some Σ'(E) uncertainty values are missing. "
|
|
2304
|
+
"Error bars omitted at those energies."
|
|
2305
|
+
)
|
|
2306
|
+
kwargs.setdefault("yerr", stdv * y_sigma)
|
|
2307
|
+
|
|
2308
|
+
ax.errorbar(x, y, **kwargs)
|
|
2309
|
+
ax.set_xlabel(r"$E-\mu$ (eV)")
|
|
2310
|
+
ax.set_ylabel(r"$\Sigma'(E)$ (eV)")
|
|
2311
|
+
ax.legend()
|
|
2312
|
+
|
|
2313
|
+
return fig
|
|
2314
|
+
|
|
2315
|
+
@add_fig_kwargs
|
|
2316
|
+
def plot_imag(self, ax=None, **kwargs):
|
|
2317
|
+
r"""Plot the imaginary part -Σ'' of the self-energy vs. E-μ.
|
|
2318
|
+
|
|
2319
|
+
Parameters
|
|
2320
|
+
----------
|
|
2321
|
+
ax : Matplotlib-Axes or None
|
|
2322
|
+
Axis to plot on. Created if not provided by the user.
|
|
2323
|
+
**kwargs :
|
|
2324
|
+
Additional keyword arguments passed to ``ax.errorbar``.
|
|
2325
|
+
|
|
2326
|
+
Returns
|
|
2327
|
+
-------
|
|
2328
|
+
fig : Matplotlib-Figure
|
|
2329
|
+
Figure containing the -Σ''(E) plot.
|
|
2330
|
+
"""
|
|
2331
|
+
|
|
2332
|
+
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
2333
|
+
|
|
2334
|
+
x = self.enel_range
|
|
2335
|
+
y = self.imag
|
|
2336
|
+
y_sigma = self.imag_sigma
|
|
2337
|
+
|
|
2338
|
+
_, imag_label = self._se_legend_labels()
|
|
2339
|
+
kwargs.setdefault("label", imag_label)
|
|
2340
|
+
|
|
2341
|
+
if y_sigma is not None:
|
|
2342
|
+
if np.isnan(y_sigma).any():
|
|
2343
|
+
print(
|
|
2344
|
+
"Warning: some -Σ''(E) uncertainty values are missing. "
|
|
2345
|
+
"Error bars omitted at those energies."
|
|
2346
|
+
)
|
|
2347
|
+
kwargs.setdefault("yerr", stdv * y_sigma)
|
|
2348
|
+
|
|
2349
|
+
ax.errorbar(x, y, **kwargs)
|
|
2350
|
+
ax.set_xlabel(r"$E-\mu$ (eV)")
|
|
2351
|
+
ax.set_ylabel(r"$-\Sigma''(E)$ (eV)")
|
|
2352
|
+
ax.legend()
|
|
2353
|
+
|
|
2354
|
+
return fig
|
|
2355
|
+
|
|
2356
|
+
@add_fig_kwargs
|
|
2357
|
+
def plot_both(self, ax=None, **kwargs):
|
|
2358
|
+
r"""Plot Σ'(E) and -Σ''(E) vs. E-μ on the same axis."""
|
|
2359
|
+
|
|
2360
|
+
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
2361
|
+
|
|
2362
|
+
x = self.enel_range
|
|
2363
|
+
real = self.real
|
|
2364
|
+
imag = self.imag
|
|
2365
|
+
real_sigma = self.real_sigma
|
|
2366
|
+
imag_sigma = self.imag_sigma
|
|
2367
|
+
|
|
2368
|
+
real_label, imag_label = self._se_legend_labels()
|
|
2369
|
+
|
|
2370
|
+
# --- plot Σ'
|
|
2371
|
+
kw_real = dict(kwargs)
|
|
2372
|
+
if real_sigma is not None:
|
|
2373
|
+
if np.isnan(real_sigma).any():
|
|
2374
|
+
print(
|
|
2375
|
+
"Warning: some Σ'(E) uncertainty values are missing. "
|
|
2376
|
+
"Error bars omitted at those energies."
|
|
2377
|
+
)
|
|
2378
|
+
kw_real.setdefault("yerr", stdv * real_sigma)
|
|
2379
|
+
kw_real.setdefault("label", real_label)
|
|
2380
|
+
ax.errorbar(x, real, **kw_real)
|
|
2381
|
+
|
|
2382
|
+
# --- plot -Σ''
|
|
2383
|
+
kw_imag = dict(kwargs)
|
|
2384
|
+
if imag_sigma is not None:
|
|
2385
|
+
if np.isnan(imag_sigma).any():
|
|
2386
|
+
print(
|
|
2387
|
+
"Warning: some -Σ''(E) uncertainty values are missing. "
|
|
2388
|
+
"Error bars omitted at those energies."
|
|
2389
|
+
)
|
|
2390
|
+
kw_imag.setdefault("yerr", stdv * imag_sigma)
|
|
2391
|
+
kw_imag.setdefault("label", imag_label)
|
|
2392
|
+
ax.errorbar(x, imag, **kw_imag)
|
|
2393
|
+
|
|
2394
|
+
ax.set_xlabel(r"$E-\mu$ (eV)")
|
|
2395
|
+
ax.set_ylabel(r"$\Sigma'(E),\ -\Sigma''(E)$ (eV)")
|
|
2396
|
+
ax.legend()
|
|
2397
|
+
|
|
2398
|
+
return fig
|
|
2097
2399
|
|
|
2098
2400
|
|
|
2099
2401
|
class CreateSelfEnergies:
|
|
@@ -2171,5 +2473,4 @@ class CreateSelfEnergies:
|
|
|
2171
2473
|
r"""
|
|
2172
2474
|
Return a {label: self_energy} dictionary for convenient access.
|
|
2173
2475
|
"""
|
|
2174
|
-
return {se.label: se for se in self.self_energies}
|
|
2175
|
-
|
|
2476
|
+
return {se.label: se for se in self.self_energies}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xarpes
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Extraction from angle resolved photoemission spectra
|
|
5
5
|
Author: xARPES Developers
|
|
6
6
|
Requires-Python: >=3.7.0
|
|
@@ -88,10 +88,10 @@ Example for Linux:
|
|
|
88
88
|
|
|
89
89
|
Answer `y` to questions. Create and activate a new environment:
|
|
90
90
|
|
|
91
|
-
conda create -n <my_env> -c
|
|
91
|
+
conda create -n <my_env> -c conda-forge
|
|
92
92
|
conda activate <my_env>
|
|
93
93
|
|
|
94
|
-
Where `<my_env>` must be replaced by your desired name.
|
|
94
|
+
Where `<my_env>` must be replaced by your desired name. Package compatibility ssues may arise if conda installs from different channels. This can be prevented by appending `--strict-channel-priority` to the creation command.
|
|
95
95
|
|
|
96
96
|
### Installing xARPES
|
|
97
97
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
xarpes/__init__.py,sha256=c_dJwE9MtE67k6ms-2ljYZxPwTHEHDUDtOiI_g6s9QE,125
|
|
2
|
+
xarpes/constants.py,sha256=vQxxFeCdGIxMpdh5XGbeRbn7-HF1d5snWkR09d8spGc,587
|
|
3
|
+
xarpes/distributions.py,sha256=svzhvf994_5gndJA1M04SW4MVfHEVwiAumbhO5Jj22s,23434
|
|
4
|
+
xarpes/functions.py,sha256=4s2atkWyPUb1ipJApRDVMsow_47kt25wvSwLtfqD2fs,14261
|
|
5
|
+
xarpes/plotting.py,sha256=3nwq-6q3i3hUG_tMv6y-62v2FceB2LuayDeE_fSdUr0,6499
|
|
6
|
+
xarpes/spectral.py,sha256=2AmqiyAk3xYJpUj1zPwbdA1Q62mGAVvXJAWmyiGHb6s,93908
|
|
7
|
+
xarpes-0.4.0.dist-info/entry_points.txt,sha256=917UR-cqFTMMI_vMqIbk7boYSuFX_zHwQlXKcj9vlCE,79
|
|
8
|
+
xarpes-0.4.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
9
|
+
xarpes-0.4.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
10
|
+
xarpes-0.4.0.dist-info/METADATA,sha256=cBUTzdc-CF8QCIag1q7kgSISydC2o1Mo4ZlAHMe87n0,6526
|
|
11
|
+
xarpes-0.4.0.dist-info/RECORD,,
|
xarpes-0.3.4.dist-info/RECORD
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
xarpes/__init__.py,sha256=WAZKbz4gEW1H7Yb24GVBAryDrMsQiAn0UNmeJwEM_no,124
|
|
2
|
-
xarpes/constants.py,sha256=vQxxFeCdGIxMpdh5XGbeRbn7-HF1d5snWkR09d8spGc,587
|
|
3
|
-
xarpes/distributions.py,sha256=svzhvf994_5gndJA1M04SW4MVfHEVwiAumbhO5Jj22s,23434
|
|
4
|
-
xarpes/functions.py,sha256=4s2atkWyPUb1ipJApRDVMsow_47kt25wvSwLtfqD2fs,14261
|
|
5
|
-
xarpes/plotting.py,sha256=W-5WaKjBtg8PIxTypqja2R29mgWkQ844lgRWci0nhn0,5679
|
|
6
|
-
xarpes/spectral.py,sha256=GT_1GUMy9Md4X8W7UM0l8ir_WRaPAaUbgvS5Ep0uSY8,82863
|
|
7
|
-
xarpes-0.3.4.dist-info/entry_points.txt,sha256=917UR-cqFTMMI_vMqIbk7boYSuFX_zHwQlXKcj9vlCE,79
|
|
8
|
-
xarpes-0.3.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
9
|
-
xarpes-0.3.4.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
10
|
-
xarpes-0.3.4.dist-info/METADATA,sha256=FLClCjMjfV2D_MYH3o9o3PlFG2KsDJLZLyNUzwD2FG4,6369
|
|
11
|
-
xarpes-0.3.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|