erlab.analysis.gold

Fermi edge fitting.

Functions

correct_with_edge(darr, modelresult, *[, ...])

Corrects the given data array darr with the given values or fit result.

edge(gold, *[, along, adaptive, bin_size, ...])

Fit a Fermi edge to the given gold data.

guess_edge_fit_range(edc, *[, energy_dim, ...])

Estimate the energy range for fitting one Fermi edge.

poly(gold, *[, along, adaptive, bin_size, ...])

Fit a polynomial Fermi edge and optionally correct the data.

poly_from_edge(center[, weights, degree, ...])

Fit a polynomial to Fermi edge centers.

quick_fit(darr, *[, eV_range, method, temp, ...])

Perform a Fermi edge fit on an EDC.

quick_resolution(darr[, ax])

Fit a Fermi edge to the given data and plot the results.

resolution(gold, angle_range, eV_range_edge)

Fit a Fermi edge and obtain the resolution from the corrected data.

resolution_roi(gold_roi, eV_range[, ...])

Fit a Fermi edge to the data and obtain the resolution.

spline_from_edge(center[, weights, lam, along])

Fit a smoothing spline to Fermi edge centers.

erlab.analysis.gold.correct_with_edge(darr, modelresult, *, along='alpha', shift_coords=True, plot=False, plot_kw=None, **shift_kwargs)[source]

Corrects the given data array darr with the given values or fit result.

Parameters:
  • darr (DataArray) – The input data array to be corrected.

  • modelresult (ModelResult | Dataset | ndarray[tuple[Any, ...], dtype[floating]] | Callable | tuple[float, ...]) – The model result that contains the Fermi edge information. It can be an instance of lmfit.model.ModelResult, a numpy array containing the edge position at each angle, a fit result dataset that contains polynomial coefficients, a callable function that takes an array of angles and returns the corresponding energy value, or a tuple of coefficients for a polynomial (lowest order first).

  • along (str, default: 'alpha') – The angular dimension name in the data.

  • shift_coords (bool, default: True) – If True, the coordinates of the output data will be changed so that the output contains all the values of the original data. If False, the coordinates and shape of the original data will be retained, and only the data will be shifted. Defaults to True.

  • plot (bool, default: False) – Whether to plot the original and corrected data arrays. Defaults to False.

  • plot_kw (dict | None, default: None) – Additional keyword arguments passed to erlab.plotting.plot_array() when plot is True. Defaults to None.

  • **shift_kwargs – Additional keyword arguments passed to erlab.analysis.transform.shift().

Returns:

corrected (xarray.DataArray) – A new array containing the edge-corrected data. The input dimension names are retained. By default, the energy coordinate is sorted in ascending order. If shift_coords is True, it is also shifted and can be extended, which can increase the length of the eV dimension. If shift_coords is False, the energy coordinate values and shape are retained. The data name and attributes are preserved.

Return type:

DataArray

erlab.analysis.gold.edge(gold, *, along='alpha', angle_range, eV_range, adaptive=False, bin_size=(1, 1), temp=None, vary_temp=False, bkg_slope=True, resolution=0.02, use_step_edge=False, method='least_squares', scale_covar=True, normalize=True, fixed_center=None, progress=True, parallel_kw=None, parallel_obj=None, return_full=False, drop_nans=False, **kwargs)[source]

Fit a Fermi edge to the given gold data.

Only successful fits with valid error estimates are returned.

Parameters:
  • gold (DataArray) – The gold data to fit the edge model to.

  • along (str, default: 'alpha') –

    The dimension along which to parallelize the fitting. By default "alpha". It is better to choose the dimension with the largest number of points.

    If gold is chunked, this parameter is only used to specify the dimension along which to apply angle_range.

  • angle_range (tuple[float, float]) – Coordinate range to fit along along, in the units of that coordinate.

  • eV_range (tuple[float, float]) – Energy range to fit, in eV.

  • adaptive (bool, default: False) – If True, estimate and use a separate energy range for each EDC within eV_range. If no valid falling edge is detected in one EDC, that EDC uses the complete eV_range. Defaults to False.

  • bin_size (tuple[int, int], default: (1, 1)) – Number of points to average along (along, "eV") before fitting. Data at an incomplete final bin is discarded. Default is (1, 1).

  • temp (float | None, default: None) – The temperature in Kelvins. If None, the temperature is inferred from the attributes, by default None

  • vary_temp (bool, default: False) – Whether to fit the temperature value during fitting, by default False.

  • bkg_slope (bool, default: True) – Whether to include a linear background above the Fermi level. If False, the background above the Fermi level is fit with a constant. Defaults to True.

  • resolution (float, default: 0.02) – Initial energy broadening FWHM in eV. Default is 0.02.

  • use_step_edge (bool, default: False) – Whether to use the Gaussian-broadened step function to fit the edge, by default False.

  • method (str, default: 'least_squares') – The fitting method to use, by default "least_squares".

  • scale_covar (bool, default: True) – Whether to scale the covariance matrix, by default True.

  • fixed_center (float | None, default: None) – The center value in eV. If supplied, the center is fixed at this value.

  • normalize (bool, default: True) – Whether to normalize the energy coordinates, by default True.

  • progress (bool, default: True) – Whether to display the fitting progress, by default True.

  • parallel_kw (dict | None, default: None) – Additional keyword arguments passed to joblib.Parallel.

  • parallel_obj (Parallel | None, default: None) – The joblib.Parallel object to use for fitting, by default None. If provided, parallel_kw will be ignored.

  • return_full (bool, default: False) – Whether to return the full fit results, by default False.

  • drop_nans (bool, default: False) – Whether to drop fits that resulted in NaN values, by default False. If True, the function will always return the computed data even for chunked inputs, because dropping NaNs requires computing all fit results. If return_full is True, this option is ignored.

  • **kwargs – Additional keyword arguments passed to xarray.DataArray.xlm.modelfit().

Returns:

  • center_arr, center_stderr (tuple of xarray.DataArray) – Fitted Fermi-level positions and standard errors in eV when return_full is False. The eV dimension is removed. Other dimensions and coordinates come from the selected and optionally coarsened input. Both arrays have empty attributes. If drop_nans is True, coordinate labels without valid fits are removed.

  • fit_result (xarray.Dataset) – Full result from xarray.DataArray.xlm.modelfit() when return_full is True. The input gold is not modified.

Return type:

tuple[DataArray, DataArray] | Dataset

erlab.analysis.gold.guess_edge_fit_range(edc, *, energy_dim='eV', temp=None, resolution=0.02, bkg_slope=True, use_step_edge=False, **kwargs)[source]

Estimate the energy range for fitting one Fermi edge.

The returned bounds are ordered from low to high energy and can be used as edc.sel(eV=slice(*bounds)) when the energy coordinate is increasing.

Parameters:
  • edc (DataArray) – One energy distribution curve.

  • energy_dim (str, default: 'eV') – Name of the energy dimension.

  • temp (float | None, default: None) – Sample temperature in kelvins. If None, infer it from edc. The broadened step model uses 10 K when the temperature is not available.

  • resolution (float, default: 0.02) – Initial energy-resolution FWHM in electronvolts.

  • bkg_slope (bool, default: True) – If True, include a linear background above the Fermi level.

  • use_step_edge (bool, default: False) – If True, use the nominal width of a broadened step edge. If False, use the combined thermal and resolution width of a Fermi edge. Defaults to False.

Returns:

lower, upper – Estimated energy bounds in the units of the energy coordinate.

Return type:

tuple[float, float]

Notes

The estimator uses the following steps:

  1. It calculates a nominal edge standard deviation. For a Fermi edge model, this is

    \[\sigma_0 = \max\left[\Delta x, \sqrt{\left(\frac{R}{\sqrt{8\ln 2}}\right)^2 + \left(\frac{\pi k_\mathrm{B}T}{\sqrt{3}}\right)^2}\right].\]

    For the step function, it uses

    \[\sigma_0 = \max\left[\Delta x, \frac{R + 3.5255 k_\mathrm{B}T}{\sqrt{8\ln 2}}\right].\]

    Here, \(R\) is the resolution FWHM and \(\Delta x\) is the energy spacing.

  2. It estimates the local point noise from the second-difference residual

    \[r_i = 2y_i-y_{i-2}-y_{i+2}, \qquad \hat\sigma_{n,i} = \frac{1.4826}{\sqrt{6}}\operatorname{MAD}(r).\]

    The MAD uses a rolling window of approximately \(16\sigma_0\), with a 25-sample minimum when that many residual samples are available. The factors 1.4826 and \(\sqrt{6}\) correct the MAD for Gaussian noise and the variance of the second difference, respectively.

  3. It replaces samples that differ from a five-sample median by more than six local noise levels in the detection copy. This replacement does not modify the data used for fits.

  4. It performs a multiscale search for local maxima of negative Gaussian derivatives with widths of \(\{0.5,1,2,4\}\sigma_0\). A candidate must have derivative prominence above the propagated local noise. It must also have a falling-side contrast above three contrast-noise levels and 1% of the robust signal span. A quadratic interpolation refines its position. The highest-energy valid candidate becomes the edge anchor.

  5. It fits broadened step models with lower bounds at offsets of \(\{4,6,8,10,12,16,20,24,32\}\sigma_0\) below the anchor. The anchor and nominal width initialize each fit. The linear coefficients are initialized conditionally on the broadened step \(s(x)\):

    \[y(x) = [1-s(x)](b_0+b_1x) + s(x)(d_0+d_1x).\]

    When bkg_slope=False, the fit fixes \(b_1=0\).

  6. A trial is accepted when the fitted center remains inside the fit domain and the fitted width is between \(0.05\sigma_0\) and \(3\sigma_0\). The domain must contain at least three fitted widths below the center and half a fitted width above it.

  7. The estimator returns the middle lower bound of the first three consecutive accepted fits whose centers span at most \(0.5\sigma_0\) and whose widths differ by at most a factor of three. If this plateau is unavailable, it uses the longest shorter plateau, then a local single-step fallback. The fallback can return the full input range when the available support is insufficient. The upper bound is the highest input energy.

