working_procedures.py
Useful procedures, basic line shapes and fitting functions, but also more
sophisticated data processing routines.
Some implemented within piva GUI, some for independent application.
- working_procedures.gaussian(x, a=1, mu=0, sigma=1)[source]
Gaussian line shape function represented as:
\[G(x) = a_0 \exp{\bigg(-\frac{(x - \mu)^2}{2\sigma^2}\bigg)}\]
- working_procedures.two_gaussians(x, a0=1, mu0=0, sigma0=1, a1=1, mu1=0, sigma1=1)[source]
Two overlapping gaussians. See
gaussian()for more details.- Parameters:
x (ndarray) – arguments
a0 (float) – normalization factor of the 1st gaussian
mu0 (float) – expected value of the 1st gaussian
sigma0 (float) – standard deviation of the 1st gaussian
a1 (float) – normalization factor of the 2nd gaussian
mu1 (float) – expected value of the 2nd gaussian
sigma1 (float) – standard deviation of the 2nd gaussian
- Returns:
function values
- Return type:
- working_procedures.lorentzian(x, a0, mu, gamma, resol=0)[source]
Lorentzian line shape function represented as:
\[L(x) = \frac{a_0}{2\pi} \frac{\Gamma}{(x-\mu)^2 + \frac{1}{4} \Gamma^2}\]
- working_procedures.asym_lorentzian(x, a0, mu, gamma, alpha=0, resol=0)[source]
Asymmetric Lorentzian line shape represented as:
\[L(x) = \frac{a_0}{2\pi} \frac{\Gamma(x)}{(x-\mu)^2 + \frac{1}{4} \Gamma(x)^2}\]where
\[\Gamma(x) = \frac{2 \Gamma_0}{1 + \exp{(\alpha(x - \mu))}}\]- Parameters:
- Returns:
function values
- Return type:
- working_procedures.two_lorentzians(x, a0, mu0, gamma0, a1, mu1, gamma1, resol=0)[source]
Two overlapping lorentzians. See
lorentzian()for more details.- Parameters:
x (ndarray) – arguments
a0 (float) – normalization factor of the 1st lorentzian
mu0 (float) – expected value of the 1st lorentzian
gamma0 (float) – full width at half maximum of the 1st lorentzian
a1 (float) – normalization factor of the 2nd lorentzian
mu1 (float) – expected value of the 2nd lorentzian
gamma1 (float) – full width at half maximum of the 2nd lorentzian
resol (float) – resolution parameter for convolving with gaussian; optional, default = 0
- Returns:
function values
- Return type:
- working_procedures.lorentzian_dublet(x, *p, delta=1, line='f')[source]
Return a two lorentzian line shapes representing doublet of the XPS core-level spectra.
- Parameters:
- Returns:
function values (spectra)
- Return type:
- working_procedures.fit_n_dublets(data, x, a0, mu, gamma, delta, constr=None, fit_delta=False, line='d')[source]
Fit multiple lorentzian doublets, corresponding to different chemical shifts of the core-level line.
- Parameters:
data (ndarray) – XPS data
x (ndarray) – arguments (energy axis)
a0 (float | list | ndarray | tuple) – normalization factors of each doublet. len(a0) corresponds to number of individual chemical shifts.
mu (float | list | ndarray | tuple) – expected values of each doublet. len(mu) corresponds to number of individual chemical shifts.
gamma (float | list | ndarray | tuple) – full width at half maximum of each doublet. len(gamma) corresponds to number of individual chemical shifts.
delta (float) – energy splitting between doublet lines
constr (tuple | None) – constrains on the fitting, according to
scipy.curve_fit()formatfit_delta (bool) – if
True, fit also splitting delta; defaultFalseline (str) – type of the orbital line. Can be ‘p’, ‘d’ or ‘f’.
- Returns:
results of the fitting in format:
res[0]-np.ndarray; fitted_profiles,res[1]-np.ndarray; fitted parameters,res[2]-np.ndarray; parameters’ errors,res[3]-np.ndarray; parameters’ covariance matrix,res[4]-pandas.DataFrame, contains results in summarized form
- Return type:
- working_procedures.shirley_calculate(x, y, tol=1e-05, maxit=10)[source]
Calculate the best auto-Shirley background S for a dataset (
x,``y``). Finds the biggest peak and then uses the minimum value either side of this peak as the terminal points of the Shirley background.Note
Implemented from: https://github.com/kaneod/physics/blob/master/python/specs.py
- working_procedures.print_fit_results(p, cov, labels=None)[source]
Print fit results in a nice
pandas.DataFrameformat
- working_procedures.kk_im2re(gamma, vF=1)[source]
Transform imaginary part of the self-energy (scattering rates) to real parts using Kramers-Kronig relations in Fourier transform approach.
- working_procedures.kk_re2im(re)[source]
Transform real part of the self-energy (energy differences) to imaginary part using Kramers-Kronig relations in Fourier transform approach.
- working_procedures.find_vF(gamma, re_disp, vF0=3, method='Nelder-Mead')[source]
Iteratively find a value of the Fermi velocity by minimizing the difference between real parts of self energy calculated by Kramers-Kronig transformation of the scattering rates and obtained directly from the experiment.
- Parameters:
- Returns:
minimized value
- Return type:
- working_procedures.find_vF_v2(omega, km, kF, gamma, vF0=3, method='Nelder-Mead')[source]
Iteratively find a value of the Fermi velocity by minimizing the difference between real parts of self energy calculated by Kramers-Kronig transformation of the scattering rates and obtained directly from the experiment.
- Parameters:
omega (ndarray) – energy axis
km (ndarray) – momenta positions of the fitted MDCs
kF (float) – Fermi momentum
gamma (ndarray) – scattering rates
re_disp – real part of the self-energy; difference between real and bare band dispersion
vF0 (float) – initial guess Fermi velocity
method (str) – minimization method, see
scipy.optimize.minimize()for more details
- Returns:
minimized value
- Return type:
- working_procedures.get_chi(ek, ek_kwargs, kx, qx, ky=None, kz=0.0, qy=None, qz=None, in_plnae=True, crop=False)[source]
Calculate real part of the Lindhard susceptibility at the limit omega -> 0.
Note
Algorithm implemented for a single-band case, based on the approach described by Inosov et al..
- Parameters:
ek (Callable) – function returning electronic dispersion, e.g., using tight-binding model
ek_kwargs (dict) – keyword arguments for the dispersion function
kx (ndarray) – momentum axis along x direction
qx (ndarray) – scattering q-vectors along x direction
ky (ndarray | None) – momentum axis along y direction; if
None, equal to kxqy (ndarray | None) – scattering q-vectors along y direction
qz (ndarray | None) – scattering q-vectors along z direction
in_plnae (bool) – determine direction of the calculated susceptibility; if
True- compute in-plane scattering (qx, qy, qz = 0), ifFalse- compute diagonal scattering (qx, qy=qx, qz)crop (bool) – if
True- compute only one quarter of the map. Helps to save a lot of time taking advantage of the symmetry conditions.
- Returns:
2D Lindhard susceptibility map
- Return type:
- working_procedures.single_q(qi, Qi)[source]
Get a single vector scattered by a density wave ordering vector Q.
- working_procedures.get_1D_modulation(qx, permutations, Q=0.5, N=10, a=3.141592653589793)[source]
1D Lorentzian modulation centered at the modulation vector Q.
- Parameters:
qx (ndarray) – q-axis along the x direction, q-axis along the y direction is assumed to be the same
permutations (list) – all symmetry equivalent permutations of the considered scattering vector Q
Q (float) – density wave vector
N (float) – modulation span in a number of unit cells
a (float) – lattice constant
- Returns:
Lorentzian-like density wave modulation
- Return type:
- working_procedures.get_2D_modulation(qx, permutations, Q=array([0.5, 0.5]), N=10, a=3.141592653589793)[source]
2D Lorentzian modulation centered at the modulation vector Q.
- Parameters:
qx (ndarray) – q-axis along the x direction, q-axis along the y direction is assumed to be the same
permutations (list) – all symmetry equivalent permutations of the considered scattering vector Q
Q (ndarray) – density wave vector
N (float) – modulation span in a number of unit cells
a (float) – lattice constant
- Returns:
Lorentzian-like density wave modulation
- Return type:
- working_procedures.get_3D_modulation(qx, qz, permutations, Q=array([0.5, 0.5, 0.5]), N=10, a=3.141592653589793)[source]
3D Lorentzian modulation centered at the modulation vector Q.
- Parameters:
qx (ndarray) – q-axis along the x direction, q-axis along the y direction is assumed to be the same
qz (ndarray) – q-axis along the z direction
permutations (list) – all symmetry equivalent permutations of the considered scattering vector Q
Q (ndarray) – density wave vector
N (int) – modulation span in a number of unit cells
a (float) – lattice constant
- Returns:
Lorentzian-like density wave modulation
- Return type:
- working_procedures.get_self_energy_of_FDW(Q, K, ek_tb, ek_kwargs, omega, Pq, eta=0.1)[source]
Calculate self-energy of the fluctuating density wave order in a 3D case.
Note
Algorithm based on the approach described by Hashimoto et al..
- Parameters:
Q (tuple) – 3-element tuple of the (qx, qy, qz) axes, each being a 1D
np.ndarrayK (tuple) – 3-element tuple of the (kx, ky, kz) axes, each being a 1D
np.ndarrayek – function returning electronic dispersion, e.g., using tight-binding model
ek_kwargs (dict) – keyword arguments for the dispersion function
omega (ndarray) – real frequencies (energies), must be the same shape as ek
Pq (ndarray) – 3D Lorentzian describing the modulation
eta (float) – imaginary factor, responsible for broadening of the spectra
ek_tb (Callable)
- Returns:
self energy of the density wave modulation
- Return type:
- working_procedures.get_A(omega, ek, eta=0.075, sigma=None)[source]
Calculate spectral function A(k, omega) based on known dispersion.
- Parameters:
omega (ndarray) – real frequencies (energies), must be the same shape as ek
ek (ndarray) – electronic dispersion obtained using, e.g., tight-binding model
eta (float) – imaginary factor, responsible for broadening of the spectra
sigma (tuple | None) – self-energy of electronic excitations. If provided, include contributions from various electronic excitations in the spectral function.
- Returns:
spectral function A(k, omega)
- Return type:
- working_procedures.pgm_calibration(hv, error_offset, dtheta, dbeta, cff=2.25, k=1, lines_per_mm=300)[source]
Function for PGM motors calibration.
Note
Follows procedure described by Weiss et al.
- Parameters:
- Returns:
- Return type:
- working_procedures.fit_PGM_calibration(data, hv, error_offset=-0.06, dtheta=0.001, dbeta=-0.001, cff=2.25, k=1, lines_per_mm=300)[source]
Run PGM calubration procedure (see
pgm_calibration()for more details) and find angles corrections for monochromator.- Parameters:
- Returns:
results of the fitting in format:
res[0]-np.ndarray; fitted parameters,res[1]-np.ndarray; parameters’ covariance matrix
- Return type:
- working_procedures.dec_fermi_div(edc, erg, res, Ef, fd_cutoff, T=5)[source]
Divide measured EDC by Fermi-Dirac function.
- working_procedures.deconvolve_resolution(edc, energy, resolution)[source]
Deconvolve instrumental resolution from EDC by dividing the Fourier transforms.
- working_procedures.detect_step(signal, n_box=15, n_smooth=3)[source]
Detect the biggest, clearest step in a signal by smoothing it and looking at the maximum of the first derivative.
- working_procedures.fermi_dirac(E, mu=0, T=4.2)[source]
Fermi-Dirac distribution with chemical potential mu at temperature T for energy E. The Fermi Dirac distribution is given by:
\[n(E) = \frac{1}{\exp{\big(\frac{E - \mu}{k_B T}\big)} + 1}\]
- working_procedures.fermi_fit_func(E, E_F, sigma, a0, b0, a1, b1, T=5)[source]
Fermi Dirac distribution with an additional linear inelastic background and convoluted with a Gaussian for the instrument resolution.
- Parameters:
E (ndarray) – energy values [eV]
E_F (float) – position of Fermi energy [eV]
sigma (float) – experimental resolution in units of E step size
a0 (float) – slope of the linear background below the E_F
b0 (float) – offset of the linear background below E_F.
a1 (float) – slope of the linear background above the E_F
b1 (float) – offset of the linear background above E_F.
T (float) – temperature [K]
- Returns:
Fermi-Dirac distribution at given temperature
- Return type:
- working_procedures.find_mid_old(xdata, ydata, xrange=None)[source]
Find step point at the middle of step intensity
- working_procedures.fit_fermi_dirac(energies, edc, e_0, T=5, sigma0=10, a0=-0.5, b0=-0.1, a1=0, b1=-0.1)[source]
Fit Fermi-Dirac distribution convoluted by a Gaussian (simulating the instrument resolution) plus a linear components to a given energy distribution curve.
- Parameters:
energies (ndarray) – energy values [eV]
edc (ndarray) – energy distribution curve (intensities)
e_0 (float) – starting guess for the Fermi energy [eV]
T (float) – temperature [K]
sigma0 (float) – experimental resolution in units of E step size
a0 (float) – slope of the linear background below the E_F
b0 (float) – offset of the linear background below E_F.
a1 (float) – slope of the linear background above the E_F
b1 (float) – offset of the linear background above E_F.
- Returns:
results of the fitting in format:
- Return type:
- working_procedures.step_function(x, step_x=0, flip=False)[source]
np.ufunc wrapper for step_function_core. Confer corresponding documentation.
- working_procedures.step_function_core(x, x0=0, flip=False)[source]
Basic step function, with step occuring at x0. Gives values:
\[ \begin{align}\begin{aligned}0 \textrm{ } \textrm{ for } \textrm{ } x < x_0\\f(x) = 0.5 \textrm{ } \textrm{ for } \textrm{ } x = x_0\\ 1 \textrm{ } \textrm{ for } \textrm{ } x > x_0\end{aligned}\end{align} \]
- working_procedures.symmetrize_edc(data, energies)[source]
Symmetrize EDC around the Fermi level, sum intensities in the overlapping region.
- working_procedures.symmetrize_edc_around_Ef(data, energies)[source]
Symmetrize EDC around the Fermi level, disregard signal above it.
- working_procedures.sum_edcs_around_k(data, kx, ky, ik=0)[source]
Sum EDCs around a given k-point, in a box specified by
ik. The box is binning overikin all directions.
- working_procedures.indexof(value, array)[source]
Find first index at which given value occurs in searched array.
- working_procedures.get_step(axis)[source]
Get step of the axis. Returns difference between first and second value.
- working_procedures.smooth(x, n_box=5, recursion_level=1)[source]
Implement a linear midpoint smoother: Move an imaginary ‘box’ of size
n_boxover the data points x and replace every point with the mean value of the box centered at that point. Can be called recursively to apply the smoothing n times in a row by settingrecursion_levelto n.At the endpoints, the arrays are assumed to continue by repeating their value at the start/end as to minimize endpoint effects. I.e. the array [1,1,2,3,5,8,13] becomes [1,1,1,1,2,3,5,8,13,13,13] for a box with
n_box= 5.- Parameters:
- Returns:
smoothed data points of same shape as input
- Return type:
- working_procedures.smooth_2d(x, n_box=5, recursion_level=1)[source]
Smooth 2-dimensional dataset, uses the same principal as in
smooth()with a box of size (n_boxxn_box).
- working_procedures.normalize(data, axis=2)[source]
Normalize data along the given axis. Recognizes different dimensions.
- working_procedures.normalize_to_sum(data, axis=0)[source]
Normalize data sets to the sum of the intensity along the specified direction.
- working_procedures.rotate(matrix, alpha, deg=True)[source]
Apply rotation on the matrix of coordinate’s system.
- working_procedures.shift_k_coordinates(kx, ky, qx=0, qy=0)[source]
Shift k-space coordinate system by a wavevector q = [
q_x,q_y].- Parameters:
- Returns:
(
kx,ky) shifted coordinate axes (1D ornp.meshgrid)- Return type:
- working_procedures.sum_XPS(data, crop=None, plot=False)[source]
Sum XPS spectra from separate scans.
- Parameters:
- Returns:
result in a format:
res[0]-np.ndarray; summed spectrumres[1]-np.ndarray; energy scale
- Return type:
- working_procedures.curvature_1d(data, dx, a0=0.0005, nb=None, rl=None, xaxis=None, clip_co=0.1)[source]
Calculate 1D curvature profile, similar to second derivative.
Note
Implements method described by Zhang et al.
- Parameters:
data (ndarray) – original data, intensities
dx (float) – step in the units of experiment
a0 (float) – free parameter
nb (int | None) – size of the smoothing box, for smoothing prior to calculating curvature profile
rl (int | None) – the number of times the smoothing is applied
xaxis (ndarray | None) – energy axis. If given, zero values above the Fermi level
clip_co (float) – cutoff value of the curvature profile; useful to improve clarity of the image
- Returns:
curvature profile
- Return type:
- working_procedures.curvature_2d(data, dx, dy, a0=100, nb=None, rl=None, eaxis=None, clip_co=0.0)[source]
Calculate 2D curvature profile, similar to second derivative. Procedure is an image enhancement method to highlight small variations in a measured signal.
Note
Implements method described by Zhang et al.
- Parameters:
data (ndarray) – original data, intensities image
dx (float) – step (along the 1st dimension) in the units of experiment
dy (float) – step (along the 2nd dimension) in the units of experiment
a0 (float) – free parameter
nb (int | None) – size of the smoothing box (nb x nb), for smoothing prior to calculating curvature profile
rl (int | None) – the number of times the smoothing is applied
eaxis (ndarray | None) – energy axis. If given, zero values above the Fermi level
clip_co (float) – cutoff value of the curvature profile; useful to improve clarity of the image
- Returns:
curvature image
- Return type:
- working_procedures.find_gamma(FS, x0, y0, method='Nelder-Mead', print_output=False)[source]
Find Gamma-point (center of rotation) of an image.
Note
Implements method described by Junck et al. (PubMed ID: 2362201)
- Parameters:
- Returns:
result of the minimization routine
- Return type:
OptimizeResult
- working_procedures.imgs_corr(img1, img2)[source]
Calculate the correlation coefficient between two matrices.
Note
For reference, see Junck et al. (PubMed ID: 2362201)
- working_procedures.rotate_around_xy(init_guess, data_org)[source]
Rotate matrix by 180 deg around (
x0,y0) and return only overlapping region.- Parameters:
- Returns:
correlation coefficient between original and rotated images. See
imgs_corr()for mode details- Return type:
- working_procedures.k_fac(energy, Eb=0.001, hv=100, work_func=4.5)[source]
Calculate scaling factor for k-space conversion depending on kinetic energy of photoemitted electrons.
- working_procedures.angle2kspace(scan_ax, ana_ax, d_scan_ax=0, d_ana_ax=0, orientation='horizontal', a=3.141592653589793, energy=array([0]), **kwargs)[source]
Convert experimental axes o k-space.
Note
Follows procedure described by Ishida et al.
- Parameters:
scan_ax (ndarray) – angle axis along the scanned direction
ana_ax (ndarray) – angle axis along the analyzer direction
d_scan_ax (float) – angle offset along the scanned direction
d_ana_ax (float) – angle offset along the analyzer direction
orientation (str) – orientation of the analyzer slit. Can be ‘horizontal’ or ‘vertical’
a (float) – in-plane lattice constant [Angstrom]. When given, convert momentum axis to a/2pi units
energy (ndarray) – energy axis
kwargs (dict) – kwargs for k-factor. See
k_fac()for more details
- Returns:
result in a format:
res[0]-np.ndarray; meshgrid of kx coordinatesres[1]-np.ndarray; meshgrid of ky/energycoordinates. int = 1 for single momentum axis
- Return type:
- working_procedures.hv2kz(ang, hvs, work_func=4.5, V0=0, trans_kz=False, c=3.141592653589793, energy=array([0]), **kwargs)[source]
Convert photon energy scan to k-space.
Note
Follows procedure described by Ishida et al.
- Parameters:
ang (ndarray) – angle axis along the analyzer direction
hvs (ndarray) – photon energies
work_func (float) – work function [eV]
V0 (float) – tin potential [eV]
trans_kz (bool) – if
True, transform photon energies to momentum unitsc (float) – out-of-plane lattice constant [Angstrom]. When given, convert momentum axis to c/2pi units
energy (ndarray) – energy axis
kwargs (dict) – kwargs. See
k_fac()andangle2kspace()for more details
- Returns:
result in a format:
res[0]-np.ndarray; meshgrid of ky coordinatesres[1]-np.ndarray; meshgrid of kz coordinates
- Return type:
- working_procedures.rescale_data(data, org_scale, new_scale)[source]
Rescales dataset, to make k-space converted image from photon energy scan possible to plot on rectangular lattice. That is required to plot data as a regular image instead of
pcolormeshobject, which is incredibly slow.Method changes axes to span between lowest and highest values (specified by axis at the highest photon energy), with the smallest step (specified by axis at the lowest photon energy).
- working_procedures.dynes_formula(omega, n0, gamma, delta)[source]
Dynes formula for tunneling density of states of superconductor, given by the formula:
\[N(\omega) = N_0 \textrm{Re}\Bigg[ \frac{\omega + i\Gamma}{\sqrt{(\omega + i\Gamma)^2 - \Delta^2}}\Bigg]\]