Note
Go to the end to download the full example code.
Processing a saturation-recovery relaxation series
This example processes a pseudo-2D series of 1D spectra acquired with a variable recovery delay and fits a simple saturation-recovery model to the dominant resonance.
The bundled Bruker dataset stores the delays in vdlist and the pulse
program indicates a CP/MAS saturation-recovery experiment. The example keeps a
modest public scope:
process the 1D FIDs with explicit SpectroChemPy operations;
extract a signal trace from the dominant processed resonance;
fit a simple two-parameter recovery model to that trace.
It does not claim replay of vendor processing, nor exact equivalence with the TopSpin fitting tools bundled alongside the dataset.
Requires the official spectrochempy-nmr plugin.
Install with: pip install spectrochempy[nmr].
Import API
import spectrochempy as scp
# short version of the unit registry
U = scp.ur
Import a pseudo-2D delay series
Define the folder containing the Bruker experiment.
datadir = scp.preferences.datadir
nmrdir = datadir / "nmrdata" / "bruker" / "tests" / "nmr"
dataset = scp.nmr.read(nmrdir / "relax" / "100" / "ser", use_list="vdlist")
Analysing the data
Print dataset summary
Plot the processed spectra
The vdlist delays become the secondary coordinate of the pseudo-2D series.

Build a signal trace from the dominant resonance
The strongest processed peak in this series sits around 20–22 ppm. We integrate a narrow ppm window around that resonance for each delay.
signal = ds[:, 20.0:45.0].simpson()
_ = signal.plot(marker="^", ls=":")
signal.real
Fit a model
create an Optimize object using a simple leastsq method
fitter = scp.Optimize(log_level="INFO", method="leastsq")
Define the model to fit
def T1_model(t, I0, T1): # no underscore in parameters names.
# Simple saturation-recovery model.
import numpy as np
I = I0 * (1 - np.exp(-t / T1))
return I
Add the model to the fitter usermodels as it it not a built-in model
fitter.usermodels = {"T1_model": T1_model}
Define the parameter variables using a script (parameter: value, low_bound, high_bound) no underscore in parameters names.
fitter.script = """
MODEL: T1
shape: T1_model
$ I0: 1000.0, 1, none
$ T1: 2.0, 0.1, none
"""
Perform the fit
_ = fitter.fit(signal)
som = fitter.predict()
som
Plot the measured recovery points and the fitted curve separately so the experimental series remains a true scatter plot.

This ends the example ! The following line can be removed or commented
when the example is run as a notebook (ipynb).
# scp.show()
Total running time of the script: (0 minutes 0.701 seconds)