Raises:

ValueError – If the input is not one-dimensional, lacks required temperature metadata, has insufficient data, or has no qualifying falling edge.

erlab.analysis.gold.poly(gold, *, along='alpha', angle_range, eV_range, adaptive=False, bin_size=(1, 1), temp=None, vary_temp=False, bkg_slope=True, resolution=0.02, use_step_edge=False, method='least_squares', normalize=True, degree=4, correct=False, return_edge=False, crop_correct=False, parallel_kw=None, plot=True, fig=None, scale_covar=True, scale_covar_edge=True, **kwargs)[source]

Fit a polynomial Fermi edge and optionally correct the data.

This function fits each EDC with edge(), then fits a polynomial to the accepted Fermi level positions with poly_from_edge().

Parameters:
  • gold (DataArray) – Fermi-edge data with "eV" and along dimensions.

  • along (str, default: 'alpha') – Angular dimension along which the Fermi level varies.

  • angle_range (tuple[float, float]) – Coordinate range to fit along along, in the units of that coordinate.

  • eV_range (tuple[float, float]) – Energy range to fit, in eV.

  • adaptive (bool, default: False) – Whether to estimate a separate energy range for each EDC.

  • bin_size (tuple[int, int], default: (1, 1)) – Number of points to average along (along, "eV") before fitting.

  • temp (float | None, default: None) – Sample temperature in K. If omitted, read it from gold.

  • vary_temp (bool, default: False) – Whether each EDC fit can vary the temperature.

  • bkg_slope (bool, default: True) – Whether to fit a linear background above the Fermi level.

  • resolution (float, default: 0.02) – Initial Gaussian energy-resolution FWHM in eV.

  • use_step_edge (bool, default: False) – Whether to use a Gaussian-broadened step instead of a Fermi-Dirac edge.

  • method (str, default: 'least_squares') – Minimization method used for the EDC and polynomial fits.

  • normalize (bool, default: True) – Whether to normalize the energy coordinate internally before each EDC fit. The returned edge positions and errors remain in eV.

  • degree (int, default: 4) – Degree of the polynomial edge.

  • correct (bool, default: False) – If True, also return data corrected with the fitted edge. This option cannot be used with return_edge.

  • return_edge (bool, default: False) – If True, return the fitted edge evaluated at the original along coordinate instead of the polynomial fit result.

  • crop_correct (bool, default: False) – If True with correct=True, restrict the corrected data to angle_range and eV_range before applying the correction.

  • parallel_kw (dict | None, default: None) – Additional keyword arguments passed to joblib.Parallel for the EDC fits.

  • plot (bool, default: True) – Whether to draw the edge-fit diagnostic.

  • fig (Figure | None, default: None) – Figure that receives the diagnostic. If omitted, a new figure is created.

  • scale_covar (bool, default: True) – Whether lmfit scales the covariance matrix for the polynomial fit.

  • scale_covar_edge (bool, default: True) – Whether lmfit scales the covariance matrix for each EDC fit.

  • **kwargs – Reserved for compatibility. Do not pass additional keyword arguments.

Returns:

Return type:

Dataset | DataArray | tuple[Dataset, DataArray]

erlab.analysis.gold.poly_from_edge(center, weights=None, degree=4, method='least_squares', scale_covar=True, along='alpha')[source]

Fit a polynomial to Fermi edge centers.

Parameters:
  • center (DataArray) – Fermi level position as a function of along in eV.

  • weights (default: None) – Fit weights broadcastable to center. For inverse standard deviation weighting, pass 1 / center_stderr.

  • degree (int, default: 4) – Polynomial degree.

  • method (default: 'least_squares') – Minimization method accepted by lmfit.

  • scale_covar (default: True) – Whether lmfit scales the covariance matrix by the reduced chi-square.

  • along (str, default: 'alpha') – Independent coordinate for the polynomial fit.

Returns:

xarray.Dataset – The standard result from xarray.DataArray.xlm.modelfit(), including the polynomial coefficients and fit result. The input center is not modified.

Return type:

Dataset

erlab.analysis.gold.quick_fit(darr, *, eV_range=None, method='leastsq', temp=None, resolution=None, center=None, fix_temp=True, fix_center=False, fix_resolution=False, bkg_slope=True, plot=False, ax=None, plot_fit_kwargs=None, plot_data_kwargs=None, plot_line_kwargs=None, plot_span_kwargs=None, **kwargs)[source]

Perform a Fermi edge fit on an EDC.

This function is a convenient wrapper around DataArray.xlm.modelfit() that fits a Fermi edge to the given data.

If data with 2 or more dimensions is provided, the data is averaged over all dimensions except the energy prior to fitting.

Parameters:
  • darr (DataArray) – The input data to be fitted.

  • eV_range (tuple[float, float] | None, default: None) – Energy range to fit, in eV. If None, use the full energy coordinate.

  • method (str, default: 'leastsq') – The fitting method to use that is compatible with lmfit. Defaults to “leastsq”.

  • temp (float | None, default: None) – Sample temperature in K. If None, infer it from the data attributes.

  • resolution (float | None, default: None) – Initial Gaussian energy-resolution FWHM in eV. If None, use the "TotalResolution" attribute after conversion from meV to eV, or use 0.02 eV when that attribute is absent.

  • center (float | None, default: None) – Initial Fermi level position in eV. If None, guess it unless fix_center is True, in which case it is fixed at zero.

  • fix_temp (bool, default: True) – Whether to fix the temperature value during fitting. Defaults to True.

  • fix_center (bool, default: False) – Whether to fix the Fermi level during fitting. If True, the Fermi level is fixed to 0. Defaults to False.

  • fix_resolution (bool, default: False) – Whether to fix the resolution value during fitting. Defaults to False.

  • bkg_slope (bool, default: True) – Whether to include a linear background above the Fermi level. If False, the background above the Fermi level is fit with a constant. Defaults to True.

  • plot (bool, default: False) – Whether to plot the result of the fit. Defaults to False.

  • ax (Axes | None, default: None) – The axes to plot the result on if plot is True. If None, the current axes are used.

  • plot_fit_kwargs (dict[str, Any] | None, default: None) – Additional keyword arguments for the fit plot, passed to matplotlib.axes.Axes.plot(). Defaults to None.

  • plot_data_kwargs (dict[str, Any] | None, default: None) – Additional keyword arguments for the data plot, passed to matplotlib.axes.Axes.plot(). Defaults to None.

  • plot_line_kwargs (dict[str, Any] | None, default: None) – Additional keyword arguments for the plot line that indicates the fitted center, passed to matplotlib.axes.Axes.axvline(). Defaults to None.

  • plot_span_kwargs (dict[str, Any] | None, default: None) – Additional keyword arguments for the plot span that indicates the fitted FWHM, passed to matplotlib.axes.Axes.axvspan(). Defaults to None.

  • **kwargs – Additional keyword arguments to DataArray.xlm.modelfit().

Returns:

result (xarray.Dataset) – The standard result from xarray.DataArray.xlm.modelfit(). Before fitting, all input dimensions except "eV" are averaged and eV_range is selected. The input is not modified.

Return type:

Dataset

erlab.analysis.gold.quick_resolution(darr, ax=None, **kwargs)[source]

Fit a Fermi edge to the given data and plot the results.

Deprecated since version 3.5.1: Use quick_fit() with plot=True instead.

erlab.analysis.gold.resolution(gold, angle_range, eV_range_edge, eV_range_fit=None, bin_size=(1, 1), degree=4, use_step_edge=False, method='leastsq', plot=True, parallel_kw=None, scale_covar=True, **kwargs)[source]

Fit a Fermi edge and obtain the resolution from the corrected data.

Deprecated since version 3.5.1: Use poly() and quick_fit() instead.

erlab.analysis.gold.resolution_roi(gold_roi, eV_range, fix_temperature=True, method='leastsq', plot=True, scale_covar=True)[source]

Fit a Fermi edge to the data and obtain the resolution.

Deprecated since version 3.5.1: Use quick_fit() instead.

erlab.analysis.gold.spline_from_edge(center, weights=None, lam=None, along='alpha')[source]

Fit a smoothing spline to Fermi edge centers.

Parameters:
  • center – Fermi edge position as a function of along.

  • weights (Buffer | _SupportsArray[dtype[Any]] | _NestedSequence[_SupportsArray[dtype[Any]]] | complex | bytes | str | _NestedSequence[complex | bytes | str] | None, default: None) – One-dimensional positive weights with the same length as center.

  • lam (float | None, default: None) – Nonnegative smoothing parameter passed to scipy.interpolate.make_smoothing_spline(). If omitted, generalized cross-validation selects it.

  • along (str, default: 'alpha') – Independent coordinate for the spline.

Returns:

scipy.interpolate.BSpline – Spline that maps values of the along coordinate to fitted edge positions in the same units as center.

Return type:

BSpline