erlab.analysis.kspace

Momentum conversion functions.

Typically, the user will not have to call this module directly, but will instead use the accessor method xarray.DataArray.kspace.convert().

For more front-end utilities related to momentum conversion, see the documentation of the xarray.DataArray.kspace accessor.

Angle conventions and function forms are based on Ref. [Ishida and Shin, 2018].

Functions

change_configuration(darr, configuration)

Apply a new axis configuration to the ARPES data.

exact_cut_alpha(slit_momentum, beta, ...[, ...])

Return the exact sampled \(\alpha(k_{\mathrm{slit}}, E_k)\) for 2D cuts.

exact_hv_cut_coords(slit_momentum, kz, beta, ...)

Return exact alpha, hv, and carried momentum targets for 2D cuts.

get_kconv_forward(configuration)

Return the appropriate forward momentum conversion function.

get_kconv_func(kinetic_energy, ...)

Return appropriate momentum conversion functions.

get_kconv_inverse(configuration)

Return the appropriate inverse momentum conversion function.

hv_func(kx, ky, kz, inner_potential, ...)

Calculate the photon energy \(hν\).

kperp_from_kz(kz, inner_potential)

Calculate the out-of-plane momentum outside the sample \(k_\perp\).

kz_func(kinetic_energy, inner_potential, kx, ky)

Calculate the out-of-plane momentum inside the sample \(k_z\).

Exceptions

InvalidConfigurationError(configuration, *)

Raised when a momentum-conversion routine receives an invalid configuration.

exception erlab.analysis.kspace.InvalidConfigurationError(configuration, *, context=None)[source]

Bases: ValueError

Raised when a momentum-conversion routine receives an invalid configuration.

erlab.analysis.kspace.change_configuration(darr, configuration)[source]

Apply a new axis configuration to the ARPES data.

Returns a copy of the input data with the coordinates renamed to match the given configuration. The original data is not modified.

This function is useful for setups that are capable of changing the experimental geometry.

Parameters:
  • darr (DataArray) – The DataArray containing the ARPES data in angle space to modify.

  • configuration (AxesConfiguration | int) – The new configuration to apply.

Returns:

xarray.DataArray – The ARPES data with the new configuration.

Return type:

DataArray

erlab.analysis.kspace.exact_cut_alpha(slit_momentum, beta, kinetic_energy, alpha_reference, configuration, *, delta=0.0, chi=0.0, chi0=0.0, xi=0.0, xi0=0.0, beta0=0.0)[source]

Return the exact sampled \(\alpha(k_{\mathrm{slit}}, E_k)\) for 2D cuts.

This function exposes the exact one-dimensional cut inverse used by xarray.DataArray.kspace.convert() when the dataset has no beta dimension.

For slit analyzers (Type1 / Type2), Appendix A of Ishida and Shin [2018] reduces the slit-axis momentum to

\[k_{\mathrm{slit}} = k (A \cos \alpha + B \sin \alpha),\]

where

\[k = \frac{\sqrt{2 m_e E_k}}{\hbar},\]

and the coefficients depend only on the geometry and fixed \(\bar{\beta} = \beta - \beta_0\), \(\bar{\xi} = \xi - \xi_0\). The implemented coefficients are

\[\text{Type1}: \qquad A = \sin\delta \sin\bar{\beta} + \cos\delta \sin\bar{\xi} \cos\bar{\beta}, \qquad B = -\cos\delta \cos\bar{\xi},\]
\[\text{Type2}: \qquad A = -\cos\delta \sin\bar{\xi} + \sin\delta \sin\bar{\beta} \cos\bar{\xi}, \qquad B = \cos\delta \cos\bar{\xi} + \sin\delta \sin\bar{\beta} \sin\bar{\xi}.\]

Writing

\[A \cos \alpha + B \sin \alpha = R \cos(\alpha - \psi),\]

with \(R = \sqrt{A^2 + B^2}\) and \(\psi = \operatorname{atan}(B, A)\), gives the explicit inverse

