def test_interp(): spec = np.array([[20, 0.5], [50, 1.0]]) freq = [15, 35, 60] psdlinear = psd.interp(spec, freq, linear=True).ravel() psdlog = psd.interp(spec, freq, linear=False).ravel() assert np.allclose(psdlinear, [0, 0.75, 0]) assert np.allclose(psdlog, [0, 0.76352135927358911, 0])
def test_interp_nans(): Freq = np.arange(1, 10, 2) freq = np.arange(1, 10) PSD = (Freq**2) / 100 nan = [np.nan, np.nan] Freq = np.hstack((Freq, nan)) PSD = np.hstack((PSD, nan)) plog = (freq**2) / 100 plog2 = psd.interp((Freq, PSD), freq, linear=False) assert np.allclose(plog, plog2)
def test_area(): spec = np.array([ [20, 0.0053, 0.01], [150, 0.04, 0.04], [600, 0.04, 0.04], [2000, 0.0036, 0.04 * 600 / 2000], ]) # the last value is to trigger the s == -1 logic in area spec2 = spec[:, 1:] f2 = spec[:, 0] areas = psd.area(spec) areas2 = psd.area((f2, spec2)) fi = np.arange(200, 20001) * 0.1 pi = psd.interp(spec, fi, linear=False) areas3 = np.trapz(pi, fi, axis=0) assert np.allclose(areas, areas2) assert np.allclose(areas, areas3) s1 = spec[:, :2] assert np.all(psd.area(s1) == psd.area((*s1.T, )))
def test_psd2time(): spec = np.array([[20, 0.0768], [50, 0.48], [100, 0.48]]) sig, sr = psd.psd2time(spec, ppc=10, fstart=35, fstop=70, df=0.01, winends=dict(portion=0.01)) # ensure that expand_method works: sig2, sr2 = psd.psd2time( spec, ppc=10, fstart=35, fstop=70, df=0.01, winends=dict(portion=0.01), expand_method="rescale", ) f1, p1 = psd.psdmod(sig, sr, timeslice=f"{len(sig)}") f2, p2 = psd.psdmod(sig2, sr2, timeslice=f"{len(sig)}") assert np.trapz(p1, f1) < np.trapz(p2, f2) assert_raises( ValueError, psd.psd2time, spec, ppc=10, fstart=35, fstop=70, df=0.01, winends=dict(portion=0.01), expand_method="bad expand method", ) assert np.allclose(700.0, sr) # 70*10 assert sig.size == 700 * 100 f, p = signal.welch(sig, sr, nperseg=sr) pv = np.logical_and(f >= 37, f <= 68) fi = f[pv] psdi = p[pv] speci = psd.interp(spec, fi).flatten() assert abs(speci - psdi).max() < 0.05 assert abs(np.trapz(psdi, fi) - np.trapz(speci, fi)) < 0.25 spec = ([0.1, 5], [0.1, 0.1]) sig, sr = psd.psd2time(spec, ppc=10, fstart=0.1, fstop=5, df=0.2, winends=dict(portion=0.01)) # df gets internally reset to fstart assert np.allclose(5 * 10.0, sr) assert sig.size == 50 * 10 f, p = signal.welch(sig, sr, nperseg=sr) pv = np.logical_and(f >= 0.5, f <= 3.0) fi = f[pv] psdi = p[pv] speci = psd.interp(spec, fi).flatten() assert abs(speci - psdi).max() < 0.05 assert abs(np.trapz(psdi, fi) - np.trapz(speci, fi)) < 0.065 # ppc gets reset to 2 case: spec = np.array([[0.1, 2.0], [5, 2.0]]) sig, sr = psd.psd2time(spec, ppc=1, fstart=0.1, fstop=5, df=0.2, winends=dict(portion=0.01)) assert (np.sum(np.mean(sig**2)) - 2.0 * 4.9) / (2.0 * 4.9) < 0.1 # odd length FFT case: spec = np.array([[0.1, 2.0], [5, 2.0]]) sig, sr, t = psd.psd2time(spec, ppc=3, fstart=0.2, fstop=5, df=0.2, winends=dict(portion=0.01), gettime=1) assert np.allclose(5 * 3, sr) assert sig.size == 15 * 5 assert (np.sum(np.mean(sig**2)) - 2.0 * 4.8) / (2.0 * 4.8) < 0.1 assert np.allclose(t, np.arange(15 * 5) / sr)