def test_unbalanced_lists(): isotopes = ["13C", "71Ga", "15N"] shifts = np.arange(10) error = ".*Each entry can either be a single item or a list of items.*" with pytest.raises(ValueError, match=error): single_site_system_generator(isotopes=isotopes, isotropic_chemical_shifts=shifts)
def test_sites_to_pandas_df(): isotopes = ["29Si"] * 3 + ["17O"] shifts = [-89.0, -89.5, -87.8, 15.0] zeta = [59.8, 52.1, 69.4, 12.4] eta_n = [0.62, 0.68, 0.6, 0.5] Cq = [None, None, None, 5.3e6] eta_q = [None, None, None, 0.34] spin_systems = single_site_system_generator( isotope=isotopes, isotropic_chemical_shift=shifts, shielding_symmetric={"zeta": zeta, "eta": eta_n}, quadrupolar={"Cq": Cq, "eta": eta_q}, abundance=1, ) sim = Simulator() sim.spin_systems = spin_systems pd_o = sim.sites().to_pd() assert list(pd_o["isotope"]) == isotopes assert list(pd_o["isotropic_chemical_shift"]) == [ f"{i} ppm" if i is not None else None for i in shifts ] assert list(pd_o["shielding_symmetric.zeta"]) == [ f"{i} ppm" if i is not None else None for i in zeta ] assert list(pd_o["shielding_symmetric.eta"]) == [ i if i is not None else None for i in eta_n ] assert list(pd_o["quadrupolar.Cq"]) == [ f"{i} Hz" if i is not None else None for i in Cq ]
def test_abundance_03(): Cq_dist = np.arange(10) eta_dist = np.ones(10) * 0.5 gamma = np.random.rand(10) abundances = [0] * 10 indexes = [2, 5, 8] for i in indexes: abundances[i] = 1 sys = single_site_system_generator( isotope="27Al", shielding_symmetric={"gamma": gamma}, quadrupolar={"Cq": Cq_dist, "eta": eta_dist}, abundance=abundances, ) assert len(sys) == 3 for i, j in enumerate(indexes): assert sys[i].sites[0].isotope.symbol == "27Al" assert sys[i].sites[0].isotropic_chemical_shift == 0 assert sys[i].sites[0].shielding_symmetric.zeta is None assert sys[i].sites[0].shielding_symmetric.eta is None assert sys[i].sites[0].shielding_symmetric.alpha is None assert sys[i].sites[0].shielding_symmetric.beta is None assert sys[i].sites[0].shielding_symmetric.gamma == gamma[j] assert sys[i].sites[0].quadrupolar.Cq == Cq_dist[j] assert sys[i].sites[0].quadrupolar.eta == eta_dist[j] assert sys[i].sites[0].quadrupolar.alpha is None assert sys[i].sites[0].quadrupolar.beta is None assert sys[i].sites[0].quadrupolar.gamma is None assert sys[i].abundance == abundances[j]
def test_quad_shield(): iso_dist = np.random.normal(0, 10, 10) zeta_dist = np.random.rand(10) eta_dist_s = np.random.rand(10) Cq_dist = np.random.rand(10) eta_dist_q = np.random.rand(10) gamma_dist = np.random.rand(10) * 3.1415 sys = single_site_system_generator( isotope="17O", isotropic_chemical_shift=iso_dist, shielding_symmetric={"zeta": zeta_dist, "eta": eta_dist_s}, quadrupolar={"Cq": Cq_dist, "eta": eta_dist_q, "gamma": gamma_dist}, ) for i in range(10): assert sys[i].sites[0].isotope.symbol == "17O" assert sys[i].sites[0].isotropic_chemical_shift == iso_dist[i] assert sys[i].sites[0].shielding_symmetric.zeta == zeta_dist[i] assert sys[i].sites[0].shielding_symmetric.eta == eta_dist_s[i] assert sys[i].sites[0].shielding_symmetric.alpha is None assert sys[i].sites[0].shielding_symmetric.beta is None assert sys[i].sites[0].shielding_symmetric.gamma is None assert sys[i].sites[0].quadrupolar.Cq == Cq_dist[i] assert sys[i].sites[0].quadrupolar.eta == eta_dist_q[i] assert sys[i].sites[0].quadrupolar.alpha is None assert sys[i].sites[0].quadrupolar.beta is None assert sys[i].sites[0].quadrupolar.gamma == gamma_dist[i]
def test_quad_01(): Cq_dist = np.arange(10) eta_dist = np.ones(10) * 0.5 sys = single_site_system_generator( isotope="27Al", quadrupolar={"Cq": Cq_dist, "eta": eta_dist} ) iso_dict = np.zeros(10) assertion_quad(sys, "27Al", iso_dict, Cq_dist, eta_dist, 0.1)
def test_shielding_01(): isotopes = ["13C", "71Ga", "15N", "14N", "27Al", "29Si", "1H", "17O", "33S", "31P"] sys = single_site_system_generator(isotope=isotopes) for i in range(10): assert sys[i].sites[0].isotope.symbol == isotopes[i] assert sys[i].sites[0].isotropic_chemical_shift == 0 assert sys[i].sites[0].shielding_symmetric is None assert sys[i].sites[0].quadrupolar is None
def test_abundance_02(): Cq_dist = np.arange(10) eta_dist = np.ones(10) * 0.5 abundances = np.zeros(10) sys = single_site_system_generator( isotope="27Al", quadrupolar={"Cq": Cq_dist, "eta": eta_dist}, abundance=abundances, ) assert sys == []
def test_unbalanced_lists(): isotopes = ["13C", "71Ga", "15N"] shifts = np.arange(10) error = ".*Not all arrays/lists passed were of the same length.*" with pytest.raises(ValueError, match=error): single_site_system_generator(isotope=isotopes, isotropic_chemical_shift=shifts) shielding = {"zeta": np.arange(10)} error = ".*Not all arrays/lists passed were of the same length.*" with pytest.raises(ValueError, match=error): single_site_system_generator(isotope=isotopes, shielding_symmetric=shielding) # Calling function directly assert _check_lengths_of_args(isotopes, [1, 2, 3], "foo") == 3 error = ".*Not all arrays/lists passed were of the same length.*" with pytest.raises(ValueError, match=error): _check_lengths_of_args(isotopes, shielding)
def test_shielding_02(): isotropics = np.arange(20) sys = single_site_system_generator(isotopes="71Ga", isotropic_chemical_shifts=isotropics) for i in range(20): assert sys[i].sites[0].isotope.symbol == "71Ga" assert sys[i].sites[0].isotropic_chemical_shift == isotropics[i] assert sys[i].sites[0].shielding_symmetric is None assert sys[i].sites[0].quadrupolar is None
def generate_spin_half_int_quad_spin_system(n=1000): iso = np.random.normal(loc=0.0, scale=10.0, size=n) Cq = np.random.normal(loc=5.0e6, scale=1e5, size=n) eta = np.random.normal(loc=0.1, scale=0.012, size=n) return single_site_system_generator( isotope="17O", isotropic_chemical_shift=iso, quadrupolar={ "Cq": Cq, "eta": eta }, )
def generate_spin_half_spin_system(n=1000): iso = np.random.normal(loc=0.0, scale=10.0, size=n) zeta = np.random.normal(loc=50.0, scale=15.12, size=n) eta = np.random.normal(loc=0.25, scale=0.012, size=n) return single_site_system_generator( isotope="29Si", isotropic_chemical_shift=iso, shielding_symmetric={ "zeta": zeta, "eta": eta }, )
def test_abundance_01(): Cq_dist = np.arange(10) eta_dist = np.ones(10) * 0.5 abundance = 0.6 sys = single_site_system_generator( isotopes="27Al", quadrupolar={ "Cq": Cq_dist, "eta": eta_dist }, abundance=abundance, ) iso_dict = np.zeros(10) assertion_quad(sys, "27Al", iso_dict, Cq_dist, eta_dist, 0.6)
def test_shielding_03(): zeta_dist = np.arange(10) eta_dist = np.ones(10) * 0.5 sys = single_site_system_generator( isotope="13C", shielding_symmetric={"zeta": zeta_dist, "eta": eta_dist} ) for i in range(10): assert sys[i].sites[0].isotope.symbol == "13C" assert sys[i].sites[0].isotropic_chemical_shift == 0 assert sys[i].sites[0].shielding_symmetric.zeta == zeta_dist[i] assert sys[i].sites[0].shielding_symmetric.eta == eta_dist[i] assert sys[i].sites[0].shielding_symmetric.alpha is None assert sys[i].sites[0].shielding_symmetric.beta is None assert sys[i].sites[0].shielding_symmetric.gamma is None assert sys[i].sites[0].quadrupolar is None
def test_quad_01(): Cq_dist = np.arange(10) eta_dist = np.ones(10) * 0.5 sys = single_site_system_generator( isotopes="27Al", quadrupolar={"Cq": Cq_dist, "eta": eta_dist} ) for i in range(10): assert sys[i].sites[0].isotope.symbol == "27Al" assert sys[i].sites[0].isotropic_chemical_shift == 0 assert sys[i].sites[0].shielding_symmetric is None assert sys[i].sites[0].quadrupolar.Cq == Cq_dist[i] assert sys[i].sites[0].quadrupolar.eta == eta_dist[i] assert sys[i].sites[0].quadrupolar.alpha is None assert sys[i].sites[0].quadrupolar.beta is None assert sys[i].sites[0].quadrupolar.gamma is None
def test_shielding_05(): iso_dist = np.random.normal(0, 10, 10) zeta_dist = np.arange(10) eta_dist = np.random.rand(10) gamma_dist = np.random.rand(10) * 3.1415 sys = single_site_system_generator( isotopes="13C", isotropic_chemical_shifts=iso_dist, shielding_symmetric={"zeta": zeta_dist, "eta": eta_dist, "gamma": gamma_dist}, ) for i in range(10): assert sys[i].sites[0].isotope.symbol == "13C" assert sys[i].sites[0].isotropic_chemical_shift == iso_dist[i] assert sys[i].sites[0].shielding_symmetric.zeta == zeta_dist[i] assert sys[i].sites[0].shielding_symmetric.eta == eta_dist[i] assert sys[i].sites[0].shielding_symmetric.alpha is None assert sys[i].sites[0].shielding_symmetric.beta is None assert sys[i].sites[0].shielding_symmetric.gamma == gamma_dist[i] assert sys[i].sites[0].quadrupolar is None
def generate_spin_half_int_csa_quad_spin_system(n=1000): iso = np.random.normal(loc=0.0, scale=10.0, size=n) zeta = np.random.normal(loc=150, scale=20, size=n) eta_z = np.random.normal(loc=0.3, scale=0.012, size=n) Cq = np.random.normal(loc=5.0e6, scale=5e5, size=n) eta_q = np.random.normal(loc=0.6, scale=0.02, size=n) beta = np.random.normal(loc=2.12, scale=0.1, size=n) return single_site_system_generator( isotope="17O", isotropic_chemical_shift=iso, shielding_symmetric={ "zeta": zeta, "eta": eta_z }, quadrupolar={ "Cq": Cq, "eta": eta_q, "beta": beta }, )
def test_shielding_06(): iso_dist = np.random.normal(0, 10, 10) zeta_dist = np.arange(10) alpha_dist = np.random.rand(10) beta_dist = np.random.rand(10) * 3.1415 sys = single_site_system_generator( isotope="13C", isotropic_chemical_shift=iso_dist, shielding_antisymmetric={ "zeta": zeta_dist, "alpha": alpha_dist, "beta": beta_dist, }, ) for i in range(10): assert sys[i].sites[0].isotope.symbol == "13C" assert sys[i].sites[0].isotropic_chemical_shift == iso_dist[i] assert sys[i].sites[0].shielding_antisymmetric.zeta == zeta_dist[i] assert sys[i].sites[0].shielding_antisymmetric.alpha == alpha_dist[i] assert sys[i].sites[0].shielding_antisymmetric.beta == beta_dist[i] assert sys[i].sites[0].quadrupolar is None
# %% # The following is the plot of the extended Czjzek distribution. plt.figure(figsize=(4.25, 3.0)) plt.contourf(z_dist, e_dist, amp, levels=10) plt.xlabel(r"$\zeta$ / ppm") plt.ylabel(r"$\eta$") plt.tight_layout() plt.show() # %% # Simulate the spectrum # ''''''''''''''''''''' # # Create the spin systems from the above :math:`\zeta` and :math:`\eta` parameters. systems = single_site_system_generator( isotope="13C", shielding_symmetric={"zeta": z_dist, "eta": e_dist}, abundance=amp ) print(len(systems)) # %% # Create a simulator object and add the above system. sim = Simulator() sim.spin_systems = systems # add the systems sim.methods = [BlochDecaySpectrum(channels=["13C"])] # add the method sim.run() # %% # The following is the static spectrum arising from a Czjzek distribution of the # second-rank traceless shielding tensors. plt.figure(figsize=(4.25, 3.0)) ax = plt.subplot(projection="csdm")
ax[2].contourf(eta_r, Cq_r, pdf.sum(axis=0)) ax[2].set_xlabel(r"quadrupolar asymmetry, $\eta$") ax[2].set_ylabel("Cq / MHz") plt.tight_layout() plt.show() # %% # Simulation setup # ---------------- # Let's create the site and spin system objects from these parameters. Use the # :func:`~mrsimulator.utils.collection.single_site_system_generator` utility function to # generate single-site spin systems. spin_systems = single_site_system_generator( isotope="27Al", isotropic_chemical_shift=iso, quadrupolar={"Cq": Cq * 1e6, "eta": eta}, # Cq in Hz abundance=pdf, ) len(spin_systems) # %% # Simulate a :math:`^{27}\text{Al}` 3Q-MAS spectrum by using the `ThreeQ_MAS` method. mqvas = ThreeQ_VAS( channels=["27Al"], spectral_dimensions=[ dict( count=512, spectral_width=26718.475776, # in Hz reference_offset=-4174.76184, # in Hz label="Isotropic dimension", ),
# %% # Create a fitting model # ---------------------- # **Guess model** # # Create a guess list of spin systems. shifts = [120, 128, 135, 175, 55, 25] # in ppm zeta = [-70, -65, -60, -60, -10, -10] # in ppm eta = [0.8, 0.4, 0.9, 0.3, 0.0, 0.0] spin_systems = single_site_system_generator( isotope="13C", isotropic_chemical_shift=shifts, shielding_symmetric={"zeta": zeta, "eta": eta}, abundance=100 / 6, ) # %% # **Method** # # Create the SSB2D method. # Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(mat_dataset) PASS = SSB2D( channels=["13C"], magnetic_flux_density=9.395, # in T rotor_frequency=1500, # in Hz
# ---------------------- # **Guess model** # # Create a guess list of spin systems. shifts = [29, 39, 54.8, 51, 56] # in ppm Cq = [6.1e6, 5.4e6, 5.5e6, 5.5e6, 5.1e6] # in Hz eta = [0.1, 0.2, 0.15, 0.15, 0.3] abundance_ratio = [1, 1, 2, 2, 2] abundance = np.asarray(abundance_ratio) / 8 * 100 # in % spin_systems = single_site_system_generator( isotope="17O", isotropic_chemical_shift=shifts, quadrupolar={ "Cq": Cq, "eta": eta }, abundance=abundance, ) # %% # **Method** # # Create the DAS method. # Get the spectral dimension parameters from the experiment. spectral_dims = get_spectral_dimensions(experiment) DAS = Method( channels=["17O"],
plt.show() # %% # Create the Simulator object # --------------------------- # # **Spin system:** # # Let's create the sites and single-site spin system objects from these parameters. # Use the :func:`~mrsimulator.utils.collection.single_site_system_generator` utility # function to generate single-site spin systems. # Here, ``iso``, ``zeta``, and ``eta`` # are the array of tensor parameter coordinates, and ``pdf`` is the array of the # corresponding amplitudes. spin_systems = single_site_system_generator( 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 ], )