Apodization

[1]:
import spectrochempy as scp
from spectrochempy.core.units import ur
  SpectroChemPy's API - v.0.8.2.dev7
©Copyright 2014-2025 - A.Travert & C.Fernandez @ LCS

Introduction

As an example, apodization is a transformation particularly useful for preprocessing NMR time domain data before Fourier transformation. It generally helps for signal-to-noise improvement.

[2]:
# read an experimental spectra
path = scp.pathclean("nmrdata/bruker/tests/nmr/topspin_1d")

# the method pathclean allow to write pth in linux or window style indifferently
dataset = scp.read_topspin(path, expno=1, remove_digital_filter=True)
dataset = dataset / dataset.max()  # normalization

# store original data
nd = dataset.copy()

# show data
nd
Running on GitHub Actions
MPL Configuration directory: /home/runner/.config/matplotlib
Stylelib directory: /home/runner/.config/matplotlib/stylelib
[2]:
NDDataset: [complex128] dimensionless (size: 12411)[topspin_1d expno:1 procno:1 (FID)]
Summary
name
:
topspin_1d expno:1 procno:1 (FID)
author
:
runner@fv-az2211-104
created
:
2025-04-27 01:46:47+00:00
history
:
2025-04-27 01:46:47+00:00> Binary operation truediv with `(2283.5096153847107-2200.383064516033j) pp` has been performed
Data
title
:
intensity
values
:
...
R[ 0.4717 1 ... 3.96e-05 -1.135e-05]
I[0.0003036 0 ... 6.533e-05 -3.403e-05]
size
:
12411 (complex)
Dimension `x`
size
:
12411
title
:
F1 acquisition time
coordinates
:
[ 0 4 ... 4.964e+04 4.964e+04] µs

Plot of the Real and Imaginary original data

[3]:
nd.plot(xlim=(0.0, 15000.0))
nd.plot(imag=True, data_only=True, clear=False, color="r")
[3]:
../../_images/userguide_processing_apodization_5_1.png

Exponential multiplication

[4]:
nd.plot(xlim=(0.0, 15000.0))
_ = nd.em(lb=300.0 * ur.Hz)
nd.plot(data_only=True, clear=False, color="g")
[4]:
../../_images/userguide_processing_apodization_7_1.png

Warning: processing function are most of the time applied inplace. Use inplace=False option to avoid this if necessary

[5]:
nd = dataset.copy()  # to go back to the original data
nd.plot(xlim=(0.0, 5000.0))
ndlb = nd.em(lb=300.0 * ur.Hz, inplace=False)  # ndlb contain the processed data
nd.plot(data_only=True, clear=False, color="g")  # nd dataset remain unchanged
ndlb.plot(data_only=True, clear=False, color="b")
[5]:
../../_images/userguide_processing_apodization_9_1.png

Of course, imaginary data are also transformed at the same time

[6]:
nd.plot(imag=True, xlim=(0, 5000), color="r")
ndlb.plot(imag=True, data_only=True, clear=False, color="b")
[6]:
../../_images/userguide_processing_apodization_11_1.png

If we want to display the apodization function, we can use the retapod=True parameter.

[7]:
nd = dataset.copy()
nd.plot(xlim=(0.0, 5000.0))
ndlb, apod = nd.em(
    lb=300.0 * ur.Hz, inplace=False, retapod=True
)  # ndlb contain the processed data and apod the
# apodization function
ndlb.plot(data_only=True, clear=False, color="b")
apod.plot(data_only=True, clear=False, color="m", linestyle="--")
[7]:
../../_images/userguide_processing_apodization_13_1.png

Shifted apodization

[8]:
nd = dataset.copy()
nd.plot(xlim=(0.0, 5000.0))
ndlb, apod = nd.em(
    lb=300.0 * ur.Hz, shifted=1000 * ur.us, inplace=False, retapod=True
)  # ndlb contain the processed data and apod the apodization function
ndlb.plot(data_only=True, clear=False, color="b")
apod.plot(data_only=True, clear=False, color="m", linestyle="--")
[8]:
../../_images/userguide_processing_apodization_15_1.png

