Example 3: Export to NeXus

This is an example showcasing the loading of a tilt map Fermi surface mapping

The band dispersion is loaded as a xarray dataframe following a conversion to the NXmpes_arpes NeXus format using the FAIRmat pynxtools.

First, the SpecsScan class is imported which has the scan loader as its class method.

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

Definition of manual scan metadata. These should ideally come from an Electronic Lab Notebook.

[2]:
metadata = {}
#General
metadata['experiment_summary'] = 'TbTe3 tilt map around EF with 800nm pump at 20fs after pump-probe overlap'
metadata['entry_title'] = 'TbTe3 XUV Fermi surface map at 20 fs'
metadata['experiment_title'] = 'TbTe3 XUV Fermi surface map at 20 fs'

#User
# Fill general parameters of NXuser
metadata['user0'] = {}
metadata['user0']['name'] = 'Laurenz Rettig'
metadata['user0']['role'] = 'Principal Investigator'
metadata['user0']['affiliation'] = 'Fritz Haber Institute of the Max Planck Society'
metadata['user0']['address'] = 'Faradayweg 4-6, 14195 Berlin'
metadata['user0']['email'] = 'rettig@fhi-berlin.mpg.de'

metadata['instrument'] = {}
# energy resolution
metadata['instrument']['energy_resolution'] = 150.
metadata['instrument']['electronanalyser'] = {}
metadata['instrument']['electronanalyser']['energy_resolution'] = 120
metadata['instrument']['electronanalyser']['angular_resolution'] = 0.2
metadata['instrument']['electronanalyser']['spatial_resolution'] = 0.5

#probe beam
metadata['instrument']['beam']={}
metadata['instrument']['beam']['probe']={}
metadata['instrument']['beam']['probe']['incident_energy'] = 21.7
metadata['instrument']['beam']['probe']['incident_energy_spread'] = 0.11
metadata['instrument']['beam']['probe']['pulse_duration'] = 20.
metadata['instrument']['beam']['probe']['frequency'] = 500.
metadata['instrument']['beam']['probe']['incident_polarization'] = [1, 1, 0, 0] # p pol Stokes vector
metadata['instrument']['beam']['probe']['extent'] = [80., 80.]
#pump beam
metadata['instrument']['beam']['pump']={}
metadata['instrument']['beam']['pump']['incident_energy'] = 1.55
metadata['instrument']['beam']['pump']['incident_energy_spread'] = 0.08
metadata['instrument']['beam']['pump']['pulse_duration'] = 35.
metadata['instrument']['beam']['pump']['frequency'] = 500.
metadata['instrument']['beam']['pump']['incident_polarization'] = [1, -1, 0, 0] # s pol Stokes vector
metadata['instrument']['beam']['pump']['incident_wavelength'] = 800.
metadata['instrument']['beam']['pump']['average_power'] = 224.
metadata['instrument']['beam']['pump']['pulse_energy'] = metadata['instrument']['beam']['pump']['average_power']/metadata['instrument']['beam']['pump']['frequency']#µJ
metadata['instrument']['beam']['pump']['extent'] = [300/4*2.34, 270/4*2.35] #Gaussian 4sigma -> FWHM
metadata['instrument']['beam']['pump']['fluence'] = 1.00
metadata['instrument']['beam']['pump']['delay'] = 0.02

#sample
metadata['sample']={}
metadata['sample']['preparation_date'] = '2017-03-19T10:00:00+00:00'
metadata['sample']['preparation_description'] = 'Cleaved'
metadata['sample']['sample_history'] = 'Cleaved in UHV'
metadata['sample']['chemical_formula'] = 'TbTe3'
metadata['sample']['description'] = 'cleaved single crystal of TbTe3'
metadata['sample']['name'] = 'TbTe3 Single Crystal'

metadata["scan_info"] = {}
metadata["scan_info"]["trARPES:XGS600:PressureAC:P_RD"] = 2.5E-11
metadata["scan_info"]["trARPES:Carving:TEMP_RBV"] = 70
metadata["scan_info"]["trARPES:Sample:Measure"] = 0

The SpecsScan instance is created from a config, that contains a rewrite entry to change names of axes

[3]:
config = {"nexus":{"definition": "NXmpes_arpes"}, "spa_params":{"crop":True, "ek_range_min":0.07597844332538181, "ek_range_max":0.9117413199045858, "ang_range_min":0.16453159041394336, "ang_range_max":0.8840087145969499,}}
sps = SpecsScan(config=config, user_config="../specsscan/config/example_config_FHI.yaml")
path = "../tests/data/" # Path to the test data set
User config loaded from: [/home/runner/work/specsanalyzer/specsanalyzer/docs/specsscan/config/example_config_FHI.yaml]
Default config loaded from: [/home/runner/work/specsanalyzer/specsanalyzer/specsscan/config/default.yaml]
Default config loaded from: [/home/runner/work/specsanalyzer/specsanalyzer/specsanalyzer/config/default.yaml]

The load_scan method loads the scan as an xarray along with the metadata needed for nexus conversion.

[4]:
res_xarray = sps.load_scan(
    scan=1496, # Tilt scan
    path=path,
    metadata=metadata,
    collect_metadata=True,
)
Cropping parameters not found, using cropping ranges from config...
Gathering metadata from different locations
Collecting time stamps...
Done!

The resulting 3-dimensional data cube

[5]:
res_xarray.dims
[5]:
('angular0', 'angular1', 'energy')

A Gamma-point cut

[6]:
plt.figure()
res_xarray[:,30,:].T.plot()
[6]:
<matplotlib.collections.QuadMesh at 0x7f1d14e20e80>

The Fermi surface

[7]:
plt.figure()
res_xarray.loc[{"energy":slice(21.6, 21.8)}].sum(axis=2).plot()
[7]:
<matplotlib.collections.QuadMesh at 0x7f1ce74fa3d0>

Save as nexus file

[8]:
sps.save("FSmapping.nxs")
Using mpes reader to convert the given files:
• ../specsscan/config/NXmpes_arpes_config.json
The output file generated: FSmapping.nxs.
[ ]: