Accessors (erlab.accessors)

Some xarray accessors for convenient data analysis and visualization.

Modules

class erlab.accessors.InteractiveDataArrayAccessor(xarray_obj)[source]

Bases: ERLabDataArrayAccessor

xarray.DataArray.qshow accessor for interactive visualization.

__call__(*args, **kwargs)[source]

Visualize the data interactively.

Chooses the appropriate interactive visualization method based on the number of dimensions in the data.

Parameters:
  • *args – Positional arguments passed onto the interactive visualization function.

  • **kwargs – Keyword arguments passed onto the interactive visualization function.

hvplot(*args, **kwargs)[source]

hvplot-based interactive visualization.

Parameters:
  • *args – Positional arguments passed onto DataArray.hvplot().

  • **kwargs – Keyword arguments passed onto DataArray.hvplot().

Raises:

ImportError – If hvplot is not installed.

itool(*args, **kwargs)[source]

Shortcut for itool.

Parameters:
  • *args – Positional arguments passed onto itool.

  • **kwargs – Keyword arguments passed onto itool.

class erlab.accessors.InteractiveDatasetAccessor(xarray_obj)[source]

Bases: ERLabDatasetAccessor

xarray.Dataset.qshow accessor for interactive visualization.

__call__(*args, **kwargs)[source]

Visualize the data interactively.

Chooses the appropriate interactive visualization method based on the data variables.

Parameters:
  • *args – Positional arguments passed onto the interactive visualization function.

  • **kwargs – Keyword arguments passed onto the interactive visualization function.

fit(plot_components=False)[source]

Interactive visualization of fit results.

Parameters:

plot_components (bool) – If True, plot the components of the fit. Default is False. Requires the Dataset to have a modelfit_results variable.

Returns:

A panel containing the interactive visualization.

Return type:

panel.Column

hvplot(*args, **kwargs)[source]

hvplot-based interactive visualization.

Parameters:
  • *args – Positional arguments passed onto Dataset.hvplot().

  • **kwargs – Keyword arguments passed onto Dataset.hvplot().

Raises:

ImportError – If hvplot is not installed.

itool(*args, **kwargs)[source]

Shortcut for itool.

Parameters:
  • *args – Positional arguments passed onto itool.

  • **kwargs – Keyword arguments passed onto itool.

class erlab.accessors.ModelFitDataArrayAccessor(xarray_obj)[source]

Bases: ERLabDataArrayAccessor

xarray.DataArray.modelfit accessor for fitting lmfit models.

__call__(*args, **kwargs)[source]

Curve fitting optimization for arbitrary models.

Wraps lmfit.Model.fit with xarray.apply_ufunc().

Parameters:
  • coords (Hashable, xarray.DataArray, or Sequence of Hashable or xarray.DataArray) – Independent coordinate(s) over which to perform the curve fitting. Must share at least one dimension with the calling object. When fitting multi-dimensional functions, supply coords as a sequence in the same order as arguments in func. To fit along existing dimensions of the calling object, coords can also be specified as a str or sequence of strs.

  • model (lmfit.Model) – A model object to fit to the data. The model must be an instance of lmfit.Model.

  • reduce_dims (str, Iterable of Hashable or None, optional) – Additional dimension(s) over which to aggregate while fitting. For example, calling ds.modelfit(coords='time', reduce_dims=['lat', 'lon'], ...) will aggregate all lat and lon points and fit the specified function along the time dimension.

  • skipna (bool, default: True) – Whether to skip missing values when fitting. Default is True.

  • params (lmfit.Parameters, dict-like, or xarray.DataArray, optional) – Optional input parameters to the fit. If a lmfit.Parameters object, it will be used for all fits. If a dict-like object, it must look like the keyword arguments to lmfit.create_params. Additionally, each value of the dictionary may also be a DataArray, which will be broadcasted appropriately. If a DataArray, each entry must be a dictionary-like object, a lmfit.Parameters object, or a JSON string created with lmfit.Parameters.dumps. If given a Dataset, the name of the data variables in the Dataset must match the name of the data variables in the calling object, and each data variable will be used as the parameters for the corresponding data variable. If none or only some parameters are passed, the rest will be assigned initial values and bounds with lmfit.Model.make_params, or guessed with lmfit.Model.guess if guess is True.

  • guess (bool, default: False) – Whether to guess the initial parameters with lmfit.Model.guess. For composite models, the parameters will be guessed for each component.

  • errors ({"raise", "ignore"}, default: "raise") – If 'raise', any errors from the lmfit.Model.fit optimization will raise an exception. If 'ignore', the return values for the coordinates where the fitting failed will be NaN.

  • parallel (bool, optional) – Whether to parallelize the fits over the data variables. If not provided, parallelization is only applied for non-dask Datasets with more than 200 data variables.

  • parallel_kw (dict, optional) – Additional keyword arguments to pass to the parallelization backend joblib.Parallel if parallel is True.

  • progress (bool, default: False) – Whether to show a progress bar for fitting over data variables. Only useful if there are multiple data variables to fit.

  • output_result (bool, default: True) – Whether to include the full lmfit.model.ModelResult object in the output dataset. If True, the result will be stored in a variable named modelfit_results.

  • **kwargs (optional) – Additional keyword arguments to passed to lmfit.Model.fit.

