Processing

spinlab.processing.apodization.apodize(data, dim=None, kind='exponential', **kwargs)

Apply apodization to data along one SpinData dimension.

Currently the following window functions are implemented: exponential, gaussian, hann, hamming, and sin-squared. In addition, the transformation windows traf and lorentz_gauss are implemented.

Parameters:
  • data (SpinData) -- Data object

  • dim (str or None) -- Dimension to apply apodization along. If None, the first dimension is used.

  • kind (str) -- Type of apodization, "exponential" by default

  • kwargs -- Arguments to be passed to apodization function, e.g. line width parameter

Returns:

Data object with window function applied, including attr "window"

Return type:

SpinData

Examples

Examples of using apodize

Exponential line broadening using a line width of 2 Hz along the f2 dimension

>>> data = sl.load("path/to/data")
>>> data = sl.apodize(data, lw = 2)
>>> data = sl.apodize(data, dim = 'f2', lw = 2)

Lorentz-Gauss transformation:

>>> data = sl.load("path/to/data")
>>> data = sl.apodize(data, dim = 't2', kind = 'lorentz_gauss', lw = 4, gauss_lw = 8)

Functions:

\[ \begin{align}\begin{aligned}\mathrm{exponential} &= \exp(-2t * \mathrm{linewidth}) &\\\mathrm{gaussian} &= \exp((\mathrm{linewidth[0]} * t) - (\mathrm{linewidth[1]} * t^{2})) &\\\mathrm{hamming} &= 0.53836 + 0.46164\cos(\pi * n/(N-1)) &\\\mathrm{han} &= 0.5 + 0.5\cos(\pi * n/(N-1)) &\\\mathrm{sin2} &= \cos((-0.5\pi * n/(N - 1)) + \pi)^{2} &\\\mathrm{lorentz\_gauss} &= \exp(L - G^{2}) &\\ L(t) &= \pi * \mathrm{linewidth[0]} * t &\\ G(t) &= 0.6\pi * \mathrm{linewidth[1]} * (\mathrm{gaussian\_max} * (N - 1) - t) &\\\mathrm{traf} &= (f1 * (f1 + f2)) / (f1^{2} + f2^{2}) &\\ f1(t) &= \exp(-t * \pi * \mathrm{linewidth[0]}) &\\ f2(t) &= \exp((t - T) * \pi * \mathrm{linewidth[1]}) &\end{aligned}\end{align} \]
spinlab.processing.fft.fourier_transform(data, dim='t2', zero_fill_factor=1, shift=True, convert_to_ppm=None)

Perform a Fourier transform along one SpinData dimension.

If data.spinlab_attrs["data_type"] == "NMR", the output coordinate is converted from Hz to ppm regardless of the value of convert_to_ppm. This conversion requires data.spinlab_attrs["frequency"]. Frequency values in attrs or under other spinlab attribute names are not used for ppm conversion.

Parameters:
  • data (SpinData) -- Data object

  • dim (str) -- Dimension to Fourier transform. The default is "t2".

  • zero_fill_factor (int) -- Increases the number of points in the transformed dimension by this factor with zero filling. Values less than one are treated as one.

  • shift (bool) -- Apply fftshift to the transformed data and coordinate, placing zero frequency at the center of the dimension.

  • convert_to_ppm (bool or None) -- If True, convert the transformed coordinate from Hz to ppm using spinlab_attrs["frequency"]. If None, conversion is False except for NMR data, where conversion is always forced to True.

Returns:

Data object after Fourier Transformation

Return type:

data (SpinData)

Examples

Fourier transformation of a (NMR) FID stored in a SpinData object

>>> data = sl.load("path/to/data")
>>> data = sl.fourier_transform(data)

Fourier transform along t1 dimension and zero fill to twice the original length

>>> data = sl.fourier_transform(data, dim = "t1", zero_fill_factor = 2)

Note

The fourier_transform function assumes dt = t[1] - t[0]

spinlab.processing.fft.inverse_fourier_transform(data, dim='f2', zero_fill_factor=1, shift=True, convert_from_ppm=True)

Perform an inverse Fourier transform along one SpinData dimension.

If convert_from_ppm is True, the input coordinate spacing is converted from ppm to Hz using data.spinlab_attrs["frequency"] before calculating the output time coordinate. Frequency values in attrs or under other spinlab attribute names are not used.

