Example 1: SpecsAnalyzer conversion#

This is an example showcasing the conversion of Phoibos analyzer data with SpecsAnalyzer

The image is loaded from a text file, and the conversion into xarrays with calibrated dimensions is demonstrated for different modes of operation

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

Image conversion#

create specsanalyzer instance from config file

[2]:
spa = SpecsAnalyzer(config="../tests/data/dataEPFL/config/config.yaml")
INFO - Configuration loaded from: [/home/runner/work/specsanalyzer/specsanalyzer/docs/tests/data/dataEPFL/config/config.yaml]
INFO - Default config loaded from: [/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/specsanalyzer/config/default.yaml]

convert single image

[3]:
lens_mode = "WideAngleMode"
kinetic_energy = 35.000000
pass_energy = 35.000000
work_function = 4.3
binning = 4

raw_image_name = "../tests/data/dataEPFL/R9132/Data9132_RAWDATA.tsv"
with open(raw_image_name) as file:
    tsv_data = np.loadtxt(file, delimiter="\t")

res_xarray = spa.convert_image(
    tsv_data,
    lens_mode,
    kinetic_energy,
    pass_energy,
    work_function,
)
[4]:
res_xarray.dims
[4]:
('Angle', 'Ekin')
[5]:
plt.figure()
res_xarray.plot()
[5]:
<matplotlib.collections.QuadMesh at 0x7f8fbe540610>

Conversion parameters are stored in the attributes

[6]:
res_xarray.attrs["conversion_parameters"]
[6]:
{'apply_fft_filter': False,
 'binning': 4,
 'rotation_angle': 0,
 'lens_mode': 'WideAngleMode',
 'kinetic_energy': 35.0,
 'pass_energy': 35.0,
 'work_function': 4.3,
 'a_inner': 15.0,
 'da_matrix': array([[ 7.19828571e-01,  7.53542857e-01,  7.59685714e-01],
        [-1.36678571e-03,  5.85771429e-02,  1.34014286e-01],
        [-1.37997143e-02, -5.04428571e-02, -9.16571429e-02],
        [-4.20521429e-04,  9.74571429e-03,  1.95942857e-02]]),
 'retardation_ratio': 0.8771428571428571,
 'source': 'interpolated as 0.2857142857142865*WideAngleMode@0.82 + 0.7142857142857135*WideAngleMode@0.9',
 'dims': ['Angle', 'Ekin'],
 'e_shift': array([-0.05,  0.  ,  0.05]),
 'de1': [0.0033],
 'e_range': [-0.066, 0.066],
 'a_range': [-15.0, 15.0],
 'pixel_size': 0.0258,
 'magnification': 4.54,
 'angle_offset_px': -2,
 'energy_offset_px': 0}

Adjusting offsets and angle#

image rotation angle and center offsets can be adjusted by keyword arguments, or from the config.

[7]:
res_xarray = spa.convert_image(
    tsv_data,
    lens_mode,
    kinetic_energy,
    pass_energy,
    work_function,
    rotation_angle=2,
    angle_offset_px=-3,
)
plt.figure()
res_xarray.plot()
[7]:
<matplotlib.collections.QuadMesh at 0x7f8fbbbe1de0>

Removal of mesh artefact#

The mesh in front of the MCP introduces some visual artifacts. These can be mitigated by applying a Fourier filter approach, with Peaks in the Fourier plane to remove defined in the config file.

[8]:
spa = SpecsAnalyzer(config="../tests/data/dataEPFL/config/config_filterON.yaml")
INFO - Configuration loaded from: [/home/runner/work/specsanalyzer/specsanalyzer/docs/tests/data/dataEPFL/config/config_filterON.yaml]
INFO - Default config loaded from: [/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/specsanalyzer/config/default.yaml]
[9]:
res_xarray = spa.convert_image(
    tsv_data,
    lens_mode,
    kinetic_energy,
    pass_energy,
    work_function,
)
plt.figure()
res_xarray.plot()
[9]:
<matplotlib.collections.QuadMesh at 0x7f8fbbb8e6b0>

Alternatively, one can use the interactive fft tool to optimize the fft peak positions of the grid.

[10]:
spa.fft_tool(tsv_data)

The peak parameters are stored in the config dict which can be passed as kwds to the convert_image function

[11]:
fft_filter_peaks = spa.config['fft_filter_peaks']

[12]:
res_xarray = spa.convert_image(
    tsv_data,
    lens_mode,
    kinetic_energy,
    pass_energy,
    work_function,
    apply_fft_filter=True,
    fft_filter_peaks=fft_filter_peaks
)
plt.figure()
res_xarray.plot()
[12]:
<matplotlib.collections.QuadMesh at 0x7f8fb81a1f30>

Conversion into spatially resolved modes#

[13]:
lens_mode = "HighMagnification2"
res_xarray = spa.convert_image(
    tsv_data,
    lens_mode,
    kinetic_energy,
    pass_energy,
    work_function,
)
plt.figure()
res_xarray.plot()
[13]:
<matplotlib.collections.QuadMesh at 0x7f8fb80f3a30>

Conversion using conversion_parameters dict#

If no valid calib2d file is available, conversion can also be performed by passing the interpolated conversion parameters, as e.g. stored in SPECS .sp2 files:

[14]:
spa = SpecsAnalyzer() # Using default config w/o calib2d file

conversion_parameters = {
    'apply_fft_filter': False,
    'binning': 4,
    'rotation_angle': 0,
    'lens_mode': 'WideAngleMode',
    'kinetic_energy': 35.0,
    'pass_energy': 35.0,
    'work_function': 4.3,
    'a_inner': 15.0,
    'da_matrix': np.array(
        [[ 7.19828571e-01,  7.53542857e-01,  7.59685714e-01],
        [-1.36678571e-03,  5.85771429e-02,  1.34014286e-01],
        [-1.37997143e-02, -5.04428571e-02, -9.16571429e-02],
        [-4.20521429e-04,  9.74571429e-03,  1.95942857e-02]]),
    'retardation_ratio': 0.8771428571428571,
    'source': 'interpolated as 0.2857142857142865*WideAngleMode@0.82 + 0.7142857142857135*WideAngleMode@0.9',
    'dims': ['Angle', 'Ekin'],
    'e_shift': np.array([-0.05,  0.  ,  0.05]),
    'de1': [0.0033],
    'e_range': [-0.066, 0.066],
    'a_range': [-15.0, 15.0],
    'pixel_size': 0.0258,
    'magnification': 4.54,
    'angle_offset_px': -2,
    'energy_offset_px': 0
}

res_xarray = spa.convert_image(
    tsv_data,
    lens_mode,
    kinetic_energy,
    pass_energy,
    work_function,
    conversion_parameters=conversion_parameters,
)
plt.figure()
res_xarray.plot()
INFO - Default config loaded from: [/opt/hostedtoolcache/Python/3.10.16/x64/lib/python3.10/site-packages/specsanalyzer/config/default.yaml]
No valid calib2 file found. Please provide the path to the calib2d file
corresponding to your detector in the config, or copy into the config
folder of the package! Without valid calib2d file, calibration parameters
have to be provided explicitly.
[14]:
<matplotlib.collections.QuadMesh at 0x7f8fb3fb1b70>