Ejemplo n.º 1
0
def test_5Q_VAS_general():
    """5Q-VAS method test"""
    mth = FiveQ_VAS(
        channels=["17O"], spectral_dimensions=[SpectralDimension(), SpectralDimension()]
    )

    assert mth.name == "FiveQ_VAS"
    assert mth.description == "Simulate a 5Q variable-angle spinning spectrum."
    assert mth.spectral_dimensions[0].events[0].transition_queries == [
        TransitionQuery(ch1={"P": [-5], "D": [0]})
    ]
    assert mth.spectral_dimensions[1].events[0].transition_queries == [
        TransitionQuery(ch1={"P": [-1], "D": [0]})
    ]
    assert FiveQ_VAS.parse_dict_with_units(mth.json()) == mth

    assert np.allclose(
        mth.affine_matrix, [0.3243243243243243, 0.6756756756756757, 0.0, 1.0]
    )

    serialize = mth.json()
    _ = serialize.pop("affine_matrix")

    assert serialize == {
        "channels": ["17O"],
        "description": "Simulate a 5Q variable-angle spinning spectrum.",
        "name": "FiveQ_VAS",
        **sample_test_output(-5),
    }
Ejemplo n.º 2
0
    def check_event_objects_for_compatibility(cls, default_dim, obj_dim,
                                              method_dict):
        """Checks Events for compatibility and sets global method attributes

        Args:
            default_dim (dict): Dict representation of SpectralDimension in base method
            obj_dim (SpectralDimension): User-passed SpectralDimension object to check
            method_dict (dict): Dict representation of passed method
        """
        required = ["magnetic_flux_density", "rotor_frequency", "rotor_angle"]
        check_dim = SpectralDimension(**default_dim)
        for i, (ev_check,
                ev_obj) in enumerate(zip(check_dim.events, obj_dim.events)):

            default_obj = SpectralDimension(events=[{}]).events[0]
            obj_keys = ev_obj.dict(exclude={"property_units"}).keys()
            check_keys = default_dim["events"][i].keys()
            for k in obj_keys:  # iterate over event attributes
                fail = False
                if k in check_keys:
                    obj_attr, default_attr, check_attr = (getattr(
                        _, k) for _ in [ev_obj, default_obj, ev_check])
                    fail_1 = obj_attr != default_attr  # not default (user passed value)
                    fail_2 = obj_attr != check_attr  # passed attr does not match base
                    fail_3 = default_attr is not None
                    fail = fail_1 and fail_2 and fail_3
                    setattr(ev_obj, k, check_attr)
                elif k in required and k in method_dict:
                    # True if passed attr does not match global attr defined by method
                    fail = getattr(ev_obj, k) != method_dict[k]
                    # Set event attr to global method attr
                    setattr(ev_obj, k, method_dict[k])
                if fail:
                    raise ImmutableEventError(cls.__name__)
Ejemplo n.º 3
0
def assertion(csdm, res, test_ref=""):
    assert get_spectral_dimensions(csdm)[0] == res, f"failed ref {test_ref}"

    csdm_coordinates = csdm.x[0].coordinates.to("Hz").value
    if csdm.x[0].increment < 0:
        csdm_coordinates = csdm_coordinates[::-1]
    spectral_dimension = SpectralDimension(**res)
    mrsim_coordinates = spectral_dimension.coordinates_Hz()
    assert np.allclose(csdm_coordinates,
                       mrsim_coordinates), f"failed ref {test_ref}"
Ejemplo n.º 4
0
def test_BaseNamedMethod1D_spectral_dimension_count():
    e = "Method requires exactly 1 spectral dimensions, given 2."
    # test for SpectralDimension passed as dictionary
    with pytest.raises(ValueError, match=f".*{e}.*"):
        BaseNamedMethod1D(spectral_dimensions=[{}, {}])
    # test for SpectralDimension passed as object
    with pytest.raises(ValueError, match=f".*{e}.*"):
        BaseNamedMethod1D(spectral_dimensions=[
            SpectralDimension(),
            SpectralDimension(),
        ])