Parameters:
  • data (SpinData) -- Data object

  • dim (str) -- Dimension to inverse Fourier transform. The default is "f2".

  • zero_fill_factor (int) -- Increases the number of points in the inverse transformed dimension by this factor with zero filling. Values less than one are treated as one.

  • shift (bool) -- Apply ifftshift before the inverse transform when the input data has been shifted.

  • convert_from_ppm (bool) -- If True, convert the input coordinate spacing from ppm to Hz using spinlab_attrs["frequency"].

Returns:

Data object after inverse Fourier Transformation

Return type:

data (SpinData)

Examples

>>> data = sl.load("path/to/data")
>>> data = sl.fourier_transform(data)
>>> data = sl.inverse_fourier_transform(data)

Note

Assumes df = f[1] - f[0]

spinlab.processing.phase.autophase(inputData, dim=None, reference_slice=False, deriv=1, gamma=0.005, full_proc_attr=True)

Autophase function to phase spectral data

The autophase function is based on: Chen et al., "An efficient algorithm for automatic phase correction of NMR spectra based on entropy minimization", JMR 158 (2002) 164-168

By default, the autophase function will phase all spectra independently along the first dimension. This can be changed by providing a specific dataset as a reference slice.

Parameters:
  • inputData (SpinData) -- SpinData object containing NMR spectra

  • dim (str or None) -- Dimension to autophase. If None, the first dimension is used.

  • reference_slice (bool,tuple) -- Tuple of (dimension, index) to select reference slice. The default value is 'False'

  • deriv (int) -- Integer for derivative value (1-4, default=1)

  • gamma (float) -- Scaling factor for phase optimization (default=5e-3)

  • full_proc_attr (bool) -- when this is true the phase tuple for each single autphased spectrum will be added. Default True.

Returns:

Phased data. The function will add the attribute "autophase" = {pivot,deriv,dim,(phasetuples)}. phasetuples is only included if reference_slice is True

Return type:

data (SpinData)

Examples

>>> data = sl.load("path/to/data")
>>> phased = sl.autophase(data)
spinlab.processing.phase.autophase_dep(data, dim='f2', method='search', reference_range=None, pts_lim=None, order='zero', pivot=0, delta=0, phase=None, reference_slice=None, force_positive=False)

Automatically phase correct data, or apply manual phase correction

This function is deprecated and will be removed from SpinLab on 10/01/2023

Parameters:
  • data (SpinData) -- Data object to autophase

  • dim (str) -- Dimension to autophase

  • method (str) -- Autophase method, "search" by default

  • reference_range

  • pts_lim

  • order

  • pivot

  • delta

  • phase

  • reference_slice

  • force_positive

Returns:

Autophased data, including attrs "phase0" for order="zero", and "phase1" if order="first"

Return type:

SpinData

\[ \begin{align}\begin{aligned}\mathrm{data} &= \exp(-1j * \mathrm{phase}) &\\\mathrm{phase(arctan)} &= \mathrm{arctan}(\mathrm{sum}(\mathrm{data.imag}) / \mathrm{sum}(\mathrm{data.real})) &\\\mathrm{phase(search)} &= \mathrm{argmax}(\mathrm{sum}(phased\_real^{2}) / \mathrm{sum}(phased\_imag^{2})) &\\phased\_real &= \mathrm{data.real} * \exp(-1j * \mathrm{phase}) &\\phased\_imag &= \mathrm{data.imag} * \exp(-1j * \mathrm{phase}) &\end{aligned}\end{align} \]
spinlab.processing.phase.phase(data, dim=None, p0=0.0, p1=0.0, pivot=None)

Apply phase correction to SpinData object

Parameters:
  • data (SpinData) -- Data object to phase

  • dim (str or None) -- Dimension to phase. If None, the first dimension is used.

  • p0 (float, array) -- Zero order phase correction (degree, 0 - 360)

  • p1 (float, array) -- First order phase correction (degree, 0 - 360)

  • pivot (float) -- Pivot point for first order phase correction

Returns:

Phased data, including new attributes "p0", "p1", and "pivot"

Return type:

data (SpinData)

Examples

0th-order phase correction of 1D or 2D SpinData object. If the SpinData object has multiple 1D spectra the same phase p0 is applied to all spectra.

>>> data = sl.load("path/to/data")
>>> data = sl.phase(data, p0=15)

0th-order phase correction of all spectra of a 2D SpinData object using a (numpy) array p0 of phases:

>>> p0 = np.array([15, 15, 5, -5, 0])
>>> data = sl.phase(data, p0=p0)

Note

A 2D SpinData object can either be phase using a single p0 (p1) value, or using an array of phases. When using an array, the size of the phase array has to be equal to the number of spectra to be phased.