Returns:

curvefit_results – A single dataset which contains:

modelfit_results

The full lmfit.model.ModelResult object from the fit. Only included if output_result is True.

modelfit_coefficients

The coefficients of the best fit.

modelfit_stderr

The standard errors of the coefficients.

modelfit_covariance

The covariance matrix of the coefficients. Note that elements corresponding to non varying parameters are set to NaN, and the actual size of the covariance matrix may be smaller than the array.

modelfit_stats

Statistics from the fit. See lmfit.minimize.

modelfit_data

Data used for the fit.

modelfit_best_fit

The best fit data of the fit.

Return type:

xarray.Dataset

class erlab.accessors.ModelFitDatasetAccessor(xarray_obj)[source]

Bases: ERLabDatasetAccessor

xarray.Dataset.modelfit accessor for fitting lmfit models.

__call__(coords, model, reduce_dims=None, skipna=True, params=None, guess=False, errors='raise', parallel=None, parallel_kw=None, progress=False, output_result=True, **kwargs)[source]

Curve fitting optimization for arbitrary models.

Wraps lmfit.Model.fit with xarray.apply_ufunc().

Parameters:
  • coords (Hashable, xarray.DataArray, or Sequence of Hashable or xarray.DataArray) – Independent coordinate(s) over which to perform the curve fitting. Must share at least one dimension with the calling object. When fitting multi-dimensional functions, supply coords as a sequence in the same order as arguments in func. To fit along existing dimensions of the calling object, coords can also be specified as a str or sequence of strs.

  • model (lmfit.Model) – A model object to fit to the data. The model must be an instance of lmfit.Model.

  • reduce_dims (str, Iterable of Hashable or None, optional) – Additional dimension(s) over which to aggregate while fitting. For example, calling ds.modelfit(coords='time', reduce_dims=['lat', 'lon'], ...) will aggregate all lat and lon points and fit the specified function along the time dimension.

  • skipna (bool, default: True) – Whether to skip missing values when fitting. Default is True.

  • params (lmfit.Parameters, dict-like, or xarray.DataArray, optional) – Optional input parameters to the fit. If a lmfit.Parameters object, it will be used for all fits. If a dict-like object, it must look like the keyword arguments to lmfit.create_params. Additionally, each value of the dictionary may also be a DataArray, which will be broadcasted appropriately. If a DataArray, each entry must be a dictionary-like object, a lmfit.Parameters object, or a JSON string created with lmfit.Parameters.dumps. If given a Dataset, the name of the data variables in the Dataset must match the name of the data variables in the calling object, and each data variable will be used as the parameters for the corresponding data variable. If none or only some parameters are passed, the rest will be assigned initial values and bounds with lmfit.Model.make_params, or guessed with lmfit.Model.guess if guess is True.

  • guess (bool, default: False) – Whether to guess the initial parameters with lmfit.Model.guess. For composite models, the parameters will be guessed for each component.

  • errors ({"raise", "ignore"}, default: "raise") – If 'raise', any errors from the lmfit.Model.fit optimization will raise an exception. If 'ignore', the return values for the coordinates where the fitting failed will be NaN.

  • parallel (bool, optional) – Whether to parallelize the fits over the data variables. If not provided, parallelization is only applied for non-dask Datasets with more than 200 data variables.

  • parallel_kw (dict, optional) – Additional keyword arguments to pass to the parallelization backend joblib.Parallel if parallel is True.

  • progress (bool, default: False) – Whether to show a progress bar for fitting over data variables. Only useful if there are multiple data variables to fit.

  • output_result (bool, default: True) – Whether to include the full lmfit.model.ModelResult object in the output dataset. If True, the result will be stored in a variable named [var]_modelfit_results.

  • **kwargs (optional) – Additional keyword arguments to passed to lmfit.Model.fit.

