.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "fitting/1D_fitting/plot_5_119Sn_sideband.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_1D_fitting_plot_5_119Sn_sideband.py: ¹¹⁹Sn MAS NMR of SnO ^^^^^^^^^^^^^^^^^^^^ .. GENERATED FROM PYTHON SOURCE LINES 7-9 The following is a spinning sideband manifold fitting example for the 119Sn MAS NMR of SnO. The dataset was acquired and shared by Altenhof `et al.` [#f1]_. .. GENERATED FROM PYTHON SOURCE LINES 9-22 .. code-block:: Python import csdmpy as cp import numpy as np import matplotlib.pyplot as plt from lmfit import Minimizer from mrsimulator import Simulator, SpinSystem, Site, Coupling from mrsimulator.method.lib import BlochDecaySpectrum from mrsimulator import signal_processor as sp from mrsimulator.utils import spectral_fitting as sf from mrsimulator.utils import get_spectral_dimensions from mrsimulator.spin_system.tensors import SymmetricTensor .. GENERATED FROM PYTHON SOURCE LINES 24-26 Import the dataset ------------------ .. GENERATED FROM PYTHON SOURCE LINES 26-44 .. code-block:: Python filename = "https://ssnmr.org/sites/default/files/mrsimulator/119Sn_SnO.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. plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") ax.plot(experiment, "k", alpha=0.5) ax.set_xlim(-1200, 600) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_001.png :alt: plot 5 119Sn sideband :srcset: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 45-46 Estimate noise statistics from the dataset .. GENERATED FROM PYTHON SOURCE LINES 46-61 .. code-block:: Python coords = experiment.dimensions[0].coordinates noise_region = np.where(coords > 300e-6) noise_data = experiment[noise_region] plt.figure(figsize=(3.75, 2.5)) ax = plt.subplot(projection="csdm") ax.plot(noise_data, label="noise") plt.title("Noise section") plt.axis("off") plt.tight_layout() plt.show() noise_mean, sigma = experiment[noise_region].mean(), experiment[noise_region].std() noise_mean, sigma .. image-sg:: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_002.png :alt: Noise section :srcset: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none (, ) .. GENERATED FROM PYTHON SOURCE LINES 62-70 Create a fitting model ---------------------- **Guess model** Create a guess list of spin systems. There are two spin systems present in this example, - 1) an uncoupled :math:`^{119}\text{Sn}` and - 2) a coupled :math:`^{119}\text{Sn}`-:math:`^{117}\text{Sn}` spin systems. .. GENERATED FROM PYTHON SOURCE LINES 70-92 .. code-block:: Python sn119 = Site( isotope="119Sn", isotropic_chemical_shift=-210, shielding_symmetric=SymmetricTensor(zeta=700, eta=0.1), ) sn117 = Site( isotope="117Sn", isotropic_chemical_shift=0, ) j_sn = Coupling( site_index=[0, 1], isotropic_j=8150.0, ) sn117_abundance = 7.68 # in % spin_systems = [ # uncoupled spin system SpinSystem(sites=[sn119], abundance=100 - sn117_abundance), # coupled spin systems SpinSystem(sites=[sn119, sn117], couplings=[j_sn], abundance=sn117_abundance), ] .. GENERATED FROM PYTHON SOURCE LINES 93-94 **Method** .. GENERATED FROM PYTHON SOURCE LINES 94-107 .. code-block:: Python # Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(experiment) MAS = BlochDecaySpectrum( channels=["119Sn"], magnetic_flux_density=9.395, # in T rotor_frequency=10000, # in Hz spectral_dimensions=spectral_dims, experiment=experiment, # add the measurement to the method. ) .. GENERATED FROM PYTHON SOURCE LINES 108-109 **Guess Spectrum** .. GENERATED FROM PYTHON SOURCE LINES 109-140 .. code-block:: Python # Simulation # ---------- sim = Simulator(spin_systems=spin_systems, methods=[MAS]) sim.run() # Post Simulation Processing # -------------------------- processor = sp.SignalProcessor( operations=[ sp.IFFT(), sp.apodization.Exponential(FWHM="1500 Hz"), sp.FFT(), sp.Scale(factor=50000), ] ) 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.plot(experiment, "k", linewidth=1, label="Experiment") ax.plot(processed_dataset, "r", alpha=0.75, linewidth=1, label="guess spectrum") ax.set_xlim(-1200, 600) plt.grid() plt.legend() plt.tight_layout() plt.show() .. image-sg:: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_003.png :alt: plot 5 119Sn sideband :srcset: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 141-145 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 145-167 .. code-block:: Python params = sf.make_LMFIT_params(sim, processor, include={"rotor_frequency"}) # Remove the abundance parameters from params. Since the measurement detects 119Sn, we # also remove the isotropic chemical shift parameter of 117Sn site from params. The # 117Sn is the site at index 1 of the spin system at index 1. params.pop("sys_0_abundance") params.pop("sys_1_abundance") params.pop("sys_1_site_1_isotropic_chemical_shift") # Since the 119Sn site is shared between the two spin systems, we add constraints to the # 119Sn site parameters from the spin system at index 1 to be the same as 119Sn site # parameters from the spin system at index 0. lst = [ "isotropic_chemical_shift", "shielding_symmetric_zeta", "shielding_symmetric_eta", ] for item in lst: params[f"sys_1_site_0_{item}"].expr = f"sys_0_site_0_{item}" 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_Exponential_FWHM 1500 -inf inf True None SP_0_operation_3_Scale_factor 5e+04 -inf inf True None mth_0_rotor_frequency 1e+04 9900 1.01e+04 True None sys_0_site_0_isotropic_chemical_shift -210 -inf inf True None sys_0_site_0_shielding_symmetric_eta 0.1 0 1 True None sys_0_site_0_shielding_symmetric_zeta 700 -inf inf True None sys_1_coupling_0_isotropic_j 8150 -inf inf True None sys_1_site_0_isotropic_chemical_shift -210 -inf inf False sys_0_site_0_isotropic_chemical_shift sys_1_site_0_shielding_symmetric_eta 0.1 0 1 False sys_0_site_0_shielding_symmetric_eta sys_1_site_0_shielding_symmetric_zeta 700 -inf inf False sys_0_site_0_shielding_symmetric_zeta None .. GENERATED FROM PYTHON SOURCE LINES 168-169 **Solve the minimizer using LMFIT** .. GENERATED FROM PYTHON SOURCE LINES 169-179 .. 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 180-182 The best fit solution --------------------- .. GENERATED FROM PYTHON SOURCE LINES 182-198 .. code-block:: Python best_fit = sf.bestfit(sim, processor)[0].real residuals = sf.residuals(sim, processor)[0].real # Plot the spectrum plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") ax.plot(experiment, "k", linewidth=1, label="Experiment") ax.plot(best_fit, "r", alpha=0.75, linewidth=1, label="Best Fit") ax.plot(residuals, alpha=0.75, linewidth=1, label="Residuals") ax.set_xlim(-1200, 600) plt.grid() plt.legend() plt.tight_layout() plt.show() .. image-sg:: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_004.png :alt: plot 5 119Sn sideband :srcset: /fitting/1D_fitting/images/sphx_glr_plot_5_119Sn_sideband_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 199-204 .. [#f1] Altenhof A. R., Jaroszewicz M. J., Lindquist A. W., Foster L. D. D., Veinberg S. L., and Schurko R. W. Practical Aspects of Recording Ultra-Wideline NMR Patterns under Magic-Angle Spinning Conditions. J. Phys. Chem. C. 2020, **124**, 27, 14730–14744 `DOI: 10.1021/acs.jpcc.0c04510 `_ .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 2.932 seconds) .. _sphx_glr_download_fitting_1D_fitting_plot_5_119Sn_sideband.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_5_119Sn_sideband.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_5_119Sn_sideband.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_