spinlab.processing.phase.phase_cycle(data, dim=None, receiver_phase=None)

Apply phase cycle to data

Parameters:
  • data (SpinData) -- data to process

  • dim (str or None) -- dimension to perform phase cycle. If None, the first dimension is used.

  • receiver_phase (numpy.array, list) -- Receiver Phase 0 (x), 1 (y), 2 (-x), 3 (-y)

Returns:

data object after phase cycle applied

Return type:

sldata

Examples

>>> data = sl.load("path/to/data")
>>> cycled = sl.phase_cycle(data, receiver_phase=[0, 1, 2, 3])
spinlab.processing.offset.background(data, dim=None, deg=0, regions=None, func: callable = None, **kwargs)

Fit and return the background of data.

Parameters:
  • data (SpinData) -- Data object

  • dim (str or None) -- Dimension to perform background fit. If None, the first dimension is used.

  • deg (int) -- Polynomial degree

  • regions (None, list) -- Background regions. If None, the entire dimension is used for the fit. Regions can be specified as a list of tuples [(min, max), ...]

  • func (optional callable) -- Optional fitting function to fit the background instead of a polynomial.

  • **kwargs -- arguments for fitting function

Returns:

Background fit

Return type:

SpinData

Examples

0th-order background fit (DC offset)

>>> data = sl.load("path/to/data")
>>> bg = sl.background(data)

Background with a given fit function

>>> data = sl.load("path/to/data")
>>> bg = sl.background(data, dim = 'tau', func= sl.relaxation.general_exp, p0=(1,-1,900))
spinlab.processing.offset.remove_background(data, dim=None, deg=0, regions=None, func: callable = None, **kwargs)

Remove a fitted background from data.

Parameters:
  • data (SpinData) -- Data object

  • dim (str or None) -- Dimension to perform background fit. If None, the first dimension is used.

  • deg (int) -- Polynomial degree

  • regions (None, list) -- Background regions. If None, the entire dimension is used to calculate the background correction. Regions can be specified as a list of tuples [(min, max), ...]

  • func (optional callable) -- Optional fitting function to fit the background instead of a polynomial.

  • **kwargs -- arguments for fitting function

Returns:

Background corrected data

Return type:

data (SpinData)

Examples

0th-order background removal (DC offset)

>>> data = sl.load("path/to/data")
>>> data = sl.remove_background(data)

Background removal with a given fit function

>>> data = sl.load("path/to/data")
>>> data = sl.remove_background(data, dim = 'tau', func= sl.relaxation.general_exp, p0=(1,-1,900))
spinlab.processing.integration.cumulative_integrate(data, dim=None, regions=None)

Cumulative integration

Parameters:
  • data (SpinData) -- Data object

  • dim (str or None) -- Dimension to perform cumulative integration. If None, the first dimension is used.

  • regions (None, list) -- List of tuples to specify range of integration [(min, max), ...]

Returns:

cumulative sum of data

Return type:

data

Examples

Example showing cumulative integration of lorentzian function

>>> import numpy as np
>>> import spinlab as sl
>>> data = sl.load("path/to/data")
>>> data_int = sl.cumulative_integrate(data)  # integrates along first dim
>>> sl.plt.figure()
>>> sl.fancy_plot(data)
>>> sl.fancy_plot(data_int)
>>> sl.show()
spinlab.processing.integration.integrate(data, dim=None, regions=None)

Integrate data along given dimension.

If no dimension is given, the first dimension is used. If no region is given, the integral is calculated over the entire range.

Parameters:
  • data (SpinData) -- Data object

  • dim (str or None) -- Dimension to perform integration. If None, the first dimension is used.

  • regions (None, list) -- List of tuples defining the region to integrate

Returns:

Integrals of data. If multiple regions are given the first value corresponds to the first region, the second value corresponds to the second region, etc.

Return type:

data (SpinData)

Examples

Integrated entire data region:

>>> data = sl.load("path/to/data")
>>> integrals = sl.integrate(data)  # integrates along first dim
>>> integrals = sl.integrate(data, dim='f2')

Integrate single peak/region:

>>> data = sl.load("path/to/data")
>>> integrals = sl.integrate(data, regions=[(4, 5)])

Integrate two regions:

>>> data = sl.load("path/to/data")
>>> integrals = sl.integrate(data, regions=[(1.1, 2.1), (4.5, 4.9)])
spinlab.processing.align.ndalign(data, dim=None, reference=None, center=None, width=None)

Align spectra using direct cross correlation.

