Пример #1
0
def pre_setup(isotope, shift, reference_offset):
    spin_system = SpinSystem(
        sites=[Site(isotope=isotope, isotropic_chemical_shift=shift)])
    method = Method.parse_dict_with_units(
        dict(
            channels=[isotope],
            spectral_dimensions=[{
                "count":
                2048,
                "spectral_width":
                "25 kHz",
                "reference_offset":
                f"{reference_offset} Hz",
                "events": [{
                    "magnetic_flux_density": "9.4 T"
                }],
            }],
        ))
    sim = Simulator()
    sim.spin_systems.append(spin_system)
    sim.methods += [method]
    sim.run()
    x, y = sim.methods[0].simulation.to_list()
    return x[np.argmax(y)], abs(x[1] - x[0])
def setup_simulator():
    site = Site(
        isotope="23Na",
        isotropic_chemical_shift=32,
        shielding_symmetric={
            "zeta": -120,
            "eta": 0.1
        },
        quadrupolar={
            "Cq": 1e5,
            "eta": 0.31,
            "beta": 5.12
        },
    )
    sys = SpinSystem(sites=[site], abundance=0.123)
    sim = Simulator()
    sim.spin_systems.append(sys)
    sim.methods.append(
        BlochDecayCTSpectrum(channels=["2H"], rotor_frequency=1e3))
    sim.methods.append(
        BlochDecaySpectrum(channels=["2H"], rotor_frequency=12.5e3))
    sim.methods.append(ThreeQ_VAS(channels=["27Al"]))
    sim.methods.append(SSB2D(channels=["17O"], rotor_frequency=35500))
    return sim
Пример #3
0
# 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(100, -100)
plt.grid()
plt.tight_layout()
plt.show()

# %%
# Create a fitting model
# ----------------------
# **Spin System**
B11 = Site(
    isotope="11B",
    isotropic_chemical_shift=20.0,  # in ppm
    quadrupolar=SymmetricTensor(Cq=2.3e6, eta=0.03),  # Cq in Hz
)
spin_systems = [SpinSystem(sites=[B11])]

# %%
# **Method**

# Get the spectral dimension parameters from the experiment.
spectral_dims = get_spectral_dimensions(experiment)