Returns:

curvefit_results – A single dataset which contains:

[var]_modelfit_results

The full lmfit.model.ModelResult object from the fit. Only included if output_result is True.

[var]_modelfit_coefficients

The coefficients of the best fit.

[var]_modelfit_stderr

The standard errors of the coefficients.

[var]_modelfit_covariance

The covariance matrix of the coefficients. Note that elements corresponding to non varying parameters are set to NaN, and the actual size of the covariance matrix may be smaller than the array.

[var]_modelfit_stats

Statistics from the fit. See lmfit.minimize.

[var]_modelfit_data

Data used for the fit.

[var]_modelfit_best_fit

The best fit data of the fit.

Return type:

xarray.Dataset

class erlab.accessors.MomentumAccessor(xarray_obj)[source]

Bases: ERLabDataArrayAccessor

xarray.DataArray.kspace accessor for momentum conversion related utilities.

This class provides convenient access to various momentum-related properties of a data object. It allows getting and setting properties such as configuration, inner potential, work function, angle resolution, slit axis, momentum axes, angle parameters, and offsets.

convert(bounds=None, resolution=None, *, silent=False, **coords)[source]

Convert to momentum space.

Parameters:
  • bounds (dict[str, tuple[float, float]] | None) – A dictionary specifying the bounds for each coordinate axis. The keys are the names of the axes, and the values are tuples representing the lower and upper bounds of the axis. If not provided, the bounds will be estimated based on the data.

  • resolution (dict[str, float] | None) – A dictionary specifying the resolution for each momentum axis. The keys are the names of the axes, and the values are floats representing the desired resolution of the axis. If not provided, the resolution will be estimated based on the data. For in-plane momentum, the resolution is estimated from the angle resolution and kinetic energy. For out-of-plane momentum, two values are calculated. One is based on the number of photon energy points, and the other is estimated as the inverse of the photoelectron inelastic mean free path given by the universal curve. The resolution is estimated as the smaller of the two values.

  • silent (bool) – If True, suppresses printing, by default False.

  • **coords – Array-like keyword arguments that specifies the coordinate array for each momentum axis. If provided, the bounds and resolution will be ignored.

Returns:

The converted data.

Return type:

xarray.DataArray

Note

This method converts the data to a new coordinate system specified by the provided bounds and resolution. It uses interpolation to map the data from the original coordinate system to the new one.

The converted data is returned as a DataArray object with updated coordinates and dimensions.

Examples

Set parameters and convert with automatic bounds and resolution:

data.kspace.offsets = {"delta": 0.1, "xi": 0.0, "beta": 0.3}
data.kspace.work_function = 4.3
data.kspace.inner_potential = 12.0
converted_data = data.kspace.convert()

Convert with specified bounds and resolution:

bounds = {"kx": (0.0, 1.0), "ky": (-1.0, 1.0)}
resolution = {"kx": 0.01, "ky": 0.01}
converted_data = data.kspace.convert(bounds, resolution)
convert_coords()[source]

Convert the coordinates to momentum space.

Assigns new exact momentum coordinates to the data. This is useful when you want to work with momentum coordinates but don’t want to interpolate the data.

Returns:

The DataArray with transformed coordinates.

Return type:

xarray.DataArray

estimate_bounds()[source]

Estimate the bounds of the data in momentum space.

Returns:

bounds – A dictionary containing the estimated bounds for each parameter. The keys of the dictionary are ‘kx’, ‘ky’, and ‘kz’ (for \(hν\)-dependent data). The values are tuples representing the minimum and maximum values.

Return type:

dict[str, tuple[float, float]]

estimate_resolution(axis, lims=None, from_numpoints=False)[source]

Estimate the resolution for a given momentum axis.

Parameters:
  • axis (Literal['kx', 'ky', 'kz']) – Axis to estimate the resolution for.

  • lims (tuple[float, float] | None) – The limits of the axis used when from_numpoints is True. If not provided, reasonable limits will be calculated by estimate_bounds(), by default None

  • from_numpoints (bool) – If True, estimate the resolution from the number of points in the relevant axis. If False, estimate the resolution based on the data, by default False

Returns:

The estimated resolution.

