.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "gettingstarted/examples/gallery/auto_examples_processing/nmr/plot_processing_cp_nmr.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_gettingstarted_examples_gallery_auto_examples_processing_nmr_plot_processing_cp_nmr.py: Analysis CP NMR spectra ======================== Example with handling of a series of CP NMR spectra. .. GENERATED FROM PYTHON SOURCE LINES 15-17 Import API ---------- .. GENERATED FROM PYTHON SOURCE LINES 17-19 .. code-block:: default import spectrochempy as scp .. GENERATED FROM PYTHON SOURCE LINES 20-23 Import NMR spectra ------------------ Define the folder where are the spectra .. GENERATED FROM PYTHON SOURCE LINES 23-26 .. code-block:: default datadir = scp.preferences.datadir nmrdir = datadir / "nmrdata" / "bruker" / "tests" / "nmr" / "CP" .. GENERATED FROM PYTHON SOURCE LINES 27-30 Set the `glob` pattern in order to load a series of spectra of given type in the given directory (here we read fid, but we could also read "1r" files when available) .. GENERATED FROM PYTHON SOURCE LINES 30-32 .. code-block:: default dataset = scp.read_topspin(nmrdir, glob="**/fid") .. rst-class:: sphx-glr-script-out .. code-block:: none /home/runner/micromamba/envs/scpy_docs/lib/python3.10/site-packages/spectrochempy/extern/nmrglue.py:1068: UserWarning: Error reading the pulse program warn("Error reading the pulse program") .. GENERATED FROM PYTHON SOURCE LINES 33-34 15 fids have been read and merged into a single dataset .. GENERATED FROM PYTHON SOURCE LINES 34-36 .. code-block:: default dataset .. raw:: html
name CP expno:94 procno:1 (FID)
author runner@fv-az1152-754
created 2024-03-08 01:00:09+00:00
description
Concatenation of 15 datasets:
( CP expno:80 procno:1 (FID), CP expno:81 procno:1 (FID), CP expno:82 procno:1 (FID), CP expno:83 procno:1 (FID), CP expno:84 procno:1 (FID), CP expno:85 procno:1 (FID), CP expno:86 procno:1 (FID), CP expno:87 procno:1 (FID), CP expno:88 procno:1 (FID), CP expno:89 procno:1 (FID), CP expno:90 procno:1 (FID), CP expno:91 procno:1 (FID), CP expno:92 procno:1 (FID), CP expno:93 procno:1 (FID), CP expno:94 procno:1 (FID) )
history
2024-03-08 01:00:09+00:00> Created by concatenate
2024-03-08 01:00:09+00:00> Stacked from several files
DATA
title intensity
values
R[[-0.05957 -0.3873 ... -0.003637 -0.00117]
[-0.08434 -0.5342 ... -0.004302 0.003153]
...
[-0.04476 -0.2129 ... 0.002508 0.007919]
[-0.01885 -0.1031 ... 0.001875 -0.005607]] pp
I[[0.0007904 0.02556 ... -0.003612 -0.007104]
[-0.006849 0.01868 ... -0.002714 0.004092]
...
[0.006191 0.02719 ... -0.008843 -0.009201]
[0.004219 0.02111 ... 0.003521 0.002012]] pp
shape (y:15, x:1947(complex))
DIMENSION `x`
size 1947
title F1 acquisition time
coordinates
[ 0 24.8 ... 4.824e+04 4.826e+04] µs
DIMENSION `y`
size 15
(_1)
title timestamp
coordinates
[1359924945 1359949976 ... 1360100375 1360112954]
(_2)
title expno
coordinates
[ 80 81 ... 93 94]
(_3)
title p15
coordinates
[ 100 200 ... 1e+04 1.5e+04] µs


