def test_2D_area(): data = np.zeros((256, 128), dtype=float) data[128, 64] = 1.0 csdm_obj = cp.as_csdm(data) # test00 PS = [ sp.IFFT(dim_index=(0, 1)), sp.apodization.Gaussian(FWHM="35", dim_index=0), sp.apodization.Gaussian(FWHM="55", dim_index=1), sp.FFT(dim_index=(0, 1)), ] post_sim = sp.SignalProcessor(operations=PS) data_new = post_sim.apply_operations(data=csdm_obj.copy()) _, __, y1 = data_new.to_list() assert np.allclose(y1.sum(), data.sum()) # test01 PS = [ sp.IFFT(dim_index=(0, 1)), sp.apodization.Gaussian(FWHM="35", dim_index=0), sp.apodization.Exponential(FWHM="55", dim_index=1), sp.FFT(dim_index=(0, 1)), ] post_sim = sp.SignalProcessor(operations=PS) data_new = post_sim.apply_operations(data=csdm_obj.copy()) _, __, y1 = data_new.to_list() assert np.allclose(y1.sum(), data.sum())
def test_Gaussian(): post_sim = sp.SignalProcessor(operations=PS_2) data = post_sim.apply_operations(data=sim.methods[0].simulation) _, y0, y1, _ = data.to_list() sigma = 20 test = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-((freqHz / sigma)**2) / 2) assert np.allclose(y0, y1) print((test / test.max() - y0 / y0.max()).max()) assert np.allclose(test / test.max(), y0 / y0.max(), atol=1e-04), "Gaussian apodization amplitude failed" # test None for dv_index post_sim = sp.SignalProcessor(operations=PS_3) data = post_sim.apply_operations(data=sim.methods[0].simulation) _, y0, y1, y2 = data.to_list() sigma = 20 test = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-((freqHz / sigma)**2) / 2) assert np.allclose(y0, y1) assert np.allclose(y0, y2) assert np.allclose(test / test.max(), y0 / y0.max(), atol=1e-04), "Gaussian apodization amplitude failed"
def test_baseline_polynomial(): data_in = generate_data() data_in.dimensions[0] *= cp.ScalarQuantity("1 ms") x_c = data_in.dimensions[0].coordinates.value # zeroth order PS_0 = [sp.baseline.Polynomial(polynomial_dictionary={"c0": 10})] data_out = sp.SignalProcessor(operations=PS_0).apply_operations(data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_.max() - in_.max(), 10), "Offset failed" # first order PS_0 = [sp.baseline.Polynomial(polynomial_dictionary={"c0": 30, "c1": 1})] data_out = sp.SignalProcessor(operations=PS_0).apply_operations(data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_, in_ + 30 + x_c), "Polynomial 1st order failed" # second order PS_0 = [sp.baseline.Polynomial(polynomial_dictionary={"c0": 1, "c2": 1})] data_out = sp.SignalProcessor(operations=PS_0).apply_operations(data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_, in_ + 1 + x_c**2), "Polynomial 2nd order failed" # third order PS_0 = [ sp.baseline.Polynomial(polynomial_dictionary={"c0": 10, "c3": 2, "c1": 13.1}) ] data_out = sp.SignalProcessor(operations=PS_0).apply_operations(data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose( out_, in_ + 10 + 13.1 * x_c + 2 * x_c**3 ), "Polynomial3rd order failed"
def test_TopHat(): test_data = cp.CSDM( dependent_variables=[cp.as_dependent_variable(np.ones(500))], dimensions=[cp.LinearDimension(500, "1 s")], ) processor = sp.SignalProcessor() processor.operations = [ sp.apodization.TopHat(rising_edge="100 s", falling_edge="400 s") ] rise_and_fall_data = processor.apply_operations(test_data.copy()) rise_and_fall_should_be = np.zeros(500) rise_and_fall_should_be[100:400] = 1 assert np.allclose(rise_and_fall_data.y[0].components, rise_and_fall_should_be) processor.operations = [sp.apodization.TopHat(rising_edge="100 s")] rise_only_data = processor.apply_operations(test_data.copy()) rise_only_should_be = np.zeros(500) rise_only_should_be[100:] = 1 assert np.allclose(rise_only_data.y[0].components, rise_only_should_be) processor.operations = [sp.apodization.TopHat(falling_edge="400 s")] fall_only_data = processor.apply_operations(test_data.copy()) fall_only_should_be = np.zeros(500) fall_only_should_be[:400] = 1 assert np.allclose(fall_only_data.y[0].components, fall_only_should_be)
def test_serialization_and_parse(): processor = sp.SignalProcessor(operations=[ sp.IFFT(dim_index=1), sp.affine.Shear(factor="-1 K/s", dim_index=1, parallel=0), sp.FFT(dim_index=1), ]) serialize = processor.json() expected = { "operations": [ { "dim_index": 1, "function": "IFFT" }, { "dim_index": 1, "factor": "-1.0 K / s", "function": "affine", "parallel": 0, "type": "Shear", }, { "dim_index": 1, "function": "FFT" }, ], } assert serialize == expected recovered = sp.SignalProcessor.parse_dict_with_units(serialize) assert recovered == processor
def setup_sim_and_processor(): site = Site(isotope="1H", shielding_symmetric={"zeta": -100, "eta": 0.3}) spin_sys = SpinSystem(sites=[site, site], abundance=45) method = BlochDecaySpectrum(channels=["1H"]) sim = Simulator(spin_systems=[spin_sys, spin_sys], methods=[method, method]) sim.run(method_index=0) processor = sp.SignalProcessor(operations=[ sp.IFFT(), sp.apodization.Exponential(FWHM="2500 Hz"), sp.FFT(), sp.Scale(factor=20), ]) processors = [processor] * 2 application = { "com.github.DeepanshS.mrsimulator": { "foo": "This is some metadata" }, "com.github.DeepanshS.mrsimulator-app": { "params": "The JSON string of params" }, } return sim, processors, application
def test_scale(): post_sim = sp.SignalProcessor(operations=PS_0) data = post_sim.apply_operations(data=sim.methods[0].simulation.copy()) _, y0, y1, y2 = sim.methods[0].simulation.to_list() _, y0_, y1_, y2_ = data.to_list() assert y0_.max() / y0.max() == 10, "Scaling failed" assert y1_.max() / y1.max() == 10, "Scaling failed" assert y2_.max() / y2.max() == 10, "Scaling failed"
def test_scale(): PS_0 = [sp.Scale(factor=10)] post_sim = sp.SignalProcessor(operations=PS_0) data = post_sim.apply_operations(data=sim.methods[0].simulation.copy()) _, y0, y1, y2 = sim.methods[0].simulation.to_list() _, y0_, y1_, y2_ = data.to_list() # cast complex data assert np.allclose(y0_, y0 * 10), "Scaling failed" assert np.allclose(y1_, y1 * 10), "Scaling failed" assert np.allclose(y2_, y2 * 10), "Scaling failed"
def test_linear(): data_in = generate_data() PS_0 = [sp.Linear(amplitude=4.1, offset=10)] operator = sp.SignalProcessor(operations=PS_0) data_out = operator.apply_operations(data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose((out_.max() - 10) / in_.max(), 4.1), "Offset failed"
def test_scale(): data_in = generate_data() PS_0 = [sp.Scale(factor=10)] operator = sp.SignalProcessor(operations=PS_0) data_out = operator.apply_operations(data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_.max() / in_.max(), 10), "Scaling failed"
def test_Lorentzian(): post_sim = sp.SignalProcessor(operations=PS_1) data = post_sim.apply_operations(data=sim.methods[0].simulation) _, y0, y1, y2 = data.to_list() FWHM = 200 test = (FWHM / 2) / (np.pi * (freqHz**2 + (FWHM / 2)**2)) assert np.allclose(y1, y2) assert np.all(y0 != y1) assert np.allclose(test / test.max(), y0 / y0.max(), atol=1e-04), "Lorentzian apodization amplitude failed"
def test_Gaussian(): FWHM = 200 * 2.354820045030949 PS_2 = [ sp.IFFT(dim_index=0), sp.apodization.Gaussian(FWHM=f"{FWHM} Hz", dim_index=0, dv_index=[0, 1]), sp.FFT(dim_index=0), ] PS_3 = [ sp.IFFT(dim_index=0), sp.apodization.Gaussian(FWHM=f"{FWHM} Hz", dim_index=0, dv_index=None), sp.FFT(dim_index=0), ] post_sim = sp.SignalProcessor(operations=PS_2) data = post_sim.apply_operations(data=sim.methods[0].simulation.copy()) _, y0, y1, _ = data.to_list() sigma = 200 test = (1 / (sigma * np.sqrt(2 * np.pi))) * np.exp(-((freqHz / sigma)**2) / 2) assert np.allclose(y0, y1), "Gaussian apodization on two dv are not equal." assert np.allclose(test / test.sum(), y0 / y0.sum(), atol=1e-04), "Gaussian apodization amplitude failed" # test None for dv_index post_sim = sp.SignalProcessor(operations=PS_3) data = post_sim.apply_operations(data=sim.methods[0].simulation.copy()) _, y0, y1, y2 = data.to_list() assert np.allclose( y0, y1), "Gaussian apodization on dv at 0 and 1 are unequal." assert np.allclose( y0, y2), "Gaussian apodization on dv at 0 and 2 are unequal." assert np.allclose(test / test.sum(), y0 / y0.sum(), atol=1e-04), "Gaussian apodization amplitude failed"
def test_scale(): c_inc = csdm_object.x[1].increment.value c_off = csdm_object.x[1].coordinates_offset.value processor = sp.SignalProcessor( operations=[sp.affine.Scale(factor=2, dim_index=1)]) scaled_data = processor.apply_operations(data=csdm_object) s_inc = scaled_data.x[1].increment.value s_off = scaled_data.x[1].coordinates_offset.value assert s_inc == 2 * c_inc assert s_off == 2 * c_off
def test_shear_01(): processor = sp.SignalProcessor(operations=[ sp.IFFT(dim_index=1), af.Shear(factor="-1 K/s", dim_index=1, parallel=0), sp.FFT(dim_index=1), ]) shear_data = processor.apply_operations(data=csdm_object) index = np.where( shear_data.dependent_variables[0].components[0] > 0.99999999) a = np.arange(40) assert np.allclose(index, [a, a]) # complex_fft dim=0 to false csdm_object.dimensions[0].complex_fft = False csdm_object.dimensions[1].complex_fft = True shear_data = processor.apply_operations(data=csdm_object) index = np.where( shear_data.dependent_variables[0].components[0] > 0.99999999) a1 = np.arange(20) b1 = a1 + 20 b = np.append(b1, a1) assert np.allclose(index, [a, b]) # complex_fft dim=1 to false csdm_object.dimensions[0].complex_fft = True csdm_object.dimensions[1].complex_fft = False shear_data = processor.apply_operations(data=csdm_object) index = np.where( shear_data.dependent_variables[0].components[0] > 0.99999999) b = np.arange(40) b[1:] = a[::-1][:-1] assert np.allclose(index, [a, b]) # both complex_fft set to false csdm_object.dimensions[0].complex_fft = False csdm_object.dimensions[1].complex_fft = False shear_data = processor.apply_operations(data=csdm_object) index = np.where( shear_data.dependent_variables[0].components[0] > 0.99999999) a1 = np.arange(21)[::-1] b1 = a1[1:-1] + 20 b = np.append(a1, b1) assert np.allclose(index, [a, b])
def setup_signal_processor(): op_list1 = [ sp.IFFT(dim_index=0), sp.apodization.Exponential(FWHM=100), sp.apodization.Gaussian(FWHM=200), sp.FFT(dim_index=0), sp.Scale(factor=10), sp.baseline.ConstantOffset(offset=43.1), sp.Linear(amplitude=32.9, offset=13.4), ] op_list2 = [ sp.Scale(factor=20), sp.baseline.ConstantOffset(offset=-43.1), sp.Linear(amplitude=1.2, offset=0.4), ] return [sp.SignalProcessor(operations=op) for op in [op_list1, op_list2]]
def test_baseline_constant_offset(): data_in = generate_data() PS_0 = [sp.baseline.ConstantOffset(offset=10)] operator = sp.SignalProcessor(operations=PS_0) data_out = operator.apply_operations(data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_.max() - in_.max(), 10), "Offset failed" py_dict = { "function": "baseline", "type": "ConstantOffset", "offset": 10.0, } setup_read_write(PS_0[0], py_dict, sp.baseline.ConstantOffset)
def test_SkewedGaussian(): # TODO: update this test for multiple skewes and using npp.convolve skew = 2 FWHM = 200 * 2.354820045030949 PS_2 = [ sp.IFFT(dim_index=0), sp.apodization.SkewedGaussian(skew=skew, FWHM=f"{FWHM} Hz", dim_index=0, dv_index=[0, 1]), sp.FFT(dim_index=0), ] post_sim = sp.SignalProcessor(operations=PS_2) data = post_sim.apply_operations(data=sim.methods[0].simulation.copy()) _, y0, y1, _ = data.to_list() assert np.allclose(y0, y1), "Gaussian apodization on two dv are not equal."
def test_Lorentzian(): PS_1 = [ sp.IFFT(dim_index=0), sp.apodization.Exponential(FWHM="200 Hz", dim_index=0, dv_index=0), sp.FFT(dim_index=0), ] post_sim = sp.SignalProcessor(operations=PS_1) data = post_sim.apply_operations(data=sim.methods[0].simulation.copy()) _, y0, y1, y2 = data.to_list() FWHM = 200 test = (FWHM / 2) / (np.pi * (freqHz**2 + (FWHM / 2)**2)) assert np.allclose(y1, y2) assert np.all(y0 != y1) assert np.allclose(test / test.sum(), y0 / y0.sum(), atol=1e-04), "Lorentzian apodization amplitude failed" assert np.allclose( y1.sum(), y0.sum()), "Area not conserved after Lorentzian apodization"
def setup(): site = Site(isotope="1H", shielding_symmetric={"zeta": -100, "eta": 0.3}) spin_sys = SpinSystem(sites=[site, site], abundance=45) method = BlochDecaySpectrum(channels=["1H"]) sim = Simulator(spin_systems=[spin_sys, spin_sys], methods=[method, method]) sim.run(method_index=0) processor = sp.SignalProcessor(operations=[ sp.IFFT(), sp.apodization.Exponential(FWHM="2500 Hz"), sp.FFT(), sp.Scale(factor=20), ]) processors = [processor] * 2 return sim, processors
def test_01(): post_sim = sp.SignalProcessor() operations = [ sp.IFFT(), sp.apodization.Gaussian(FWHM="12 K", dim_index=0, dv_index=0), sp.FFT(), ] post_sim.operations = operations with pytest.raises(ValueError, match="The data must be a CSDM object."): post_sim.apply_operations([]) data = cp.as_csdm(np.arange(20)) data.x[0] = cp.LinearDimension(count=20, increment="10 K") post_sim.apply_operations(data) # to dict with units dict_ = post_sim.json() assert dict_ == { "operations": [ { "dim_index": 0, "function": "IFFT" }, { "function": "apodization", "type": "Gaussian", "FWHM": "12.0 K", "dim_index": 0, "dv_index": 0, }, { "dim_index": 0, "function": "FFT" }, ], } # parse dict with units post_sim_2 = sp.SignalProcessor.parse_dict_with_units(dict_) assert post_sim.operations == post_sim_2.operations
def test_6_coupled(): sim = Simulator() spin_system = {"sites": [H, C], "couplings": [CH], "abundance": "100%"} system_object = SpinSystem.parse_dict_with_units(spin_system) sim.spin_systems += [system_object] post_sim = sp.SignalProcessor(operations=op_list) params = sf.make_LMFIT_params(sim, post_sim) valuesdict_system = { "sys_0_site_0_isotropic_chemical_shift": 10, "sys_0_site_0_shielding_symmetric_zeta": 5, "sys_0_site_0_shielding_symmetric_eta": 0.1, "sys_0_site_0_shielding_symmetric_alpha": 3.12, "sys_0_site_0_shielding_symmetric_gamma": 0.341, "sys_0_site_1_isotropic_chemical_shift": -10, "sys_0_site_1_shielding_symmetric_zeta": 15, "sys_0_site_1_shielding_symmetric_eta": 0.2, "sys_0_site_1_shielding_symmetric_beta": 4.12, "sys_0_coupling_0_isotropic_j": 10, "sys_0_coupling_0_j_symmetric_zeta": 60, "sys_0_coupling_0_j_symmetric_eta": 0.4, "sys_0_abundance": 100, } valuedict_proc = { "SP_0_operation_1_Exponential_FWHM": 100, "SP_0_operation_3_Scale_factor": 10, } assert params.valuesdict() == { **valuesdict_system, **valuedict_proc, }, "Parameter creation failed" params = sf.make_LMFIT_params(sim) assert params.valuesdict( ) == valuesdict_system, "Parameter creation failed" # alias params = sf.make_LMFIT_parameters(sim) assert params.valuesdict( ) == valuesdict_system, "Parameter creation failed"
def test_Mask(): one_mask = np.zeros(shape=len(freqHz)) PS_5 = [ sp.IFFT(dim_index=0), sp.apodization.Mask(mask=one_mask, dim_index=0, dv_index=[0, 1]), sp.FFT(dim_index=0), ] post_sim = sp.SignalProcessor(operations=PS_5) data = post_sim.apply_operations(data=sim.methods[0].simulation.copy()) _, y0, y1, _ = data.to_list() _, test_y0, test_y1, _ = sim.methods[0].simulation.to_list() nonzero_y0 = np.count_nonzero(y0) nonzero_y1 = np.count_nonzero(y1) assert np.allclose(y0, y1), "Mask on two dv are not equal." assert np.allclose(nonzero_y0, nonzero_y1, atol=1e-04), "Mask apodization amplitude failed"
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() data = processor.apply_operations(sim.methods[0].simulation) data_sum = 0 for dv in data.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(data.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()
# evaluate the transition pathways once and store it as follows for sys in spin_systems: sys.transition_pathways = MAS_CT.get_transition_pathways(sys) # %% # **Step 3:** Create the Simulator object and add the method and spin system objects. sim = Simulator(spin_systems=spin_systems, methods=[MAS_CT]) sim.config.decompose_spectrum = "spin_system" sim.run() # %% # **Step 4:** Create a SignalProcessor class object and apply the post-simulation # signal processing operations. processor = sp.SignalProcessor(operations=[ sp.IFFT(), sp.apodization.Gaussian(FWHM="100 Hz"), sp.FFT(), sp.Scale(factor=200.0), ]) processed_data = processor.apply_operations( data=sim.methods[0].simulation).real # %% # **Step 5:** The plot of the data and the guess spectrum. plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") ax.plot(experiment, color="black", linewidth=0.5, label="Experiment") ax.plot(processed_data, linewidth=2, alpha=0.6) ax.set_xlim(100, -50) plt.legend() plt.grid() plt.tight_layout()
def test_baseline_polynomial(): data_in = generate_data() data_in.dimensions[0] *= cp.ScalarQuantity("1 ms") x_c = data_in.dimensions[0].coordinates.to("s").value # zeroth order PS_0 = [sp.baseline.Polynomial(x0="10")] data_out = sp.SignalProcessor(operations=PS_0).apply_operations( data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_.max() - in_.max(), 10), "Offset failed" py_dict = { "function": "baseline", "type": "Polynomial", "x0": "10.0", "dim_index": 0, } setup_read_write(PS_0[0], py_dict, sp.baseline.Polynomial) # first order PS_0 = [sp.baseline.Polynomial(x0="30", x1="1 Hz")] data_out = sp.SignalProcessor(operations=PS_0).apply_operations( data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_, in_ + 30 + x_c), "Polynomial 1st order failed" py_dict = { "function": "baseline", "type": "Polynomial", "x0": 30.0, "x1": "1.0 Hz", "dim_index": 0, } setup_read_write(PS_0[0], py_dict, sp.baseline.Polynomial) # second order PS_0 = [sp.baseline.Polynomial(x0="1", x2="1 Hz^2")] data_out = sp.SignalProcessor(operations=PS_0).apply_operations( data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_, in_ + 1 + x_c**2), "Polynomial 2nd order failed" py_dict = { "function": "baseline", "type": "Polynomial", "x0": 1.0, "x2": "1.0 Hz2", "dim_index": 0, } setup_read_write(PS_0[0], py_dict, sp.baseline.Polynomial) # third order PS_0 = [sp.baseline.Polynomial(x0="10", x3="2 Hz^3", x1="13.1 Hz")] data_out = sp.SignalProcessor(operations=PS_0).apply_operations( data=data_in.copy()) _, y0, y1, y2 = data_in.to_list() _, y0_, y1_, y2_ = data_out.to_list() for in_, out_ in zip([y0, y1, y2], [y0_, y1_, y2_]): assert np.allclose(out_, in_ + 10 + 13.1 * x_c + 2 * x_c**3), "Polynomial 3rd order failed"
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")
# %% # **Step 5:** Simulate the spectrum. sim.run() # The plot of the simulation before signal processing. ax = plt.subplot(projection="csdm") ax.plot(sim.methods[0].simulation.real, color="black", linewidth=1) ax.invert_xaxis() plt.tight_layout() plt.show() # %% # **Step 6:** Add post-simulation signal processing. processor = sp.SignalProcessor(operations=[ sp.IFFT(), apo.Exponential(FWHM="30 Hz"), apo.Gaussian(FWHM="145 Hz"), sp.FFT(), ]) processed_data = processor.apply_operations(data=sim.methods[0].simulation) # The plot of the simulation after signal processing. ax = plt.subplot(projection="csdm") ax.plot(processed_data.real, color="black", linewidth=1) ax.invert_xaxis() plt.tight_layout() plt.show() # %% # .. [#f1] Grandinetti, P. J., Baltisberger, J. H., Farnan, I., Stebbins, J. F., # Werner, U. and Pines, A. # Solid-State :math:`^{17}\text{O}` Magic-Angle and Dynamic-Angle Spinning NMR
plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") cb = ax.imshow(data / data.max(), aspect="auto", cmap="gist_ncar_r") plt.colorbar(cb) ax.invert_xaxis() ax.invert_yaxis() plt.tight_layout() plt.show() # %% # Add post-simulation signal processing. processor = sp.SignalProcessor(operations=[ # Gaussian convolution along both dimensions. sp.IFFT(dim_index=(0, 1)), sp.apodization.Gaussian(FWHM="0.3 kHz", dim_index=0), sp.apodization.Gaussian(FWHM="0.15 kHz", dim_index=1), sp.FFT(dim_index=(0, 1)), ]) processed_data = processor.apply_operations(data=data) processed_data /= processed_data.max() # %% # The plot of the simulation after signal processing. plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") cb = ax.imshow(processed_data.real, cmap="gist_ncar_r", aspect="auto") plt.colorbar(cb) ax.invert_xaxis() ax.invert_yaxis() plt.tight_layout()
) # %% # Create the Simulator object, add the method and spin system objects, and run the # simulation. sim = Simulator() sim.spin_systems = spin_systems # add the spin systems sim.methods = [maf] # add the method sim.run() # %% # Add post-simulation signal processing. csdm_data = sim.methods[0].simulation processor = sp.SignalProcessor(operations=[ sp.IFFT(dim_index=(0, 1)), apo.Gaussian(FWHM="50 Hz", dim_index=0), apo.Gaussian(FWHM="50 Hz", dim_index=1), sp.FFT(dim_index=(0, 1)), ]) processed_data = processor.apply_operations(data=csdm_data).real processed_data /= processed_data.max() # %% # The plot of the simulation after signal processing. ax = plt.subplot(projection="csdm") cb = ax.imshow(processed_data.T, aspect="auto", cmap="gist_ncar_r") plt.colorbar(cb) ax.invert_xaxis() ax.invert_yaxis() plt.tight_layout() plt.show()
], 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(spin_systems=[spin_system], methods=[MAS]) 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. sp.apodization.Exponential(FWHM="200 Hz"), # apodization of time domain signal. sp.FFT(), # forward FFT to convert time domain signal to frequency spectrum. sp.Scale(factor=3), # scale the frequency spectrum. ] ) processed_data = processor.apply_operations(data=sim.methods[0].simulation).real # %% # **Step 5:** The plot the spectrum. We also plot the synthetic dataset for comparison. plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm") ax.plot(synthetic_experiment, "k", linewidth=1, label="Experiment") ax.plot(processed_data, "r", alpha=0.75, linewidth=1, label="guess spectrum") ax.set_xlim(50, -200) plt.legend() plt.grid() plt.tight_layout()