Example #1
0
def test_BlochDecaySpectrum():
    # test-1
    m1 = BlochDecaySpectrum()

    dimension_dictionary_ = {
        "count": 1024,
        "spectral_width": "25000.0 Hz",
        "reference_offset": "0.0 Hz",
    }

    should_be = {
        "name": "BlochDecaySpectrum",
        "channels": ["1H"],
        "magnetic_flux_density": "9.4 T",
        "rotor_frequency": "0.0 Hz",
        "rotor_angle": "0.955316618 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",
        "reference_offset": "0.0 Hz",
    }

    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
Example #2
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)
Example #3
0
}
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")
ax[1].plot(freq2, amp2, linewidth=1.0, color="k")
ax[1].set_xlabel(f"frequency ratio / {freq2.unit}")
Example #4
0
    def __init__(
        self,
        kernel_dimension,
        inverse_kernel_dimension,
        channel,
        magnetic_flux_density="9.4 T",
        rotor_angle="54.735 deg",
        rotor_frequency=None,
        number_of_sidebands=None,
    ):
        super().__init__(kernel_dimension, inverse_kernel_dimension, 1, 2)

        kernel = self.__class__.__name__
        dim_types = ["frequency", "dimensionless"]
        _check_dimension_type(self.kernel_dimension, "anisotropic", dim_types,
                              kernel)
        _check_dimension_type(self.inverse_kernel_dimension, "inverse",
                              dim_types, kernel)

        dim = self.kernel_dimension

        temp_method = BlochDecaySpectrum.parse_dict_with_units({
            "channels": [channel],
            "magnetic_flux_density":
            magnetic_flux_density
        })
        # larmor frequency from method.
        B0 = temp_method.spectral_dimensions[0].events[
            0].magnetic_flux_density  # in T
        gamma = temp_method.channels[0].gyromagnetic_ratio  # in MHz/T
        self.larmor_frequency = -gamma * B0  # in MHz

        spectral_width = dim.increment * dim.count
        reference_offset = dim.coordinates_offset
        if dim.complex_fft is False:
            reference_offset = dim.coordinates_offset + spectral_width / 2.0

        if dim.increment.unit.physical_type == "dimensionless":
            lf = abs(self.larmor_frequency)
            val = spectral_width.to("ppm")
            spectral_width = f"{val.value * lf} Hz"
            val = reference_offset.to("ppm")
            reference_offset = f"{val.value * lf} Hz"

        spectral_dimensions = [
            dict(
                count=dim.count,
                reference_offset=str(reference_offset),
                spectral_width=str(spectral_width),
            )
        ]

        if rotor_frequency is None:
            if dim.increment.unit.physical_type == "dimensionless":
                rotor_frequency = f"{dim.increment.to('ppm').value * lf} Hz"
            else:
                rotor_frequency = str(dim.increment)

        self.method_args = {
            "channels": [channel],
            "magnetic_flux_density": magnetic_flux_density,
            "rotor_angle": rotor_angle,
            "rotor_frequency": rotor_frequency,
            "spectral_dimensions": spectral_dimensions,
        }

        self.number_of_sidebands = number_of_sidebands
        if number_of_sidebands is None:
            self.number_of_sidebands = dim.count