Esempio n. 1
0
def test_method_exp_sim():
    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
        )
    ])

    data = cp.as_csdm(np.random.rand(1024, 512))
    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
            },
        ],
        experiment=data,
    )

    sim = Simulator()
    sim.spin_systems = [spin_system]
    sim.methods = [method]
    sim.run()
Esempio n. 2
0
def test_sites_to_pandas_df():
    isotopes = ["29Si"] * 3 + ["17O"]
    shifts = [-89.0, -89.5, -87.8, 15.0]
    zeta = [59.8, 52.1, 69.4, 12.4]
    eta_n = [0.62, 0.68, 0.6, 0.5]
    Cq = [None, None, None, 5.3e6]
    eta_q = [None, None, None, 0.34]

    spin_systems = single_site_system_generator(
        isotope=isotopes,
        isotropic_chemical_shift=shifts,
        shielding_symmetric={"zeta": zeta, "eta": eta_n},
        quadrupolar={"Cq": Cq, "eta": eta_q},
        abundance=1,
    )

    sim = Simulator()
    sim.spin_systems = spin_systems
    pd_o = sim.sites().to_pd()

    assert list(pd_o["isotope"]) == isotopes
    assert list(pd_o["isotropic_chemical_shift"]) == [
        f"{i} ppm" if i is not None else None for i in shifts
    ]
    assert list(pd_o["shielding_symmetric.zeta"]) == [
        f"{i} ppm" if i is not None else None for i in zeta
    ]
    assert list(pd_o["shielding_symmetric.eta"]) == [
        i if i is not None else None for i in eta_n
    ]
    assert list(pd_o["quadrupolar.Cq"]) == [
        f"{i} Hz" if i is not None else None for i in Cq
    ]
Esempio n. 3
0
def test_simulator_assignments():
    a = Simulator()
    assert a.spin_systems == []

    error = "value is not a valid list"
    with pytest.raises(Exception, match=f".*{error}.*"):
        a.spin_systems = ""

    with pytest.raises(Exception, match=f".*{error}.*"):
        a.methods = ""
Esempio n. 4
0
def generate_simulator(spin_systems,
                       method,
                       integration_volume="octant",
                       number_of_sidebands=64):
    sim = Simulator()
    sim.spin_systems = spin_systems
    sim.methods = [method]
    sim.config.integration_volume = integration_volume
    sim.config.number_of_sidebands = number_of_sidebands
    return sim
def test_sites():
    iso = [1.02, 2.12, 13.2, 5.2, 2.1, 1.2]
    zeta = [1.02, 2.12, 13.2, 5.2, 2.1, 1.2]
    eta = [0.1, 0.4, 0.3, 0.6, 0.9, 1.0]
    sites = [
        Site(
            isotope="13C",
            isotropic_chemical_shift=i,
            shielding_symmetric={
                "zeta": z,
                "eta": e
            },
        ) for i, z, e in zip(iso, zeta, eta)
    ]
    sim = Simulator()
    sim.spin_systems = [SpinSystem(sites=[s]) for s in sites]
    r_sites = sim.sites()
    for i, site in enumerate(sites):
        assert r_sites[i] == site

    # test sites to pd
    sites_table = sim.sites().to_pd()

    assert list(sites_table["isotope"]) == ["13C"] * len(iso)
    assert list(sites_table["isotropic_chemical_shift"]) == [
        f"{i} ppm" if i is not None else None for i in iso
    ]
    assert list(sites_table["shielding_symmetric.zeta"]) == [
        f"{i} ppm" if i is not None else None for i in zeta
    ]
    assert list(sites_table["shielding_symmetric.eta"]) == [
        i if i is not None else None for i in eta
    ]

    # test Sites Class
    a = Sites([])

    site = Site(isotope="1H")
    a.append(site)
    assert a[0] == site

    site2 = Site(isotope="17O")
    a[0] = site2
    assert a[0] == site2

    site_dict = {"isotope": "13C"}
    a[0] = site_dict
    assert a[0] == Site(**site_dict)

    with pytest.raises(ValueError,
                       match="Only object of type Site is allowed."):
        a[0] = ""
Esempio n. 6
0
def generate_shielding_kernel(zeta_,
                              eta_,
                              angle,
                              freq,
                              n_sidebands,
                              to_ppm=True):
    method = BlochDecaySpectrum(
        channels=["29Si"],
        magnetic_flux_density=9.4,
        spectral_dimensions=[
            dict(count=96, spectral_width=208.33 * 96, reference_offset=0)
        ],
        rotor_angle=angle,
        rotor_frequency=freq,
    )
    if to_ppm:
        larmor_frequency = -method.channels[
            0].gyromagnetic_ratio * 9.4  # in MHz
        zeta_ /= larmor_frequency

    spin_systems = [
        SpinSystem(sites=[
            Site(isotope="29Si", shielding_symmetric={
                "zeta": z,
                "eta": e
            })
        ]) for z, e in zip(zeta_, eta_)
    ]

    sim = Simulator()
    sim.spin_systems = spin_systems
    sim.methods = [method]
    sim.config.decompose_spectrum = "spin_system"
    sim.config.number_of_sidebands = n_sidebands
    sim.run(pack_as_csdm=False)
    sim_lineshape = sim.methods[0].simulation.real
    sim_lineshape = np.asarray(sim_lineshape).reshape(4, 4, 96)
    sim_lineshape = sim_lineshape / sim_lineshape[0, 0].sum()
    sim_lineshape[0, :, :] /= 2.0
    sim_lineshape[:, 0, :] /= 2.0
    sim_lineshape.shape = (16, 96)
    return sim_lineshape
def test_simulator_2():
    sim = Simulator()
    sim.spin_systems = [
        SpinSystem(
            sites=[Site(isotope="1H"),
                   Site(isotope="23Na")],
            couplings=[Coupling(site_index=[0, 1], isotropic_j=15)],
        )
    ]
    sim.methods = [
        BlochDecaySpectrum(
            channels=["1H"],
            spectral_dimensions=[{
                "count": 10
            }],
            experiment=cp.as_csdm(np.arange(10)),
        )
    ]
    sim.name = "test"
    sim.label = "test0"
    sim.description = "testing-testing 1.2.3"

    sim.run()

    # save
    sim.save("test_sim_save.temp")
    sim_load = Simulator.load("test_sim_save.temp")

    sim_load_data = sim_load.methods[0].simulation
    sim_data = sim.methods[0].simulation
    sim_load_data._timestamp = ""
    assert sim_load_data.dict() == sim_data.dict()

    sim_load.methods[0].simulation = None
    sim.methods[0].simulation = None
    assert sim_load.spin_systems == sim.spin_systems
    assert sim_load.methods == sim.methods
    assert sim_load.name == sim.name
    assert sim_load.description == sim.description

    os.remove("test_sim_save.temp")
Esempio n. 8
0
    def kernel(self, supersampling=1):
        """
        Return the NMR nuclear shielding anisotropic line-shape kernel.

        Args:
            supersampling: An integer. Each cell is supersampled by the factor
                    `supersampling` along every dimension.
        Returns:
            A numpy array containing the line-shape kernel.
        """
        args_ = deepcopy(self.method_args)
        method = BlochDecaySpectrum.parse_dict_with_units(args_)
        isotope = args_["channels"][0]
        zeta, eta = self._get_zeta_eta(supersampling)

        x_csdm = self.inverse_kernel_dimension[0]
        if x_csdm.coordinates.unit.physical_type == "frequency":
            # convert zeta to ppm if given in frequency units.
            zeta /= self.larmor_frequency  # zeta in ppm

            for dim_i in self.inverse_kernel_dimension:
                if dim_i.origin_offset.value == 0:
                    dim_i.origin_offset = f"{abs(self.larmor_frequency)} MHz"

        spin_systems = [
            SpinSystem(sites=[
                dict(isotope=isotope, shielding_symmetric=dict(zeta=z, eta=e))
            ]) for z, e in zip(zeta, eta)
        ]

        sim = Simulator()
        sim.config.number_of_sidebands = self.number_of_sidebands
        sim.config.decompose_spectrum = "spin_system"

        sim.spin_systems = spin_systems
        sim.methods = [method]
        sim.run(pack_as_csdm=False)

        amp = sim.methods[0].simulation.real
        return self._averaged_kernel(amp, supersampling)
def test_7():
    site = Site(isotope="23Na")
    sys = SpinSystem(sites=[site], abundance=50)
    sim = Simulator()
    sim.spin_systems = [sys, sys]
    sim.methods = [BlochDecayCTSpectrum(channels=["23Na"])]
    sim.methods[0].experiment = cp.as_csdm(np.zeros(1024))

    processor = sp.SignalProcessor(operations=[
        sp.IFFT(dim_index=0),
        sp.apodization.Gaussian(FWHM="0.2 kHz", dim_index=0),
        sp.FFT(dim_index=0),
    ])

    def test_array():
        sim.run()
        dataset = processor.apply_operations(sim.methods[0].simulation)

        data_sum = 0
        for dv in dataset.y:
            data_sum += dv.components[0]

        params = sf.make_LMFIT_params(sim, processor)
        a = sf.LMFIT_min_function(params, sim, processor)
        np.testing.assert_almost_equal(-a, data_sum, decimal=8)

        dat = sf.add_csdm_dvs(dataset.real)
        fits = sf.bestfit(sim, processor)
        assert sf.add_csdm_dvs(fits[0]) == dat

        res = sf.residuals(sim, processor)
        assert res[0] == -dat

    test_array()

    sim.config.decompose_spectrum = "spin_system"
    test_array()
Esempio n. 10
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())
Esempio n. 11
0
        {"count": 2048, "spectral_width": "25 kHz", "reference_offset": "0 Hz",}
    ],
}
method2 = {
    "channels": ["1H"],
    "magnetic_flux_density": "9.4 T",
    "rotor_frequency": "1 kHz",
    "rotor_angle": "54.735 deg",
    "spectral_dimensions": [
        {"count": 2048, "spectral_width": "25 kHz", "reference_offset": "0 Hz",}
    ],
}


sim = Simulator()
sim.spin_systems = [SpinSystem.parse_dict_with_units(item) for item in spin_systems]
sim.methods = [
    BlochDecaySpectrum.parse_dict_with_units(method1),
    BlochDecaySpectrum.parse_dict_with_units(method2),
]

sim.run()

freq1, amp1 = sim.methods[0].simulation.to_list()
freq2, amp2 = sim.methods[1].simulation.to_list()

fig, ax = plt.subplots(1, 2, figsize=(6, 3))
ax[0].plot(freq1, amp1, linewidth=1.0, color="k")
ax[0].set_xlabel(f"frequency ratio / {freq2.unit}")
ax[0].grid(color="gray", linestyle="--", linewidth=0.5, alpha=0.5)
ax[0].set_title("Static")
                }])
            ],
        ),
    ],
)

# A graphical representation of the method object.
plt.figure(figsize=(5, 3.5))
coaster.plot()
plt.show()

# %%
# Create the Simulator object, add the method and spin system objects, and
# run the simulation.
sim = Simulator()
sim.spin_systems = [spin_system]  # add the spin systems
sim.methods = [coaster]  # add the method.

# configure the simulator object. For non-coincidental tensors, set the value of the
# `integration_volume` attribute to `hemisphere`.
sim.config.integration_volume = "hemisphere"
sim.run()

# %%
# The plot of the simulation.
data = sim.methods[0].simulation

plt.figure(figsize=(4.25, 3.0))
ax = plt.subplot(projection="csdm")
cb = ax.imshow(data.real / data.real.max(), aspect="auto", cmap="gist_ncar_r")
plt.colorbar(cb)
# %%
# As mentioned before, a method object is decoupled from the spin system object. Notice,
# when we get the transition pathways from this method for a single-site spin system, we
# get a single transition pathway.
print(hahn_echo.get_transition_pathways(spin_system_1))

# %%
# In the case of a homonuclear two-site spin 1/2 spin system, the same method returns
# four transition pathways.
print(hahn_echo.get_transition_pathways(spin_system_2))

# %%
# Create the Simulator object, add the method and spin system objects, and run the
# simulation.
sim = Simulator()
sim.spin_systems = [spin_system_1, spin_system_2]  # add the spin systems
sim.methods = [hahn_echo]  # add the method
sim.config.decompose_spectrum = "spin_system"

sim.run()

# %%
# The simulation from each spin system is stored as a dependent variable within the
# CSDM object. Use the `split` function to split the list of the dependent variables
# into a list of CSDM objects.
simulation_results = sim.methods[0].simulation.split()

# The plot of the two simulations.
fig, ax = plt.subplots(1,
                       2,
                       figsize=(8.0, 3.0),
Esempio n. 14
0
            reference_offset=-4174.76184,  # in Hz
            label="Isotropic dimension",
        ),
        dict(
            count=512,
            spectral_width=2e4,  # in Hz
            reference_offset=2e3,  # in Hz
            label="MAS dimension",
        ),
    ],
)

# %%
# Create the simulator object, add the spin systems and method, and run the simulation.
sim = Simulator()
sim.spin_systems = spin_systems  # add the spin systems
sim.methods = [mqvas]  # add the method
sim.config.number_of_sidebands = 1
sim.run()

data = sim.methods[0].simulation.real

# %%
# The plot of the corresponding spectrum.
plt.figure(figsize=(4.25, 3.0))
ax = plt.subplot(projection="csdm")
cb = ax.imshow(data / data.max(), cmap="gist_ncar_r", aspect="auto")
plt.colorbar(cb)
ax.set_ylim(-20, -50)
ax.set_xlim(80, 20)
plt.tight_layout()
Esempio n. 15
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")
Esempio n. 16
0
def test_simulator_1():
    sim = Simulator()
    sim.spin_systems = [SpinSystem(sites=[Site(isotope="1H"), Site(isotope="23Na")])]
    sim.methods = [BlochDecaySpectrum(channels=["1H"])]
    sim.name = "test"
    sim.label = "test0"
    sim.description = "testing-testing 1.2.3"

    red_dict = sim.json(units=False)
    _ = [item.pop("description") for item in red_dict["methods"]]

    assert red_dict == {
        "name": "test",
        "label": "test0",
        "description": "testing-testing 1.2.3",
        "spin_systems": [
            {
                "sites": [
                    {"isotope": "1H", "isotropic_chemical_shift": 0.0},
                    {"isotope": "23Na", "isotropic_chemical_shift": 0.0},
                ],
            }
        ],
        "methods": [
            {
                "channels": ["1H"],
                "name": "BlochDecaySpectrum",
                "magnetic_flux_density": 9.4,
                "rotor_angle": 0.9553166181245,
                "rotor_frequency": 0.0,
                "spectral_dimensions": [
                    {
                        "count": 1024,
                        "events": [{"transition_queries": [{"ch1": {"P": [-1]}}]}],
                        "spectral_width": 25000.0,
                    }
                ],
            }
        ],
        "config": {
            "decompose_spectrum": "none",
            "integration_density": 70,
            "integration_volume": "octant",
            "number_of_sidebands": 64,
        },
    }

    # save
    sim.save("test_sim_save.temp")
    sim_load = Simulator.load("test_sim_save.temp")

    assert sim_load.spin_systems == sim.spin_systems
    assert sim_load.methods == sim.methods
    assert sim_load.name == sim.name
    assert sim_load.description == sim.description
    assert sim_load == sim

    # without units
    sim.save("test_sim_save_no_unit.temp", with_units=False)
    sim_load = Simulator.load("test_sim_save_no_unit.temp", parse_units=False)
    assert sim_load == sim

    os.remove("test_sim_save.temp")
    os.remove("test_sim_save_no_unit.temp")
Esempio n. 17
0
methods = [
    BlochDecaySpectrum(
        channels=["13C"],
        magnetic_flux_density=9.4,  # in T
        rotor_frequency=vr,  # in Hz
        spectral_dimensions=[dict(count=2048, spectral_width=8.0e4)],
    )
    for vr in spin_rates
]

# %%
# **Simulator**
#
# Create the Simulator object and add the method and the spin system objects.
sim = Simulator()
sim.spin_systems = spin_systems  # add the three spin systems
sim.methods = methods  # add the four methods
sim.config.integration_volume = "hemisphere"  # set averaging to hemisphere
# decompose spectrum to individual spin systems.
sim.config.decompose_spectrum = "spin_system"

# %%
# The run command will simulate twelve spectra corresponding to the three spin systems
# evaluated at four different methods (spinning speeds).
sim.run()

# %%
# **Post-Simulation Processing**
#
# Add post-simulation signal processing.
processor = sp.SignalProcessor(
Esempio n. 18
0
def test_DAS():
    B0 = 11.7
    das = Method2D(
        channels=["17O"],
        magnetic_flux_density=B0,  # in T
        spectral_dimensions=[
            {
                "count":
                912,
                "spectral_width":
                5e3,  # in Hz
                "reference_offset":
                0,  # in Hz
                "label":
                "DAS isotropic dimension",
                "events": [
                    {
                        "fraction": 0.5,
                        "rotor_angle": 37.38 * 3.14159 / 180
                    },
                    {
                        "fraction": 0.5,
                        "rotor_angle": 79.19 * 3.14159 / 180
                    },
                ],
            },
            # The last spectral dimension block is the direct-dimension
            {
                "count": 2048,
                "spectral_width": 2e4,  # in Hz
                "reference_offset": 0,  # in Hz
                "label": "MAS dimension",
                "events": [{
                    "rotor_angle": 54.735 * 3.14159 / 180
                }],
            },
        ],
    )

    sim = Simulator()
    sim.spin_systems = spin_systems  # add spin systems
    sim.methods = [das]  # add the method.
    sim.config.decompose_spectrum = "spin_system"
    sim.run(pack_as_csdm=False)

    data_das = sim.methods[0].simulation
    data_das_coords_ppm = das.spectral_dimensions[0].coordinates_ppm()

    # Bloch decay central transition method
    bloch = BlochDecayCentralTransitionSpectrum(
        channels=["17O"],
        magnetic_flux_density=B0,  # in T
        rotor_frequency=1e9,  # in Hz
        rotor_angle=54.735 * 3.14159 / 180,
        spectral_dimensions=[
            {
                "count": 2048,
                "spectral_width": 2e4,  # in Hz
                "reference_offset": 0,  # in Hz
                "label": "MAS dimension",
            },
        ],
    )

    sim = Simulator()
    sim.spin_systems = spin_systems
    sim.methods = [bloch]
    sim.config.decompose_spectrum = "spin_system"
    sim.run(pack_as_csdm=False)

    data_bloch = sim.methods[0].simulation

    larmor_freq = das.channels[0].gyromagnetic_ratio * B0 * 1e6
    spin = das.channels[0].spin
    for i, sys in enumerate(spin_systems):
        for site in sys.sites:
            Cq = site.quadrupolar.Cq
            eta = site.quadrupolar.eta
            iso = site.isotropic_chemical_shift
            factor1 = -(3 / 40) * (Cq / larmor_freq)**2
            factor2 = (spin * (spin + 1) - 3 / 4) / (spin**2 *
                                                     (2 * spin - 1)**2)
            factor3 = 1 + (eta**2) / 3
            iso_obs = factor1 * factor2 * factor3 * 1e6 + iso

            # get the index where there is a signal
            id1 = data_das[i] / data_das[i].max()
            index = np.where(id1 == id1.max())[0]
            iso_spectrum = data_das_coords_ppm[
                index[0]]  # x[1].coords[index[0]]

            # test for the position of isotropic peaks.
            np.testing.assert_almost_equal(iso_obs, iso_spectrum, decimal=1)

            # test for the spectrum across the isotropic peaks.
            data_bloch_i = data_bloch[i] / data_bloch[i].max()
            assert np.allclose(id1[index[0]], data_bloch_i)
Esempio n. 19
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())
Esempio n. 20
0
def setup_simulation(site, affine_matrix, class_id=0):

    isotope = site.isotope.symbol
    spin_system = [SpinSystem(sites=[site])]

    method_C = method_class[class_id]

    method = method_C(
        channels=[isotope],
        magnetic_flux_density=7,  # in T
        rotor_angle=54.735 * np.pi / 180,
        spectral_dimensions=[
            {
                "count": 512,
                "spectral_width": 4e4,  # in Hz
                "reference_offset": -3e3,  # in Hz
            },
            {
                "count": 1024,
                "spectral_width": 1e4,  # in Hz
                "reference_offset": -4e3,  # in Hz
            },
        ],
        affine_matrix=affine_matrix,
    )

    method_1 = Method(
        channels=[isotope],
        magnetic_flux_density=7,  # in T
        rotor_angle=54.735 * np.pi / 180,
        rotor_frequency=np.inf,
        spectral_dimensions=[
            {
                "count": 1024,
                "spectral_width": 1e4,  # in Hz
                "reference_offset": -4e3,  # in Hz
                "events": [
                    {
                        "fraction": 27 / 17,
                        "freq_contrib": ["Quad2_0"],
                        "transition_queries": [{"ch1": {"P": [-1], "D": [0]}}],
                    },
                    {
                        "fraction": 1,
                        "freq_contrib": ["Quad2_4"],
                        "transition_queries": [{"ch1": {"P": [-1], "D": [0]}}],
                    },
                ],
            }
        ],
    )

    sim = Simulator()
    sim.spin_systems = spin_system  # add the spin-system
    sim.methods = [method, method_1]  # add the method

    # run the simulation
    sim.config.number_of_sidebands = 1
    sim.run()

    csdm_data1 = sim.methods[0].simulation.real.sum(axis=1)
    csdm_data2 = sim.methods[1].simulation.real
    csdm_data1 /= csdm_data1.max()
    csdm_data2 /= csdm_data2.max()

    np.testing.assert_almost_equal(
        csdm_data1.y[0].components, csdm_data2.y[0].components, decimal=3
    )