Ejemplo n.º 5
0
def csa_1D_projection():
    csa_only = Method(
        channels=["87Rb"],
        magnetic_flux_density=9.4,  # in T
        rotor_angle=70.12 * np.pi / 180,  # in rads
        rotor_frequency=np.inf,
        spectral_dimensions=[
            SpectralDimension(
                count=512,
                spectral_width=4e4,
                reference_offset=-8e3,
                events=[
                    SpectralEvent(
                        freq_contrib=[
                            "Quad2_0", "Shielding1_0", "Shielding1_2"
                        ],
                        transition_queries=[{
                            "ch1": {
                                "P": [3],
                                "D": [0]
                            }
                        }],
                    ),
                ],
            )
        ],
    )
    return process_spectrum(csa_only)
Ejemplo n.º 6
0
def test_BaseNamedMethod2D_spectral_dimension_count():
    e = "Method requires exactly 2 spectral dimensions, given 1."
    # test for SpectralDimension passed as dictionary
    with pytest.raises(ValueError, match=f".*{e}.*"):
        BaseNamedMethod2D(channels=["1H"], spectral_dimensions=[{}])
    # test for SpectralDimension passed as object
    with pytest.raises(ValueError, match=f".*{e}.*"):
        BaseNamedMethod2D(channels=["1H"],
                          spectral_dimensions=[SpectralDimension()])
Ejemplo n.º 7
0
def coaster_simulation():
    coaster = Method(
        name="COASTER",
        channels=["87Rb"],
        magnetic_flux_density=9.4,  # in T
        rotor_angle=70.12 * np.pi / 180,  # in rads
        rotor_frequency=np.inf,
        spectral_dimensions=[
            SpectralDimension(
                count=512,
                spectral_width=4e4,  # in Hz
                reference_offset=-8e3,  # in Hz
                label="$\\omega_1$ (CSA)",
                events=[
                    SpectralEvent(transition_queries=[{
                        "ch1": {
                            "P": [3],
                            "D": [0]
                        }
                    }]),
                    MixingEvent(query={"ch1": {
                        "angle": np.pi * 109.5 / 180
                    }}),
                ],
            ),
            SpectralDimension(
                count=512,
                spectral_width=8e3,  # in Hz
                reference_offset=-4e3,  # in Hz
                label="$\\omega_2$ (Q)",
                events=[
                    SpectralEvent(transition_queries=[{
                        "ch1": {
                            "P": [-1],
                            "D": [0]
                        }
                    }])
                ],
            ),
        ],
        affine_matrix=[[1, 0], [1 / 4, 3 / 4]],
    )
    return process_spectrum(coaster)
Ejemplo n.º 8
0
    def check_event_objects_for_compatibility(cls, py, obj, obj_dict):
        required = ["magnetic_flux_density", "rotor_frequency", "rotor_angle"]
        py_obj = SpectralDimension(**py)
        for i, (ev_py, ev_obj) in enumerate(zip(py_obj.events, obj.events)):

            default_obj = SpectralDimension(events=[{}]).events[0]
            obj_keys = ev_obj.dict(exclude={"property_units"}).keys()
            py_keys = py["events"][i].keys()
            for k in obj_keys:
                a = False
                if k in py_keys:
                    a1, a2, a3 = [getattr(_, k) for _ in [ev_obj, default_obj, ev_py]]
                    a = a1 != a2 and a1 != a3 and a2 is not None
                    setattr(ev_obj, k, a3)
                elif k in required and k in obj_dict:
                    a = getattr(ev_obj, k) != obj_dict[k]
                    setattr(ev_obj, k, obj_dict[k])
                if a:
                    raise ImmutableEventError(cls.__name__)
def contrib_method(contrib):
    return Method(
        channels=["1H"],
        magnetic_flux_density=9.4,  # in T
        spectral_dimensions=[
            SpectralDimension(
                count=512,
                spectral_width=2e4,
                events=[
                    SpectralEvent(freq_contrib=contrib,
                                  transition_queries=negative_sq_tq)
                ],
            )
        ],
    )
Ejemplo n.º 10
0
def test_empty_spec_dims():
    # Empty list
    empty_method = Method(channels=["1H"], spectral_dimensions=[])
    error = (
        r".*Method has empty spectral_dimensions. At least one SpectralDimension "
        r"is needed with at least one Event..*")
    with pytest.raises(AttributeError, match=error):
        empty_method.summary()

    # No events
    empty_method.spectral_dimensions = [SpectralDimension(events=[])]
    error = (r".*Method has no Events. At least one SpectralDimension "
             r"is needed with at least one Event..*")
    with pytest.raises(AttributeError, match=error):
        empty_method.summary()
Ejemplo n.º 11
0
def test_rotor_frequency():
    """Ensures only 1 non-zero finite spinning speed in method"""
    # Good method, should not throw error
    Method(
        channels=["1H"],
        spectral_dimensions=[
            SpectralDimension(events=[
                SpectralEvent(fraction=0.5, rotor_frequency=123),
                SpectralEvent(fraction=0.5, rotor_frequency=0),
            ]),
            SpectralDimension(events=[SpectralEvent(rotor_frequency=np.inf)]),
        ],
    )

    # Bad method, should throw error for multiple finite speeds
    for cls in [Method]:
        with pytest.raises(NotImplementedError):
            cls(
                channels=["1H"],
                spectral_dimensions=[
                    SpectralDimension(events=[
                        SpectralEvent(fraction=0.5, rotor_frequency=123),
                        SpectralEvent(fraction=0.5, rotor_frequency=456),
                    ])
                ],
            )

    with pytest.raises(NotImplementedError):
        Method(
            channels=["1H"],
            spectral_dimensions=[
                SpectralDimension(events=[
                    SpectralEvent(fraction=0.5, rotor_frequency=123),
                    SpectralEvent(fraction=0.5, rotor_frequency=np.inf),
                ]),
                SpectralDimension(events=[
                    SpectralEvent(fraction=0.5, rotor_frequency=0),
                    SpectralEvent(fraction=0.5, rotor_frequency=456),
                ]),
            ],
        )

    with pytest.raises(NotImplementedError):
        # Both events should take 10000 Hz rotor_frequency
        Method(
            channels=["27Al"],
            rotor_frequency=10000,
            spectral_dimensions=[
                SpectralDimension(events=[
                    SpectralEvent(fraction=0.5),
                    SpectralEvent(fraction=0.5)
                ])
            ],
        )
Ejemplo n.º 12
0
def quad_1D_projection():
    quad_only = Method(
        channels=["87Rb"],
        magnetic_flux_density=9.4,  # in T
        rotor_angle=70.12 * np.pi / 180,  # in rads
        rotor_frequency=np.inf,
        spectral_dimensions=[
            SpectralDimension(
                count=512,
                spectral_width=8e3,
                reference_offset=-4e3,
                events=[
                    SpectralEvent(
                        fraction=1 / 4,
                        freq_contrib=["Quad2_0"],
                        transition_queries=[{
                            "ch1": {
                                "P": [3],
                                "D": [0]
                            }
                        }],
                    ),
                    MixingEvent(query={
                        "ch1": {
                            "angle": np.pi * 109.5 / 180,
                            "phase": 0
                        }
                    }),
                    SpectralEvent(
                        fraction=3 / 4,
                        freq_contrib=["Quad2_0", "Quad2_2"],
                        transition_queries=[{
                            "ch1": {
                                "P": [-1],
                                "D": [0]
                            }
                        }],
                    ),
                ],
            )
        ],
    )
    return process_spectrum(quad_only)
