Bruker EPR data, EPRpy and ILTpy

[1]:
# This file is part of ILTpy examples.
# Author : Dr. Davis Thomas Daniel
# Last updated : 25.08.2025
  • This example shows an ILTpy workflow involving EPR data acuqired on a Bruker spectrometer, reading it using eprpy and then ILT analysis using ILTpy.

  • eprpy is a python library for reading EPR data stored in Bruker file formats. For more information see eprpy’s documentation.

  • The dataset is a field-resolved inversion recovery dataset, the sample is TEMPO radical. The measurement was done at room temperature.

Imports

[2]:
import eprpy as epr # eprpy
import iltpy as ilt # iltpy
import numpy as np # numpy
import matplotlib.pyplot as plt # matplotlib
plt.style.use("../../../examples/latex_style.mplstyle")

print("eprpy version: ",epr.__version__)
print("ILTpy version: ",ilt.__version__)
eprpy version:  0.9.0a8
ILTpy version:  1.0.0

Read the Bruker data using eprpy

[3]:
epr_data = epr.load("../../../examples/EPR/bruker_data_IR/T1_VS_FIELD.DSC")
[4]:
data,t,field_vals = epr_data.data.real,epr_data.x,epr_data.y # extract real data, echo delays, and field values
[5]:
print(f"Data shape : {data.shape}")
print(f"Number of delays : {t.shape}")
print(f"Number of field values: {field_vals.shape}")

Data shape : (128, 512)
Number of delays : (512,)
Number of field values: (128,)
[6]:
# note that iltpy requires the dimension which is to be inverted to be the first in case of inversions where both dimensions are not inverted.

Data preparation

[7]:
plt.plot(data[64]) # 64th recovery delay
[7]:
[<matplotlib.lines.Line2D at 0x1352b5190>]
../_images/Gallery_plot_workflow_eprpy_11_1.png
[8]:
# set noise variance to unity by finding a noise region and its standard deviation
noise = np.std(data[0][0:200])

print(f"SD: {noise}")

data = data/noise
SD: 791.9111297992977
[9]:
# iltpy expects the dimension to be inverted to be the first, so we transpose the data
data = data.T # new shape : (512,128)

ILTpy workflow

Load the data

[10]:
ilt_data = ilt.iltload(data=data,t=t)

Initialize and invert

[11]:
ilt_data.init(tau = np.logspace(2,8,100),kernel=ilt.Exponential())
[12]:
ilt_data.invert()
Starting iterations ...
100%|██████████| 100/100 [00:37<00:00,  2.65it/s]
Done.

Plot the results

[13]:
import numpy as np
import matplotlib.pyplot as plt
# Prepare the data
x = field_vals/10 # convert Gauss to mT
y = np.log10(ilt_data.tau[0].flatten()/1000) # convert from ns to µs
Z = -ilt_data.g  # Relaxation distribution, we use the negative since this is an inversion recovery dataset

X, Y = np.meshgrid(x, y)
fig = plt.figure(figsize=(8*0.8, 6*0.8))
ax = fig.add_subplot(111, projection='3d')
ax.view_init(elev=50, azim=-35)
surf = ax.plot_surface(X, Y, Z, cmap='jet', edgecolor='none', antialiased=True)
ax.set_xlabel("Magnetic field [mT]",fontsize=10)
ax.set_ylabel(r'$log(T_{1}/ \mu s)$',fontsize=10)
fig.colorbar(surf, ax=ax, shrink=0.5)
plt.tight_layout()
plt.show()

../_images/Gallery_plot_workflow_eprpy_21_0.png

Note

  • Inversion recovery curves may exhibit non-zero baselines, which may be interpreted by the algorithm as a slow relaxing component.

  • This artefact manifests in the obtained relaxation distribution as a negative peak with a long relaxation time constant, as seen above.

  • You can separate this artifact from the real feature by defining a tau vector which has its maximum farther away from the feature of interest.