\[\alpha = \psi \pm \cos^{-1}\left(\frac{k_{\mathrm{slit}}}{k R}\right).\]

The sign is determined from the measured alpha interval by replaying the normalized source relation on alpha_reference. If the sampled source \(k_{\mathrm{slit}}(\alpha)\) turns around within the measured interval, the inverse is multi-valued and the function raises.

For deflector analyzers (Type1DA / Type2DA), the exact inverse is written in a rotated frame. If the measured momentum vector is rotated back into the deflector frame, let \((P_1, P_2, P_3)\) denote the resulting momentum components along that frame’s three orthogonal axes. The implemented DA inverse uses the identities

\[P_1 = -k \beta \operatorname{sinc}\eta, \qquad P_2 = k \alpha \operatorname{sinc}\eta, \qquad P_3 = k \cos\eta,\]

with \(\eta = \sqrt{\alpha^2 + \beta^2}\) where \(0 \le \eta < \pi\) due to the photoemission horizon. For fixed \(\beta\), the slit-axis component has the form

\[k_{\mathrm{slit}} = k \left[A \cos\eta + \left(B \alpha + C \beta\right)\operatorname{sinc}\eta\right],\]

which does not reduce to an elementary explicit inverse \(\alpha(k_{\mathrm{slit}})\). The deflector implementation therefore evaluates the exact slit-axis curve on the measured alpha interval and interpolates target slit-momentum values onto that monotonic sampled source curve. This is still exact in the sense that it does not use small-angle or other geometric approximations; the only requirement is that the measured source curve be one-to-one on alpha_reference.

Parameters:
  • slit_momentum – Target slit-axis momentum values in Å⁻¹. For Type1 and Type1DA this is \(k_x\); for Type2 and Type2DA it is \(k_y\).

  • beta – Analyzer angle \(\beta\) in degrees on the source grid. This may be a scalar, an array-like object, or an xarray.DataArray. For \(h\nu\)-dependent cuts, beta may vary along the source hv axis.

  • kinetic_energy – Kinetic energy \(E_k\) in eV on the source grid. This may be scalar, array-like, or an xarray.DataArray.

  • alpha_reference – Measured source alpha coordinate in degrees. The exact inverse is defined on this sampled interval, so branch selection and invertibility are determined from this coordinate.

  • configuration (AxesConfiguration | int) – Experimental configuration, one of erlab.constants.AxesConfiguration.

  • delta (default: 0.0) – Sample azimuth \(\delta\) in degrees.

  • chi (default: 0.0) – Deflector rotation angle \(\chi\) in degrees. Used only for Type1DA and Type2DA.

  • chi0 (default: 0.0) – Offset \(\chi_0\) in degrees. Used only for Type1DA and Type2DA.

  • xi (default: 0.0) – Sample tilt \(\xi\) in degrees.

  • xi0 (default: 0.0) – Offset \(\xi_0\) in degrees.

  • beta0 (default: 0.0) – Offset \(\beta_0\) in degrees. Used only for Type1 and Type2.

Returns:

xarray.DataArray or numpy.ndarray – Exact sampled \(\alpha\) values on the target slit-momentum grid. The return type follows slit_momentum: if it is a DataArray, a DataArray is returned; otherwise a NumPy array is returned.

Raises:

ValueError – If the exact source relation is not invertible on the measured interval, if the slit-axis momentum becomes effectively constant, or if the target slit momentum lies outside the physically reachable domain.

erlab.analysis.kspace.exact_hv_cut_coords(slit_momentum, kz, beta, hv, kinetic_energy, alpha_reference, configuration, inner_potential, *, delta=0.0, chi=0.0, chi0=0.0, xi=0.0, xi0=0.0, beta0=0.0)[source]

Return exact alpha, hv, and carried momentum targets for 2D cuts.

This function exposes the exact \(h\nu\)-dependent cut inversion used by xarray.DataArray.kspace.convert() when the dataset has no beta dimension.