Return type:

float

Raises:

ValueError – If no photon energy axis is found in data for axis 'kz'.

hv_to_kz(hv)[source]

Return \(k_z\) for a given photon energy.

Useful when creating overlays on \(hν\)-dependent data.

Parameters:

hv (float) – Photon energy in eV.

Note

This will be inexact for hv-dependent cuts that do not pass through the BZ center since we lost the exact angle values, i.e. the exact momentum perpendicular to the slit, during momentum conversion.

interactive(**kwargs)[source]

Open the interactive momentum space conversion tool.

property alpha: DataArray
property angle_params: dict[str, float]

Parameters passed to erlab.analysis.kspace.get_kconv_func().

property angle_resolution: float

Retrieve the angular resolution of the data in degrees.

Checks for the angle_resolution attribute of the data. If not found, a default value of 0.1° is silently assumed.

This property is used in best_kp_resolution upon estimating momentum step sizes through estimate_resolution.

property best_kp_resolution: float

Estimate the minimum in-plane momentum resolution.

The resolution is estimated with the kinetic energy and angular resolution:

\[\Delta k_{\parallel} \sim \sqrt{2 m_e E_k/\hbar^2} \cos(\alpha) \Delta\alpha\]
property best_kz_resolution: float

Estimate the minimum out-of-plane momentum resolution.

The resolution is estimated based on the mean free path [8] and the kinetic energy.

\[\Delta k_z \sim 1/\lambda\]
property beta: DataArray
property binding_energy: DataArray
property configuration: AxesConfiguration

Return the experimental configuration.

For a properly implemented data loader, the configuration attribute must be set on data import. See erlab.analysis.kspace.AxesConfiguration for details.

property has_beta: bool

Check if the coordinate array for \(β\) has more than one element.

Returns:

Returns True if the size of the coordinate array for \(β\) is greater than 1, False otherwise.

Return type:

bool

Note

This may be True for data that are not maps. For instance, \(hν\)-dependent cuts with an in-plane momentum offset may have a \(hν\)-dependent \(β\) offset.

property has_eV: bool

Return True if object has an energy axis.

property has_hv: bool

Return True for photon energy dependent data.

property hv: DataArray
property inner_potential: float

Inner potential of the sample in eV.

The inner potential is stored in the inner_potential attribute of the data. If the inner potential is not set, a warning is issued and a default value of 10.0 eV is assumed.

Note

This property provides a setter method that takes a float value and sets the data attribute accordingly.

Example

>>> data.kspace.inner_potential = 13.0
>>> data.kspace.inner_potential
13.0
property kinetic_energy: DataArray
property momentum_axes: tuple[Literal['kx', 'ky', 'kz'], ...]

Return the momentum axes of the data after conversion.

Returns:

For photon energy dependent scans, it returns the slit axis and 'kz'. For maps, it returns 'kx' and 'ky'. Otherwise, it returns only the slit axis.

Return type:

tuple

property offsets: OffsetView

Angle offsets used in momentum conversion.

Returns:

A mapping between valid offset keys and their corresponding offsets.

Return type:

OffsetView

Examples

  • View all offsets

    >>> data.kspace.offsets
    {'delta': 0.0, 'xi': 0.0, 'beta': 0.0}
    
  • View single offset

    >>> data.kspace.offsets["beta"]
    0.0
    
  • Offsets to dictionary

    >>> dict(data.kspace.offsets)
    {'delta': 0.0, 'xi': 0.0, 'beta': 0.0}
    
  • Set single offset

    >>> data.kspace.offsets["beta"] = 3.0
    >>> data.kspace.offsets
    {'delta': 0.0, 'xi': 0.0, 'beta': 3.0}
    
  • Overwrite offsets with dictionary

    >>> data.kspace.offsets = dict(delta=1.5, xi=2.7)
    >>> data.kspace.offsets
    {'delta': 1.5, 'xi': 2.7, 'beta': 0.0}
    
  • Update offsets

    >>> data.kspace.offsets.update(beta=0.1, xi=0.0)
    {'delta': 1.5, 'xi': 0.0, 'beta': 0.1}
    
  • Reset all offsets

    >>> data.kspace.offsets.reset()
    {'delta': 0.0, 'xi': 0.0, 'beta': 0.0}
    
property other_axis: Literal['kx', 'ky']

Return the momentum axis perpendicular to the slit.

Returns:

Returns 'ky' for type 1 configurations, 'kx' otherwise.