.. GENERATED FROM PYTHON SOURCE LINES 37-42 The new dimension (y) have several coordinates corresponding to all metadata that change from fid to fid. In the present case, the relevant coordinates is given by the `p15` array which is the array of CP contact times. To have y using this coordinates, we need to select it .. GENERATED FROM PYTHON SOURCE LINES 42-44 .. code-block:: default dataset.y.select(3) .. GENERATED FROM PYTHON SOURCE LINES 45-46 plot the dataset (zoom on the begining of the fid) .. GENERATED FROM PYTHON SOURCE LINES 46-51 .. code-block:: default prefs = dataset.preferences prefs.figure.figsize = (9, 4) _ = ax = dataset.plot(colorbar=True) _ = ax.set_xlim(0, 5000) .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_001.png :alt: plot processing cp nmr :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 52-53 Process a fourier transform along the x dimension .. GENERATED FROM PYTHON SOURCE LINES 53-57 .. code-block:: default # exponential multiplication nd1 = scp.em(dataset, lb=50) .. GENERATED FROM PYTHON SOURCE LINES 58-59 fourier transform .. GENERATED FROM PYTHON SOURCE LINES 59-61 .. code-block:: default nd2 = scp.fft(nd1, si=4096) .. GENERATED FROM PYTHON SOURCE LINES 62-63 perform a phase correction of order 0 (need to be tuned carefully) .. GENERATED FROM PYTHON SOURCE LINES 63-65 .. code-block:: default nd3 = scp.pk(nd2, phc0=-118) .. GENERATED FROM PYTHON SOURCE LINES 66-67 plot .. GENERATED FROM PYTHON SOURCE LINES 67-69 .. code-block:: default _ = nd3.plot() .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_002.png :alt: plot processing cp nmr :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 70-72 ## Baseline correction Here we use the snip algorithm .. GENERATED FROM PYTHON SOURCE LINES 72-78 .. code-block:: default nd4 = scp.snip(nd3, snip_width=200) ax = nd4.plot() _ = ax.set_xlim(225, 25) _ = ax.set_ylim(-1, 10) .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_003.png :alt: plot processing cp nmr :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 79-81 ## Peak peaking we will use here the max of each spectra .. GENERATED FROM PYTHON SOURCE LINES 81-84 .. code-block:: default peaks, properties = nd4.max(dim=0).find_peaks(height=2.0, width=0.5, wlen=33.0) print(f"position of the peaks : {peaks.x.data}") .. rst-class:: sphx-glr-script-out .. code-block:: none position of the peaks : [ 174.2 99.38 70.46] .. GENERATED FROM PYTHON SOURCE LINES 85-86 properties of the peaks .. GENERATED FROM PYTHON SOURCE LINES 86-95 .. code-block:: default table_pos = " ".join([f"{peaks[i].x.value.m:>10.3f}" for i in range(len(peaks))]) print(f'{"peak_position (cm⁻¹)":>26}: {table_pos}') for key in properties: table_property = " ".join( [f"{properties[key][i].m:>10.3f}" for i in range(len(peaks))] ) title = f"{key:>.16} ({properties[key][0].u:~P})" print(f"{title:>26}: {table_property}") .. rst-class:: sphx-glr-script-out .. code-block:: none peak_position (cm⁻¹): 174.243 99.379 70.458 peak_heights (pp): 2.579 3.516 9.606 prominences (pp): 2.242 3.069 9.028 left_bases (ppm): 186.765 110.857 86.891 right_bases (ppm): 162.408 88.945 56.763 widths (ppm): 5.575 8.569 11.783 width_heights (pp): 1.458 1.982 5.092 left_ips (ppm): 177.015 103.010 76.346 right_ips (ppm): 171.440 94.441 64.562 .. GENERATED FROM PYTHON SOURCE LINES 96-97 plot with peak markers and the left/right-bases indicators .. GENERATED FROM PYTHON SOURCE LINES 97-123 .. code-block:: default ax = nd4.plot() # output the spectrum on ax. ax will receive next plot too pks = peaks + 0.5 # add a small offset on the y position of the markers _ = pks.plot_scatter( ax=ax, marker="v", color="black", clear=False, # we need to keep the previous output on ax data_only=True, # we don't need to redraw all things like labels, etc... ylim=(-0.1, 13), xlim=(225, 25), ) for i, p in enumerate(pks): x, y = p.x.values, (p + 0.5).values _ = ax.annotate( f"{x.m:0.1f}", xy=(x, y), xytext=(-5, 5), rotation=90, textcoords="offset points", ) for w in (properties["left_bases"][i], properties["right_bases"][i]): ax.axvline(w, linestyle="--", color="green") for w in (properties["left_ips"][i], properties["right_ips"][i]): ax.axvline(w, linestyle=":", color="red") .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_004.png :alt: plot processing cp nmr :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 124-125 Get the section at once using fancy indexing .. GENERATED FROM PYTHON SOURCE LINES 125-135 .. code-block:: default sections = nd4[:, peaks.x.data] # The array sections has a shape (15, 3). # We must transpose it to plot the three sections has a function of contact time sections = sections.T # now plot it ax = sections.plot(marker="o", lw="1", ls=":", legend="best", colormap="jet") _ = ax.set_xlim(0, 16000) .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_005.png :alt: plot processing cp nmr :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_005.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 136-139 The sections we have taken here represent the maximum heigths of the peaks. However it could may be interesting to have the area of the peak instead. Let's use the left and right bases to perform the integration of the peaks. .. GENERATED FROM PYTHON SOURCE LINES 139-155 .. code-block:: default area = [] for i in range(len(peaks)): lb, ub = properties["left_bases"][i].m, properties["right_bases"][i].m a = nd4[:, lb:ub].simpson() area.append(a) area = scp.NDDataset( area, dims=["y", "x"], coordset=scp.CoordSet({"y": peaks.x.copy(), "x": nd4.y.default.copy()}), units=a.units, title="area", ) area.plot(marker="o", lw="1", ls=":", legend="best", colormap="jet") area .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_006.png :alt: plot processing cp nmr :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_006.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none /home/runner/micromamba/envs/scpy_docs/lib/python3.10/site-packages/spectrochempy/analysis/integration/integrate.py:178: DeprecationWarning: 'scipy.integrate.simps' is deprecated in favour of 'scipy.integrate.simpson' and will be removed in SciPy 1.14.0 return scipy.integrate.simps(dataset.data, **kwargs) .. raw:: html
name NDDataset_37165c60
author runner@fv-az1152-754
created 2024-03-08 01:00:11+00:00
DATA
title area
values
[[ 5.345 6.433 ... 14.57 10.45]
[ 19.07 25.3 ... 14.14 9.299]
[ 70.81 92 ... 47.23 25.29]] pp.ppm
shape (y:3, x:15)
DIMENSION `x`
size 15
title p15
coordinates
[ 100 200 ... 1e+04 1.5e+04] µs
DIMENSION `y`
size 3
title $\delta\ ^{13}C$
coordinates
[ 174.2 99.38 70.46] ppm


