xarpes 0.2.4__py3-none-any.whl → 0.6.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 +34 -6
- xarpes/bandmap.py +897 -0
- xarpes/constants.py +13 -0
- xarpes/distributions.py +516 -245
- xarpes/functions.py +573 -79
- xarpes/mdcs.py +1078 -0
- xarpes/plotting.py +37 -35
- xarpes/selfenergies.py +1816 -0
- xarpes/settings_parameters.py +75 -0
- xarpes/settings_plots.py +54 -0
- {xarpes-0.2.4.dist-info → xarpes-0.6.0.dist-info}/LICENSE +0 -0
- xarpes-0.6.0.dist-info/METADATA +181 -0
- xarpes-0.6.0.dist-info/RECORD +15 -0
- {xarpes-0.2.4.dist-info → xarpes-0.6.0.dist-info}/WHEEL +1 -1
- xarpes-0.6.0.dist-info/entry_points.txt +3 -0
- xarpes/.ipynb_checkpoints/__init__-checkpoint.py +0 -8
- xarpes/band_map.py +0 -302
- xarpes-0.2.4.dist-info/METADATA +0 -122
- xarpes-0.2.4.dist-info/RECORD +0 -10
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Copyright (C) 2025 xARPES Developers
|
|
2
|
+
# This program is free software under the terms of the GNU GPLv3 license.
|
|
3
|
+
|
|
4
|
+
"""User-configurable numerical parameters for xARPES."""
|
|
5
|
+
|
|
6
|
+
# Extend data range by this many Gaussian sigmas
|
|
7
|
+
sigma_extend = 5.0
|
|
8
|
+
|
|
9
|
+
# Gaussian confidence level expressed in "sigma"
|
|
10
|
+
sigma_confidence = 2.0
|
|
11
|
+
|
|
12
|
+
def parameter_settings(new_sigma_extend=None, new_sigma=None):
|
|
13
|
+
"""
|
|
14
|
+
Configure global numerical parameters for xARPES.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
new_sigma_extend : float or None
|
|
19
|
+
Number of Gaussian sigmas used to extend arrays before convolution.
|
|
20
|
+
new_sigma : float or None
|
|
21
|
+
Gaussian confidence level expressed in units of sigma
|
|
22
|
+
(e.g. 1, 2, 3). Default is 2.
|
|
23
|
+
"""
|
|
24
|
+
global sigma_extend, sigma_confidence
|
|
25
|
+
|
|
26
|
+
if new_sigma_extend is not None:
|
|
27
|
+
sigma_extend = float(new_sigma_extend)
|
|
28
|
+
|
|
29
|
+
if new_sigma is not None:
|
|
30
|
+
sigma_confidence = float(new_sigma)
|
|
31
|
+
|
|
32
|
+
# ---------------- Defaults for MEM / chi2kink alpha-selection ----------------
|
|
33
|
+
|
|
34
|
+
mem_defaults = {
|
|
35
|
+
"method": "chi2kink",
|
|
36
|
+
"parts": "both",
|
|
37
|
+
"iter_max": 1e4,
|
|
38
|
+
"alpha_min": 1.0,
|
|
39
|
+
"alpha_max": 9.0,
|
|
40
|
+
"alpha_num": 10,
|
|
41
|
+
"ecut_left": 0.0,
|
|
42
|
+
"ecut_right": None,
|
|
43
|
+
"f_chi_squared": None,
|
|
44
|
+
"W": None,
|
|
45
|
+
"power": 4,
|
|
46
|
+
"mu": 1.0,
|
|
47
|
+
"omega_S": 1.0,
|
|
48
|
+
"sigma_svd": 1e-4,
|
|
49
|
+
"t_criterion": 1e-8,
|
|
50
|
+
"a_guess": 1.0,
|
|
51
|
+
"b_guess": 2.5,
|
|
52
|
+
"c_guess": 3.0,
|
|
53
|
+
"d_guess": 1.5,
|
|
54
|
+
"h_n": None,
|
|
55
|
+
"impurity_magnitude": 0.0,
|
|
56
|
+
"lambda_el": 0.0,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
# ---------------- Defaults for bayesian_loop optimisation --------------------
|
|
60
|
+
|
|
61
|
+
loop_defaults = {
|
|
62
|
+
"converge_iters": 50,
|
|
63
|
+
"tole": 1e-2,
|
|
64
|
+
"scale_vF": 1.0,
|
|
65
|
+
"scale_mb": 1.0,
|
|
66
|
+
"scale_imp": 1.0,
|
|
67
|
+
"scale_kF": 1.0,
|
|
68
|
+
"scale_lambda_el": 1.0,
|
|
69
|
+
"scale_hn": 1.0,
|
|
70
|
+
"opt_iter_max": 1e4,
|
|
71
|
+
"rollback_steps": 10,
|
|
72
|
+
"max_retries": 100,
|
|
73
|
+
"relative_best": 10.0,
|
|
74
|
+
"min_steps_for_regression": 25,
|
|
75
|
+
}
|
xarpes/settings_plots.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copyright (C) 2025 xARPES Developers
|
|
2
|
+
# This program is free software under the terms of the GNU GPLv3 license.
|
|
3
|
+
|
|
4
|
+
"""Plotting and notebook behaviour settings for xARPES."""
|
|
5
|
+
|
|
6
|
+
import matplotlib.pyplot as plt
|
|
7
|
+
|
|
8
|
+
def plot_settings(name="default", register_pre_run=True):
|
|
9
|
+
"""Configure default plotting style for xARPES.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
name : {"default", "large"}
|
|
14
|
+
Select a predefined style.
|
|
15
|
+
register_pre_run : bool
|
|
16
|
+
If True, register a Jupyter pre-run hook that closes figures.
|
|
17
|
+
"""
|
|
18
|
+
import matplotlib as mpl
|
|
19
|
+
|
|
20
|
+
mpl.rc("xtick", labelsize=10, direction="in")
|
|
21
|
+
mpl.rc("ytick", labelsize=10, direction="in")
|
|
22
|
+
plt.rcParams["legend.frameon"] = False
|
|
23
|
+
lw = dict(default=2.0, large=4.0)[name]
|
|
24
|
+
|
|
25
|
+
mpl.rcParams.update({
|
|
26
|
+
"lines.linewidth": lw,
|
|
27
|
+
"lines.markersize": 3,
|
|
28
|
+
"xtick.major.size": 4,
|
|
29
|
+
"xtick.minor.size": 2,
|
|
30
|
+
"xtick.major.width": 0.8,
|
|
31
|
+
"font.size": 16,
|
|
32
|
+
"axes.ymargin": 0.15,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
if register_pre_run:
|
|
36
|
+
_maybe_register_pre_run_close_all()
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _maybe_register_pre_run_close_all():
|
|
40
|
+
"""Register a pre_run_cell hook once, and only inside Jupyter."""
|
|
41
|
+
from IPython import get_ipython
|
|
42
|
+
|
|
43
|
+
if getattr(_maybe_register_pre_run_close_all, "_registered", False):
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
ip = get_ipython()
|
|
47
|
+
if ip is None or ip.__class__.__name__ != "ZMQInteractiveShell":
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
def _close_all(_info):
|
|
51
|
+
plt.close("all")
|
|
52
|
+
|
|
53
|
+
ip.events.register("pre_run_cell", _close_all)
|
|
54
|
+
_maybe_register_pre_run_close_all._registered = True
|
|
File without changes
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: xarpes
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Extraction from angle resolved photoemission spectra
|
|
5
|
+
Author: xARPES Developers
|
|
6
|
+
Requires-Python: >=3.7.0
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Requires-Dist: igor2>=0.5.8
|
|
11
|
+
Requires-Dist: jupyterlab
|
|
12
|
+
Requires-Dist: jupytext
|
|
13
|
+
Requires-Dist: matplotlib<3.10.0
|
|
14
|
+
Requires-Dist: numpy
|
|
15
|
+
Requires-Dist: scipy
|
|
16
|
+
Requires-Dist: lmfit
|
|
17
|
+
Requires-Dist: pyqt5
|
|
18
|
+
Requires-Dist: ipympl>=0.9.3
|
|
19
|
+
Requires-Dist: ipywidgets>=8.1.5
|
|
20
|
+
Requires-Dist: ipykernel<6.32.0
|
|
21
|
+
Project-URL: Documentation, https://xarpes.github.io
|
|
22
|
+
|
|
23
|
+
# xARPES
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
Repository for the code xARPES – extraction of the self-energy and Eliashberg function from angle-resolved photoemission spectroscopy. The documentation can be found on [Read the Docs](https://xarpes.readthedocs.io), while the code is maintained on [GitHub](https://github.com/xARPES/xARPES). Instructions for installing the code and downloading the code are found below. An extensive description of the functionalities and examples is found at the [arXiv preprint](https://arxiv.org/abs/2508.13845).
|
|
28
|
+
|
|
29
|
+
# Warning
|
|
30
|
+
|
|
31
|
+
This project is currently undergoing **beta testing**. Some of the functionalities are in the process of being implemented. If you encounter any bugs, you can open an issue.
|
|
32
|
+
|
|
33
|
+
# Contributing
|
|
34
|
+
|
|
35
|
+
Contributions to the code are most welcome. xARPES is intended to co-develop alongside the increasing complexity of experimental ARPES data sets. Contributions can be made by forking the code and creating a pull request. Importing of file formats from different beamlines is particularly encouraged. For development of the examples, the following scripts in `/dev_tools` could be useful:
|
|
36
|
+
- The `Rmd2ipynb.py` file, to generate the `.ipynb` from which the examples can conveniently be developed; to be executed after cloning/pulling updated `.Rmd` and `.py` files, or if you prefer developing with `.Rmd` files.
|
|
37
|
+
- The `ipynb2Rmd2py.py` file, to synchronise the `.Rmd` and `.py` files from the `.ipynb` file; to be executed right before pushing modifications to the repository. Note that this script resets some metadata in the `.Rmd` to prevent the tracking of their changes due to local virtual environments, etc.
|
|
38
|
+
|
|
39
|
+
# Installation
|
|
40
|
+
|
|
41
|
+
xARPES installation can be divided into graphical package manager instructions, and command-line instructions for either conda or pip. With command-line instructions, an editable installation of xARPES can be created; on Windows, we strongly recommend Windows Powershell to do so. Here is a summary for the three options:
|
|
42
|
+
- via a graphical package manager (Anaconda Navigator, VS Code, PyCharm, Spyder, JupyterLab)
|
|
43
|
+
- via conda-forge, out-of-the-box or editable installation, sourcing the [conda-forge package](https://anaconda.org/conda-forge/xarpes).
|
|
44
|
+
- via Pip, out-of-the-box or editable installation, sourcing the [PyPI package](https://pypi.org/project/xarpes).
|
|
45
|
+
|
|
46
|
+
We strongly recommend installing xARPES in a (conda/pip) virtual environment, and to activate the environment each time before activating xARPES.
|
|
47
|
+
|
|
48
|
+
## Graphical package manager installation
|
|
49
|
+
|
|
50
|
+
Most IDEs and scientific Python distributions include a GUI-based package manager.
|
|
51
|
+
These typically install from conda-forge (for conda environments) or PyPI (for venv/system Python).
|
|
52
|
+
|
|
53
|
+
### Anaconda Navigator
|
|
54
|
+
|
|
55
|
+
1. Open Anaconda Navigator
|
|
56
|
+
2. Select or create an environment
|
|
57
|
+
3. Set the package channel to conda-forge
|
|
58
|
+
4. Search for “xarpes”
|
|
59
|
+
5. Click Install
|
|
60
|
+
|
|
61
|
+
This installs the latest stable release from conda-forge.
|
|
62
|
+
|
|
63
|
+
### PyCharm, VS Code, Spyder, or JupyterLab
|
|
64
|
+
|
|
65
|
+
These IDEs install from the active environment’s package source:
|
|
66
|
+
- conda environment → installs from conda-forge
|
|
67
|
+
- venv/system Python → installs from PyPI
|
|
68
|
+
|
|
69
|
+
### Installation steps (generic)
|
|
70
|
+
|
|
71
|
+
1. Open your IDE
|
|
72
|
+
2. Select or create a Python environment
|
|
73
|
+
3. Open the environment/package manager panel
|
|
74
|
+
4. Search for “xarpes”
|
|
75
|
+
5. Click Install
|
|
76
|
+
|
|
77
|
+
## Conda Forge installation
|
|
78
|
+
|
|
79
|
+
Install xARPES inside a conda environment, either out of the box or as an editable.
|
|
80
|
+
|
|
81
|
+
### Setting up a conda environment
|
|
82
|
+
|
|
83
|
+
Download and install Miniconda (see the [Miniconda installation page](https://docs.anaconda.com/free/miniconda/)).
|
|
84
|
+
|
|
85
|
+
Example for Linux:
|
|
86
|
+
|
|
87
|
+
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
|
88
|
+
bash Miniconda3-latest-Linux-x86_64.sh
|
|
89
|
+
|
|
90
|
+
Answer `y` to questions. Create and activate a new environment:
|
|
91
|
+
|
|
92
|
+
conda create -n <my_env> -c conda-forge
|
|
93
|
+
conda activate <my_env>
|
|
94
|
+
|
|
95
|
+
Where `<my_env>` must be replaced by your desired name. Package compatibility issues may arise if conda installs from different channels. This can be prevented by appending `--strict-channel-priority` to the creation command.
|
|
96
|
+
|
|
97
|
+
### Installing xARPES
|
|
98
|
+
|
|
99
|
+
#### Option A — Out-of-the-box installation (from conda-forge)
|
|
100
|
+
|
|
101
|
+
conda install conda-forge::xarpes
|
|
102
|
+
|
|
103
|
+
#### Option B — Editable installation (GitHub)
|
|
104
|
+
|
|
105
|
+
First, clone the repository:
|
|
106
|
+
|
|
107
|
+
git clone git@github.com:xARPES/xARPES.git
|
|
108
|
+
cd xARPES
|
|
109
|
+
|
|
110
|
+
Then perform editable installation (this mixes conda and pip):
|
|
111
|
+
|
|
112
|
+
pip install -e .
|
|
113
|
+
|
|
114
|
+
## Pip installation
|
|
115
|
+
|
|
116
|
+
Install xARPES using pip, either out of the box or as an editable.
|
|
117
|
+
|
|
118
|
+
### Setting up a virtual environment
|
|
119
|
+
|
|
120
|
+
Install venv if necessary:
|
|
121
|
+
|
|
122
|
+
sudo apt install python3-venv
|
|
123
|
+
|
|
124
|
+
Create and activate a virtual environment:
|
|
125
|
+
|
|
126
|
+
python3 -m venv <my_env>
|
|
127
|
+
source <my_env>/bin/activate
|
|
128
|
+
|
|
129
|
+
Upgrade pip:
|
|
130
|
+
|
|
131
|
+
python3 -m pip install --upgrade pip
|
|
132
|
+
|
|
133
|
+
### Installing xARPES
|
|
134
|
+
|
|
135
|
+
#### Option A — Out-of-the-box installation (PyPI)
|
|
136
|
+
|
|
137
|
+
python3 -m pip install xarpes
|
|
138
|
+
|
|
139
|
+
#### Option B — Editable installation (GitHub)
|
|
140
|
+
|
|
141
|
+
First, clone the repository:
|
|
142
|
+
|
|
143
|
+
git clone git@github.com:xARPES/xARPES.git
|
|
144
|
+
cd xARPES
|
|
145
|
+
|
|
146
|
+
Then perform editable installation:
|
|
147
|
+
|
|
148
|
+
pip install -e .
|
|
149
|
+
|
|
150
|
+
# Examples
|
|
151
|
+
|
|
152
|
+
After installation of xARPES, the `examples/` folder can be downloaded from the terminal into the current directory:
|
|
153
|
+
|
|
154
|
+
xarpes_download_examples
|
|
155
|
+
|
|
156
|
+
This attempts to download the examples from the version corresponding encountered in `__init__.py`. If no corresponding tagged version can be downloaded, the code attempts to download the latest examples instead.
|
|
157
|
+
|
|
158
|
+
The examples can also be installed by executing `.py`or `.ipynb` executable files containing the following:
|
|
159
|
+
|
|
160
|
+
import xarpes
|
|
161
|
+
xarpes.download_examples()
|
|
162
|
+
|
|
163
|
+
# Execution
|
|
164
|
+
|
|
165
|
+
It is recommended to use JupyterLab to analyse data. JupyterLab is launched using:
|
|
166
|
+
|
|
167
|
+
jupyter lab
|
|
168
|
+
|
|
169
|
+
# Citation
|
|
170
|
+
|
|
171
|
+
If you have used xARPES for your research, please cite the following preprint:
|
|
172
|
+
[arXiv preprint 2508.13845](https://arxiv.org/abs/2508.13845).
|
|
173
|
+
|
|
174
|
+
# License
|
|
175
|
+
|
|
176
|
+
Copyright (C) 2025 xARPES Developers
|
|
177
|
+
|
|
178
|
+
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 3, as published by the Free Software Foundation.
|
|
179
|
+
|
|
180
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
181
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
xarpes/__init__.py,sha256=dfT64reIAoDadP6Kz8T8s8lXi7jgcoau4Jy2Du_GzCY,756
|
|
2
|
+
xarpes/bandmap.py,sha256=CGmXhY1ViZMlpDdqpgVUJsmhGRQdcPLa79l53QMP-Fc,34365
|
|
3
|
+
xarpes/constants.py,sha256=XOdgSzyrmHr5xocHZfmcFHHoVAa1G05a305hm3XOTtY,504
|
|
4
|
+
xarpes/distributions.py,sha256=pC8V5MlZDNFdooMonFREEASiN5QodHiyKc2ehnxMKvQ,23498
|
|
5
|
+
xarpes/functions.py,sha256=_ecottx3vi1twu_7lUrO_G3UbhCd0YMIaKezYEAW0Sw,20837
|
|
6
|
+
xarpes/mdcs.py,sha256=WRKSfGlRVKBssJp9FIHcAFsINVunPkmW9fBnFjqBHYI,42844
|
|
7
|
+
xarpes/plotting.py,sha256=lGCReHcXhYLQXR5ns3EHFjCQjJ9Sc-HifV7n4BnWby4,5189
|
|
8
|
+
xarpes/selfenergies.py,sha256=mal1SiezXq0Upg8xBL8PagUQN2ZAzCF84geRtY3gSDc,64611
|
|
9
|
+
xarpes/settings_parameters.py,sha256=yOYvgEiDeDiLzzLkvysCTiVwqg6fKIkN48B-WSad728,1912
|
|
10
|
+
xarpes/settings_plots.py,sha256=X-qteB2fIbBKOAcLMvMYDfQ8QdlUeA5xYQqF_Nyb4uA,1562
|
|
11
|
+
xarpes-0.6.0.dist-info/entry_points.txt,sha256=917UR-cqFTMMI_vMqIbk7boYSuFX_zHwQlXKcj9vlCE,79
|
|
12
|
+
xarpes-0.6.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
13
|
+
xarpes-0.6.0.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81
|
|
14
|
+
xarpes-0.6.0.dist-info/METADATA,sha256=NlUZioy3lvyew1P0QlKuBbyxO0g_YkTC6A5MmzVZLdY,7154
|
|
15
|
+
xarpes-0.6.0.dist-info/RECORD,,
|
xarpes/band_map.py
DELETED
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
# Copyright (C) 2024 xARPES Developers
|
|
2
|
-
# This program is free software under the terms of the GNU GPLv3 license.
|
|
3
|
-
|
|
4
|
-
# get_ax_fig_plt and add_fig_kwargs originate from pymatgen/util/plotting.py.
|
|
5
|
-
# Copyright (C) 2011-2024 Shyue Ping Ong and the pymatgen Development Team
|
|
6
|
-
# Pymatgen is released under the MIT License.
|
|
7
|
-
|
|
8
|
-
# See also abipy/tools/plotting.py.
|
|
9
|
-
# Copyright (C) 2021 Matteo Giantomassi and the AbiPy Group
|
|
10
|
-
# AbiPy is free software under the terms of the GNU GPLv2 license.
|
|
11
|
-
|
|
12
|
-
"""The band map class and allowed operations on it."""
|
|
13
|
-
|
|
14
|
-
import numpy as np
|
|
15
|
-
|
|
16
|
-
from .plotting import get_ax_fig_plt, add_fig_kwargs
|
|
17
|
-
from .functions import fit_leastsq
|
|
18
|
-
from .distributions import fermi_dirac
|
|
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
|
-
|
|
54
|
-
class band_map():
|
|
55
|
-
r"""Class for the band map from the ARPES experiment.
|
|
56
|
-
|
|
57
|
-
Parameters
|
|
58
|
-
----------
|
|
59
|
-
intensities : ndarray
|
|
60
|
-
2D array of counts for given (E,k) or (E,angle) pairs [counts]
|
|
61
|
-
angles : ndarray
|
|
62
|
-
1D array of angular values for the abscissa [degrees]
|
|
63
|
-
ekin : ndarray
|
|
64
|
-
1D array of kinetic energy values for the ordinate [eV]
|
|
65
|
-
angular_resolution : float, None
|
|
66
|
-
Angular resolution of the detector [degrees]
|
|
67
|
-
energy_resolution : float, None
|
|
68
|
-
Energy resolution of the detector [eV]
|
|
69
|
-
temperature : float, None
|
|
70
|
-
Temperature of the sample [K]
|
|
71
|
-
hnuminphi : float, None
|
|
72
|
-
Kinetic energy minus the work function [eV]
|
|
73
|
-
hnuminphi_std : float, None
|
|
74
|
-
Standard deviation of kinetic energy minus work function [eV]
|
|
75
|
-
"""
|
|
76
|
-
def __init__(self, intensities, angles, ekin, energy_resolution=None,
|
|
77
|
-
angular_resolution=None, temperature=None, hnuminphi=None,
|
|
78
|
-
hnuminphi_std=None):
|
|
79
|
-
self.intensities = intensities
|
|
80
|
-
self.angles = angles
|
|
81
|
-
self.ekin = ekin
|
|
82
|
-
self.energy_resolution = energy_resolution
|
|
83
|
-
self.angular_resolution = angular_resolution
|
|
84
|
-
self.temperature = temperature
|
|
85
|
-
self.hnuminphi = hnuminphi
|
|
86
|
-
self.hnuminphi_std = hnuminphi_std
|
|
87
|
-
|
|
88
|
-
@property
|
|
89
|
-
def hnuminphi(self):
|
|
90
|
-
r"""Returns the photon energy minus the work function in eV if it has
|
|
91
|
-
been set, either during instantiation, with the setter, or by fitting
|
|
92
|
-
the Fermi-Dirac distribution to the integrated weight.
|
|
93
|
-
|
|
94
|
-
Returns
|
|
95
|
-
-------
|
|
96
|
-
hnuminphi : float, None
|
|
97
|
-
Kinetic energy minus the work function [eV]
|
|
98
|
-
"""
|
|
99
|
-
return self._hnuminphi
|
|
100
|
-
|
|
101
|
-
@hnuminphi.setter
|
|
102
|
-
def hnuminphi(self, hnuminphi):
|
|
103
|
-
r"""Manually sets the photon energy minus the work function in eV if it
|
|
104
|
-
has been set; otherwise returns None.
|
|
105
|
-
|
|
106
|
-
Parameters
|
|
107
|
-
----------
|
|
108
|
-
hnuminphi : float, None
|
|
109
|
-
Kinetic energy minus the work function [eV]
|
|
110
|
-
"""
|
|
111
|
-
self._hnuminphi = hnuminphi
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def hnuminphi_std(self):
|
|
115
|
-
r"""Returns standard deviation of the photon energy minus the work
|
|
116
|
-
function in eV.
|
|
117
|
-
|
|
118
|
-
Returns
|
|
119
|
-
-------
|
|
120
|
-
hnuminphi_std : float
|
|
121
|
-
Standard deviation of energy minus the work function [eV]
|
|
122
|
-
"""
|
|
123
|
-
return self._hnuminphi_std
|
|
124
|
-
|
|
125
|
-
@hnuminphi_std.setter
|
|
126
|
-
def hnuminphi_std(self, hnuminphi_std):
|
|
127
|
-
r"""Manually sets the standard deviation of photon energy minus the
|
|
128
|
-
work function in eV.
|
|
129
|
-
|
|
130
|
-
Parameters
|
|
131
|
-
----------
|
|
132
|
-
hnuminphi_std : float
|
|
133
|
-
Standard deviation of energy minus the work function [eV]
|
|
134
|
-
"""
|
|
135
|
-
self._hnuminphi_std = hnuminphi_std
|
|
136
|
-
|
|
137
|
-
def shift_angles(self, shift):
|
|
138
|
-
r"""
|
|
139
|
-
Shifts the angles by the specified amount in degrees. Used to shift
|
|
140
|
-
from the detector angle to the material angle.
|
|
141
|
-
|
|
142
|
-
Parameters
|
|
143
|
-
----------
|
|
144
|
-
shift : float
|
|
145
|
-
Angular shift [degrees]
|
|
146
|
-
"""
|
|
147
|
-
self.angles = self.angles + shift
|
|
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
|
-
|
|
209
|
-
@add_fig_kwargs
|
|
210
|
-
def fit_fermi_edge(self, hnuminphi_guess, background_guess=0.0,
|
|
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.
|
|
215
|
-
Also sets hnuminphi, the kinetic energy minus the work function in eV.
|
|
216
|
-
The fitting includes an energy convolution with an abscissa range
|
|
217
|
-
expanded by 5 times the energy resolution standard deviation.
|
|
218
|
-
|
|
219
|
-
Parameters
|
|
220
|
-
----------
|
|
221
|
-
hnuminphi_guess : float
|
|
222
|
-
Initial guess for kinetic energy minus the work function [eV]
|
|
223
|
-
background_guess : float
|
|
224
|
-
Initial guess for background intensity [counts]
|
|
225
|
-
integrated_weight_guess : float
|
|
226
|
-
Initial guess for integrated spectral intensity [counts]
|
|
227
|
-
angle_min : float
|
|
228
|
-
Minimum angle of integration interval [degrees]
|
|
229
|
-
angle_max : float
|
|
230
|
-
Maximum angle of integration interval [degrees]
|
|
231
|
-
ekin_min : float
|
|
232
|
-
Minimum kinetic energy of integration interval [eV]
|
|
233
|
-
ekin_max : float
|
|
234
|
-
Maximum kinetic energy of integration interval [eV]
|
|
235
|
-
ax : Matplotlib-Axes / NoneType
|
|
236
|
-
Axis for plotting the Fermi edge on. Created if not provided by
|
|
237
|
-
the user.
|
|
238
|
-
|
|
239
|
-
Other parameters
|
|
240
|
-
----------------
|
|
241
|
-
**kwargs : dict, optional
|
|
242
|
-
Additional arguments passed on to add_fig_kwargs. See the keyword
|
|
243
|
-
table below.
|
|
244
|
-
|
|
245
|
-
Returns
|
|
246
|
-
-------
|
|
247
|
-
fig : Matplotlib-Figure
|
|
248
|
-
Figure containing the Fermi edge fit
|
|
249
|
-
"""
|
|
250
|
-
ax, fig, plt = get_ax_fig_plt(ax=ax)
|
|
251
|
-
|
|
252
|
-
min_angle_index = np.argmin(np.abs(self.angles - angle_min))
|
|
253
|
-
max_angle_index = np.argmin(np.abs(self.angles - angle_max))
|
|
254
|
-
|
|
255
|
-
min_ekin_index = np.argmin(np.abs(self.ekin - ekin_min))
|
|
256
|
-
max_ekin_index = np.argmin(np.abs(self.ekin - ekin_max))
|
|
257
|
-
|
|
258
|
-
energy_range = self.ekin[min_ekin_index:max_ekin_index]
|
|
259
|
-
|
|
260
|
-
integrated_intensity = np.trapz(
|
|
261
|
-
self.intensities[min_ekin_index:max_ekin_index,
|
|
262
|
-
min_angle_index:max_angle_index], axis=1)
|
|
263
|
-
|
|
264
|
-
fdir_initial = fermi_dirac(temperature=self.temperature,
|
|
265
|
-
hnuminphi=hnuminphi_guess,
|
|
266
|
-
background=background_guess,
|
|
267
|
-
integrated_weight=integrated_weight_guess,
|
|
268
|
-
name='Initial guess')
|
|
269
|
-
|
|
270
|
-
parameters = np.array(
|
|
271
|
-
[hnuminphi_guess, background_guess, integrated_weight_guess])
|
|
272
|
-
|
|
273
|
-
extra_args = (self.energy_resolution)
|
|
274
|
-
|
|
275
|
-
popt, pcov = fit_leastsq(parameters, energy_range, integrated_intensity,
|
|
276
|
-
fdir_initial, extra_args)
|
|
277
|
-
|
|
278
|
-
fdir_final = fermi_dirac(temperature=self.temperature,
|
|
279
|
-
hnuminphi=popt[0], background=popt[1],
|
|
280
|
-
integrated_weight=popt[2],
|
|
281
|
-
name='Fitted result')
|
|
282
|
-
|
|
283
|
-
self.hnuminphi = popt[0]
|
|
284
|
-
self.hnuminphi_std = np.sqrt(np.diag(pcov))[0][0]
|
|
285
|
-
|
|
286
|
-
ax.set_xlabel(r'$E_{\mathrm{kin}}$ (-)')
|
|
287
|
-
ax.set_ylabel('Counts (-)')
|
|
288
|
-
ax.set_xlim([ekin_min, ekin_max])
|
|
289
|
-
|
|
290
|
-
ax.plot(energy_range, integrated_intensity, label='Data')
|
|
291
|
-
|
|
292
|
-
ax.plot(energy_range, fdir_initial.convolve(energy_range,
|
|
293
|
-
energy_resolution=self.energy_resolution),
|
|
294
|
-
label=fdir_initial.name)
|
|
295
|
-
|
|
296
|
-
ax.plot(energy_range, fdir_final.convolve(energy_range,
|
|
297
|
-
energy_resolution=self.energy_resolution),
|
|
298
|
-
label=fdir_final.name)
|
|
299
|
-
|
|
300
|
-
ax.legend()
|
|
301
|
-
|
|
302
|
-
return fig
|