예제 #1
0
def test_methods():
    das = Method(
        name="DAS",
        channels=["87Rb"],
        magnetic_flux_density=4.2,  # in T
        rotor_angle=54.735 * 3.14159 / 180,  # in rads
        rotor_frequency=1000000000000,
        spectral_dimensions=[
            {
                "count":
                256,
                "spectral_width":
                2e4,  # in Hz
                "reference_offset":
                -5e3,  # in Hz
                "label":
                "70.12 dimension",
                "events": [
                    {
                        "fraction": 0.5,
                        "rotor_angle": 70.12 * 3.14159 / 180,  # in rads
                        "transition_queries": [{
                            "ch1": {
                                "P": [-1],
                                "D": [0]
                            }
                        }],
                    },
                    {
                        "fraction": 0.5,
                        "rotor_angle": 30.12 * 3.14159 / 180,  # in rads
                        "transition_queries": [{
                            "ch1": {
                                "P": [-1],
                                "D": [0]
                            }
                        }],
                    },
                ],
            },
            # The last spectral dimension block is the direct-dimension
            {
                "count":
                256,
                "spectral_width":
                3e4,  # in Hz
                "reference_offset":
                -7e3,  # in Hz
                "label":
                "MAS dimension",
                "events": [{
                    "transition_queries": [{
                        "ch1": {
                            "P": [-1],
                            "D": [0]
                        }
                    }]
                }],
            },
        ],
    )

    assert das.affine_matrix is None
    assert das.json() == TESTDATA["DAS"]
    assert Method.parse_dict_with_units(das.json()) == das
예제 #2
0
def test_2D_method():
    # Method2D replaced with generic Method object
    error = "The first element of the affine matrix cannot be zero."
    with pytest.raises(ValueError, match=f".*{error}.*"):
        Method(spectral_dimensions=[{}, {}], affine_matrix=[0, 1, 2, 3])
예제 #3
0
def test_BlochDecaySpectrum():
    # test-1
    m1 = BlochDecaySpectrum(channels=["1H"])

    dimension_dictionary_ = {
        "count": 1024,
        "spectral_width": "25000.0 Hz",
        "events": [{
            "transition_queries": [{
                "ch1": {
                    "P": [-1]
                }
            }]
        }],
    }

    should_be = {
        "name": "BlochDecaySpectrum",
        "channels": ["1H"],
        "magnetic_flux_density": "9.4 T",
        "rotor_frequency": "0.0 Hz",
        "rotor_angle": "0.9553166181245 rad",
        "spectral_dimensions": [dimension_dictionary_],
    }
    dict_ = m1.json()
    assert Method.parse_dict_with_units(dict_) == m1

    dict_.pop("description")
    assert dict_ == should_be

    # test-2
    m2_dict = {
        "channels": ["29Si"],
        "magnetic_flux_density": "11.7 T",
        "rotor_angle": "90 deg",
        "spectral_dimensions": [{}],
    }
    m2 = BlochDecaySpectrum.parse_dict_with_units(m2_dict)

    angle = 90 * np.pi / 180
    dimension_dictionary_ = {
        "count": 1024,
        "spectral_width": "25000.0 Hz",
        "events": [{
            "transition_queries": [{
                "ch1": {
                    "P": [-1]
                }
            }]
        }],
    }

    should_be = {
        "name": "BlochDecaySpectrum",
        "channels": ["29Si"],
        "magnetic_flux_density": "11.7 T",
        "rotor_frequency": "0.0 Hz",
        "rotor_angle": f"{angle} rad",
        "spectral_dimensions": [dimension_dictionary_],
    }

    dict_ = m2.json()
    assert Method.parse_dict_with_units(dict_) == m2

    dict_.pop("description")
    assert dict_ == should_be
예제 #4
0
# -*- coding: utf-8 -*-
import numpy as np
from mrsimulator import SpinSystem
from mrsimulator.method import Method
from mrsimulator.methods import Method1D
from mrsimulator.methods import Method2D
from mrsimulator.transition import TransitionPathway

__author__ = "Deepansh J. Srivastava"
__email__ = "*****@*****.**"

method1 = Method(
    channels=["13C"],
    spectral_dimensions=[{"events": [{"transition_query": [{"ch1": {"P": [-1]}}]}]}],
)

method2 = Method(
    channels=["13C"],
    spectral_dimensions=[{"events": [{"transition_query": [{"ch1": {"P": [-2]}}]}]}],
)


def check_transition_set(got, expected):
    assert len(got) == len(expected), "Inconsistent transition pathway count"
    for item in got:
        assert item in expected, f"Transition pathways not found: {item}"


def test_00():
    system = SpinSystem(sites=[{"isotope": "13C"}])
    tr = method1.get_transition_pathways(system)
예제 #5
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
    sq_tq = {"transition_queries": [{"ch1": {"P": [-1]}}]}
    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 = Method(
            channels=[ist],
            magnetic_flux_density=B0,  # in T
            rotor_frequency=1e12,
            spectral_dimensions=[
                {
                    "count": 64,
                    "spectral_width": 8e4,  # in Hz
                    "label": "Anisotropic dimension",
                    "events": [{
                        "rotor_angle": 90 * 3.14159 / 180,
                        **sq_tq
                    }],
                },
                # 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",
                    "events": [sq_tq],
                },
            ],
            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=4)
예제 #6
0
def test_method_2D():

    error = "The first element of the affine matrix cannot be zero."
    with pytest.raises(ValueError, match=f".*{error}.*"):
        Method2D(spectral_dimensions=[{}, {}], affine_matrix=[0, 1, 2, 3])

    # parse dict with units test
    dict_1d = {
        "channels": ["87Rb"],
        "magnetic_flux_density":
        "7 T",  # in T
        "rotor_angle":
        "54.735 deg",
        "spectral_dimensions": [
            {
                "count":
                1024,
                "spectral_width":
                "10 kHz",  # in Hz
                "events": [
                    {
                        "fraction": 27 / 17,
                        "freq_contrib": ["Quad2_0"]
                    },
                    {
                        "fraction": 1,
                        "freq_contrib": ["Quad2_4"]
                    },
                ],
            },
            {
                "count":
                1024,
                "spectral_width":
                "10 kHz",  # in Hz
                "events": [
                    {
                        "fraction": 27 / 17,
                        "freq_contrib": ["Quad2_0"]
                    },
                    {
                        "fraction": 1,
                        "freq_contrib": ["Quad2_4"]
                    },
                ],
            },
        ],
    }
    method1a = Method2D.parse_dict_with_units(dict_1d)
    assert Method.parse_dict_with_units(method1a.json()) == method1a

    method1b = Method2D(
        channels=["87Rb"],
        magnetic_flux_density=7,  # in T
        rotor_angle=54.735 * np.pi / 180,
        spectral_dimensions=[
            {
                "count":
                1024,
                "spectral_width":
                1e4,  # in Hz
                "events": [
                    {
                        "fraction": 27 / 17,
                        "freq_contrib": ["Quad2_0"]
                    },
                    {
                        "fraction": 1,
                        "freq_contrib": ["Quad2_4"]
                    },
                ],
            },
            {
                "count":
                1024,
                "spectral_width":
                1e4,  # in Hz
                "events": [
                    {
                        "fraction": 27 / 17,
                        "freq_contrib": ["Quad2_0"]
                    },
                    {
                        "fraction": 1,
                        "freq_contrib": ["Quad2_4"]
                    },
                ],
            },
        ],
    )

    assert method1a == method1b
예제 #7
0
def test_method_1D():
    error = "Expecting a 1x1 affine matrix."
    with pytest.raises(ValueError, match=f".*{error}.*"):
        Method1D(spectral_dimensions=[{}], affine_matrix=[1, 2, 3, 4])

    error = r"The method allows 1 spectral dimension\(s\), 2 given."
    with pytest.raises(ValueError, match=f".*{error}.*"):
        Method1D(spectral_dimensions=[{}, {}])

    # parse dict with units test
    dict_1d = {
        "channels": ["87Rb"],
        "magnetic_flux_density":
        "7 T",  # in T
        "rotor_angle":
        "54.735 deg",
        "rotor_frequency":
        "1e9 Hz",
        "spectral_dimensions": [{
            "count":
            1024,
            "spectral_width":
            "10 kHz",  # in Hz
            "reference_offset":
            "-4 kHz",  # in Hz
            "events": [
                {
                    "fraction": 27 / 17,
                    "freq_contrib": ["Quad2_0"]
                },
                {
                    "fraction": 1,
                    "freq_contrib": ["Quad2_4"]
                },
            ],
        }],
    }
    method1a = Method1D.parse_dict_with_units(dict_1d)
    assert Method.parse_dict_with_units(method1a.json()) == method1a

    method1b = Method1D(
        channels=["87Rb"],
        magnetic_flux_density=7,  # in T
        rotor_angle=54.735 * np.pi / 180,
        rotor_frequency=1e9,
        spectral_dimensions=[{
            "count":
            1024,
            "spectral_width":
            1e4,  # in Hz
            "reference_offset":
            -4e3,  # in Hz
            "events": [
                {
                    "fraction": 27 / 17,
                    "freq_contrib": ["Quad2_0"]
                },
                {
                    "fraction": 1,
                    "freq_contrib": ["Quad2_4"]
                },
            ],
        }],
    )

    assert method1a == method1b
예제 #8
0
    def parse_dict_with_units(cls, py_dict: dict):
        """Parse the physical quantity from a dictionary representation of the Simulator
        object, where the physical quantity is expressed as a string with a number and
        a unit.

        Args:
            dict py_dict: A required python dict object.

        Returns:
            A :ref:`simulator_api` object.

        Example
        -------

        >>> sim_py_dict = {
        ...     'config': {
        ...         'decompose_spectrum': 'none',
        ...         'integration_density': 70,
        ...         'integration_volume': 'octant',
        ...         'number_of_sidebands': 64
        ...     },
        ...     'spin_systems': [
        ...         {
        ...             'abundance': '100 %',
        ...             'sites': [{
        ...                 'isotope': '13C',
        ...                 'isotropic_chemical_shift': '20.0 ppm',
        ...                 'shielding_symmetric': {'eta': 0.5, 'zeta': '10.0 ppm'}
        ...             }]
        ...         },
        ...         {
        ...             'abundance': '100 %',
        ...             'sites': [{
        ...                 'isotope': '1H',
        ...                     'isotropic_chemical_shift': '-4.0 ppm',
        ...                     'shielding_symmetric': {'eta': 0.1, 'zeta': '2.1 ppm'}
        ...             }]
        ...         },
        ...         {
        ...             'abundance': '100 %',
        ...             'sites': [{
        ...                 'isotope': '27Al',
        ...                 'isotropic_chemical_shift': '120.0 ppm',
        ...                 'shielding_symmetric': {'eta': 0.1, 'zeta': '2.1 ppm'}
        ...             }]
        ...         }
        ...     ]
        ... }
        >>> sim = Simulator.parse_dict_with_units(sim_py_dict)
        >>> len(sim.spin_systems)
        3
        """
        py_copy_dict = deepcopy(py_dict)

        if "spin_systems" in py_copy_dict:
            spin_sys = py_copy_dict["spin_systems"]
            spin_sys = [SpinSystem.parse_dict_with_units(obj) for obj in spin_sys]
            py_copy_dict["spin_systems"] = spin_sys

        if "methods" in py_copy_dict:
            methods = py_copy_dict["methods"]
            methods = [Method.parse_dict_with_units(obj) for obj in methods]
            py_copy_dict["methods"] = methods

        return Simulator(**py_copy_dict)