MAS_CT = BlochDecayCTSpectrum(
    channels=["11B"],
    magnetic_flux_density=14.1,  # in T
    rotor_frequency=12500,  # in Hz
    spectral_dimensions=spectral_dims,
Пример #4
0
def SSB2D_setup(ist, vr, method_type):
    sites = [
        Site(
            isotope=ist,
            isotropic_chemical_shift=29,
            shielding_symmetric={
                "zeta": -70,
                "eta": 0.000
            },
        ),
        Site(
            isotope=ist,
            isotropic_chemical_shift=44,
            shielding_symmetric={
                "zeta": -96,
                "eta": 0.166
            },
        ),
        Site(
            isotope=ist,
            isotropic_chemical_shift=57,
            shielding_symmetric={
                "zeta": -120,
                "eta": 0.168
            },
        ),
    ]
    spin_systems = [SpinSystem(sites=[s]) for s in sites]

    B0 = 11.7
    if method_type == "PASS":
        method = SSB2D(
            channels=[ist],
            magnetic_flux_density=B0,  # in T
            rotor_frequency=vr,
            spectral_dimensions=[
                {
                    "count": 32,
                    "spectral_width": 32 * vr,  # in Hz
                    "label": "Anisotropic dimension",
                },
                # The last spectral dimension block is the direct-dimension
                {
                    "count": 2048,
                    "spectral_width": 2e4,  # in Hz
                    "reference_offset": 5e3,  # in Hz
                    "label": "Fast MAS dimension",
                },
            ],
        )
    else:
        method = Method2D(
            channels=[ist],
            magnetic_flux_density=B0,  # in T
            spectral_dimensions=[
                {
                    "count": 64,
                    "spectral_width": 8e4,  # in Hz
                    "label": "Anisotropic dimension",
                    "events": [{
                        "rotor_angle": 90 * 3.14159 / 180
                    }],
                },
                # The last spectral dimension block is the direct-dimension
                {
                    "count": 2048,
                    "spectral_width": 2e4,  # in Hz
                    "reference_offset": 5e3,  # in Hz
                    "label": "Fast MAS dimension",
                },
            ],
            affine_matrix=[[1, -1], [0, 1]],
        )
    sim = Simulator()
    sim.spin_systems = spin_systems  # add spin systems
    sim.methods = [method]  # add the method.
    sim.run()

    data_ssb = sim.methods[0].simulation
    dim_ssb = data_ssb.x[0].coordinates.value

    if method_type == "PASS":
        bloch = BlochDecaySpectrum(
            channels=[ist],
            magnetic_flux_density=B0,  # in T
            rotor_frequency=vr,  # in Hz
            spectral_dimensions=[
                {
                    "count": 32,
                    "spectral_width": 32 * vr,  # in Hz
                    "reference_offset": 0,  # in Hz
                    "label": "MAS dimension",
                },
            ],
        )
    else:
        bloch = BlochDecaySpectrum(
            channels=[ist],
            magnetic_flux_density=B0,  # in T
            rotor_frequency=vr,  # in Hz
            rotor_angle=90 * 3.14159 / 180,
            spectral_dimensions=[
                {
                    "count": 64,
                    "spectral_width": 8e4,  # in Hz
                    "reference_offset": 0,  # in Hz
                    "label": "MAS dimension",
                },
            ],
        )

    for i in range(3):
        iso = spin_systems[i].sites[0].isotropic_chemical_shift
        sys = spin_systems[i].copy()
        sys.sites[0].isotropic_chemical_shift = 0
        sim2 = Simulator()
        sim2.spin_systems = [sys]  # add spin systems
        sim2.methods = [bloch]  # add the method.
        sim2.run()

        index = np.where(dim_ssb < iso)[0][-1]

        one_d_section = data_ssb.y[0].components[0][:, index]
        one_d_section /= one_d_section.max()

        one_d_sim = sim2.methods[0].simulation.y[0].components[0]
        one_d_sim /= one_d_sim.max()

        np.testing.assert_almost_equal(one_d_section, one_d_sim, decimal=6)
Пример #5
0
def test_MQMAS():
    site = Site(
        isotope="87Rb",
        isotropic_chemical_shift=-9,
        shielding_symmetric={
            "zeta": 100,
            "eta": 0
        },
        quadrupolar={
            "Cq": 3.5e6,
            "eta": 0.36,
            "beta": 70 / 180 * np.pi
        },
    )
    spin_system = SpinSystem(sites=[site])

    method = Method2D(
        channels=["87Rb"],
        magnetic_flux_density=9.4,
        spectral_dimensions=[
            {
                "count": 128,
                "spectral_width": 20000,
                "events": [{
                    "transition_query": [{
                        "P": [-3],
                        "D": [0]
                    }]
                }],
            },
            {
                "count": 128,
                "spectral_width": 20000,
                "events": [{
                    "transition_query": [{
                        "P": [-1],
                        "D": [0]
                    }]
                }],
            },
        ],
    )

    sim = Simulator()
    sim.spin_systems = [spin_system]
    sim.methods = [method]
    sim.config.integration_volume = "hemisphere"
    sim.run()

    # process
    k = 21 / 27  # shear factor
    processor = sp.SignalProcessor(operations=[
        sp.IFFT(dim_index=1),
        aft.Shear(factor=-k, dim_index=1, parallel=0),
        aft.Scale(factor=1 + k, dim_index=1),
        sp.FFT(dim_index=1),
    ])
    processed_data = processor.apply_operations(
        data=sim.methods[0].simulation).real

    # Since there is a single site, after the shear and scaling transformations, there
    # should be a single perak along the isotropic dimension at index 70.
    # The isotropic coordinate of this peak is given by
    # w_iso = (17.8)*iso_shift + 1e6/8 * (vq/v0)^2 * (eta^2 / 3 + 1)
    # ref: D. Massiot et al. / Solid State Nuclear Magnetic Resonance 6 (1996) 73-83
    iso_slice = processed_data[40, :]
    assert np.argmax(iso_slice.y[0].components[0]) == 70

    # calculate the isotropic coordinate
    spin = method.channels[0].spin
    w0 = method.channels[0].gyromagnetic_ratio * 9.4 * 1e6
    wq = 3 * 3.5e6 / (2 * spin * (2 * spin - 1))
    w_iso = -9 * 17 / 8 + 1e6 / 8 * (wq / w0)**2 * ((0.36**2) / 3 + 1)

    # the coordinate from spectrum
    w_iso_spectrum = processed_data.x[1].coordinates[70].value
    np.testing.assert_almost_equal(w_iso, w_iso_spectrum, decimal=2)

    # The projection onto the  MAS dimension should be the 1D block decay central
    # transition spectrum
    mas_slice = processed_data.sum(axis=1).y[0].components[0]

    # MAS spectrum
    method = BlochDecayCTSpectrum(
        channels=["87Rb"],
        magnetic_flux_density=9.4,
        rotor_frequency=1e9,
        spectral_dimensions=[{
            "count": 128,
            "spectral_width": 20000
        }],
    )

    sim = Simulator()
    sim.spin_systems = [spin_system]
    sim.methods = [method]
    sim.config.integration_volume = "hemisphere"
    sim.run()

    data = sim.methods[0].simulation.y[0].components[0]
    np.testing.assert_almost_equal(data / data.max(),
                                   mas_slice / mas_slice.max(),
                                   decimal=2,
                                   err_msg="not equal")
Пример #6
0
# The 2D QMAT spectrum is a correlation of finite speed MAS to an infinite speed MAS
# spectrum. The parameters for the simulation are obtained from Walder `et al.` [#f1]_.
import matplotlib.pyplot as plt

from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator.methods import SSB2D
from mrsimulator.spin_system.tensors import SymmetricTensor

# sphinx_gallery_thumbnail_number = 2

# %%
# Generate the site and spin system objects.
sites = [
    Site(
        isotope="87Rb",
        isotropic_chemical_shift=16,  # in ppm
        quadrupolar=SymmetricTensor(Cq=5.3e6, eta=0.1),  # Cq in Hz
    ),
    Site(
        isotope="87Rb",
        isotropic_chemical_shift=40,  # in ppm
        quadrupolar=SymmetricTensor(Cq=2.6e6, eta=1.0),  # Cq in Hz
    ),
]
spin_systems = [SpinSystem(sites=[s]) for s in sites]

# %%
# Use the ``SSB2D`` method to simulate a PASS, MAT, QPASS, QMAT, or any equivalent
# sideband separation spectrum. Here, we use the method to generate a QMAT spectrum.
# The QMAT method is created from the ``SSB2D`` method in the same as a PASS or MAT
# method. The difference is that the observed channel is a half-integer quadrupolar
Пример #7
0
def test_2D():
    site_Ni = Site(
        isotope="2H",
        isotropic_chemical_shift=-97,  # in ppm
        shielding_symmetric=dict(
            zeta=-551,
            eta=0.12,
            alpha=62 * np.pi / 180,
            beta=114 * np.pi / 180,
            gamma=171 * np.pi / 180,
        ),
        quadrupolar=dict(Cq=77.2e3, eta=0.9),  # Cq in Hz
    )
    spin_system = SpinSystem(sites=[site_Ni])

    data = []
    for angle, n_gamma in zip([0, np.pi / 4], [1, 500]):
        shifting_d = Method(
            name="Shifting-d",
            channels=["2H"],
            magnetic_flux_density=9.395,  # in T
            rotor_frequency=0,  # in Hz
            rotor_angle=angle,  # in Hz
            spectral_dimensions=[
                SpectralDimension(
                    count=512,
                    spectral_width=2.5e5,  # in Hz
                    label="Quadrupolar frequency",
                    events=[
                        SpectralEvent(
                            transition_queries=[{
                                "ch1": {
                                    "P": [-1]
                                }
                            }],
                            freq_contrib=["Quad1_2"],
                        ),
                        MixingEvent(query="NoMixing"),
                    ],
                ),
                SpectralDimension(
                    count=256,
                    spectral_width=2e5,  # in Hz
                    reference_offset=2e4,  # in Hz
                    label="Paramagnetic shift",
                    events=[
                        SpectralEvent(
                            transition_queries=[{
                                "ch1": {
                                    "P": [-1]
                                }
                            }],
                            freq_contrib=["Shielding1_0", "Shielding1_2"],
                        )
                    ],
                ),
            ],
        )

        sim = Simulator(spin_systems=[spin_system], methods=[shifting_d])
        sim.config.integration_volume = "hemisphere"
        sim.config.number_of_gamma_angles = n_gamma
        sim.run(auto_switch=False)

        res = sim.methods[0].simulation.y[0].components[0]
        data.append(res / res.max())

    # _, ax = plt.subplots(1, 2)
    # ax[0].imshow(data[0].real)
    # ax[1].imshow(data[1].real)
    # plt.show()

    np.testing.assert_almost_equal(data[0], data[1], decimal=1.8)
Пример #8
0
# broadening is applied to the spectrum as a post-simulation step.
import matplotlib.pyplot as plt

from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator.method.lib import ThreeQ_VAS
from mrsimulator import signal_processor as sp
from mrsimulator.spin_system.tensors import SymmetricTensor
from mrsimulator.method import SpectralDimension

# sphinx_gallery_thumbnail_number = 3

# %%
# Generate the site and spin system objects.
Rb87_1 = Site(
    isotope="87Rb",
    isotropic_chemical_shift=-27.4,  # in ppm
    quadrupolar=SymmetricTensor(Cq=1.68e6, eta=0.2),  # Cq is in Hz
)
Rb87_2 = Site(
    isotope="87Rb",
    isotropic_chemical_shift=-28.5,  # in ppm
    quadrupolar=SymmetricTensor(Cq=1.94e6, eta=1.0),  # Cq is in Hz
)
Rb87_3 = Site(
    isotope="87Rb",
    isotropic_chemical_shift=-31.3,  # in ppm
    quadrupolar=SymmetricTensor(Cq=1.72e6, eta=0.5),  # Cq is in Hz
)

sites = [Rb87_1, Rb87_2, Rb87_3]  # all sites
spin_systems = [SpinSystem(sites=[s]) for s in sites]
import numpy as np

from mrsimulator import Simulator, SpinSystem, Site, Coupling
from mrsimulator.methods import Method1D
from mrsimulator.method import SpectralDimension, SpectralEvent, MixingEvent
from mrsimulator.spin_system.tensors import SymmetricTensor

# sphinx_gallery_thumbnail_number = 2

# %%
# For demonstration, we will create two spin systems, one with a single site and other
# with two spin 1/2 sites.

S1 = Site(
    isotope="1H",
    isotropic_chemical_shift=10,  # in ppm
    shielding_symmetric=SymmetricTensor(zeta=-80, eta=0.25),  # zeta in ppm
)
S2 = Site(isotope="1H", isotropic_chemical_shift=-10)
S12 = Coupling(site_index=[0, 1],
               isotropic_j=100,
               dipolar=SymmetricTensor(D=2000, eta=0, alpha=0))

spin_system_1 = SpinSystem(sites=[S1], label="Uncoupled system")
spin_system_2 = SpinSystem(sites=[S1, S2],
                           couplings=[S12],
                           label="Coupled system")

# %%
# **Create a custom method**
#
plt.grid()
plt.tight_layout()
plt.show()

# %%
# Create a fitting model
# ----------------------
# **Guess model**
#
# Create a guess list of spin systems. For fitting the sideband profile at an isotropic
# chemical shift cross-section from PASS/MAT datasets, set the isotropic_chemical_shift
# parameter of the site object as zero.
site = Site(
    isotope="13C",
    isotropic_chemical_shift=0,  #
    shielding_symmetric={
        "zeta": -70,
        "eta": 0.8
    },
)
spin_systems = [SpinSystem(sites=[site])]

# %%
# **Method**
#
# For the sideband-only cross-section, use the BlochDecaySpectrum method.

# Get the dimension information from the experiment.
spectral_dims = get_spectral_dimensions(pass_cross_section)

PASS = BlochDecaySpectrum(
    channels=["13C"],
Пример #11
0
# :math:`^{29}\text{Si}` sites. The :math:`^{29}\text{Si}` tensor parameters
# were obtained from Hansen `et al.` [#f1]_
import matplotlib.pyplot as plt

from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator import signal_processing as sp
from mrsimulator.methods import BlochDecaySpectrum
from mrsimulator.spin_system.tensors import SymmetricTensor

# sphinx_gallery_thumbnail_number = 3

# %%
# **Step 1:** Create the sites.
Si29_1 = Site(
    isotope="29Si",
    isotropic_chemical_shift=-89.0,  # in ppm
    shielding_symmetric=SymmetricTensor(zeta=59.8, eta=0.62),  # zeta in ppm
)
Si29_2 = Site(
    isotope="29Si",
    isotropic_chemical_shift=-89.5,  # in ppm
    shielding_symmetric=SymmetricTensor(zeta=52.1, eta=0.68),  # zeta in ppm
)
Si29_3 = Site(
    isotope="29Si",
    isotropic_chemical_shift=-87.8,  # in ppm
    shielding_symmetric=SymmetricTensor(zeta=69.4, eta=0.60),  # zeta in ppm
)

# %%
# **Step 2:** Create the spin systems from these sites. Again, we create three
import matplotlib as mpl
import matplotlib.pyplot as plt
from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator.methods import Method1D

# global plot configuration
mpl.rcParams["figure.figsize"] = [4.5, 3.0]
# sphinx_gallery_thumbnail_number = 1

# %%
# Create a single-site arbitrary spin system.
site = Site(
    name="27Al",
    isotope="27Al",
    isotropic_chemical_shift=35.7,  # in ppm
    quadrupolar={
        "Cq": 2.959e6,
        "eta": 0.98
    },  # Cq is in Hz
)
spin_system = SpinSystem(sites=[site])

# %%
# Selecting the triple-quantum transition
# ---------------------------------------
#
# For spin-site spin-5/2 spin system, there are three triple-quantum transition
#
# - :math:`|1/2\rangle\rightarrow|-5/2\rangle` (:math:`P=-3, D=6`)
# - :math:`|3/2\rangle\rightarrow|-3/2\rangle` (:math:`P=-3, D=0`)
# - :math:`|5/2\rangle\rightarrow|-1/2\rangle` (:math:`P=-3, D=-6`)
plt.show()

# %%
# Create a fitting model
# ----------------------
# **Guess model**
#
# Create a guess list of spin systems.
site = Site(
    isotope="2H",
    isotropic_chemical_shift=200,  # in ppm
    shielding_symmetric={
        "zeta": -1300,  # in ppm
        "eta": 0.2,
        "alpha": np.pi,  # in rads
        "beta": np.pi / 2,  # in rads
        "gamma": np.pi / 2,  # in rads
    },
    quadrupolar={
        "Cq": 110e3,
        "eta": 0.83
    },  # Cq in Hz
)

spin_systems = [SpinSystem(sites=[site])]

# %%
# **Method**
#
# Use the generic 2D method, `Method2D`, to generate a shifting-d echo method.
Пример #14
0
def test_site_quad_set_to_None():
    a = Site(isotope="27Al", quadrupolar=None)
    assert a.isotope.symbol == "27Al"
    assert a.quadrupolar is None
Пример #15
0
# plot of the dataset.
plt.figure(figsize=(4.25, 3.0))
ax = plt.subplot(projection="csdm")
ax.plot(experiment, color="black", linewidth=0.5, label="Experiment")
ax.set_xlim(600, -700)
plt.grid()
plt.tight_layout()
plt.show()

# %%
# Create a fitting model
# ----------------------
# **Spin System**
H_2 = Site(
    isotope="2H",
    isotropic_chemical_shift=-57.12,  # in ppm,
    quadrupolar=SymmetricTensor(Cq=3e4, eta=0.0),  # Cq in Hz
)

spin_systems = [SpinSystem(sites=[H_2])]

# %%
# **Method**

# Get the spectral dimension parameters from the experiment.
spectral_dims = get_spectral_dimensions(experiment)

MAS = BlochDecaySpectrum(
    channels=["2H"],
    magnetic_flux_density=9.395,  # in T
    rotor_frequency=4517.1,  # in Hz
Пример #16
0
import mrsimulator.signal_processing as sp
import mrsimulator.signal_processing.apodization as apo
from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator.methods import Method2D

# global plot configuration
mpl.rcParams["figure.figsize"] = [4.5, 3.0]
# sphinx_gallery_thumbnail_number = 1

# %%
# Create the sites and spin systems
sites = [
    Site(
        isotope="29Si",
        isotropic_chemical_shift=-89.0,  # in ppm
        shielding_symmetric={
            "zeta": 59.8,
            "eta": 0.62
        },  # zeta in ppm
    ),
    Site(
        isotope="29Si",
        isotropic_chemical_shift=-89.5,  # in ppm
        shielding_symmetric={
            "zeta": 52.1,
            "eta": 0.68
        },  # zeta in ppm
    ),
    Site(
        isotope="29Si",
        isotropic_chemical_shift=-87.8,  # in ppm
        shielding_symmetric={
Пример #17
0
# The following is an example of the STMAS simulation of :math:`\text{RbNO}_3`. The
# :math:`^{87}\text{Rb}` tensor parameters were obtained from Massiot `et al.` [#f1]_.
import matplotlib.pyplot as plt

from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator.methods import ST1_VAS
from mrsimulator import signal_processing as sp

# sphinx_gallery_thumbnail_number = 2

# %%
# Generate the site and spin system objects.
Rb87_1 = Site(
    isotope="87Rb",
    isotropic_chemical_shift=-27.4,  # in ppm
    quadrupolar={
        "Cq": 1.68e6,
        "eta": 0.2
    },  # Cq is in Hz
)
Rb87_2 = Site(
    isotope="87Rb",
    isotropic_chemical_shift=-28.5,  # in ppm
    quadrupolar={
        "Cq": 1.94e6,
        "eta": 1.0
    },  # Cq is in Hz
)
Rb87_3 = Site(
    isotope="87Rb",
    isotropic_chemical_shift=-31.3,  # in ppm
    quadrupolar={
Пример #18
0
# plot of the dataset.
plt.figure(figsize=(4.25, 3.0))
ax = plt.subplot(projection="csdm")
ax.plot(experiment, color="black", linewidth=0.5, label="Experiment")
ax.set_xlim(200, -200)
plt.grid()
plt.tight_layout()
plt.show()

# %%
# Create a fitting model
# ----------------------
# **Spin System**
P_31 = Site(
    isotope="31P",
    isotropic_chemical_shift=5.0,  # in ppm,
    shielding_symmetric=SymmetricTensor(zeta=-80, eta=0.5),  # zeta in Hz
)

spin_systems = [SpinSystem(sites=[P_31])]

# %%
# **Method**

# Get the spectral dimension parameters from the experiment.
spectral_dims = get_spectral_dimensions(experiment)

static1D = BlochDecaySpectrum(
    channels=["31P"],
    magnetic_flux_density=9.395,  # in T
    rotor_frequency=0,  # in Hz
Пример #19
0
def test_csa_01():
    site = Site(isotope="13C", shielding_symmetric={"zeta": 50, "eta": 0.5})
    spin_system = SpinSystem(sites=[site])
    setup_test(spin_system, volume="octant", sw=2.5e4)
Пример #20
0
ax.plot(experiment, color="black", linewidth=0.5, label="Experiment")
ax.set_xlim(100, -50)
plt.grid()
plt.tight_layout()
plt.show()

# %%
# Create a fitting model
# ----------------------
#
# A fitting model is a composite of ``Simulator`` and ``SignalProcessor`` objects.
#
# **Step 1:** Create initial guess sites and spin systems
O1 = Site(
    isotope="17O",
    isotropic_chemical_shift=60.0,  # in ppm,
    quadrupolar=SymmetricTensor(Cq=4.2e6, eta=0.5),  # Cq in Hz
)

O2 = Site(
    isotope="17O",
    isotropic_chemical_shift=40.0,  # in ppm,
    quadrupolar=SymmetricTensor(Cq=2.4e6, eta=0.0),  # Cq in Hz
)

spin_systems = [
    SpinSystem(sites=[O1], abundance=50, name="O1"),
    SpinSystem(sites=[O2], abundance=50, name="O2"),
]

# %%
Пример #21
0
import mrsimulator.signal_processing as sp
import mrsimulator.signal_processing.apodization as apo
from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator.methods import BlochDecayCentralTransitionSpectrum

# global plot configuration
mpl.rcParams["figure.figsize"] = [4.5, 3.0]
# sphinx_gallery_thumbnail_number = 2

# %%
# **Step 1:** Create the sites.

# default unit of isotropic_chemical_shift is ppm and Cq is Hz.
O17_1 = Site(isotope="17O",
             isotropic_chemical_shift=29,
             quadrupolar={
                 "Cq": 6.05e6,
                 "eta": 0.000
             })
O17_2 = Site(isotope="17O",
             isotropic_chemical_shift=41,
             quadrupolar={
                 "Cq": 5.43e6,
                 "eta": 0.166
             })
O17_3 = Site(isotope="17O",
             isotropic_chemical_shift=57,
             quadrupolar={
                 "Cq": 5.45e6,
                 "eta": 0.168
             })
O17_4 = Site(isotope="17O",
Пример #22
0
# you will first need to create a fitting model. We will use the ``mrsimulator`` objects
# as tools in creating a model for the least-squares fitting.
#
# **Step 1:** Create initial guess sites and spin systems.
#
# The initial guess is often based on some prior knowledge about the system under
# investigation. For the current example, we know that Cuspidine is a crystalline silica
# polymorph with one crystallographic Si site. Therefore, our initial guess model is a
# single :math:`^{29}\text{Si}` site spin system. For non-linear fitting algorithms, as
# a general recommendation, the initial guess model parameters should be a good starting
# point for the algorithms to converge.

# the guess model comprising of a single site spin system
site = Site(
    isotope="29Si",
    isotropic_chemical_shift=-82.0,  # in ppm,
    shielding_symmetric=SymmetricTensor(zeta=-63, eta=0.4),  # zeta in ppm
)

spin_system = SpinSystem(
    name="Si Site",
    description="A 29Si site in cuspidine",
    sites=[site],  # from the above code
    abundance=100,
)

# %%
# **Step 2:** Create the method object.
#
# The method should be the same as the one used
# in the measurement. In this example, we use the `BlochDecaySpectrum` method. Note,
Пример #23
0
def test_ThreeQ_VAS_spin_3halves():
    site = Site(
        isotope="87Rb",
        isotropic_chemical_shift=-9,
        shielding_symmetric={
            "zeta": 100,
            "eta": 0
        },
        quadrupolar={
            "Cq": 3.5e6,
            "eta": 0.36,
            "beta": 70 / 180 * np.pi
        },
    )
    spin_system = SpinSystem(sites=[site])

    method = ThreeQ_VAS(
        channels=["87Rb"],
        magnetic_flux_density=9.4,
        spectral_dimensions=[
            {
                "count": 1024,
                "spectral_width": 20000
            },
            {
                "count": 512,
                "spectral_width": 20000
            },
        ],
    )
    sim = Simulator()
    sim.spin_systems = [spin_system]
    sim.methods = [method]
    sim.config.integration_volume = "hemisphere"
    sim.run()

    data = sim.methods[0].simulation
    dat = data.y[0].components[0]
    index = np.where(dat == dat.max())[0]

    # The isotropic coordinate of this peak is given by
    # v_iso = (17/8)*iso_shift + 1e6/8 * (vq/v0)^2 * (eta^2 / 3 + 1)
    # ref: D. Massiot et al. / Solid State Nuclear Magnetic Resonance 6 (1996) 73-83
    spin = method.channels[0].spin
    v0 = method.channels[0].gyromagnetic_ratio * 9.4 * 1e6
    vq = (3 * 3.5e6) / (2 * spin * (2 * spin - 1))
    v_iso = -9 * 17 / 8 + 1e6 / 8 * ((vq / v0)**2) * ((0.36**2) / 3 + 1)

    # the coordinate from spectrum along the iso dimension must be equal to v_iso
    v_iso_spectrum = data.x[1].coordinates[index[0]].value
    np.testing.assert_almost_equal(v_iso, v_iso_spectrum, decimal=2)

    # The projection onto the  MAS dimension should be the 1D block decay central
    # transition spectrum
    mas_slice = data.sum(axis=1).y[0].components[0]

    # MAS spectrum
    method = BlochDecayCTSpectrum(
        channels=["87Rb"],
        magnetic_flux_density=9.4,
        rotor_frequency=1e9,
        spectral_dimensions=[{
            "count": 512,
            "spectral_width": 20000
        }],
    )

    sim = Simulator()
    sim.spin_systems = [spin_system]
    sim.methods = [method]
    sim.config.integration_volume = "hemisphere"
    sim.run()

    data = sim.methods[0].simulation.y[0].components[0]
    assert np.allclose(data / data.max(), mas_slice / mas_slice.max())
Пример #24
0
from mrsimulator import Simulator, SpinSystem, Site
from mrsimulator.methods import Method2D
from mrsimulator import signal_processing as sp
from mrsimulator.spin_system.tensors import SymmetricTensor
from mrsimulator.method import SpectralDimension, SpectralEvent

# sphinx_gallery_thumbnail_number = 3

# %%
# Generate the site and spin system objects.
site = Site(
    isotope="87Rb",
    isotropic_chemical_shift=-9,  # in ppm
    shielding_symmetric=SymmetricTensor(zeta=110, eta=0),
    quadrupolar=SymmetricTensor(
        Cq=3.5e6,  # in Hz
        eta=0.36,
        alpha=0,  # in rads
        beta=70 * 3.14159 / 180,  # in rads
        gamma=0,  # in rads
    ),
)
spin_system = SpinSystem(sites=[site])

# %%
# Use the generic 2D method, `Method2D`, to simulate a COASTER spectrum by customizing
# the method parameters, as shown below. Note, the Method2D method simulates an infinite
# spinning speed spectrum.
coaster = Method2D(
    name="COASTER",
    channels=["87Rb"],
    magnetic_flux_density=9.4,  # in T
Пример #25
0
def test_MQMAS_spin_5halves():
    spin_system = SpinSystem(sites=[
        Site(
            isotope="27Al",
            isotropic_chemical_shift=64.5,  # in ppm
            quadrupolar={
                "Cq": 3.22e6,
                "eta": 0.66
            },  # Cq is in Hz
        )
    ])

    method = ThreeQ_VAS(
        channels=["27Al"],
        magnetic_flux_density=7,
        spectral_dimensions=[
            {
                "count": 1024,
                "spectral_width": 5000,
                "reference_offset": -3e3
            },
            {
                "count": 512,
                "spectral_width": 10000,
                "reference_offset": 4e3
            },
        ],
    )

    sim = Simulator()
    sim.spin_systems = [spin_system]
    sim.methods = [method]
    sim.run()

    data = sim.methods[0].simulation
    dat = data.y[0].components[0]
    index = np.where(dat == dat.max())[0]

    # The isotropic coordinate of this peak is given by
    # v_iso = -(17/31)*iso_shift + 8e6/93 * (vq/v0)^2 * (eta^2 / 3 + 1)
    # ref: D. Massiot et al. / Solid State Nuclear Magnetic Resonance 6 (1996) 73-83
    spin = method.channels[0].spin
    v0 = method.channels[0].gyromagnetic_ratio * 7 * 1e6
    vq = 3 * 3.22e6 / (2 * spin * (2 * spin - 1))
    v_iso = -(17 / 31) * 64.5 - (8e6 / 93) * (vq / v0)**2 * ((0.66**2) / 3 + 1)

    # the coordinate from spectrum along the iso dimension must be equal to v_iso
    v_iso_spectrum = data.x[1].coordinates[index[0]].value
    np.testing.assert_almost_equal(v_iso, v_iso_spectrum, decimal=2)

    # The projection onto the  MAS dimension should be the 1D block decay central
    # transition spectrum
    mas_slice = data.sum(axis=1).y[0].components[0]

    # MAS spectrum
    method = BlochDecayCTSpectrum(
        channels=["27Al"],
        magnetic_flux_density=7,
        rotor_frequency=1e9,
        spectral_dimensions=[{
            "count": 512,
            "spectral_width": 10000,
            "reference_offset": 4e3
        }],
    )

    sim = Simulator()
    sim.spin_systems = [spin_system]
    sim.methods = [method]
    sim.config.integration_volume = "hemisphere"
    sim.run()

    data = sim.methods[0].simulation.y[0].components[0]
    assert np.allclose(data / data.max(), mas_slice / mas_slice.max())
Пример #26
0
def test_direct_init_spin_system():
    # test-1 # empty spin system
    the_spin_system = SpinSystem(sites=[],
                                 abundance=10,
                                 transition_pathways=None)

    assert the_spin_system.sites == []
    assert the_spin_system.abundance == 10.0
    assert the_spin_system.transition_pathways is None

    assert the_spin_system.json() == {"abundance": "10.0 %"}
    assert the_spin_system.json(units=False) == {
        "abundance": 10.0,
    }

    # test-2 # site
    test_site = Site(isotope="29Si", isotropic_chemical_shift=10)

    assert test_site.isotope.symbol == "29Si"
    assert test_site.isotropic_chemical_shift == 10.0
    assert test_site.property_units["isotropic_chemical_shift"] == "ppm"

    assert test_site.json() == {
        "isotope": "29Si",
        "isotropic_chemical_shift": "10.0 ppm",
    }
    assert test_site.json(units=False) == {
        "isotope": "29Si",
        "isotropic_chemical_shift": 10.0,
    }

    # test-3 # one site spin system
    the_spin_system = SpinSystem(sites=[test_site], abundance=10)
    assert isinstance(the_spin_system.sites[0], Site)
    assert the_spin_system.abundance == 10.0
    assert the_spin_system.json() == {
        "sites": [{
            "isotope": "29Si",
            "isotropic_chemical_shift": "10.0 ppm"
        }],
        "abundance": "10.0 %",
    }
    assert the_spin_system.json(units=False) == {
        "sites": [{
            "isotope": "29Si",
            "isotropic_chemical_shift": 10.0
        }],
        "abundance": 10,
    }

    # test-4 # two sites spin system
    the_spin_system = SpinSystem(sites=[test_site, test_site], abundance=10)
    assert isinstance(the_spin_system.sites[0], Site)
    assert isinstance(the_spin_system.sites[1], Site)
    assert id(the_spin_system.sites[0]) != id(the_spin_system.sites[1])
    assert the_spin_system.abundance == 10.0
    assert the_spin_system.json() == {
        "sites": [
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": "10.0 ppm"
            },
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": "10.0 ppm"
            },
        ],
        "abundance":
        "10.0 %",
    }
    assert the_spin_system.json(units=False) == {
        "sites": [
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": 10.0
            },
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": 10.0
            },
        ],
        "abundance":
        10,
    }

    # test-5 # coupling
    test_coupling = Coupling(site_index=[0, 1],
                             isotropic_j=10,
                             dipolar={"D": 100})

    assert test_coupling.site_index == [0, 1]
    assert test_coupling.isotropic_j == 10.0
    assert test_coupling.property_units["isotropic_j"] == "Hz"

    assert test_coupling.dipolar.D == 100.0
    assert test_coupling.dipolar.property_units["D"] == "Hz"

    assert test_coupling.json() == {
        "site_index": [0, 1],
        "isotropic_j": "10.0 Hz",
        "dipolar": {
            "D": "100.0 Hz"
        },
    }
    assert test_coupling.json(units=False) == {
        "site_index": [0, 1],
        "isotropic_j": 10.0,
        "dipolar": {
            "D": 100.0
        },
    }

    # test-6 #  two sites and one coupling spin system
    the_spin_system = SpinSystem(sites=[test_site, test_site],
                                 couplings=[test_coupling],
                                 abundance=10)
    assert isinstance(the_spin_system.sites[0], Site)
    assert isinstance(the_spin_system.sites[1], Site)
    assert isinstance(the_spin_system.couplings[0], Coupling)
    assert id(the_spin_system.sites[0]) != id(the_spin_system.sites[1])
    assert the_spin_system.abundance == 10.0
    assert the_spin_system.json() == {
        "sites": [
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": "10.0 ppm"
            },
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": "10.0 ppm"
            },
        ],
        "couplings": [{
            "site_index": [0, 1],
            "isotropic_j": "10.0 Hz",
            "dipolar": {
                "D": "100.0 Hz"
            },
        }],
        "abundance":
        "10.0 %",
    }
    assert the_spin_system.json(units=False) == {
        "sites": [
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": 10.0
            },
            {
                "isotope": "29Si",
                "isotropic_chemical_shift": 10.0
            },
        ],
        "couplings": [{
            "site_index": [0, 1],
            "isotropic_j": 10.0,
            "dipolar": {
                "D": 100.0
            }
        }],
        "abundance":
        10,
    }

    # test-5
    the_spin_system = SpinSystem(
        name="Just a test",
        description="The same",
        sites=[
            {
                "isotope": "1H",
                "isotropic_chemical_shift": 0
            },
            {
                "isotope": "17O",
                "isotropic_chemical_shift": -10,
                "quadrupolar": {
                    "Cq": 5.1e6,
                    "eta": 0.5
                },
            },
        ],
        couplings=[{
            "site_index": [0, 1],
            "isotropic_j": 34
        }],
        abundance=4.23,
    )
    assert the_spin_system.name == "Just a test"
    assert the_spin_system.description == "The same"
    assert the_spin_system.sites[0].isotope.symbol == "1H"
    assert the_spin_system.sites[0].isotropic_chemical_shift == 0
    assert the_spin_system.sites[1].isotope.symbol == "17O"
    assert the_spin_system.sites[1].isotropic_chemical_shift == -10
    assert the_spin_system.sites[1].quadrupolar.Cq == 5.1e6
    assert the_spin_system.sites[1].quadrupolar.eta == 0.5
    assert the_spin_system.couplings[0].site_index == [0, 1]
    assert the_spin_system.couplings[0].isotropic_j == 34.0
    assert the_spin_system.abundance == 4.23

    serialize = the_spin_system.json()
    assert serialize == {
        "name":
        "Just a test",
        "description":
        "The same",
        "sites": [
            {
                "isotope": "1H",
                "isotropic_chemical_shift": "0.0 ppm"
            },
            {
                "isotope": "17O",
                "isotropic_chemical_shift": "-10.0 ppm",
                "quadrupolar": {
                    "Cq": "5100000.0 Hz",
                    "eta": 0.5
                },
            },
        ],
        "couplings": [{
            "site_index": [0, 1],
            "isotropic_j": "34.0 Hz"
        }],
        "abundance":
        "4.23 %",
    }
    assert the_spin_system == SpinSystem.parse_dict_with_units(serialize)

    json_no_unit = the_spin_system.json(units=False)
    assert json_no_unit == {
        "name":
        "Just a test",
        "description":
        "The same",
        "sites": [
            {
                "isotope": "1H",
                "isotropic_chemical_shift": 0
            },
            {
                "isotope": "17O",
                "isotropic_chemical_shift": -10.0,
                "quadrupolar": {
                    "Cq": 5100000,
                    "eta": 0.5
                },
            },
        ],
        "couplings": [{
            "site_index": [0, 1],
            "isotropic_j": 34.0
        }],
        "abundance":
        4.23,
    }
    assert the_spin_system == SpinSystem(**json_no_unit)
Пример #27
0
ax.set_xlim(100, -50)
plt.grid()
plt.tight_layout()
plt.show()

# %%
# Create a fitting model
# ----------------------
#
# A fitting model is a composite of ``Simulator`` and ``SignalProcessor`` objects.
#
# **Step 1:** Create initial guess sites and spin systems
O1 = Site(
    isotope="17O",
    isotropic_chemical_shift=60.0,  # in ppm,
    quadrupolar={
        "Cq": 4.2e6,
        "eta": 0.5
    },  # Cq in Hz
)

O2 = Site(
    isotope="17O",
    isotropic_chemical_shift=40.0,  # in ppm,
    quadrupolar={
        "Cq": 2.4e6,
        "eta": 0
    },  # Cq in Hz
)

spin_systems = [
    SpinSystem(sites=[O1], abundance=50, name="O1"),
Пример #28
0
def get_spin_system_list():
    isotopes = [
        "19F", "31P", "2H", "6Li", "14N", "27Al", "25Mg", "45Sc", "87Sr"
    ]
    return SpinSystem(sites=[Site(isotope=item) for item in isotopes])
Пример #29
0
def test_warnings():
    s = SpinSystem(sites=[Site(isotope="23Na")])
    m = Method1D(channels=["1H"])
    assert m.get_transition_pathways(s) == []
Пример #30
0
def test_bad_assignments():
    error = "value is not a valid list"
    with pytest.raises(ValidationError, match=f".*{error}.*"):
        SpinSystem(sites=Site())