def test_lc_keyword_deprecation(self): cs1 = AveragedPowerspectrum(self.lc, segment_size=self.lc.tseg) with pytest.warns(DeprecationWarning) as record: cs2 = AveragedPowerspectrum(lc=self.lc, segment_size=self.lc.tseg) assert np.any(['lc keyword' in r.message.args[0] for r in record]) assert np.allclose(cs1.power, cs2.power) assert np.allclose(cs1.freq, cs2.freq)
def test_common_mean_gives_comparable_scatter(self, norm): acs = AveragedPowerspectrum( self.events, dt=self.dt, silent=True, segment_size=self.segment_size, norm=norm, use_common_mean=False) acs_comm = AveragedPowerspectrum( self.events, dt=self.dt, silent=True, segment_size=self.segment_size, norm=norm, use_common_mean=True) assert np.isclose(acs_comm.power.std(), acs.power.std(), rtol=0.1)
def test_with_iterable_of_variable_length_lightcurves(self): gti = [[0, 0.05], [0.05, 0.5], [0.555, 1.0]] lc = copy.deepcopy(self.lc) lc.gti = gti lc_split = lc.split_by_gti() cs = AveragedPowerspectrum(lc_split, segment_size=0.05, norm="leahy", gti=lc.gti) cs_lc = AveragedPowerspectrum(lc, segment_size=0.05, norm="leahy", gti=lc.gti) for attr in ("power", "unnorm_power", "power_err", "unnorm_power_err", "freq"): assert np.allclose(getattr(cs, attr), getattr(cs_lc, attr)) for attr in ("m", "n", "norm"): assert getattr(cs, attr) == getattr(cs_lc, attr)
def test_legacy_equivalent(self): leahy_pds = AveragedPowerspectrum( self.lc, segment_size=self.segment_size, dt=self.dt, norm="leahy", silent=True, legacy=True) for attr in ["power", "unnorm_power"]: assert np.allclose( getattr(leahy_pds, attr), getattr(self.leahy_pds, attr))
def test_with_iterable_of_variable_length_lightcurves(self): gti = [[0, 0.05], [0.05, 0.5], [0.555, 1.0]] lc = copy.deepcopy(self.lc) lc.gti = gti lc_split = lc.split_by_gti() cs = AveragedPowerspectrum(lc_split, segment_size=0.05, norm="leahy")
def test_rebin_with_invalid_type_attribute(self): new_df = 2 aps = AveragedPowerspectrum(lc=self.lc1, segment_size=1, norm='leahy') aps.type = 'invalid_type' with pytest.raises(AttributeError): assert aps.rebin(df=new_df)
def test_rebin_log(self, df): # For now, just verify that it doesn't crash aps = AveragedPowerspectrum(self.lc, segment_size=1, norm="Leahy", dt=self.dt) bin_aps = aps.rebin_log(df)
def test_init_with_nonsense_segment(self, legacy): segment_size = "foo" with pytest.raises(TypeError): assert AveragedPowerspectrum(self.lc, segment_size, dt=self.dt, legacy=legacy)
def test_list_with_nonsense_component(self): n_lcs = 10 tstart = 0.0 tend = 1.0 dt = 0.0001 time = np.linspace(tstart, tend, int((tend - tstart) / dt)) mean_count_rate = 1000.0 mean_counts = mean_count_rate * dt lc_all = [] for n in range(n_lcs): poisson_counts = np.random.poisson(mean_counts, size=len(time)) lc = Lightcurve(time, counts=poisson_counts) lc_all.append(lc) lc_all.append(1.0) segment_size = 0.5 with pytest.raises(TypeError): assert AveragedPowerspectrum(lc_all, segment_size)
def test_fractional_rms_in_frac_norm_is_consistent_averaged(self): time = np.arange(0, 400, 1) + 0.5 poisson_counts = np.random.poisson(100.0, size=time.shape[0]) lc = Lightcurve(time, counts=poisson_counts, dt=1, gti=[[0, 400]]) ps = AveragedPowerspectrum(lc=lc, norm="leahy", segment_size=100) rms_ps_l, rms_err_l = ps.compute_rms(min_freq=ps.freq[1], max_freq=ps.freq[-1], white_noise_offset=0) ps = AveragedPowerspectrum(lc=lc, norm="frac", segment_size=100) rms_ps, rms_err = ps.compute_rms(min_freq=ps.freq[1], max_freq=ps.freq[-1], white_noise_offset=0) assert np.allclose(rms_ps, rms_ps_l, atol=0.01) assert np.allclose(rms_err, rms_err_l, atol=0.01)
def test_make_empty_periodogram(self): ps = AveragedPowerspectrum() assert ps.norm == "frac" assert ps.freq is None assert ps.power is None assert ps.power_err is None assert ps.df is None assert ps.m == 1 assert ps.n is None
def test_no_counts_warns(self): newlc = copy.deepcopy(self.lc) newlc.counts[:newlc.counts.size // 2] = \ 0 * newlc.counts[:newlc.counts.size // 2] with pytest.warns(UserWarning) as record: ps = AveragedPowerspectrum(newlc, 0.2) assert np.any(["No counts in " in r.message.args[0] for r in record])
def test_list_of_light_curves(self): n_lcs = 10 tstart = 0.0 tend = 1.0 dt = 0.0001 time = np.arange(tstart + 0.5 * dt, tend + 0.5 * dt, dt) mean_count_rate = 1000.0 mean_counts = mean_count_rate * dt lc_all = [] for n in range(n_lcs): poisson_counts = np.random.poisson(mean_counts, size=len(time)) lc = Lightcurve(time, counts=poisson_counts, gti=[[tstart, tend]], dt=dt) lc_all.append(lc) segment_size = 0.5 assert AveragedPowerspectrum(lc_all, segment_size) def rebin_several_averagedps(self, df): """ TODO: Not sure how to write tests for the rebin method! """ aps = AveragedPowerspectrum(lc=self.lc, segment_size=1, norm="Leahy") bin_aps = aps.rebin(df) assert np.isclose(bin_aps.freq[1] - bin_aps.freq[0], bin_aps.df, atol=1e-4, rtol=1e-4) assert np.isclose(bin_aps.freq[0], (aps.freq[0] - aps.df * 0.5 + bin_aps.df * 0.5), atol=1e-4, rtol=1e-4) def test_rebin_averagedps(self): df_all = [2, 3, 5, 1.5, 10, 45] for df in df_all: yield self.rebin_several, df def test_rebin_with_invalid_type_attribute(self): new_df = 2 aps = AveragedPowerspectrum(lc=self.lc, segment_size=1, norm='leahy') aps.type = 'invalid_type' with pytest.raises(AttributeError): assert aps.rebin(df=new_df)
def test_with_zero_counts(self): nbins = 100 x = np.linspace(0, 10, nbins) y0 = np.random.normal(loc=10, scale=0.5, size=int(0.4*nbins)) y1 = np.zeros(int(0.6*nbins)) y = np.hstack([y0, y1]) lc = Lightcurve(x, y) aps = AveragedPowerspectrum(lc, segment_size=5.0, norm="leahy") assert aps.m == 1
def test_rebin_factor(self, f): """ TODO: Not sure how to write tests for the rebin method! """ aps = AveragedPowerspectrum(self.lc, segment_size=1, norm="Leahy", dt=self.dt) bin_aps = aps.rebin(f=f) assert np.isclose(bin_aps.freq[1]-bin_aps.freq[0], bin_aps.df, atol=1e-4, rtol=1e-4) assert np.isclose(bin_aps.freq[0], (aps.freq[0]-aps.df*0.5+bin_aps.df*0.5), atol=1e-4, rtol=1e-4)
def test_leahy_correct_for_multiple(self): n = 100 lc_all = [] for i in range(n): time = np.arange(0.0, 10.0, 10./100000) counts = np.random.poisson(1000, size=time.shape[0]) lc = Lightcurve(time, counts) lc_all.append(lc) ps = AveragedPowerspectrum(lc_all, 10.0, norm="leahy") assert np.isclose(np.mean(ps.ps), 2.0, atol=1e-3, rtol=1e-3) assert np.isclose(np.std(ps.ps), 2.0/np.sqrt(n), atol=0.1, rtol=0.1)
def setup_class(cls): total_length = 10000 f_qpo = 1.5 cls.dt = 1 / f_qpo / 40 approx_Q = 10 q_len = approx_Q / f_qpo sigma = 0.1 astep = 0.01 phstep = 1 real_dphi = 0.4 * np.pi cls.n_seconds = 500 cls.n_seg = int(total_length / cls.n_seconds) cls.n_bins = cls.n_seconds / cls.dt times = np.arange(0, total_length, cls.dt) _, cls.ref_counts = fake_qpo(times, f0=f_qpo, astep=astep, rms=sigma, waveform=waveform_simple, phstep=phstep, timescale=q_len, waveform_opts={'dph': real_dphi}) _, ci_counts = fake_qpo(times, f0=f_qpo, astep=astep, rms=sigma, waveform=waveform_simple, phstep=phstep, timescale=q_len, waveform_opts={'dph': real_dphi}) cls.ci_counts = np.array([ci_counts]) cls.ref_times = np.arange(0, cls.n_seconds * cls.n_seg, cls.dt) cls.ref_lc = Lightcurve(cls.ref_times, cls.ref_counts, dt=cls.dt) ref_aps = AveragedPowerspectrum(cls.ref_lc, segment_size=cls.n_seconds, norm='abs') df = ref_aps.freq[1] - ref_aps.freq[0] amplitude_0 = np.max(ref_aps.power) x_0_0 = ref_aps.freq[np.argmax(ref_aps.power)] amplitude_1 = amplitude_0 / 2 x_0_1 = x_0_0 * 2 fwhm = df cls.model = models.Lorentz1D(amplitude=amplitude_0, x_0=x_0_0, fwhm=fwhm) + \ models.Lorentz1D(amplitude=amplitude_1, x_0=x_0_1, fwhm=fwhm) cls.ref_aps = ref_aps
def plot_pds(time, flux): ## 画光变曲线,即光子流量随时间的变化 ## lc = Lightcurve(time, flux) fig, ax = plt.subplots(1, 1, figsize=(10, 6)) ax.plot(lc.time, lc.counts, lw=2, color='blue') ax.set_xlabel("Time (s)", fontproperties=font1) ax.set_ylabel("Counts (cts)/bin", fontproperties=font1) ax.tick_params(axis='x', labelsize=16) ax.tick_params(axis='y', labelsize=16) ax.tick_params(which='major', width=1.5, length=7) ax.tick_params(which='minor', width=1.5, length=4) plt.show() ## 画功率谱图 ## ps = Powerspectrum(lc, norm='leahy') fig, ax1 = plt.subplots(1, 1, figsize=(9, 6), sharex=True) ax1.loglog() ax1.step(ps.freq, ps.power, lw=2, color='blue') ax1.set_ylabel("Frequency (Hz)", fontproperties=font1) ax1.set_ylabel("Power ", fontproperties=font1) ax1.set_yscale('log') ax1.tick_params(axis='x', labelsize=16) ax1.tick_params(axis='y', labelsize=16) ax1.tick_params(which='major', width=1.5, length=7) ax1.tick_params(which='minor', width=1.5, length=4) for axis in ['top', 'bottom', 'left', 'right']: ax1.spines[axis].set_linewidth(1.5) plt.show() ## 画average的功率谱,对于绝大多数的源不需要做这张图,除非所给的参考文献中有做average power density spectrum ### avg_ps = AveragedPowerspectrum(lc, 500, dt=lc.time[1] - lc.time[0], norm='leahy') print("Number of segments: %d" % avg_ps.m) fig, ax1 = plt.subplots(1, 1, figsize=(9, 6)) ax1.loglog() ax1.step(avg_ps.freq, avg_ps.power, lw=2, color='blue') ax1.set_xlabel("Frequency (Hz)", fontproperties=font1) ax1.set_ylabel("Power ", fontproperties=font1) ax1.set_yscale('log') ax1.tick_params(axis='x', labelsize=16) ax1.tick_params(axis='y', labelsize=16) ax1.tick_params(which='major', width=1.5, length=7) ax1.tick_params(which='minor', width=1.5, length=4) for axis in ['top', 'bottom', 'left', 'right']: ax1.spines[axis].set_linewidth(1.5) plt.show()
def rebin_several_averagedps(self, df): """ TODO: Not sure how to write tests for the rebin method! """ aps = AveragedPowerspectrum(lc=self.lc, segment_size=1, norm="Leahy") bin_aps = aps.rebin(df) assert np.isclose(bin_aps.freq[1] - bin_aps.freq[0], bin_aps.df, atol=1e-4, rtol=1e-4) assert np.isclose(bin_aps.freq[0], (aps.freq[0] - aps.df * 0.5 + bin_aps.df * 0.5), atol=1e-4, rtol=1e-4)
def test_leahy_correct_for_multiple(self, legacy, use_common_mean): n = 10 lc_all = [] for i in range(n): time = np.arange(0.0, 10.0, 10. / 10000) counts = np.random.poisson(1000, size=time.shape[0]) lc = Lightcurve(time, counts) lc_all.append(lc) ps = AveragedPowerspectrum(lc_all, 1.0, norm="leahy", legacy=legacy, use_common_mean=use_common_mean) assert ps.m == 100 assert np.isclose(np.mean(ps.power), 2.0, atol=1e-2, rtol=1e-2) assert np.isclose(np.std(ps.power), 2.0 / np.sqrt(ps.m), atol=0.1, rtol=0.1)
def setup_class(cls): tstart = 0.0 tend = 10.0 cls.dt = 0.0001 cls.segment_size = tend - tstart times = np.sort(np.random.uniform(tstart, tend, 1000)) gti = np.array([[tstart, tend]]) cls.events = EventList(times, gti=gti) cls.lc = cls.events cls.leahy_pds = AveragedPowerspectrum( cls.lc, segment_size=cls.segment_size, dt=cls.dt, norm="leahy", silent=True) cls.leahy_pds_sng = Powerspectrum( cls.lc, dt=cls.dt, norm="leahy")
def test_list_of_light_curves(self): n_lcs = 10 tstart = 0.0 tend = 1.0 dt = 0.0001 time = np.linspace(tstart, tend, int((tend - tstart) / dt)) mean_count_rate = 1000.0 mean_counts = mean_count_rate * dt lc_all = [] for n in range(n_lcs): poisson_counts = np.random.poisson(mean_counts, size=len(time)) lc = Lightcurve(time, counts=poisson_counts) lc_all.append(lc) segment_size = 0.5 assert AveragedPowerspectrum(lc_all, segment_size)
def powerspectrum(self, lc, seg_size=None): """ Make a powerspectrum of the simulated light curve. Parameters ---------- lc : lightcurve.Lightcurve object OR iterable of lightcurve.Lightcurve objects The light curve data to be Fourier-transformed. Returns ------- power : numpy.ndarray The array of normalized squared absolute values of Fourier amplitudes """ if seg_size is None: seg_size = lc.tseg return AveragedPowerspectrum(lc, seg_size).power
def test_with_iterable_of_lightcurves(self, legacy): def iter_lc(lc, n): "Generator of n parts of lc." t0 = int(len(lc) / n) t = t0 i = 0 while (True): lc_seg = lc[i:t] yield lc_seg if t + t0 > len(lc): break else: i, t = t, t + t0 with pytest.warns(UserWarning) as record: cs = AveragedPowerspectrum( iter_lc(self.lc, 1), segment_size=1, legacy=legacy, gti=self.lc.gti) message = "The averaged Power spectrum from a generator " assert np.any([message in r.message.args[0] for r in record])
def test_init_with_nan_segment(self): segment_size = np.nan with pytest.raises(ValueError): assert AveragedPowerspectrum(self.lc, segment_size)
def test_init_with_none_segment(self): segment_size = None with pytest.raises(TypeError): assert AveragedPowerspectrum(self.lc, segment_size)
def test_init_without_segment(self): with pytest.raises(TypeError): assert AveragedPowerspectrum(self.lc)
def test_segments_with_leftover(self): segment_size = self.lc.tseg / 2. - 1. ps = AveragedPowerspectrum(self.lc, segment_size) assert np.isclose(ps.segment_size, segment_size) assert ps.m == 2
def check_segment_size(self, nseg): segment_size = self.lc.tseg / nseg ps = AveragedPowerspectrum(self.lc, segment_size) assert ps.m == nseg
def test_one_segment(self): segment_size = self.lc.tseg ps = AveragedPowerspectrum(self.lc, segment_size) assert np.isclose(ps.segment_size, segment_size)