Esempio n. 21
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)
Esempio n. 22
0
def generate_simulator(spin_systems, method):
    sim = Simulator()
    sim.spin_systems = spin_systems
    sim.methods = [method]
    return sim
Esempio n. 23
0
plt.show()

# %%
# Simulate the spectrum
# '''''''''''''''''''''
#
# Create the spin systems from the above :math:`\zeta` and :math:`\eta` parameters.
systems = single_site_system_generator(
    isotope="13C", shielding_symmetric={"zeta": z_dist, "eta": e_dist}, abundance=amp
)
print(len(systems))

# %%
# Create a simulator object and add the above system.
sim = Simulator()
sim.spin_systems = systems  # add the systems
sim.methods = [BlochDecaySpectrum(channels=["13C"])]  # add the method
sim.run()

# %%
# The following is the static spectrum arising from a Czjzek distribution of the
# second-rank traceless shielding tensors.
plt.figure(figsize=(4.25, 3.0))
ax = plt.subplot(projection="csdm")
ax.plot(sim.methods[0].simulation.real, color="black", linewidth=1)
plt.tight_layout()
plt.show()

# %%
# Quadrupolar tensor
# ------------------
Esempio n. 24
0
    rotor_frequency=780,  # in Hz
    spectral_dimensions=[
        {
            "count": 2048,
            "spectral_width": 25000,  # in Hz
            "reference_offset": -5000,  # in Hz
        }
    ],
    experiment=synthetic_experiment,  # add the measurement to the method.
)

# %%
# **Step 3:** Create the Simulator object, add the method and spin system objects, and
# run the simulation.
sim = Simulator()
sim.spin_systems = [spin_system]
sim.methods = [method]
sim.run()

# %%
# **Step 4:** Create a SignalProcessor class and apply post simulation processing.
processor = sp.SignalProcessor(
    operations=[
        sp.IFFT(),  # inverse FFT to convert frequency based spectrum to time domain.
        apo.Exponential(FWHM="200 Hz"),  # apodization of time domain signal.
        sp.FFT(),  # forward FFT to convert time domain signal to frequency spectrum.
        sp.Scale(factor=1.5),  # scale the frequency spectrum.
    ]
)
processed_data = processor.apply_operations(data=sim.methods[0].simulation).real