.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "fitting/2D_fitting/plot_2_Coesite_DAS.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_fitting_2D_fitting_plot_2_Coesite_DAS.py: ¹⁷O 2D DAS NMR of Coesite ^^^^^^^^^^^^^^^^^^^^^^^^^ .. GENERATED FROM PYTHON SOURCE LINES 7-11 Coesite is a high-pressure (2-3 GPa) and high-temperature (700°C) polymorph of silicon dioxide :math:`\text{SiO}_2`. Coesite has five crystallographic :math:`^{17}\text{O}` sites. The experimental dataset used in this example is published in Grandinetti `et al.` [#f1]_ .. GENERATED FROM PYTHON SOURCE LINES 11-24 .. code-block:: default import numpy as np import csdmpy as cp import matplotlib.pyplot as plt from lmfit import Minimizer from mrsimulator import Simulator from mrsimulator import signal_processor as sp from mrsimulator.utils import spectral_fitting as sf from mrsimulator.utils import get_spectral_dimensions from mrsimulator.utils.collection import single_site_system_generator from mrsimulator.method import Method, SpectralDimension, SpectralEvent, MixingEvent .. GENERATED FROM PYTHON SOURCE LINES 26-28 Import the dataset ------------------ .. GENERATED FROM PYTHON SOURCE LINES 28-54 .. code-block:: default filename = "https://ssnmr.org/sites/default/files/mrsimulator/DASCoesite.csdf" experiment = cp.load(filename) # standard deviation of noise from the dataset sigma = 921.6698 # For spectral fitting, we only focus on the real part of the complex dataset experiment = experiment.real # Convert the coordinates along each dimension from Hz to ppm. _ = [item.to("ppm", "nmr_frequency_ratio") for item in experiment.dimensions] # plot of the dataset. max_amp = experiment.max() levels = (np.arange(14) + 1) * max_amp / 15 # contours are drawn at these levels. options = dict(levels=levels, alpha=0.75, linewidths=0.5) # plot options plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") ax.contour(experiment, colors="k", **options) ax.invert_xaxis() ax.set_ylim(30, -30) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_001.png :alt: plot 2 Coesite DAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 55-60 Create a fitting model ---------------------- **Guess model** Create a guess list of spin systems. .. GENERATED FROM PYTHON SOURCE LINES 60-74 .. code-block:: default shifts = [29, 39, 54.8, 51, 56] # in ppm Cq = [6.1e6, 5.4e6, 5.5e6, 5.5e6, 5.1e6] # in Hz eta = [0.1, 0.2, 0.15, 0.15, 0.3] abundance_ratio = [1, 1, 2, 2, 2] abundance = np.asarray(abundance_ratio) / 8 * 100 # in % spin_systems = single_site_system_generator( isotope="17O", isotropic_chemical_shift=shifts, quadrupolar={"Cq": Cq, "eta": eta}, abundance=abundance, ) .. GENERATED FROM PYTHON SOURCE LINES 75-78 **Method** Create the DAS method. .. GENERATED FROM PYTHON SOURCE LINES 78-123 .. code-block:: default # Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(experiment) DAS = Method( channels=["17O"], magnetic_flux_density=11.744, # in T rotor_frequency=np.inf, spectral_dimensions=[ SpectralDimension( **spectral_dims[0], events=[ SpectralEvent( fraction=0.5, rotor_angle=37.38 * 3.14159 / 180, # in rads transition_queries=[{"ch1": {"P": [-1], "D": [0]}}], ), MixingEvent(query="NoMixing"), SpectralEvent( fraction=0.5, rotor_angle=79.19 * 3.14159 / 180, # in rads transition_queries=[{"ch1": {"P": [-1], "D": [0]}}], ), MixingEvent(query="NoMixing"), ], ), # The last spectral dimension block is the direct-dimension SpectralDimension( **spectral_dims[1], events=[ SpectralEvent( rotor_angle=54.735 * 3.14159 / 180, # in rads transition_queries=[{"ch1": {"P": [-1], "D": [0]}}], ) ], ), ], experiment=experiment, # also add the measurement to the method. ) # Optimize the script by pre-setting the transition pathways for each spin system from # the das method. for sys in spin_systems: sys.transition_pathways = DAS.get_transition_pathways(sys) .. GENERATED FROM PYTHON SOURCE LINES 124-125 **Guess Spectrum** .. GENERATED FROM PYTHON SOURCE LINES 125-159 .. code-block:: default # Simulation # ---------- sim = Simulator(spin_systems=spin_systems, methods=[DAS]) sim.config.number_of_sidebands = 1 # no sidebands are required for this dataset. sim.run() # Post Simulation Processing # -------------------------- processor = sp.SignalProcessor( operations=[ # Gaussian convolution along both dimensions. sp.IFFT(dim_index=(0, 1)), sp.apodization.Gaussian(FWHM="0.15 kHz", dim_index=0), sp.apodization.Gaussian(FWHM="0.1 kHz", dim_index=1), sp.FFT(dim_index=(0, 1)), sp.Scale(factor=4e7), ] ) processed_dataset = processor.apply_operations(dataset=sim.methods[0].simulation).real # Plot of the guess Spectrum # -------------------------- plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") ax.contour(experiment, colors="k", **options) ax.contour(processed_dataset, colors="r", linestyles="--", **options) ax.invert_xaxis() ax.set_ylim(30, -30) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_002.png :alt: plot 2 Coesite DAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 160-164 Least-squares minimization with LMFIT ------------------------------------- Use the :func:`~mrsimulator.utils.spectral_fitting.make_LMFIT_params` for a quick setup of the fitting parameters. .. GENERATED FROM PYTHON SOURCE LINES 164-167 .. code-block:: default params = sf.make_LMFIT_params(sim, processor) print(params.pretty_print(columns=["value", "min", "max", "vary", "expr"])) .. rst-class:: sphx-glr-script-out Out: .. code-block:: none Name Value Min Max Vary Expr SP_0_operation_1_Gaussian_FWHM 0.15 -inf inf True None SP_0_operation_2_Gaussian_FWHM 0.1 -inf inf True None SP_0_operation_4_Scale_factor 4e+07 -inf inf True None sys_0_abundance 12.5 0 100 True None sys_0_site_0_isotropic_chemical_shift 29 -inf inf True None sys_0_site_0_quadrupolar_Cq 6.1e+06 -inf inf True None sys_0_site_0_quadrupolar_eta 0.1 0 1 True None sys_1_abundance 12.5 0 100 True None sys_1_site_0_isotropic_chemical_shift 39 -inf inf True None sys_1_site_0_quadrupolar_Cq 5.4e+06 -inf inf True None sys_1_site_0_quadrupolar_eta 0.2 0 1 True None sys_2_abundance 25 0 100 True None sys_2_site_0_isotropic_chemical_shift 54.8 -inf inf True None sys_2_site_0_quadrupolar_Cq 5.5e+06 -inf inf True None sys_2_site_0_quadrupolar_eta 0.15 0 1 True None sys_3_abundance 25 0 100 True None sys_3_site_0_isotropic_chemical_shift 51 -inf inf True None sys_3_site_0_quadrupolar_Cq 5.5e+06 -inf inf True None sys_3_site_0_quadrupolar_eta 0.15 0 1 True None sys_4_abundance 25 0 100 False 100-sys_0_abundance-sys_1_abundance-sys_2_abundance-sys_3_abundance sys_4_site_0_isotropic_chemical_shift 56 -inf inf True None sys_4_site_0_quadrupolar_Cq 5.1e+06 -inf inf True None sys_4_site_0_quadrupolar_eta 0.3 0 1 True None None .. GENERATED FROM PYTHON SOURCE LINES 168-169 **Solve the minimizer using LMFIT** .. GENERATED FROM PYTHON SOURCE LINES 169-174 .. code-block:: default minner = Minimizer(sf.LMFIT_min_function, params, fcn_args=(sim, processor, sigma)) result = minner.minimize(method="powell") result .. raw:: html