The calculation proceeds in three exact sampled steps.

  1. Recover \(\alpha_{\mathrm{source}}(h\nu)\) on the measured source grid with exact_cut_alpha().

  2. Reconstruct the in-plane momentum perpendicular to the slit on that same source grid. For slit analyzers this is

    \[k_{\mathrm{other}} = k(C \cos\alpha + D \sin\alpha),\]

    with geometry-dependent coefficients \(C\) and \(D\). For deflector analyzers, \(k_x\) and \(k_y\) are reconstructed directly from the exact forward transform.

  3. Build the exact sampled out-of-plane source curve from the free-electron final-state relation

\[k_z(h\nu)^2 = \frac{2 m_e}{\hbar^2}\left(E_k(h\nu) + V_0\right) - k_x(h\nu)^2 - k_y(h\nu)^2,\]

with

\[E_k(h\nu) = h\nu - \Phi + E_b,\]

where \(\Phi\) is the work function and \(E_b\) is the binding energy.

The implementation then inverts the sampled monotonic curve \(k_z(h\nu)\) along the measured hv axis to obtain hv_target and uses the same interpolation to obtain alpha_target and the carried orthogonal in-plane momentum other_target on the target grid. As with exact_cut_alpha(), invertibility still requires the sampled source relation to remain one-to-one over the measured interval.

Parameters:
  • slit_momentum – Target slit-axis momentum values in Å⁻¹. For Type1 and Type1DA this is \(k_x\); for Type2 and Type2DA it is \(k_y\).

  • kz – Target \(k_z\) values in Å⁻¹.

  • beta – Analyzer angle \(\beta\) in degrees on the source grid. This may be a scalar, an array-like object, or an xarray.DataArray.

  • hv – Measured photon-energy coordinate in eV. This defines the sampled source axis along which the exact \(k_z(h\nu)\) relation is inverted.

  • kinetic_energy – Kinetic energy \(E_k\) in eV on the source grid.

  • alpha_reference – Measured source alpha coordinate in degrees.

  • configuration (AxesConfiguration | int) – Experimental configuration, one of erlab.constants.AxesConfiguration.

  • inner_potential – Inner potential \(V_0\) in eV.

  • delta (default: 0.0) – Sample azimuth \(\delta\) in degrees.

  • chi (default: 0.0) – Deflector rotation angle \(\chi\) in degrees. Used only for Type1DA and Type2DA.

  • chi0 (default: 0.0) – Offset \(\chi_0\) in degrees. Used only for Type1DA and Type2DA.

  • xi (default: 0.0) – Sample tilt \(\xi\) in degrees.

  • xi0 (default: 0.0) – Offset \(\xi_0\) in degrees.

  • beta0 (default: 0.0) – Offset \(\beta_0\) in degrees. Used only for Type1 and Type2.

Returns:

tuple of xarray.DataArray(alpha_target, hv_target, other_target) where other_target is the carried in-plane momentum perpendicular to the slit.

Raises:

ValueError – If the exact sampled source relation is not invertible on the measured interval.

erlab.analysis.kspace.get_kconv_forward(configuration)[source]

Return the appropriate forward momentum conversion function.

The returned function takes \((α, β, k_{tot})\) as mandatory arguments and returns \((k_x, k_y)\). Note that \(k_{tot}\) must be computed from the kinetic energy before passing it to the function. The angle parameters can be passed as optional arguments with default values of zero.

Parameters:

configuration (AxesConfiguration | int) – Experimental configuration.

Returns:

forward (Callable) – The forward conversion function with the following signature:

def forward(alpha, beta, kinetic_energy, **angle_params) -> (kx, ky)
...

**angle_params are the optional angle parameters. For geometry without DA, they are delta, xi, xi0, beta0. For geometry with DA, they are delta, chi, chi0, xi, xi0. All angle parameters have default values of zero.

Return type:

Callable

