.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "fitting/2D_fitting/plot_3_RbNO3_MQMAS.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_fitting_2D_fitting_plot_3_RbNO3_MQMAS.py: ⁸⁷Rb 2D 3QMAS NMR of RbNO₃ ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. GENERATED FROM PYTHON SOURCE LINES 7-9 The following is a 3QMAS fitting example for :math:`\text{RbNO}_3`. The dataset was acquired and shared by Brendan Wilson. .. GENERATED FROM PYTHON SOURCE LINES 9-22 .. code-block:: Python import numpy as np import csdmpy as cp import matplotlib.pyplot as plt from lmfit import Minimizer from mrsimulator import Simulator from mrsimulator.method.lib import ThreeQ_VAS 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 .. GENERATED FROM PYTHON SOURCE LINES 24-26 Import the dataset ------------------ .. GENERATED FROM PYTHON SOURCE LINES 26-49 .. code-block:: Python filename = "https://ssnmr.org/sites/default/files/mrsimulator/RbNO3_MQMAS.csdf" experiment = cp.load(filename) # 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(24) + 1) * max_amp / 25 # 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.set_xlim(-20, -50) ax.set_ylim(-45, -65) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_001.png :alt: plot 3 RbNO3 MQMAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 50-51 Estimate noise statistics from the dataset. .. GENERATED FROM PYTHON SOURCE LINES 51-65 .. code-block:: Python noise_region = np.where(experiment.dimensions[0].coordinates > -25e-6) noise_data = experiment[noise_region] plt.figure(figsize=(3.75, 2.5)) ax = plt.subplot(projection="csdm") ax.imshow(noise_data, aspect="auto", interpolation="none") plt.title("Noise section") plt.axis("off") plt.tight_layout() plt.show() noise_mean, sigma = noise_data.mean(), noise_data.std() noise_mean, sigma .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_002.png :alt: Noise section :srcset: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none (, ) .. GENERATED FROM PYTHON SOURCE LINES 66-71 Create a fitting model ---------------------- **Guess model** Create a guess list of spin systems. .. GENERATED FROM PYTHON SOURCE LINES 71-85 .. code-block:: Python shifts = [-26.8, -28.4, -31.2] # in ppm Cq = [1.7e6, 2.0e6, 1.7e6] # in Hz eta = [0.2, 0.95, 0.6] abundance = [40.0, 25.0, 35.0] # in % spin_systems = single_site_system_generator( isotope="87Rb", isotropic_chemical_shift=shifts, quadrupolar={"Cq": Cq, "eta": eta}, abundance=abundance, ) .. GENERATED FROM PYTHON SOURCE LINES 86-89 **Method** Create the 3QMAS method. .. GENERATED FROM PYTHON SOURCE LINES 89-100 .. code-block:: Python # Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(experiment) MQMAS = ThreeQ_VAS( channels=["87Rb"], magnetic_flux_density=9.395, # in T spectral_dimensions=spectral_dims, experiment=experiment, # add the measurement to the method. ) .. GENERATED FROM PYTHON SOURCE LINES 101-102 **Guess Spectrum** .. GENERATED FROM PYTHON SOURCE LINES 102-136 .. code-block:: Python # Simulation # ---------- sim = Simulator(spin_systems=spin_systems, methods=[MQMAS]) sim.config.number_of_sidebands = 1 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.08 kHz", dim_index=0), sp.apodization.Gaussian(FWHM="0.2 kHz", dim_index=1), sp.FFT(dim_index=(0, 1)), sp.Scale(factor=2e8), ] ) 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.set_xlim(-20, -50) ax.set_ylim(-45, -65) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_003.png :alt: plot 3 RbNO3 MQMAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 137-141 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 141-144 .. code-block:: Python params = sf.make_LMFIT_params(sim, processor) print(params.pretty_print(columns=["value", "min", "max", "vary", "expr"])) .. rst-class:: sphx-glr-script-out .. code-block:: none Name Value Min Max Vary Expr SP_0_operation_1_Gaussian_FWHM 0.08 -inf inf True None SP_0_operation_2_Gaussian_FWHM 0.2 -inf inf True None SP_0_operation_4_Scale_factor 2e+08 -inf inf True None sys_0_abundance 40 0 100 True None sys_0_site_0_isotropic_chemical_shift -26.8 -inf inf True None sys_0_site_0_quadrupolar_Cq 1.7e+06 -inf inf True None sys_0_site_0_quadrupolar_eta 0.2 0 1 True None sys_1_abundance 25 0 100 True None sys_1_site_0_isotropic_chemical_shift -28.4 -inf inf True None sys_1_site_0_quadrupolar_Cq 2e+06 -inf inf True None sys_1_site_0_quadrupolar_eta 0.95 0 1 True None sys_2_abundance 35 0 100 False 100-sys_0_abundance-sys_1_abundance sys_2_site_0_isotropic_chemical_shift -31.2 -inf inf True None sys_2_site_0_quadrupolar_Cq 1.7e+06 -inf inf True None sys_2_site_0_quadrupolar_eta 0.6 0 1 True None None .. GENERATED FROM PYTHON SOURCE LINES 145-146 **Solve the minimizer using LMFIT** .. GENERATED FROM PYTHON SOURCE LINES 146-156 .. code-block:: Python opt = sim.optimize() # Pre-compute transition pathways minner = Minimizer( sf.LMFIT_min_function, params, fcn_args=(sim, processor, sigma), fcn_kws={"opt": opt}, ) result = minner.minimize() result .. raw:: html

Fit Result



.. GENERATED FROM PYTHON SOURCE LINES 157-159 The best fit solution --------------------- .. GENERATED FROM PYTHON SOURCE LINES 159-172 .. code-block:: Python 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.set_xlim(-20, -50) ax.set_ylim(-45, -65) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_004.png :alt: plot 3 RbNO3 MQMAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 173-175 Image plots with residuals -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 175-194 .. code-block:: Python 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", cmap="gist_ncar_r", vmax=vmax, vmin=vmin, interpolation="none", ) ax[i].set_xlim(-20, -50) ax[0].set_ylim(-45, -65) plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_005.png :alt: plot 3 RbNO3 MQMAS :srcset: /fitting/2D_fitting/images/sphx_glr_plot_3_RbNO3_MQMAS_005.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 16.006 seconds) .. _sphx_glr_download_fitting_2D_fitting_plot_3_RbNO3_MQMAS.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_3_RbNO3_MQMAS.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_3_RbNO3_MQMAS.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_