def test_flatten(): npts = 10000 np.random.seed(12069424) lc = LightCurve( time=np.arange(npts), flux=np.random.normal(1, 0.1, npts), flux_err=np.zeros(npts) + 0.1, ) lc = lc.normalize() p = lc.to_periodogram(normalization="psd", freq_unit=1 / u.day) # Check method returns equal frequency assert all(p.flatten(method="logmedian").frequency == p.frequency) assert all(p.flatten(method="boxkernel").frequency == p.frequency) # Check logmedian flatten of white noise returns mean of ~unity assert np.isclose(np.mean(p.flatten(method="logmedian").power.value), 1.0, atol=0.05) # Check return trend works s, b = p.flatten(return_trend=True) assert all( b.power == p.smooth(method="logmedian", filter_width=0.01).power) assert all(s.power == p.flatten().power) str(s) s.plot() plt.close()
def test_periodogram_slicing(): """Tests whether periodograms can be sliced""" # Fake, noisy data lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) lc = lc.normalize() p = lc.to_periodogram() assert len(p[0:200].frequency) == 200 # Test divide orig = p.power.sum() p /= 2 assert np.sum(p.power) == orig / 2 # Test multiplication p *= 0 assert np.sum(p.power) == 0 # Test addition p += 100 assert np.all(p.power.value >= 100) # Test subtraction p -= 100 assert np.sum(p.power) == 0
def test_periodogram_normalization(): """Tests the normalization options""" lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, flux_unit="electron/second", ) # Test amplitude normalization and correct units pg = lc.to_periodogram(normalization="amplitude") assert pg.power.unit == u.electron / u.second pg = lc.normalize(unit="ppm").to_periodogram(normalization="amplitude") assert pg.power.unit == u.cds.ppm # Test PSD normalization and correct units pg = lc.to_periodogram(freq_unit=u.microhertz, normalization="psd") assert pg.power.unit == (u.electron / u.second)**2 / u.microhertz pg = lc.normalize(unit="ppm").to_periodogram(freq_unit=u.microhertz, normalization="psd") assert pg.power.unit == u.cds.ppm**2 / u.microhertz
def test_index(): """Test if you can mask out periodogram""" lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) lc = lc.normalize() p = lc.to_periodogram() mask = (p.frequency > 0.1 * (1 / u.day)) & (p.frequency < 0.2 * (1 / u.day)) assert len(p[mask].frequency) == mask.sum()
def test_periodogram_warnings(): """Tests if warnings are raised for non-normalized periodogram input""" lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) lc = lc.normalize(unit="ppm") # Test amplitude normalization and correct units pg = lc.to_periodogram(normalization="amplitude") assert pg.power.unit == u.cds.ppm pg = lc.to_periodogram(freq_unit=u.microhertz, normalization="psd") assert pg.power.unit == u.cds.ppm**2 / u.microhertz
def test_bin(): """Test if you can bin the periodogram.""" lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) lc = lc.normalize() p = lc.to_periodogram() assert len(p.bin(binsize=10, method="mean").frequency) == len(p.frequency) // 10 assert len(p.bin(binsize=10, method="median").frequency) == len(p.frequency) // 10
def test_periodogram_can_find_periods(): """Periodogram should recover the correct period""" # Light curve that is noisy lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) # Add a 100 day period signal lc.flux += np.sin( (lc.time.value / float(lc.time.value.max())) * 20 * np.pi) lc = lc.normalize() p = lc.to_periodogram(normalization="amplitude") assert np.isclose(p.period_at_max_power.value, 100, rtol=1e-3)
def test_assign_periods(): """Test if you can assign periods and frequencies.""" lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) periods = np.arange(1, 100) * u.day lc = lc.normalize() p = lc.to_periodogram(period=periods) # Get around the floating point error assert np.isclose(np.sum(periods - p.period).value, 0, rtol=1e-14) frequency = np.arange(1, 100) * u.Hz p = lc.to_periodogram(frequency=frequency) assert np.isclose(np.sum(frequency - p.frequency).value, 0, rtol=1e-14)
def test_periodogram_basics(): """Sanity check to verify that periodogram plotting works""" lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) lc = lc.normalize() pg = lc.to_periodogram() pg.plot() plt.close() pg.plot(view="period") plt.close() pg.show_properties() pg.to_table() str(pg) lc[400:500] = np.nan pg = lc.to_periodogram()
def test_smooth(): """Test if you can smooth the periodogram and check any pitfalls""" np.random.seed(42) lc = LightCurve( time=np.arange(1000), flux=np.random.normal(1, 0.1, 1000), flux_err=np.zeros(1000) + 0.1, ) lc = lc.normalize() p = lc.to_periodogram(normalization="psd", freq_unit=u.microhertz) # Test boxkernel and logmedian methods assert all(p.smooth(method="boxkernel").frequency == p.frequency) assert all(p.smooth(method="logmedian").frequency == p.frequency) # Check output units assert p.smooth().power.unit == p.power.unit # Check logmedian smooth that the mean of the smoothed power should # be consistent with the mean of the power assert np.isclose( np.mean(p.smooth(method="logmedian").power.value), np.mean(p.power.value), atol=0.05 * np.mean(p.power.value), ) # Can't pass filter_width below 0. with pytest.raises(ValueError) as err: p.smooth(method="boxkernel", filter_width=-5.0) # Can't pass a filter_width in the wrong units with pytest.raises(ValueError) as err: p.smooth(method="boxkernel", filter_width=5.0 * u.day) assert (err.value.args[0] == "the `filter_width` parameter must have frequency units.") # Can't (yet) use a periodogram with a non-evenly spaced frequencies with pytest.raises(ValueError) as err: p = np.arange(1, 100) p = lc.to_periodogram(period=p) p.smooth() # Check logmedian doesn't work if I give the filter width units with pytest.raises(ValueError) as err: p.smooth(method="logmedian", filter_width=5.0 * u.day)