erlab.analysis.kspace.get_kconv_func(kinetic_energy, configuration, angle_params)[source]

Return appropriate momentum conversion functions.

The appropriate function is chosen based on the configuration and kinetic energy.

Parameters:
Returns:

  • forward_func (Callable) – Forward function that takes \((α, β)\) and returns \((k_x, k_y)\).

  • inverse_func (Callable) – Inverse function that takes \((k_x, k_y)\) or \((k_x, k_y, k_\perp)\) and returns \((α, β)\). If \(k_\perp\) is given, it will return the angles broadcasted to \(k_\perp\) instead of the provided kinetic energy.

Raises:

ValueError – If the given configuration is not valid.

Return type:

tuple[Callable, Callable]

Note

  • The only requirement for the input parameters of the returned functions is that the shape of the input angles must be broadcastable with each other, and with the shape of the kinetic energy array. This means that the shape of the output array can be controlled By adjusting the shape of the input arrays. For instance, if the kinetic energy is given as a (L, 1, 1) array, \(k_x\) as a (1, M, 1) array, and \(k_y\) as a (1, 1, N) array, the output angle arrays \(α\) and \(β\) will each be broadcasted to a (L, M, N) array which can be directly used for interpolation.

  • However, the user will not have to worry about the shape of the input arrays, because using xarray.DataArray objects as the input will most likely broadcast the arrays automatically!

erlab.analysis.kspace.get_kconv_inverse(configuration)[source]

Return the appropriate inverse momentum conversion function.

The returned function takes \((k_x, k_y, k_\perp, E_k)\) as mandatory arguments and returns \((α, β)\). The angle parameters can be passed as optional arguments with default values of zero.

If \(k_\perp\) is None, it will be computed from the kinetic energy \(E_k\). Otherwise, the angles will be computed at the given \(k_\perp\).

Parameters:

configuration (AxesConfiguration | int) – Experimental configuration.

Returns:

inverse (Callable) – The inverse conversion function with the following signature:

def inverse(kx, ky, kperp, kinetic_energy, **angle_params) -> (alpha, beta)
...

**angle_params are the optional angle parameters. For geometry without DA, they are delta, xi, xi0, beta0. For geometry with DA, they are delta, chi, chi0, xi, xi0. All angle parameters have default values of zero.

If kperp is None, it will be computed from kinetic_energy.

Return type:

Callable

erlab.analysis.kspace.hv_func(kx, ky, kz, inner_potential, work_function, binding_energy)[source]

Calculate the photon energy \(hν\).

The kinetic energy \(E_k\) is computed from the given out-of-plane momentum \(k_z\), inner potential \(V_0\), and in-plane momenta \(k_x\), and \(k_y\) by

\[E_k = \frac{\hbar^2}{2 m_e} \left(k_x^2 + k_y^2 + k_z^2\right) - V_0\]

Then, the kinetic energy is converted to the photon energy \(hν\) by

\[hν = E_k + \Phi - E_b\]

where \(\Phi\) is the work function of the system and \(E_b\) is the binding energy (negative for occupied states).

erlab.analysis.kspace.kperp_from_kz(kz, inner_potential)[source]

Calculate the out-of-plane momentum outside the sample \(k_\perp\).

\(k_\perp\) is computed from the out-of-plane momentum \(k_z\) and inner potential \(V_0\) by

\[k_\perp = \sqrt{k_z^2 - \frac{2 m_e V_0}{\hbar^2}}\]
erlab.analysis.kspace.kz_func(kinetic_energy, inner_potential, kx, ky)[source]

Calculate the out-of-plane momentum inside the sample \(k_z\).

\(k_z\) is computed from the given kinetic energy \(E_k\), inner potential \(V_0\), and in-plane momenta \(k_x\), and \(k_y\) by

\[k_z = \sqrt{k^2 - k_x^2 - k_y^2 + \frac{2 m_e V_0}{\hbar^2}}\]

where \(k =\sqrt{2 m_e E_k}/\hbar\).