def test_fraction(): warning = ("The fraction attribute of each SpectralEvent in a " "SpectralDimension should sum to 1. Sum is 1.5") with pytest.warns(UserWarning, match=f".*{warning}.*"): SpectralDimension(events=[ SpectralEvent(fraction=0.5), SpectralEvent(fraction=0.5), SpectralEvent(fraction=0.5), ])
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)
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 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)
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), ], ) ], )
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) ], ) ], )
method = Method( name="Inner Satellite Spectrum", channels=["27Al"], magnetic_flux_density=21.14, # in T rotor_frequency=np.inf, # in Hz rotor_angle=54.7356 * np.pi / 180, # in rads spectral_dimensions=[ SpectralDimension( count=1024, spectral_width=1e4, # in Hz reference_offset=1e4, # in Hz events=[ SpectralEvent(transition_queries=[ { "ch1": { "P": [-1], "D": [2] } }, # inner satellite ]) ], ) ], ) # A graphical representation of the method object. plt.figure(figsize=(4, 2.5)) method.plot() plt.show() # %% # Create the Simulator object and add the method and the spin system object.
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)
# 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": { "P": [-1], "D": [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",
# the two SpectralEvent. A MixingEvent does not directly contribute to the frequencies. # As the name suggests, a mixing event is used for the mixing of transitions in a # multi-event method such as HahnEcho. In the following code, we define a mixing query # on channel-1 by setting the attributes ``tip_angle`` and ``phase`` to :math:`\pi` and # 0, respectively. There two parameters are analogous to the pulse angle and phase. 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] } }]), ], )
# Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(experiment) DAS = Method( channels=["17O"], magnetic_flux_density=11.744, # in T 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] } }], ),
# 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, transition_query=[{
# 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]}}], ) ],
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=[{
method = Method( name="Arbitrary Transition Method", channels=["27Al"], magnetic_flux_density=21.14, # in T rotor_frequency=np.inf, # in Hz rotor_angle=54.7356 * np.pi / 180, # in rads spectral_dimensions=[ SpectralDimension( count=1024, spectral_width=5e3, # in Hz reference_offset=2.5e4, # in Hz events=[ SpectralEvent( # symmetric triple quantum transitions transition_queries=[{ "ch1": { "P": [-3], "D": [0] } }]), ], ) ], ) # A graphical representation of the method object. plt.figure(figsize=(4, 2.5)) method.plot() plt.show() # %% # Create the Simulator object and add the method and the spin system object.
# Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(experiment) shifting_d = Method2D( channels=["2H"], magnetic_flux_density=9.395, # in T spectral_dimensions=[ SpectralDimension( **spectral_dims[0], label="Quadrupolar frequency", events=[ SpectralEvent( rotor_frequency=0, transition_query=[{ "ch1": { "P": [-1] } }], freq_contrib=["Quad1_2"], ) ], ), SpectralDimension( **spectral_dims[1], label="Paramagnetic shift", events=[ SpectralEvent( rotor_frequency=0, transition_query=[{ "ch1": { "P": [-1]
spectral_dims = get_spectral_dimensions(experiment) shifting_d = Method( channels=["2H"], magnetic_flux_density=9.395, # in T rotor_frequency=0, # in Hz rotor_angle=0, # in rads spectral_dimensions=[ SpectralDimension( **spectral_dims[0], label="Quadrupolar frequency", events=[ SpectralEvent( transition_queries=[{ "ch1": { "P": [-1] } }], freq_contrib=["Quad1_2"], ), MixingEvent(query="NoMixing"), ], ), SpectralDimension( **spectral_dims[1], label="Paramagnetic shift", events=[ SpectralEvent( transition_queries=[{ "ch1": { "P": [-1] }
def test_spectral_dimension(): # test-1 single event spectral dimensions # parse dict with units event_dictionary = { "fraction": 1, "freq_contrib": freq_default, "magnetic_flux_density": "9.6 T", "rotor_frequency": "1 kHz", "rotor_angle": "54.735 deg", } dimension_dictionary = { "count": 1024, "spectral_width": "100 Hz", "reference_offset": "0 GHz", "events": [event_dictionary], } the_dimension = SpectralDimension.parse_dict_with_units( dimension_dictionary) basic_spectral_dimension_tests(the_dimension) # direct initialization the_dimension = SpectralDimension( count=1024, spectral_width=100, events=[SpectralEvent.parse_dict_with_units(event_dictionary)], ) basic_spectral_dimension_tests(the_dimension) # test-2: two event spectral dimension # parse dict with units event_dictionary = { "fraction": 0.5, "freq_contrib": freq_default, "magnetic_flux_density": "9.6 T", "rotor_frequency": "1 kHz", "rotor_angle": "54.735 deg", } dimension_dictionary = { "count": 1024, "spectral_width": "100 Hz", "reference_offset": "0 GHz", "events": [event_dictionary, event_dictionary], } the_dimension = SpectralDimension.parse_dict_with_units( dimension_dictionary) # direct initialization the_dimension2 = SpectralDimension( count=1024, spectral_width=100, events=[ SpectralEvent.parse_dict_with_units(event_dictionary) for _ in range(2) ], ) # json() should_be = dict( count=1024, spectral_width="100.0 Hz", events=[ { "fraction": 0.5, "magnetic_flux_density": "9.6 T", "rotor_angle": "0.9553059660790962 rad", "rotor_frequency": "1000.0 Hz", "transition_queries": [{ "ch1": { "P": [0] } }], }, { "fraction": 0.5, "magnetic_flux_density": "9.6 T", "rotor_angle": "0.9553059660790962 rad", "rotor_frequency": "1000.0 Hz", "transition_queries": [{ "ch1": { "P": [0] } }], }, ], ) assert the_dimension.json() == should_be assert the_dimension2.json() == should_be # json(units=False) json_no_unit = dict( count=1024, spectral_width=100.0, events=[ { "fraction": 0.5, # "freq_contrib": freq_default, "magnetic_flux_density": 9.6, "rotor_angle": 0.9553059660790962, "rotor_frequency": 1000.0, "transition_queries": [{ "ch1": { "P": [0] } }], }, { "fraction": 0.5, # "freq_contrib": freq_default, "magnetic_flux_density": 9.6, "rotor_angle": 0.9553059660790962, "rotor_frequency": 1000.0, "transition_queries": [{ "ch1": { "P": [0] } }], }, ], ) assert the_dimension.json(units=False) == json_no_unit assert the_dimension2.json(units=False) == json_no_unit
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, Method1D]: 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): Method2D( 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): Method( channels=["27Al"], rotor_frequency=np.inf, spectral_dimensions=[ SpectralDimension(events=[ SpectralEvent(fraction=0.5, rotor_frequency=0.1), SpectralEvent(fraction=0.5, rotor_frequency=456), ]) ], )
# satellite transition. method = Method1D( name="Inner Satellite Spectrum", channels=["27Al"], magnetic_flux_density=21.14, # in T rotor_frequency=1e9, # in Hz spectral_dimensions=[ SpectralDimension( count=1024, spectral_width=1e4, # in Hz reference_offset=1e4, # in Hz events=[ SpectralEvent( # Selecting the inner satellite transitions transition_query=[{ "ch1": { "P": [-1], "D": [2] } }], ) ], ) ], ) # A graphical representation of the method object. plt.figure(figsize=(5, 3)) method.plot() plt.show() # %% # Create the Simulator object and add the method and the spin system object.