Fit Statistics

fitting methodPowell
# function evals2176
# data points131072
# variables22
chi-square 186546.917
reduced chi-square 1.42347896
Akaike info crit. 46304.0254
Bayesian info crit. 46519.2624

Variables

name value initial value min max vary expression
sys_0_site_0_isotropic_chemical_shift 27.8033938 29.0 -inf inf True
sys_0_site_0_quadrupolar_Cq 6099689.36 6100000.0 -inf inf True
sys_0_site_0_quadrupolar_eta 0.01092147 0.1 0.00000000 1.00000000 True
sys_0_abundance 11.1102195 12.5 0.00000000 100.000000 True
sys_1_site_0_isotropic_chemical_shift 38.5408343 39.0 -inf inf True
sys_1_site_0_quadrupolar_Cq 5399531.79 5400000.0 -inf inf True
sys_1_site_0_quadrupolar_eta 0.20002250 0.2 0.00000000 1.00000000 True
sys_1_abundance 13.8818117 12.5 0.00000000 100.000000 True
sys_2_site_0_isotropic_chemical_shift 55.9037390 54.8 -inf inf True
sys_2_site_0_quadrupolar_Cq 5493848.05 5500000.0 -inf inf True
sys_2_site_0_quadrupolar_eta 0.17312634 0.15 0.00000000 1.00000000 True
sys_2_abundance 24.8194483 25.0 0.00000000 100.000000 True
sys_3_site_0_isotropic_chemical_shift 51.2660261 51.0 -inf inf True
sys_3_site_0_quadrupolar_Cq 5500002.20 5500000.0 -inf inf True
sys_3_site_0_quadrupolar_eta 0.20827676 0.15 0.00000000 1.00000000 True
sys_3_abundance 23.6477259 25.0 0.00000000 100.000000 True
sys_4_site_0_isotropic_chemical_shift 55.6931410 56.0 -inf inf True
sys_4_site_0_quadrupolar_Cq 5100061.08 5100000.0 -inf inf True
sys_4_site_0_quadrupolar_eta 0.29999999 0.3 0.00000000 1.00000000 True
sys_4_abundance 26.5407946 25.0 0.00000000 100.000000 False 100-sys_0_abundance-sys_1_abundance-sys_2_abundance-sys_3_abundance
SP_0_operation_1_Gaussian_FWHM -0.34028629 0.15 -inf inf True
SP_0_operation_2_Gaussian_FWHM 0.13843807 0.1 -inf inf True
SP_0_operation_4_Scale_factor 42620532.2 40000000.0 -inf inf True


