def nspinspec_dense(freqs, couplings, normalize=True): """ Calculates second-order spectral data (freqency and intensity of signals) for *n* spin-half nuclei. Parameters --------- freqs : [float...] a list of *n* nuclei frequencies in Hz couplings : array-like an *n, n* array of couplings in Hz. The order of nuclei in the list corresponds to the column and row order in the matrix, e.g. couplings[0][1] and [1]0] are the J coupling between the nuclei of freqs[0] and freqs[1]. normalize: bool True if the intensities should be normalized so that total intensity equals the total number of nuclei. Returns ------- spectrum : [[float, float]...] numpy 2D array of [frequency, intensity] pairs. """ nspins = len(freqs) H = hamiltonian_dense(freqs, couplings) E, V = np.linalg.eigh(H) V = V.real T = transition_matrix_dense(nspins) I = np.square(V.T.dot(T.dot(V))) spectrum = new_compile_spectrum(I, E) if normalize: spectrum = normalize_spectrum(spectrum, nspins) return spectrum
def nspinspec_sparse(freqs, couplings, normalize=True): """ Calculates second-order spectral data (freqency and intensity of signals) for *n* spin-half nuclei. Parameters --------- freqs : [float...] a list of *n* nuclei frequencies in Hz couplings : array-like an *n, n* array of couplings in Hz. The order of nuclei in the list corresponds to the column and row order in the matrix, e.g. couplings[0][1] and [1]0] are the J coupling between the nuclei of freqs[0] and freqs[1]. normalize: bool True if the intensities should be normalized so that total intensity equals the total number of nuclei. Returns ------- spectrum : [[float, float]...] numpy 2D array of [frequency, intensity] pairs. """ nspins = len(freqs) H = hamiltonian_sparse(freqs, couplings) spectrum = vectorized_simsignals(H.todense(), nspins) if normalize: spectrum = normalize_spectrum(spectrum, nspins) return spectrum
def test_ABX3(): from .windnmr_defaults import ABX3dict refspec = ([(124.2804555427071, 0.04365107831800394), (131.2804555427071, 0.13095323495401182), (136.2804555427071, 0.20634892168199606), (138.2804555427071, 0.13095323495401182), (142.7195444572929, 0.20634892168199606), (143.2804555427071, 0.6190467650459882), (145.2804555427071, 0.04365107831800394), (149.7195444572929, 0.6190467650459882), (150.2804555427071, 0.6190467650459882), (154.7195444572929, 0.04365107831800394), (156.7195444572929, 0.6190467650459882), (157.2804555427071, 0.20634892168199606), (161.7195444572929, 0.13095323495401182), (163.7195444572929, 0.20634892168199606), (168.7195444572929, 0.13095323495401182), (175.7195444572929, 0.04365107831800394)]) testspec = sorted(ABX3(**ABX3dict, normalize=True)) # refspec appropriate if normalize=False, but want to cover all code, so sum_intensities = sum([y for x, y in refspec]) print('target total intensity is: ', sum_intensities) # 4 testspec = normalize_spectrum(testspec, sum_intensities) np.testing.assert_array_almost_equal(testspec, refspec, decimal=2)
def ABX3(Jab, Jax, Jbx, Vab, Vcentr, normalize=True): """ Simulation of the AB part of an ABX3 spin system. TODO: explain simplification Parameters --------- Jab : float the Ha-Hb coupling constant (Hz). Jax : float the Ha-Hb coupling constant (Hz). Jbx : float the Ha-Hb coupling constant (Hz). Vab : float the difference in the frequencies (Hz) of Ha and Hb in the absence of coupling. Vcentr : float the frequency (Hz) for the center of the AB2 signal. normalize: bool whether the signal intensity should be normalized. Returns ------- [(float, float)...] a list of (frequency, intensity) tuples. """ # Refactoring of Reich's code for simulating the ABX3 system. va = Vcentr - Vab / 2 vb = Vcentr + Vab / 2 a_quartet = first_order((va, 1), [(Jax, 3)]) b_quartet = first_order((vb, 1), [(Jbx, 3)]) res = [] for i in range(4): dv = b_quartet[i][0] - a_quartet[i][0] abcenter = (b_quartet[i][0] + a_quartet[i][0]) / 2 sub_abq = AB(Jab, dv, abcenter, normalize) # Wa, RightHz, WdthHz not # implemented scale_factor = a_quartet[i][1] scaled_sub_abq = [(v, i * scale_factor) for v, i in sub_abq] res.extend(scaled_sub_abq) if normalize: normalize_spectrum(res, 5) # TODO: check this factor return res
def test_AAXX(): from .windnmr_defaults import AAXXdict refspec = sorted([(173.0, 2), (127.0, 2), (169.6828402774396, 0.4272530047525843), (164.6828402774396, 0.5727469952474157), (135.3171597225604, 0.5727469952474157), (130.3171597225604, 0.4272530047525843), (183.6009478460092, 0.20380477476124093), (158.6009478460092, 0.7961952252387591), (141.3990521539908, 0.7961952252387591), (116.39905215399081, 0.20380477476124093)]) testspec = sorted(AAXX(**AAXXdict, normalize=True)) # refspec appropriate if normalize=False, but want to cover all code, so sum_intensities = sum([y for x, y in refspec]) print('target total intensity is: ', sum_intensities) # 8 testspec = normalize_spectrum(testspec, sum_intensities) np.testing.assert_array_almost_equal(testspec, refspec, decimal=2)
def test_AB(): from .windnmr_defaults import ABdict refspec = [(134.39531364385073, 0.3753049524455757), (146.39531364385073, 1.6246950475544244), (153.60468635614927, 1.6246950475544244), (165.60468635614927, 0.3753049524455757)] refspec_normalized = normalize_spectrum(refspec, 2) print('ref normalized:') print(refspec_normalized) print(sum([y for x, y in refspec_normalized])) print(sum(refspec_normalized[1])) testspec = AB(**ABdict) print('testspec:') print(testspec) print(sum([y for x, y in testspec])) np.testing.assert_array_almost_equal(testspec, refspec_normalized, decimal=2)
def test_AB2(): from .windnmr_defaults import dcp refspec = [(-8.892448165479056, 0.5434685012269458), (-2.300397938882746, 0.7780710767178313), (0.0, 1), (6.59205022659631, 1.6798068052995172), (22.865501607924635, 2.6784604220552235), (23.542448165479055, 2.4565314987730544), (30.134498392075365, 1.5421221179826525), (31.75794977340369, 1.3201931947004837), (55.300397938882746, 0.001346383244293953)] refspec = normalize_spectrum(refspec, 3) print('ref normalized;') print(refspec) print(sum([y for x, y in refspec])) testspec = sorted(AB2(**dcp)) # testspec.sort() print('testspec:') print(testspec) print(sum([y for x, y in testspec])) np.testing.assert_array_almost_equal(sorted(testspec), refspec, decimal=2)
def test_ABX(): from .windnmr_defaults import ABXdict refspec = sorted([(-9.48528137423857, 0.2928932188134524), (-6.816653826391969, 0.44529980377477096), (2.5147186257614305, 1.7071067811865475), (5.183346173608031, 1.554700196225229), (7.4852813742385695, 1.7071067811865475), (14.816653826391969, 1.554700196225229), (19.485281374238568, 0.2928932188134524), (26.81665382639197, 0.44529980377477096), (95.0, 1), (102.3313724521534, 0.9902903378454601), (97.6686275478466, 0.9902903378454601), (105.0, 1), (80.69806479936946, 0.009709662154539944), (119.30193520063054, 0.009709662154539944)]) refspec = normalize_spectrum(refspec, 3) print('ref normalized;') print(refspec) print(sum([y for x, y in refspec])) testspec = sorted(ABX(**ABXdict)) print('testspec:') print(testspec) print(sum([y for x, y in testspec])) np.testing.assert_array_almost_equal(testspec, refspec, decimal=2)
def test_normalize_spectrum(): unnormalized = [(1200.0, 1.0), (500.0, 2.0)] expected = [(1200.0, 2.0), (500.0, 4.0)] result = normalize_spectrum(unnormalized, n=6) assert np.allclose(result, expected)
def test_convert_refspec(): refspec = [(1, 1), (2, 3), (3, 3), (4, 1)] new_refspec = normalize_spectrum(refspec, 2) print(sum([y for x, y in new_refspec])) assert new_refspec == [(1, 0.25), (2, 0.75), (3, 0.75), (4, 0.25)]