Return type:

str

property slit_axis: Literal['kx', 'ky']

Return the momentum axis parallel to the slit.

Returns:

Returns 'kx' for type 1 configurations, 'ky' otherwise.

Return type:

str

property valid_offset_keys: tuple[str, ...]

Get valid offset angles based on the experimental configuration.

Returns:

A tuple containing the valid offset keys. For configurations with a deflector, returns ("delta", "chi", "xi"). Otherwise, returns ("delta", "xi", "beta").

Return type:

tuple

property work_function: float

Work function of the sample in eV.

The work function is stored in the sample_workfunction attribute of the data. If not found, a warning is issued and a default value of 4.5 eV is assumed.

Note

This property provides a setter method that takes a float value and sets the data attribute accordingly.

Example

>>> data.kspace.work_function = 4.5
>>> data.kspace.work_function
4.5
class erlab.accessors.OffsetView(xarray_obj)[source]

Bases: object

A class representing an offset view for an xarray.DataArray.

This class provides a convenient way to access and manipulate angle offsets associated with the given data.

Parameters:

xarray_obj (DataArray) – The xarray.DataArray for which the offset view is created.

__len__() int:

Returns the number of valid offset keys.

__iter__() Iterator[str, float]:[source]

Returns an iterator over the valid offset keys and their corresponding values.

__getitem__(key: str) float:[source]

Returns the offset value associated with the given key.

__setitem__(key: str, value: float) None:[source]

Sets the offset value for the given key.

__eq__(other: object) bool:[source]

Compares the offset view with another object for equality. True if the dictionary representation is equal, False otherwise.

__repr__() str:[source]

Returns a string representation of the offset view.

_repr_html_() str:[source]

Returns an HTML representation of the offset view.

items()[source]

Return a view of the offset view as a list of (key, value) pairs.

reset()[source]

Reset all angle offsets to zero.

update(other=None, **kwargs)[source]

Update the offset view with the provided key-value pairs.

class erlab.accessors.ParallelFitDataArrayAccessor(xarray_obj)[source]

Bases: ERLabDataArrayAccessor

xarray.DataArray.parallel_fit accessor for fitting lmfit models in parallel.

__call__(dim, model, **kwargs)[source]

Fit the specified model to the data along the given dimension.

Parameters:
  • dim (str) – The name of the dimension along which to fit the model.

  • model (lmfit.Model) – The model to fit.

  • **kwargs (dict) – Additional keyword arguments to be passed to xarray.Dataset.modelfit.

Returns:

curvefit_results – The dataset containing the results of the fit. See xarray.DataArray.modelfit for details.

Return type:

xarray.Dataset

class erlab.accessors.PlotAccessor(xarray_obj)[source]

Bases: ERLabDataArrayAccessor

xarray.DataArray.qplot accessor for plotting data.

__call__(*args, **kwargs)[source]

Plot the data.

If a 2D data array is provided, it is plotted using plot_array. Otherwise, it is equivalent to calling xarray.DataArray.plot().

Parameters:
  • *args – Positional arguments to be passed to the plotting function.

  • **kwargs – Keyword arguments to be passed to the plotting function.

class erlab.accessors.SelectionAccessor(xarray_obj)[source]

Bases: ERLabDataArrayAccessor

xarray.DataArray.qsel accessor for convenient selection and averaging.

__call__(indexers=None, *, verbose=False, **indexers_kwargs)[source]

Select and average data along specified dimensions.

Parameters:
  • indexers (Mapping[Hashable, float | slice] | None) –

    Dictionary specifying the dimensions and their values or slices. Position along a dimension can be specified in three ways:

    • As a scalar value: alpha=-1.2

      If no width is specified, the data is selected along the nearest value. It is equivalent to xarray.DataArray.sel with method='nearest'.

    • As a value and width: alpha=5, alpha_width=0.5

      The data is averaged over a slice of width alpha_width, centered at alpha.

    • As a slice: alpha=slice(-10, 10)

      The data is selected over the specified slice. No averaging is performed.

    One of indexers or indexers_kwargs must be provided.

  • verbose (bool) – If True, print information about the selected data and averaging process. Default is False.

  • **indexers_kwargs – The keyword arguments form of indexers. One of indexers or indexers_kwargs must be provided.

Returns:

The selected and averaged data.

Return type:

xarray.DataArray

Raises:

ValueError – If a specified dimension is not present in the data.