.. GENERATED FROM PYTHON SOURCE LINES 175-177 The best fit solution --------------------- .. GENERATED FROM PYTHON SOURCE LINES 177-190 .. code-block:: default best_fit = sf.bestfit(sim, processor)[0].real # Plot the spectrum plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") ax.contour(experiment, colors="k", **options) ax.contour(best_fit, colors="r", linestyles="--", **options) ax.invert_xaxis() ax.set_ylim(30, -30) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_003.png :alt: plot 2 Coesite DAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 191-193 The best fit solution --------------------- .. GENERATED FROM PYTHON SOURCE LINES 193-205 .. code-block:: default residuals = sf.residuals(sim, processor)[0].real fig, ax = plt.subplots( 1, 3, sharey=True, figsize=(10, 3.0), subplot_kw={"projection": "csdm"} ) vmax, vmin = experiment.max(), experiment.min() for i, dat in enumerate([experiment, best_fit, residuals]): ax[i].imshow(dat, aspect="auto", vmax=vmax, vmin=vmin) ax[i].invert_xaxis() ax[0].set_ylim(30, -30) plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_004.png :alt: plot 2 Coesite DAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_2_Coesite_DAS_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 206-212 .. [#f1] Grandinetti, P. J., Baltisberger, J. H., Farnan, I., Stebbins, J. F., Werner, U. and Pines, A. Solid-State :math:`^{17}\text{O}` Magic-Angle and Dynamic-Angle Spinning NMR Study of the :math:`\text{SiO}_2` Polymorph Coesite, J. Phys. Chem. 1995, **99**, *32*, 12341-12348. `DOI: 10.1021/j100032a045 `_ .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 1 minutes 23.962 seconds) .. _sphx_glr_download_fitting_2D_fitting_plot_2_Coesite_DAS.py: .. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_2_Coesite_DAS.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_2_Coesite_DAS.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_