Other apodization functions

Gaussian-Lorentzian apodization

[9]:
nd = dataset.copy()
lb = 10.0
gb = 200.0
ndlg, apod = nd.gm(lb=lb, gb=gb, inplace=False, retapod=True)
nd.plot(xlim=(0.0, 5000.0))
ndlg.plot(data_only=True, clear=False, color="b")
apod.plot(data_only=True, clear=False, color="m", linestyle="--")
[9]:
../../_images/userguide_processing_apodization_18_1.png

Shifted Gaussian-Lorentzian apodization

[10]:
nd = dataset.copy()
lb = 10.0
gb = 200.0
ndlg, apod = nd.gm(lb=lb, gb=gb, shifted=2000 * ur.us, inplace=False, retapod=True)
nd.plot(xlim=(0.0, 5000.0))
ndlg.plot(data_only=True, clear=False, color="b")
apod.plot(data_only=True, clear=False, color="m", linestyle="--")
[10]:
../../_images/userguide_processing_apodization_20_1.png

Apodization using sine window multiplication

Thesp apodization is by default performed on the last dimension.

Functional form of apodization window (cfBruker TOPSPIN manual): \(sp(t) = \sin(\frac{(\pi - \phi) t }{\text{aq}} + \phi)^{pow}\)

where

  • \(0 < t < \text{aq}\) and \(\phi = \pi ⁄ \text{sbb}\) when \(\text{ssb} \ge 2\)

or

  • \(\phi = 0\) when \(\text{ssb} < 2\)

\(\text{aq}\) is an acquisition status parameter and \(\text{ssb}\) is a processing parameter (see below) and \(\text{ pow}\) is an exponent equal to 1 for a sine bell window or 2 for a squared sine bell window.

The \(\text{ssb}\) parameter mimics the behaviour of the SSB parameter on bruker TOPSPIN software:

  • Typical values are 1 for a pure sine function and 2 for a pure cosine function.

  • Values greater than 2 give a mixed sine/cosine function. Note that all values smaller than 2, for example 0, have the same effect as \(\text{ssb}=1\), namely a pure sine function.

Shortcuts:

  • sine is strictly an alias of sp

  • sinm is equivalent to sp with \(\text{pow}=1\)

  • qsin is equivalent to sp with \(\text{pow}=2\)

Below are several examples of sinm and qsin apodization functions.

[11]:
nd = dataset.copy()
nd.plot()

new, curve = nd.qsin(ssb=3, retapod=True)
curve.plot(color="r", clear=False)
new.plot(xlim=(0, 25000), zlim=(-2, 2), data_only=True, color="r", clear=False)
[11]:
../../_images/userguide_processing_apodization_22_1.png
[12]:
nd = dataset.copy()
nd.plot()

new, curve = nd.sinm(ssb=1, retapod=True)
curve.plot(color="b", clear=False)
new.plot(xlim=(0, 25000), zlim=(-2, 2), data_only=True, color="b", clear=False)
[12]:
../../_images/userguide_processing_apodization_23_1.png
[13]:
nd = dataset.copy()
nd.plot()

new, curve = nd.sinm(ssb=3, retapod=True)
curve.plot(color="b", ls="--", clear=False)
new.plot(xlim=(0, 25000), zlim=(-2, 2), data_only=True, color="b", clear=False)
[13]:
../../_images/userguide_processing_apodization_24_1.png
[14]:
nd = dataset.copy()
nd.plot()

new, curve = nd.qsin(ssb=2, retapod=True)
curve.plot(color="m", clear=False)
new.plot(xlim=(0, 25000), zlim=(-2, 2), data_only=True, color="m", clear=False)
[14]:
../../_images/userguide_processing_apodization_25_1.png
[15]:
nd = dataset.copy()
nd.plot()

new, curve = nd.qsin(ssb=1, retapod=True)
curve.plot(color="g", clear=False)
new.plot(xlim=(0, 25000), zlim=(-2, 2), data_only=True, color="g", clear=False)
[15]:
../../_images/userguide_processing_apodization_26_1.png