Momentum conversion

Momentum conversion in ERLabPy is exact with no small angle approximation, but is also very fast, thanks to the numba-accelerated trilinear interpolation in erlab.analysis.interpolate.

Nomenclature

Momentum conversion in ERLabPy follows the nomenclature from Ishida and Shin [3]. All experimental geometry are classified into 4 types. Definition of angles differ for each geometry.

For instance, imagine a typical Type 1 setup with a vertical slit that acquires maps by rotating about the z axis in the lab frame. In this case, the polar angle (rotation about z) is \(β\), and the tilt angle is \(ξ\).

In all cases, \(δ\) is the azimuthal angle that indicates in-plane rotation, and \(α\) is the angle along the slit.

[1]:
import erlab.plotting.erplot as eplt
import matplotlib.pyplot as plt

Let’s generate some example data, this time in angle coordinates.

[3]:
from erlab.io.exampledata import generate_data_angles

dat = generate_data_angles(shape=(200, 60, 300), assign_attributes=True, seed=1).T
dat
[3]:
<xarray.DataArray (eV: 300, beta: 60, alpha: 200)> Size: 29MB
6.269 9.361 7.431 4.192 4.509 ... 0.1411 0.002556 8.644e-06 6.478e-09 3.813e-13
Coordinates:
  * alpha    (alpha) float64 2kB -15.0 -14.85 -14.7 -14.55 ... 14.7 14.85 15.0
  * beta     (beta) float64 480B -15.0 -14.49 -13.98 -13.47 ... 13.98 14.49 15.0
  * eV       (eV) float64 2kB -0.45 -0.4481 -0.4462 ... 0.1162 0.1181 0.12
    xi       float64 8B 0.0
    delta    float64 8B 0.0
    hv       float64 8B 50.0
Attributes:
    configuration:        1
    temp_sample:          20.0
    sample_workfunction:  4.5

Let us define a 2D cut from the map data we just generated.

[4]:
cut = dat.sel(beta=10.0, method="nearest")
eplt.plot_array(cut)
[4]:
<matplotlib.image.AxesImage at 0x7f759b6385d0>
../_images/user-guide_kconv_6_1.svg

Although the functions for momentum conversion are implemented in erlab.analysis.kspace, the actual conversion is performed using an xarray accessor. Let’s see how it works.

Converting to momentum space

Momentum conversion is done by the convert method of the kspace accessor. The bounds and resolution are automatically determined from the data if no input is provided. The method returns a new DataArray in momentum space.

[5]:
dat_kconv = dat.kspace.convert()
dat_kconv
Estimating bounds and resolution
Calculating destination coordinates
Converting ('eV', 'alpha', 'beta')  ->  ('eV', 'kx', 'ky')
Interpolated in 2.086 s
[5]:
<xarray.DataArray (eV: 300, kx: 310, ky: 310)> Size: 231MB
nan nan nan nan nan nan nan nan ... 2.316e-06 9.819e-07 nan nan nan nan nan nan
Coordinates:
    xi       float64 8B 0.0
    delta    float64 8B 0.0
    hv       float64 8B 50.0
  * eV       (eV) float64 2kB -0.45 -0.4481 -0.4462 ... 0.1162 0.1181 0.12
  * kx       (kx) float64 2kB -0.8956 -0.8898 -0.884 ... 0.884 0.8898 0.8956
  * ky       (ky) float64 2kB -0.8956 -0.8898 -0.884 ... 0.884 0.8898 0.8956
Attributes:
    configuration:        1
    temp_sample:          20.0
    sample_workfunction:  4.5
    delta_offset:         0.0
    xi_offset:            0.0
    beta_offset:          0.0

Let us plot the original and converted data side by side.

[6]:
fig, axs = plt.subplots(1, 2, layout="compressed")
eplt.plot_array(dat.sel(eV=-0.3, method="nearest"), ax=axs[0], aspect="equal")
eplt.plot_array(dat_kconv.sel(eV=-0.3, method="nearest"), ax=axs[1], aspect="equal")
[6]:
<matplotlib.image.AxesImage at 0x7f759923a5d0>
../_images/user-guide_kconv_10_1.svg

Setting parameters

Parameters that are needed for momentum conversion are the information about the experimental configuration, the inner potential \(V_0\) (for photon energy dependent data), work function, and angle offsets. These parameters are all stored as data attributes. The kspace accessor provides a convenient way to access and modify these parameters. See configuration, inner_potential, work_function, and offsets for more information.

First, let’s check the angle offsets.

[7]:
dat.kspace.offsets
[7]:
delta0.0
xi0.0
beta0.0

Since we haven’t set any offsets, they are all zero. We will set the azimuthal angle to 60 degrees and the polar offset to 30 degrees and see what happens.

[8]:
dat.kspace.offsets.update(delta=60.0, beta=30.0)
[8]:
delta60.0
xi0.0
beta30.0
[9]:
dat_kconv = dat.kspace.convert()
dat_kconv
Estimating bounds and resolution
Calculating destination coordinates
Converting ('eV', 'alpha', 'beta')  ->  ('eV', 'kx', 'ky')
Interpolated in 0.938 s
[9]:
<xarray.DataArray (eV: 300, kx: 380, ky: 398)> Size: 363MB
nan nan nan nan nan nan nan nan nan nan ... nan nan nan nan nan nan nan nan nan
Coordinates:
    xi       float64 8B 0.0
    delta    float64 8B 0.0
    hv       float64 8B 50.0
  * eV       (eV) float64 2kB -0.45 -0.4481 -0.4462 ... 0.1162 0.1181 0.12
  * kx       (kx) float64 3kB -2.495 -2.489 -2.483 ... -0.3111 -0.3053 -0.2995
  * ky       (ky) float64 3kB -0.3431 -0.3373 -0.3315 ... 1.946 1.952 1.957
Attributes:
    configuration:        1
    temp_sample:          20.0
    sample_workfunction:  4.5
    delta_offset:         60.0
    xi_offset:            0.0
    beta_offset:          30.0

Plotting the converted data again, we can see the effect of angle offsets on the conversion.

[10]:
fig, axs = plt.subplots(1, 2, layout="compressed")
eplt.plot_array(dat.sel(eV=-0.3, method="nearest"), ax=axs[0], aspect="equal")
eplt.plot_array(dat_kconv.sel(eV=-0.3, method="nearest"), ax=axs[1], aspect="equal")
[10]:
<matplotlib.image.AxesImage at 0x7f7598777d50>
../_images/user-guide_kconv_17_1.svg

Interactive conversion

For three dimensional momentum conversion like maps or photon energy scans, an interactive window can be opened where you can adjust the parameters and see the effect right away.

The GUI is divided into two tabs.

KspaceTool 1 KspaceTool 1

The first tab is for setting momentum conversion parameters. The image is updated in real time as you change the parameters. Clicking the “Copy code” button will copy the code for conversion to the clipboard. The “Open in ImageTool” button performs a full three-dimensional conversion and opens the result in the ImageTool.

KspaceTool 2 KspaceTool 2

The second tab provides visualization options. You can overlay Brillouin zones and high symmetry points on the result, adjust colors, and apply binning.

There are two ways to invoke the GUI. The first one is to call the interactive method on the accessor:

data.kspace.interactive()

The second option is to invoke the GUI directly with the erlab.interactive.ktool function. The difference is that the latter will automatically determine the name of the input data and apply it to the generated code that is copied to the clipboard.

import erlab.interactive as eri

eri.ktool(data)