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>
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>
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]:
delta | 0.0 |
xi | 0.0 |
beta | 0.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]:
delta | 60.0 |
xi | 0.0 |
beta | 30.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>
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.
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.
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)