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
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)
} 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}")
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