.. GENERATED FROM PYTHON SOURCE LINES 156-157 Fitting a model to these data .. GENERATED FROM PYTHON SOURCE LINES 157-174 .. code-block:: default import numpy as np # create an Optimize object using a simple leastsq method fitter = scp.Optimize(log_level="INFO", method="leastsq") # define a model # Note: This is only for sake of demonstration, # as the model is probably not sufficient to fit the data correctly. def cp_model(t, i0, tis, t1irho): # warning: no underscore in variable names I = i0 * (np.exp(-t / t1irho) - np.exp(-t * (1 / tis))) / (1 - tis / t1irho) return I # Add the model to the fitter usermodels as it it not a built-in model fitter.usermodels = {"CP_model": cp_model} .. GENERATED FROM PYTHON SOURCE LINES 175-204 .. code-block:: default index = 0 s = area[index] # Define the parameter variables using a script # (parameter: value, low_bound, high_bound) # - no underscore in parameters names. # - times are in the units of the data time coordinates (here `s`) # - initially we assume relaxation (T1rho) time constant vey large fitter.script = """ MODEL: cp shape: cp_model $ i0: 25, 0.1, none $ t1irho: 1e4, 1, none $ tis: 800, 1, 10000 """ _ = fitter.fit(s) spred = fitter.predict() ax = fitter.plotmerit( s, spred, method="scatter", show_yaxis=True, title=f"fitting CP dynamic (peaks at {peaks.x[index].values})", ) _ = ax.set_xlim(0, 16000) .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_007.png :alt: fitting CP dynamic (peaks at 174.243 ppm) :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_007.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none ************************************************** Result: ************************************************** MODEL: cp shape: cp_model $ i0: 19.2907, 0.1, none $ t1irho: 23482.1113, 1, none $ tis: 796.2717, 1, 10000 .. GENERATED FROM PYTHON SOURCE LINES 205-228 .. code-block:: default index = 1 s = area[index] fitter.script = """ MODEL: cp shape: cp_model $ i0: 35, 0.1, none $ t1irho: 1e4, 1, none $ tis: 800, 1, 10000 """ _ = fitter.fit(s) spred = fitter.predict() ax = fitter.plotmerit( s, spred, method="scatter", show_yaxis=True, title=f"fitting CP dynamic (peaks at {peaks.x[index].values})", ) _ = ax.set_xlim(0, 16000) .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_008.png :alt: fitting CP dynamic (peaks at 99.379 ppm) :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_008.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none ************************************************** Result: ************************************************** MODEL: cp shape: cp_model $ i0: 34.7742, 0.1, none $ t1irho: 11463.4261, 1, none $ tis: 174.4446, 1, 10000 .. GENERATED FROM PYTHON SOURCE LINES 229-252 .. code-block:: default index = 2 s = area[index] fitter.script = """ MODEL: cp shape: cp_model $ i0: 125, 0.1, none $ t1irho: 1e4, 1, none $ tis: 800, 1, 10000 """ _ = fitter.fit(s) spred = fitter.predict() ax = fitter.plotmerit( s, spred, method="scatter", show_yaxis=True, title=f"fitting CP dynamic (peaks at {peaks.x[index].values})", ) _ = ax.set_xlim(0, 16000) .. image-sg:: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_009.png :alt: fitting CP dynamic (peaks at 70.458 ppm) :srcset: /gettingstarted/examples/gallery/auto_examples_processing/nmr/images/sphx_glr_plot_processing_cp_nmr_009.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none ************************************************** Result: ************************************************** MODEL: cp shape: cp_model $ i0: 129.5282, 0.1, none $ t1irho: 10031.3640, 1, none $ tis: 196.1622, 1, 10000 .. GENERATED FROM PYTHON SOURCE LINES 253-256 The model looks good for the peak at 174 ppm. This peak appears to be composed of a single species, which is not the case for the other peaks at 99 and 70 ppm. Deconvolution of these two peaks is therefore probably necessary for a better analysis. .. GENERATED FROM PYTHON SOURCE LINES 258-260 This ends the example ! The following line can be removed or commented when the example is run as a notebook (*.ipynb). .. GENERATED FROM PYTHON SOURCE LINES 260-262 .. code-block:: default # scp.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 2.745 seconds) .. _sphx_glr_download_gettingstarted_examples_gallery_auto_examples_processing_nmr_plot_processing_cp_nmr.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_processing_cp_nmr.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_processing_cp_nmr.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_