def hahn_method():
    return Method(
        channels=["1H"],
        magnetic_flux_density=9.4,  # in T
        rotor_angle=0,  # in rads
        spectral_dimensions=[
            SpectralDimension(
                count=512,
                spectral_width=2e4,  # in Hz
                events=[
                    SpectralEvent(fraction=0.5,
                                  transition_queries=positive_sq_tq),
                    MixingEvent(query={"ch1": {
                        "angle": np.pi,
                        "phase": 0
                    }}),
                    SpectralEvent(fraction=0.5,
                                  transition_queries=negative_sq_tq),
                ],
            )
        ],
    )
Ejemplo n.º 14
0
    def check_when_arg_is_object(cls, method_dict):
        default_method = cls.update(**method_dict)
        default_sp = default_method["spectral_dimensions"]
        obj_sp = method_dict["spectral_dimensions"]

        for i, (dflt_dim, obj_dim) in enumerate(zip(default_sp, obj_sp)):
            if len(dflt_dim["events"]) != len(
                    obj_dim.events) and obj_dim.events != []:
                raise ImmutableEventError(cls.__name__)

            if obj_dim.events == []:
                obj_sp[i] = obj_dim.json(units=False)
                if "events" not in obj_sp[i]:
                    obj_sp[i]["events"] = dflt_dim["events"]
                obj_sp[i] = SpectralDimension(**obj_sp[i])

            cls.check_event_objects_for_compatibility(dflt_dim, obj_dim,
                                                      method_dict)

        for k, v in default_method.items():
            if k not in method_dict:
                method_dict[k] = v
Ejemplo n.º 15
0
def test_mixing_query_connect_map():
    MX1 = MixingEvent(mixing_query={"ch1": {"tip_angle": 0.12}})
    MX2 = MixingEvent(mixing_query={"ch2": {"tip_angle": 1.12}})
    spectral_dimmensions = [
        SpectralDimension(events=[
            {
                "fraction": 0.5
            },  # 0
            MX1,
            {
                "duration": 0.5
            },  # 1
            {
                "fraction": 0.5
            },  # 2
            MX2,
            {
                "duration": 0.5
            },  # 3
        ]),
        SpectralDimension(events=[
            MX1,
            MX2,
            {
                "duration": 0.5
            },  # 4
            MX2,
            {
                "duration": 0.5
            },  # 5
            {
                "fraction": 1
            },  # 2
        ]),
    ]
    res = mixing_query_connect_map(spectral_dimmensions)
    assert res == [
        {
            "mixing_query": MX1.mixing_query,
            "near_index": [0, 1]
        },
        {
            "mixing_query": MX2.mixing_query,
            "near_index": [2, 3]
        },
        {
            "mixing_query": MX1.mixing_query,
            "near_index": [3, 4]
        },
        {
            "mixing_query": MX2.mixing_query,
            "near_index": [3, 4]
        },
        {
            "mixing_query": MX2.mixing_query,
            "near_index": [4, 5]
        },
    ]

    error = "SpectralDimension requires at least one SpectralEvent"
    with pytest.raises(MissingSpectralEventError, match=f".*{error}.*"):
        SpectralDimension(
            events=[MX1, MX2, {
                "duration": 0.5
            }, MX2, {
                "duration": 0.5
            }])
Ejemplo n.º 16
0
def basic_method_tests(the_method):
    assert the_method != "r"
    assert the_method.name == "test-1-d"
    the_method.name = "test worked"
    assert the_method.name == "test worked"

    assert the_method.description == "Test-1"
    the_method.description = "test worked again"
    assert the_method.description == "test worked again"

    # spectral width test
    assert the_method.channels == [Isotope(symbol="29Si")]
    the_method.channels = ["1H", "17O"]
    assert the_method.channels == [Isotope(symbol="1H"), Isotope(symbol="17O")]

    with pytest.raises(ValidationError, match=".*value is not a valid list.*"):
        the_method.channels = "6Li"

    dimension = SpectralDimension.parse_dict_with_units(dimension_dictionary)
    assert the_method.spectral_dimensions[0] == dimension

    the_method2 = deepcopy(the_method)
    the_method2.affine_matrix = [1]
    assert the_method2 != the_method

    # json()

    evt = [{"fraction": 0.5, "transition_query": [{"ch1": {"P": [-1]}}]}] * 2
    serialize = {
        "name":
        "test worked",
        "description":
        "test worked again",
        "channels": ["1H", "17O"],
        "magnetic_flux_density":
        "9.6 T",
        "rotor_frequency":
        "1000.0 Hz",
        "rotor_angle":
        "0.9553059660790962 rad",
        "spectral_dimensions": [{
            "count": 1024,
            "spectral_width": "100.0 Hz",
            "events": evt,
        }],
    }
    assert the_method.json() == serialize

    # json(units=False)
    assert the_method.json(units=False) == {
        "name":
        "test worked",
        "description":
        "test worked again",
        "channels": ["1H", "17O"],
        "magnetic_flux_density":
        9.6,
        "rotor_frequency":
        1000.0,
        "rotor_angle":
        0.9553059660790962,
        "spectral_dimensions": [{
            "count": 1024,
            "spectral_width": 100.0,
            "events": evt,
        }],
    }
Ejemplo n.º 17
0
 channels=["17O"],
 magnetic_flux_density=11.744,  # in T
 spectral_dimensions=[
     SpectralDimension(
         **spectral_dims[0],
         events=[
             SpectralEvent(
                 fraction=0.5,
                 rotor_angle=37.38 * 3.14159 / 180,
                 transition_query=[{
                     "ch1": {
                         "P": [-1],
                         "D": [0]
                     }
                 }],
             ),
             SpectralEvent(
                 fraction=0.5,
                 rotor_angle=79.19 * 3.14159 / 180,
                 transition_query=[{
                     "ch1": {
                         "P": [-1],
                         "D": [0]
                     }
                 }],
             ),
         ],
     ),
     # The last spectral dimension block is the direct-dimension
     SpectralDimension(
         **spectral_dims[1],
Ejemplo n.º 18
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)
Ejemplo n.º 19
0
    )
    for beta in beta_orientation
]
# %%
# Next, we create methods to simulate the sideband manifolds for the above spin
# systems at four spinning rates: 3 kHz, 5 kHz, 8 kHz, 12 kHz.

spin_rates = [3e3, 5e3, 8e3, 12e3]  # in Hz

# The variable `methods` is a list of four BlochDecaySpectrum methods.
methods = [
    BlochDecaySpectrum(
        channels=["13C"],
        magnetic_flux_density=9.4,  # in T
        rotor_frequency=vr,  # in Hz
        spectral_dimensions=[SpectralDimension(count=2048, spectral_width=8.0e4)],
    )
    for vr in spin_rates
]