예제 #9
0
sas = Method(
    channels=["87Rb"],
    magnetic_flux_density=4.2,  # in T
    rotor_frequency=np.inf,
    spectral_dimensions=[
        SpectralDimension(
            count=256,
            spectral_width=1.5e4,  # in Hz
            reference_offset=-5e3,  # in Hz
            label="70.12 dimension",
            events=[
                SpectralEvent(
                    rotor_angle=70.12 * np.pi / 180,  # in radians
                    transition_queries=[{
                        "ch1": {
                            "P": [-1],
                            "D": [0]
                        }
                    }],
                )
            ],
        ),
        SpectralDimension(
            count=512,
            spectral_width=15e3,  # in Hz
            reference_offset=-7e3,  # in Hz
            label="MAS dimension",
            events=[
                SpectralEvent(
                    rotor_angle=54.74 * np.pi / 180,  # in radians
                    transition_queries=[{
                        "ch1": {
                            "P": [-1],
                            "D": [0]
                        }
                    }],
                )
            ],
        ),
    ],
)
예제 #10
0
def test_summary():
    all_defined_no_constant_spec_dims = [
        {
            "events": [
                {
                    "label": "Mix0",
                    "mixing_query": {
                        "ch1": {
                            "tip_angle": np.pi / 4,
                            "phase": np.pi / 2
                        }
                    },
                },
                {
                    "label": "Dur0",
                    "duration": 1,
                    "magnetic_flux_density": 1,
                    "rotor_frequency": 0,  # in kHz
                    "rotor_angle": 0.1,
                    "transition_query": [{
                        "ch1": {
                            "P": [0],
                            "D": [0]
                        }
                    }],
                },
                {
                    "label": "Spec0",
                    "fraction": 1,
                    "magnetic_flux_density": 2,
                    "rotor_frequency": 20000,
                    "rotor_angle": 0.2,
                    "transition_query": [{
                        "ch1": {
                            "P": [1],
                            "D": [-2]
                        }
                    }],
                },
            ]
        },
        {
            "events": [
                {
                    "label": "Mix1",
                    "mixing_query": {
                        "ch1": {
                            "tip_angle": np.pi / 2,
                            "phase": np.pi
                        }
                    },
                },
                {
                    "label": "Dur1",
                    "duration": 2,
                    "magnetic_flux_density": 3,
                    "rotor_frequency": 0,
                    "rotor_angle": 0.3,
                    "transition_query": [{
                        "ch1": {
                            "P": [3],
                            "D": [-4]
                        }
                    }],
                },
                {
                    "label": "Spec1",
                    "fraction": 1,
                    "magnetic_flux_density": 4,
                    "rotor_frequency": 0,
                    "rotor_angle": 0.4,
                    "transition_query": [{
                        "ch1": {
                            "P": [4],
                            "D": [-6]
                        }
                    }],
                },
            ]
        },
    ]

    const_mfd_rotor_ang_spec_dims = [
        {
            "events": [
                {
                    "label": "Mix0",
                    "mixing_query": {
                        "ch1": {
                            "tip_angle": np.pi / 2,
                            "phase": np.pi
                        }
                    },
                },
                {
                    "label": "Dur0",
                    "duration": 1,
                    "rotor_frequency": 0,
                    "rotor_angle": 0.5,
                    "transition_query": [{
                        "ch1": {
                            "P": [0],
                            "D": [0]
                        }
                    }],
                },
                {
                    "label": "Spec0",
                    "fraction": 1,
                    "rotor_frequency": 20000,
                    "rotor_angle": 0.5,
                    "transition_query": [{
                        "ch1": {
                            "P": [1],
                            "D": [0]
                        }
                    }],
                },
            ]
        },
        {
            "events": [
                {
                    "label": "Mix1",
                    "mixing_query": {
                        "ch1": {
                            "tip_angle": np.pi / 2,
                            "phase": np.pi
                        }
                    },
                },
                {
                    "label": "Dur1",
                    "duration": 2,
                    "rotor_frequency": 0,
                    "rotor_angle": 0.5,
                    "transition_query": [{
                        "ch1": {
                            "P": [3],
                            "D": [0]
                        }
                    }],
                },
                {
                    "label": "Spec1",
                    "fraction": 1,
                    "rotor_frequency": 0,
                    "rotor_angle": 0.5,
                    "transition_query": [{
                        "ch1": {
                            "P": [4],
                            "D": [0]
                        }
                    }],
                },
            ]
        },
    ]

    method1 = Method(
        name="test-method-1",
        channels=["1H", "13C"],
        spectral_dimensions=all_defined_no_constant_spec_dims,
    )

    # Constant 'magnetic_flux_density' and 'rotor_frequency'
    method2 = Method(
        name="test-method-2",
        channels=["1H", "13C"],
        spectral_dimensions=const_mfd_rotor_ang_spec_dims,
    )

    assert method1.name == "test-method-1"
    assert len(method1.spectral_dimensions) == 2

    basic_summary_tests(method1)

    assert method2.name == "test-method-2"
    assert len(method2.spectral_dimensions) == 2

    args_summary_tests(method2)

    assert isinstance(method2.plot(), Figure)
예제 #11
0
def test_SSB_affine():
    mth = SSB2D(channels=["13C"], rotor_frequency=1200)
    np.allclose(mth.affine_matrix, [1, -1, 0, 0])
    assert Method.parse_dict_with_units(mth.json()) == mth
예제 #12
0
shifting_d = Method(
    name="Shifting-d",
    channels=["2H"],
    magnetic_flux_density=9.395,  # in T
    rotor_frequency=0,  # in Hz
    rotor_angle=0,  # 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"],
                )
            ],
        ),
    ],
)