Parameters:
  • data (SpinData) -- Data object.

  • dim (str or None) -- Dimension to align along. If None, the first dimension is used.

  • reference (array_like or SpinData) -- Reference spectrum for alignment. If None, the last spectrum along the unfolded data is used.

  • center (float) -- Center of alignment range. If None, the entire dimension is used.

  • width (float) -- Width of alignment range. Must be supplied together with center.

Returns:

Aligned data

Return type:

SpinData

Note

Shifts are calculated relative to the supplied reference, then adjusted relative to the first spectrum in the unfolded data. This preserves the first spectrum's position while aligning the remaining spectra to it.

Examples

>>> data = sl.load("path/to/data")
>>> data_aligned = sl.ndalign(data)
>>> data_aligned = sl.ndalign(data, center = 10, width = 20)
spinlab.processing.average.average(data, dim=None, axis=None)

Average a dimension using numpy.mean

Parameters:
  • data (object) -- SpinData object

  • dim (str or None) -- Dimension to average. If None, the first dimension is used.

  • axis (str or None) -- Deprecated alias for dim.

Returns:

Averaged data

Return type:

SpinData

Examples

>>> data = sl.load("path/to/data")
>>> data_averaged = sl.average(data)
>>> data_averaged = sl.average(data, dim="Average")
spinlab.processing.conversion.calc_conversion_factor(tp90, P, Q=1, alpha=0, verbose=False)

Calculate probe conversion factor

Calculate the probe microwave conversion factor from the 90 degree pulse length (tp90) and applied RF power. Optionally, the quality factor and attenuation can be given as input arguments. A formatted output can be generated when setting the verbose flag to True.

Parameters:
  • tp90 (float) -- 90 degree pulse length (ns)

  • P (float) -- Input RF power

  • Q (float) -- Optionally, probe quality factor. Default value is 1

  • alpha (float) -- Optionally, attenuation (dB)

  • verbose (boolean) -- Optionally, return results in formatted output

Returns:

Probe conversion factor (G/sqrt(W))

Return type:

c (float)

Examples

>>> tp90 = sl.calc_tp90(c=120.0, P=0.5, Q=2.0, alpha=3.0)
>>> c = sl.calc_conversion_factor(tp90, P=0.5, Q=2.0, alpha=3.0)
>>> round(c)
120
\[\begin{split}P_\mathrm{probe} &= \frac{P}{10^{\alpha / 10}} \\ B_1(\mathrm{MHz}) &= \frac{1}{4 t_{90}} \times 10^{-12} \\ B_1(\mathrm{G}) &= \frac{B_1(\mathrm{MHz})}{2.804 \times 10^{-6}} \\ c &= \frac{B_1(\mathrm{G})}{\sqrt{P_\mathrm{probe} Q}}\end{split}\]
spinlab.processing.conversion.calc_tp90(c, P, Q=1, alpha=0, verbose=False)

Calculate 90 degree pulse length

Calculate 90 degree pulse length (tp90) from probe conversion factor and applied RF power. Optionally, the quality factor and attenuation can be given as input arguments. A formatted output can be generated when setting the verbose flag to True.

Parameters:
  • c (float) -- Probe conversion factor (G/sqrt(W))

  • P (float) -- Input RF power

  • Q (float) -- Optionally, probe quality factor. Default value is 1

  • alpha (float) -- Optionally, attenuation (dB)

  • verbose (boolean) -- Optionally, return results in formatted output

Returns:

90 degree pulse length

Return type:

tp90 (float)

Examples

>>> tp90 = sl.calc_tp90(c=120.0, P=0.5, Q=2.0, alpha=3.0)
>>> tp90 > 0
True
\[\begin{split}P_\mathrm{probe} &= \frac{P}{10^{\alpha / 10}} \\ B_1(\mathrm{G}) &= c \sqrt{P_\mathrm{probe} Q} \\ B_1(\mathrm{MHz}) &= 2.804 \times 10^{-6} B_1(\mathrm{G}) \\ t_{90} &= \frac{1}{4 B_1(\mathrm{MHz})} \times 10^{-12}\end{split}\]
spinlab.processing.conversion.convert_power(data, mode='dBm2W')

Convert power between dBm and W.

For SpinData input, the coordinate whose dimension is named "Power" or "powers" is converted. If spinlab_attrs["power_unit"] is present, it determines the conversion direction regardless of mode. Otherwise, mode determines the conversion direction.

Non-SpinData input is converted directly according to mode.

