Distortion correction with orthorhombic symmetry

This example showcases how to use the distortion correction workflow with landmarks that are not at symmetry-equivalent positions, such as for orthorhombic systems with different in-plane axis parameters.

[1]:
%load_ext autoreload
%autoreload 2
import numpy as np
import matplotlib.pyplot as plt

import sed
from sed.dataset import dataset

%matplotlib widget

Load Data

For this example, we use the example data from WSe2. Even though the system is hexagonal, we will use it for demonstration.

[2]:
dataset.get("WSe2") # Put in Path to a storage of at least 20 GByte free space.
data_path = dataset.dir # This is the path to the data
scandir, _ = dataset.subdirs # scandir contains the data, _ contains the calibration files
INFO - Not downloading WSe2 data as it already exists at "/home/runner/work/sed/sed/docs/tutorial/datasets/WSe2".
Set 'use_existing' to False if you want to download to a new location.
INFO - Using existing data path for "WSe2": "/home/runner/work/sed/sed/docs/tutorial/datasets/WSe2"
INFO - WSe2 data is already present.
[3]:
# create sed processor using the config file with time-stamps:
sp = sed.SedProcessor(folder=scandir, user_config="../sed/config/mpes_example_config.yaml", time_stamps=True, verbose=True)
sp.add_jitter()
Folder config loaded from: [/home/runner/work/sed/sed/docs/tutorial/sed_config.yaml]
User config loaded from: [/home/runner/work/sed/sed/docs/sed/config/mpes_example_config.yaml]
Default config loaded from: [/home/runner/work/sed/sed/sed/config/default.yaml]

Get slice for momentum calibration

[4]:
sp.bin_and_load_momentum_calibration(df_partitions=100, plane=203, width=10, apply=True)

Feature definition:

We will describe the symmetry of the system with a 4-fold symmetry, and select two K points and two M points as symmetry points (as well as the Gamma point).

[5]:
features = np.array([[252., 355.], [361., 251.], [250., 144.], [156., 247.], [254., 247.]])
sp.define_features(features=features, rotation_symmetry=4, include_center=True, apply=True)
# Manual selection: Use a GUI tool to select peaks:
# sp.define_features(rotation_symmetry=4, include_center=True)

Spline-warp generation:

For the spline-warp generation, we need to tell the algorithm the difference in length of Gamma-K and Gamma-M. This we can do using the ascale parameter, which can either be a single number (the ratio), or a list of length rotation_symmetry defining the relative length of the respective vectors.

[6]:
gamma_m = np.pi/3.28
gamma_k = 2/np.sqrt(3)*np.pi/3.28
# Option 1: Ratio of the two distances:
#sp.generate_splinewarp(include_center=True, ascale=gamma_k/gamma_m)
# Option 2: List of distances:
sp.generate_splinewarp(include_center=True, ascale=[gamma_m, gamma_k, gamma_m, gamma_k])
Calculated thin spline correction based on the following landmarks:
pouter: [[252. 355.]
 [361. 251.]
 [250. 144.]
 [156. 247.]]
pcent: (254.0, 247.0)
Original slice with reference features
Corrected slice with target features
Original slice with target features
[7]:
sp.pose_adjustment(xtrans=4, ytrans=7, angle=1, apply=True)
[8]:
sp.apply_momentum_correction()
Adding corrected X/Y columns to dataframe:
Calculating inverse deformation field, this might take a moment...
Dask DataFrame Structure:
                       X        Y        t      ADC timeStamps       Xm       Ym
npartitions=100
                 float64  float64  float64  float64    float64  float64  float64
                     ...      ...      ...      ...        ...      ...      ...
...                  ...      ...      ...      ...        ...      ...      ...
                     ...      ...      ...      ...        ...      ...      ...
                     ...      ...      ...      ...        ...      ...      ...
Dask Name: apply_dfield, 206 graph layers

Momentum calibration with orthorhombic axes

For the momentum calibration using symmetry points with non-equal distances, the option equiscale can be used:

[9]:
point_a = [256, 155]
point_b = [370, 256]
sp.calibrate_momentum_axes(point_a=point_a, point_b=point_b, k_coord_a=[0, gamma_m], k_coord_b=[gamma_k, 0], equiscale=False, apply=True)
[10]:
sp.apply_momentum_calibration()
Adding kx/ky columns to dataframe:
Dask DataFrame Structure:
                       X        Y        t      ADC timeStamps       Xm       Ym       kx       ky
npartitions=100
                 float64  float64  float64  float64    float64  float64  float64  float64  float64
                     ...      ...      ...      ...        ...      ...      ...      ...      ...
...                  ...      ...      ...      ...        ...      ...      ...      ...      ...
                     ...      ...      ...      ...        ...      ...      ...      ...      ...
                     ...      ...      ...      ...        ...      ...      ...      ...      ...
Dask Name: assign, 216 graph layers

Bin the top of the valence band

[11]:
axes = ['kx', 'ky']
bins = [100, 100]
ranges = [[-2, 2], [-2, 2]]
res = sp.compute(bins=bins, axes=axes, ranges=ranges, filter=[{"col":"t", "lower_bound": 66100, "upper_bound": 66300}])
plt.figure()
res.T.plot()
[11]:
<matplotlib.collections.QuadMesh at 0x7f4d25276fa0>
[ ]: