.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "fitting/2D_fitting/plot_4_NiCl2.2D2O_shifting-d.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_4_NiCl2.2D2O_shifting-d.py: NiCl₂.2D₂O, ²H (I=1) Shifting-d echo ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ²H (I=1) 2D NMR CSA-Quad 1st order correlation spectrum. .. GENERATED FROM PYTHON SOURCE LINES 9-12 The following is an example of fitting static shifting-*d* echo NMR correlation spectrum of :math:`\text{NiCl}_2\cdot 2\text{D}_2\text{O}` crystalline solid. The spectrum used here is from Walder `et al.` [#f1]_. .. GENERATED FROM PYTHON SOURCE LINES 12-25 .. code-block:: default import numpy as np import csdmpy as cp import matplotlib.pyplot as plt from lmfit import Minimizer from mrsimulator import Simulator, Site, SpinSystem 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 from mrsimulator.method import Method, SpectralDimension, SpectralEvent, MixingEvent .. GENERATED FROM PYTHON SOURCE LINES 27-29 Import the dataset ------------------ .. GENERATED FROM PYTHON SOURCE LINES 29-55 .. code-block:: default filename = "https://ssnmr.org/sites/default/files/mrsimulator/NiCl2.2D2O.csdf" experiment = cp.load(filename) # standard deviation of noise from the dataset sigma = 7.500 # 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(29) + 1) * max_amp / 30 # contours are drawn at these levels. options = dict(levels=levels, 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(1000, -1000) ax.set_ylim(1500, -1500) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_001.png :alt: plot 4 NiCl2.2D2O shifting d :srcset: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 56-61 Create a fitting model ---------------------- **Guess model** Create a guess list of spin systems. .. GENERATED FROM PYTHON SOURCE LINES 61-76 .. code-block:: default site = Site( isotope="2H", isotropic_chemical_shift=-90, # in ppm shielding_symmetric=SymmetricTensor( zeta=-610, # in ppm eta=0.15, alpha=0.7, # in rads beta=2.0, # in rads gamma=3.0, # in rads ), quadrupolar=SymmetricTensor(Cq=75.2e3, eta=0.9), # Cq in Hz ) spin_systems = [SpinSystem(sites=[site])] .. GENERATED FROM PYTHON SOURCE LINES 77-91 **Method** Use the generic method, `Method`, to generate a shifting-d echo method. The reported shifting-d 2D sequence is a correlation of the shielding frequencies to the first-order quadrupolar frequencies. Here, we create a correlation method using the :attr:`~mrsimulator.method.event.freq_contrib` attribute, which acts as a switch for including the frequency contributions from interaction during the event. In the following method, we assign the ``["Quad1_2"]`` and ``["Shielding1_0", "Shielding1_2"]`` as the value to the ``freq_contrib`` key. The *Quad1_2* is an enumeration for selecting the first-order second-rank quadrupolar frequency contributions. *Shielding1_0* and *Shielding1_2* are enumerations for the first-order shielding with zeroth and second-rank tensor contributions, respectively. See :ref:`freq_contrib_api` for details. .. GENERATED FROM PYTHON SOURCE LINES 91-130 .. code-block:: default # Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(experiment) shifting_d = Method( channels=["2H"], magnetic_flux_density=9.395, # in T rotor_frequency=0, spectral_dimensions=[ SpectralDimension( **spectral_dims[0], label="Quadrupolar frequency", events=[ SpectralEvent( transition_queries=[{"ch1": {"P": [-1]}}], freq_contrib=["Quad1_2"], ), MixingEvent(query="NoMixing"), ], ), SpectralDimension( **spectral_dims[1], label="Paramagnetic shift", events=[ SpectralEvent( transition_queries=[{"ch1": {"P": [-1]}}], freq_contrib=["Shielding1_0", "Shielding1_2"], ) ], ), ], experiment=experiment, # also add the measurement to the method. ) # Optimize the script by pre-setting the transition pathways for each spin system from # the method. for sys in spin_systems: sys.transition_pathways = shifting_d.get_transition_pathways(sys) .. GENERATED FROM PYTHON SOURCE LINES 131-132 **Guess Spectrum** .. GENERATED FROM PYTHON SOURCE LINES 132-165 .. code-block:: default # Simulation # ---------- sim = Simulator(spin_systems=spin_systems, methods=[shifting_d]) sim.config.integration_volume = "hemisphere" sim.run() # Post Simulation Processing # -------------------------- processor = sp.SignalProcessor( operations=[ # Gaussian convolution along both dimensions. sp.IFFT(dim_index=(0, 1)), sp.apodization.Gaussian(FWHM="5 kHz", dim_index=0), # along dimension 0 sp.apodization.Gaussian(FWHM="5 kHz", dim_index=1), # along dimension 1 sp.FFT(dim_index=(0, 1)), sp.Scale(factor=5e8), ] ) 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(1000, -1000) ax.set_ylim(1500, -1500) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_002.png :alt: plot 4 NiCl2.2D2O shifting d :srcset: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 166-170 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 170-173 .. 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 5 -inf inf True None SP_0_operation_2_Gaussian_FWHM 5 -inf inf True None SP_0_operation_4_Scale_factor 5e+08 -inf inf True None sys_0_abundance 100 0 100 False 100 sys_0_site_0_isotropic_chemical_shift -90 -inf inf True None sys_0_site_0_quadrupolar_Cq 7.52e+04 -inf inf True None sys_0_site_0_quadrupolar_eta 0.9 0 1 True None sys_0_site_0_shielding_symmetric_alpha 0.7 -inf inf True None sys_0_site_0_shielding_symmetric_beta 2 -inf inf True None sys_0_site_0_shielding_symmetric_eta 0.15 0 1 True None sys_0_site_0_shielding_symmetric_gamma 3 -inf inf True None sys_0_site_0_shielding_symmetric_zeta -610 -inf inf True None None .. GENERATED FROM PYTHON SOURCE LINES 174-175 **Solve the minimizer using LMFIT** .. GENERATED FROM PYTHON SOURCE LINES 175-179 .. code-block:: default minner = Minimizer(sf.LMFIT_min_function, params, fcn_args=(sim, processor, sigma)) result = minner.minimize() result .. raw:: html

Fit Statistics

fitting methodleastsq
# function evals164
# data points65536
# variables11
chi-square 213228.465
reduced chi-square 3.25415437
Akaike info crit. 77339.0519
Bayesian info crit. 77439.0458

Variables

name value standard error relative error initial value min max vary expression
sys_0_site_0_isotropic_chemical_shift -97.0787322 0.19515451 (0.20%) -90.0 -inf inf True
sys_0_site_0_shielding_symmetric_zeta -567.633193 0.41516257 (0.07%) -610.0 -inf inf True
sys_0_site_0_shielding_symmetric_eta 3.7457e-08 0.00685312 (18295734.09%) 0.15 0.00000000 1.00000000 True
sys_0_site_0_shielding_symmetric_alpha 2.69233000 51144.9226 (1899652.82%) 0.7 -inf inf True
sys_0_site_0_shielding_symmetric_beta 2.02064994 5.5168e-04 (0.03%) 2.0 -inf inf True
sys_0_site_0_shielding_symmetric_gamma 3.14157929 1.91847841 (61.07%) 3.0 -inf inf True
sys_0_site_0_quadrupolar_Cq 75678.1776 22.3489322 (0.03%) 75200.0 -inf inf True
sys_0_site_0_quadrupolar_eta 0.94902552 7.2074e-04 (0.08%) 0.9 0.00000000 1.00000000 True
sys_0_abundance 100.000000 0.00000000 (0.00%) 100 0.00000000 100.000000 False 100
SP_0_operation_1_Gaussian_FWHM 16.5865112 0.01940565 (0.12%) 5.0 -inf inf True
SP_0_operation_2_Gaussian_FWHM 4.02904370 0.04207818 (1.04%) 5.0 -inf inf True
SP_0_operation_4_Scale_factor 1.4733e+09 879542.722 (0.06%) 500000000.0 -inf inf True

Correlations (unreported correlations are < 0.100)

sys_0_site_0_shielding_symmetric_etasys_0_site_0_shielding_symmetric_alpha-0.9560
sys_0_site_0_isotropic_chemical_shiftsys_0_site_0_shielding_symmetric_zeta-0.5926
sys_0_site_0_quadrupolar_Cqsys_0_site_0_quadrupolar_eta-0.5375
sys_0_site_0_quadrupolar_etaSP_0_operation_2_Gaussian_FWHM0.4966
sys_0_site_0_shielding_symmetric_betasys_0_site_0_shielding_symmetric_gamma-0.4906
sys_0_site_0_shielding_symmetric_gammaSP_0_operation_1_Gaussian_FWHM-0.4590
SP_0_operation_1_Gaussian_FWHMSP_0_operation_4_Scale_factor0.3657
sys_0_site_0_isotropic_chemical_shiftsys_0_site_0_shielding_symmetric_beta0.3187
sys_0_site_0_shielding_symmetric_zetaSP_0_operation_4_Scale_factor-0.3045
sys_0_site_0_shielding_symmetric_zetasys_0_site_0_shielding_symmetric_alpha-0.2924
sys_0_site_0_shielding_symmetric_etasys_0_site_0_shielding_symmetric_beta0.2906
sys_0_site_0_shielding_symmetric_betaSP_0_operation_1_Gaussian_FWHM0.2826
sys_0_site_0_isotropic_chemical_shiftSP_0_operation_4_Scale_factor0.2188
sys_0_site_0_shielding_symmetric_zetasys_0_site_0_shielding_symmetric_eta0.2182
sys_0_site_0_quadrupolar_CqSP_0_operation_2_Gaussian_FWHM-0.2005
sys_0_site_0_shielding_symmetric_gammasys_0_site_0_quadrupolar_eta-0.1822
sys_0_site_0_shielding_symmetric_etasys_0_site_0_shielding_symmetric_gamma-0.1783
sys_0_site_0_quadrupolar_CqSP_0_operation_4_Scale_factor0.1663
sys_0_site_0_shielding_symmetric_etaSP_0_operation_1_Gaussian_FWHM0.1652
sys_0_site_0_shielding_symmetric_zetasys_0_site_0_shielding_symmetric_beta-0.1572
sys_0_site_0_shielding_symmetric_betasys_0_site_0_quadrupolar_Cq-0.1376
sys_0_site_0_shielding_symmetric_alphasys_0_site_0_shielding_symmetric_beta-0.1354
SP_0_operation_2_Gaussian_FWHMSP_0_operation_4_Scale_factor0.1254
sys_0_site_0_shielding_symmetric_betaSP_0_operation_4_Scale_factor0.1137
sys_0_site_0_shielding_symmetric_etaSP_0_operation_4_Scale_factor0.1095
SP_0_operation_1_Gaussian_FWHMSP_0_operation_2_Gaussian_FWHM-0.1092
sys_0_site_0_shielding_symmetric_gammasys_0_site_0_quadrupolar_Cq0.1070


.. GENERATED FROM PYTHON SOURCE LINES 180-182 The best fit solution --------------------- .. GENERATED FROM PYTHON SOURCE LINES 182-195 .. 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.set_xlim(1000, -1000) ax.set_ylim(1500, -1500) plt.grid() plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_003.png :alt: plot 4 NiCl2.2D2O shifting d :srcset: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 196-198 Image plots with residuals -------------------------- .. GENERATED FROM PYTHON SOURCE LINES 198-210 .. 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", cmap="gist_ncar_r", vmax=vmax, vmin=vmin) ax[i].set_xlim(1000, -1000) ax[0].set_ylim(1500, -1500) plt.tight_layout() plt.show() .. image-sg:: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_004.png :alt: plot 4 NiCl2.2D2O shifting d :srcset: /fitting/2D_fitting/images/sphx_glr_plot_4_NiCl2.2D2O_shifting-d_004.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 211-215 .. [#f1] Walder B.J, Patterson A.M., Baltisberger J.H, and Grandinetti P.J Hydrogen motional disorder in crystalline iron group chloride di-hydrates spectroscopy, J. Chem. Phys. (2018) **149**, 084503. `DOI: 10.1063/1.5037151 `_ .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 6.758 seconds) .. _sphx_glr_download_fitting_2D_fitting_plot_4_NiCl2.2D2O_shifting-d.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_4_NiCl2.2D2O_shifting-d.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_4_NiCl2.2D2O_shifting-d.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_