Parameters:
  • data (SpinData, array, list, float or int) -- Power values or SpinData with a power coordinate.

  • mode (str) -- "dBm2W" or "W2dBm". Defaults to "dBm2W".

Returns:

out (SpinData, array, list, float or int)

Raises:

ValueError -- If no power dimension is found, power_unit is invalid, or mode is invalid.

Examples

>>> data = sl.load("path/to/data")
>>> data = sl.convert_power(data)
>>> powers_w = sl.convert_power([0, 10, 20], mode="dBm2W")
>>> powers_dbm = sl.convert_power([0.001, 0.01, 0.1], mode="W2dBm")
spinlab.processing.conversion.dBm2w(power_in_dBm)

Convert power in dBm to power in W

Convert a microwave power given in dBm to W. Note that for values <= -190 dBm the output power in W is set to 0.

Parameters:

power_in_dBm (array, list, float or int) -- Power in (dBm)

Returns:

Power in (W). Numpy array outputs are

floating-point arrays.

Return type:

float (array, list, float or int)

Examples

>>> sl.dBm2w(0)
0.001
>>> sl.dBm2w([0, 10, 20])
[0.001, 0.01, 0.1]
>>> sl.dBm2w(np.array([0, 10, 20]))
array([0.001, 0.01 , 0.1  ])
spinlab.processing.conversion.decay2Ce(decay_time, gA, gB, FB)

Convert decay time to effective concentration

Convert the decay rate (mono exponential decay, or stretched exponential) into an effective concentration. See Jeschke/Schweiger "Principles of pulse electron paramagnetic resonance", p. 415, eq. 13.3.4

Parameters:
  • decay_time (float) -- Decay time from mono exponential fit (s)

  • gA -- (isotropic) g-values of spin A and B

  • gB -- (isotropic) g-values of spin A and B

  • FB -- Fraction of B spins excited by pump pulse (DEER modulation depth)

Returns:

Effective concentration.

Return type:

float

Examples

>>> Ce = sl.decay2Ce(decay_time=1.5e-6, gA=2.0, gB=2.1, FB=0.3)
spinlab.processing.conversion.tp90_B1(tp90)

Calculate B1 field strength from 90 degree pulse length.

Parameters:

tp90 (float) -- Pulse length of the 90 degree pulse (s)

Returns:

B1 field strength (Hz)

Return type:

B1 (float)

Examples

>>> sl.tp90_B1(10e-9)
25000000.0
spinlab.processing.conversion.w2dBm(power_in_W)

Convert power in W to power in dBm

Convert a microwave power given in W to dBm

Parameters:

power_in_W (array, list, float or int) -- Power in (W)

Returns:

Power in (dBm). Numpy array outputs

are floating-point arrays.

Return type:

float (array, list, float or int)

Examples

>>> sl.w2dBm(0.001)
0.0
>>> sl.w2dBm([0.001, 0.01, 0.1])
[0.0, 10.0, 20.0]
>>> sl.w2dBm(np.array([0.001, 0.01, 0.1]))
array([ 0., 10., 20.])

Shared processing utilities and backward-compatible helper exports.

Most user-facing processing functions now live in domain-specific modules such as spinlab.processing.normalization or spinlab.processing.snr. This module keeps small reusable helpers and re-exports the historical helper functions so older imports continue to work.

SpinLab uses numpy.interp function to interpolate SpinData object

Author: Yen-Chun Huang

spinlab.processing.interpolation.interp(data, dim=None, new_coord=None, left=None, right=None, extrapolate=False)

Interpolate SpinData object

Parameters:
  • data (SpinData) -- Data object

  • dim (str or None) -- Dimension to interpolate. If None, the first dimension is used.

  • new_coord (list or numpy.arrays) -- New one-dimensional coordinate array for the interpolated axis.

  • (optional (right) -- float or complex): Corresponding to data value, see numpy.interp for more details

  • (optional -- float or complex): Corresponding to data value, see numpy.interp for more details

  • extrapolate (bool) -- If True, linearly extrapolate outside the source coordinate range. Explicit left or right values override extrapolation on that side.

Returns:

interpolated data object

Return type:

data (SpinData)

Examples

>>> data = sl.load("path/to/data")
>>> data = sl.interp(data, new_coord=np.r_[-10:10:1000j])
>>> data = sl.interp(data, dim='f2', new_coord=np.r_[-10:10:1000j])

Note

The source coordinate along dim must be monotonic increasing or monotonic decreasing. new_coord must be monotonic in the same direction as the source coordinate. Decreasing source coordinates are handled by reversing the source coordinate and values before interpolation.