# %%
# Create the Simulator object and add the method and the spin system objects.
sim = Simulator(spin_systems=spin_systems, methods=methods)
sim.config.integration_volume = "hemisphere"  # set averaging to hemisphere
# config to 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()
Ejemplo n.º 20
0
# 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
    rotor_angle=70.12 * 3.14159 / 180,  # in rads
    spectral_dimensions=[
        SpectralDimension(
            count=256,
            spectral_width=4e4,  # in Hz
            reference_offset=-8e3,  # in Hz
            label="3Q dimension",
            events=[
                SpectralEvent(transition_query=[{
                    "ch1": {
                        "P": [3],
                        "D": [0]
                    }
                }])
            ],
        ),
        # The last spectral dimension block is the direct-dimension
        SpectralDimension(
            count=256,
            spectral_width=2e4,  # in Hz
            reference_offset=-3e3,  # in Hz
            label="70.12 dimension",
            events=[
                SpectralEvent(transition_query=[{
                    "ch1": {
Ejemplo n.º 21
0
    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]

# %%
# Select a Triple Quantum variable-angle spinning method. You may optionally
# provide a `rotor_angle` to the method. The default `rotor_angle` is the magic-angle.
method = ThreeQ_VAS(
    channels=["87Rb"],
    magnetic_flux_density=9.4,  # in T
    spectral_dimensions=[
        SpectralDimension(
            count=128,
            spectral_width=7e3,  # in Hz
            reference_offset=-7e3,  # in Hz
            label="Isotropic dimension",
        ),
        SpectralDimension(
            count=256,
            spectral_width=1e4,  # in Hz
            reference_offset=-4e3,  # in Hz
            label="MAS dimension",
        ),
    ],
)

# A graphical representation of the method object.
plt.figure(figsize=(5, 2.5))
method.plot()
plt.show()
hahn_echo = Method1D(
    channels=["1H"],
    magnetic_flux_density=9.4,  # in T
    spectral_dimensions=[
        SpectralDimension(
            count=512,
            spectral_width=2e4,  # in Hz
            events=[
                SpectralEvent(fraction=0.5,
                              transition_query=[{
                                  "ch1": {
                                      "P": [1]
                                  }
                              }]),
                MixingEvent(
                    mixing_query={"ch1": {
                        "tip_angle": np.pi,
                        "phase": 0
                    }}),
                SpectralEvent(fraction=0.5,
                              transition_query=[{
                                  "ch1": {
                                      "P": [-1]
                                  }
                              }]),
            ],
        )
    ],
)

# %%
Ejemplo n.º 23
0
# method parameters, as shown below. Note, the Method2D method simulates an infinite
# spinning speed spectrum.
das = Method2D(
    name="Dynamic Angle Spinning",
    channels=["17O"],
    magnetic_flux_density=11.74,  # in T
    spectral_dimensions=[
        SpectralDimension(
            count=256,
            spectral_width=5e3,  # in Hz
            reference_offset=0,  # in Hz
            label="DAS isotropic dimension",
            events=[
                SpectralEvent(
                    fraction=0.5,
                    rotor_angle=37.38 * 3.14159 / 180,
                    transition_query=[{"ch1": {"P": [-1], "D": [0]}}],
                ),
                SpectralEvent(
                    fraction=0.5,
                    rotor_angle=79.19 * 3.14159 / 180,
                    transition_query=[{"ch1": {"P": [-1], "D": [0]}}],
                ),
            ],
        ),
        # The last spectral dimension block is the direct-dimension
        SpectralDimension(
            count=256,
            spectral_width=2e4,  # in Hz
            reference_offset=0,  # in Hz
            label="MAS dimension",
            events=[
Ejemplo n.º 24
0
# transitions to the central transition. Note, STMAS measurements are highly suspectable
# to rotor angle mismatch. In the following, we show two methods, the first at the
# magic angle and second deliberately miss-sets by approximately 0.0059 degrees.

angles = [54.7359, 54.73]
method = []
for angle in angles:
    method.append(
        ST1_VAS(
            channels=["87Rb"],
            magnetic_flux_density=7,  # in T
            rotor_angle=angle * 3.14159 / 180,  # in rad (magic angle)
            spectral_dimensions=[
                SpectralDimension(
                    count=256,
                    spectral_width=3e3,  # in Hz
                    reference_offset=-2.4e3,  # in Hz
                    label="Isotropic dimension",
                ),
                SpectralDimension(
                    count=512,
                    spectral_width=5e3,  # in Hz
                    reference_offset=-4e3,  # in Hz
                    label="MAS dimension",
                ),
            ],
        ))

# A graphical representation of the method object.
plt.figure(figsize=(5, 2.5))
method[0].plot()
plt.show()
Ejemplo n.º 25
0
    isotope="29Si",
    isotropic_chemical_shift=iso,
    shielding_symmetric={"zeta": zeta, "eta": eta},
    abundance=pdf,
)

# %%
# **Method:**
#
# Let's also create a Bloch decay spectrum method.
method = BlochDecaySpectrum(
    channels=["29Si"],
    rotor_frequency=0,  # in Hz
    rotor_angle=0,  # in rads
    spectral_dimensions=[
        SpectralDimension(spectral_width=25000, reference_offset=-7000)  # values in Hz
    ],
)

# %%
# The above method simulates a static :math:`^{29}\text{Si}` spectrum at 9.4 T field
# (default value).
#
# **Simulator:**
#
# Now that we have the spin systems and the method, create the simulator object and
# add the respective objects.
sim = Simulator(spin_systems=spin_systems, methods=[method])

# %%
# Static spectrum
        "Cq": Cq * 1e6,
        "eta": eta
    },  # Cq in Hz
    abundance=pdf,
)

# %%
# Static spectrum
# ---------------
# Observe the static :math:`^{27}\text{Al}` NMR spectrum simulation. First,
# create a central transition selective Bloch decay spectrum method.
static_method = BlochDecayCTSpectrum(
    channels=["27Al"],
    rotor_frequency=0,  # in Hz
    rotor_angle=0,  # in rads
    spectral_dimensions=[SpectralDimension(spectral_width=80000)],
)

# %%
# Create the simulator object and add the spin systems and method.
sim = Simulator(spin_systems=spin_systems, methods=[static_method])
sim.run()

# %%
# The plot of the corresponding spectrum.
plt.figure(figsize=(4.25, 3.0))
ax = plt.subplot(projection="csdm")
ax.plot(sim.methods[0].simulation.real, color="black", linewidth=1)
ax.invert_xaxis()
plt.tight_layout()
plt.show()
Ejemplo n.º 27
0
 rotor_frequency=np.inf,
 spectral_dimensions=[
     SpectralDimension(
         **spectral_dims[0],
         events=[
             SpectralEvent(
                 fraction=0.5,
                 rotor_angle=37.38 * np.pi / 180,  # in rads
                 transition_queries=[{
                     "ch1": {
                         "P": [-1],
                         "D": [0]
                     }
                 }],
             ),
             MixingEvent(query="NoMixing"),
             SpectralEvent(
                 fraction=0.5,
                 rotor_angle=79.19 * np.pi / 180,  # in rads
                 transition_queries=[{
                     "ch1": {
                         "P": [-1],
                         "D": [0]
                     }
                 }],
             ),
             MixingEvent(query="NoMixing"),
         ],
     ),
     # The last spectral dimension block is the direct-dimension
     SpectralDimension(
Ejemplo n.º 28
0
def test_mixing_query_connect_map():
    MX1 = MixingEvent(query={"ch1": {"angle": 0.12}})
    MX2 = MixingEvent(query={"ch2": {"angle": 1.12}})
    TOTAL_MX = MixingEvent(query="TotalMixing")

    # Use MixingEvents with non-enum queries
    spectral_dimensions = [
        SpectralDimension(events=[
            {
                "fraction": 0.5
            },  # 0
            MX1,
            {
                "duration": 0.5
            },  # 1
            {
                "fraction": 0.5
            },  # 2
            MX2,
            {
                "duration": 0.5
            },  # 3
        ]),
        SpectralDimension(events=[
            MX1,
            MX2,
            {
                "duration": 0.5
            },  # 4
            MX2,
            {
                "duration": 0.5
            },  # 5
            {
                "fraction": 1
            },  # 6
        ]),
    ]
    res = mixing_query_connect_map(spectral_dimensions)
    assert res == [
        {
            "mixing_query_list": [MX1.query],
            "near_index": [0, 1]
        },
        {
            "mixing_query_list": [MX2.query],
            "near_index": [2, 3]
        },
        {
            "mixing_query_list": [MX1.query, MX2.query],
            "near_index": [3, 4]
        },
        {
            "mixing_query_list": [MX2.query],
            "near_index": [4, 5]
        },
    ]

    # Combination of MixingEvents with dict queries and enum queries (total mixing)
    spectral_dimensions = [
        SpectralDimension(events=[
            # Connect all, should return no list
            {
                "fraction": 0.5
            },  # 0
            TOTAL_MX,
            {
                "duration": 0.5
            },  # 1
            # Just MX1
            {
                "fraction": 0.5
            },  # 2
            TOTAL_MX,
            MX1,
            {
                "duration": 0.5
            },  # 3
        ]),
        SpectralDimension(events=[
            # MX1 and MX2
            {
                "fraction": 0.5
            },  # 4
            MX1,
            TOTAL_MX,
            MX2,
            {
                "duration": 0.5
            },  # 5
            # MX1, MX2, MX1
            {
                "fraction": 0.5
            },  # 6
            MX1,
            TOTAL_MX,
            MX2,
            MX1,
            TOTAL_MX,
            {
                "duration": 0.5
            },  # 7
        ]),
    ]
    res = mixing_query_connect_map(spectral_dimensions)
    assert res == [
        {
            "mixing_query_list": [MX1.query],
            "near_index": [2, 3]
        },
        {
            "mixing_query_list": [MX1.query, MX2.query],
            "near_index": [4, 5]
        },
        {
            "mixing_query_list": [MX1.query, MX2.query, MX1.query],
            "near_index": [6, 7]
        },
    ]

    error = "SpectralDimension requires at least one SpectralEvent"
    with pytest.raises(MissingSpectralEventError, match=f".*{error}.*"):
        SpectralDimension(
            events=[MX1, MX2, {
                "duration": 0.5
            }, MX2, {
                "duration": 0.5
            }])
Ejemplo n.º 29
0
# SpectralEvent. A no mixing query is equivalent to a rotation query where each
# channel has a zero phase and angle. Since all spin systems in this example have a
# single site, defining no mixing between the two spectral events is superfluous.
# We include it such that the method is applicable with multi-site spin systems.
maf = Method(
    name="Magic Angle Flipping",
    channels=["29Si"],
    magnetic_flux_density=14.1,  # in T
    rotor_frequency=np.inf,
    spectral_dimensions=[
        SpectralDimension(
            count=128,
            spectral_width=2e4,  # in Hz
            label="Anisotropic dimension",
            events=[
                SpectralEvent(
                    rotor_angle=90 * np.pi / 180,  # in rads
                    transition_queries=[{"ch1": {"P": [-1], "D": [0]}}],
                ),
                MixingEvent(query="NoMixing"),
            ],
        ),
        SpectralDimension(
            count=128,
            spectral_width=3e3,  # in Hz
            reference_offset=-1.05e4,  # in Hz
            label="Isotropic dimension",
            events=[
                SpectralEvent(
                    rotor_angle=54.735 * np.pi / 180,  # in rads
                    transition_queries=[{"ch1": {"P": [-1], "D": [0]}}],
                )
Ejemplo n.º 30
0
# Use the generic 2D method, `Method2D`, to simulate a Magic-Angle Flipping (MAF)
# spectrum by customizing the method parameters, as shown below. Note, the Method2D
# method simulates an infinite spinning speed spectrum.
maf = Method2D(
    name="Magic Angle Flipping",
    channels=["29Si"],
    magnetic_flux_density=14.1,  # in T
    spectral_dimensions=[
        SpectralDimension(
            count=128,
            spectral_width=2e4,  # in Hz
            label="Anisotropic dimension",
            events=[
                SpectralEvent(
                    rotor_angle=90 * 3.14159 / 180,
                    transition_query=[{
                        "ch1": {
                            "P": [-1],
                            "D": [0]
                        }
                    }],
                )
            ],
        ),
        SpectralDimension(
            count=128,
            spectral_width=3e3,  # in Hz
            reference_offset=-1.05e4,  # in Hz
            label="Isotropic dimension",
            events=[
                SpectralEvent(
                    rotor_angle=54.735 * 3.14159 / 180,