def test_residuals_wideband_chi2(wideband_fake): toas, model = wideband_fake r = WidebandTOAResiduals(toas, model) rn = Residuals(toas, model) f = WidebandTOAFitter(toas, model) assert_allclose(f.fit_toas(), r.chi2) assert f.fit_toas() >= rn.chi2
def wb(): m = get_model(join(datadir, "NGC6440E.par")) t = make_fake_toas(55000, 58000, 20, model=m, freq=1400 * u.MHz, dm=10 * pint.dmu) wb = WidebandTOAFitter(t, m) wb.fit_toas() return wb
def test_wideband_chi2_null_updating(wideband_fake): toas, model = wideband_fake model.free_params = ["F0"] f = WidebandTOAFitter(toas, model) assert abs(f.fit_toas() - WidebandTOAResiduals(toas, model).chi2) > 1 c2 = WidebandTOAResiduals(toas, f.model).chi2 assert_allclose(f.fit_toas(), c2) c2 = WidebandTOAResiduals(toas, f.model).chi2 assert_allclose(f.fit_toas(), c2)
def test_noise_design_matrix_index(self): model = get_model("B1855+09_NANOGrav_12yv3.wb.gls.par") toas = get_TOAs("B1855+09_NANOGrav_12yv3.wb.tim", ephem="DE436", bipm_version="BIPM2015") fitter = WidebandTOAFitter(toas, model, additional_args={}) fitter.fit_toas(full_cov=False, debug=True) # Test red noise basis pl_rd = fitter.model.pl_rn_basis_weight_pair(fitter.toas)[0] p0, p1 = fitter.resids.pl_red_noise_M_index pl_rd_backwards = (fitter.resids.pl_red_noise_M[0] * fitter.resids.norm[p0:p1][np.newaxis, :]) assert np.all(np.isclose(pl_rd, pl_rd_backwards[0:313, :]))
def calc_chi2(self, full_cov=False): """Return the weighted chi-squared for the model and toas. If the errors on the TOAs are independent this is a straightforward calculation, but if the noise model introduces correlated errors then obtaining a meaningful chi-squared value requires a Cholesky decomposition. This is carried out, here, by constructing a GLSFitter and asking it to do the chi-squared computation but not a fit. The return value here is available as self.chi2, which will not redo the computation unless necessary. The chi-squared value calculated here is suitable for use in downhill minimization algorithms and Bayesian approaches. Handling of problematic results - degenerate conditions explored by a minimizer for example - may need to be checked to confirm that they correctly return infinity. """ # Use GLS but don't actually fit from pint.fitter import WidebandTOAFitter m = copy.deepcopy(self.model) m.free_params = [] f = WidebandTOAFitter( self.toas, m, additional_args=dict(toa=dict(track_mode=self.toa.track_mode)) ) try: return f.fit_toas(maxiter=1, full_cov=full_cov) except LinAlgError as e: log.warning( "Degenerate conditions encountered when " "computing chi-squared: %s" % (e,) ) return np.inf
def test_wideband_chi2_updating(wideband_fake): toas, model = wideband_fake model.free_params = ["F0"] model.F0.value += 1e-6 c2 = WidebandTOAResiduals( toas, model, toa_resid_args=dict(track_mode="use_pulse_numbers") ).chi2 f2 = WidebandTOAFitter( toas, model, additional_args=dict(toa=dict(track_mode="use_pulse_numbers")) ) ftc2 = f2.fit_toas() assert abs(ftc2 - c2) > 100 assert_allclose(f2.model.F0.value, 1) assert 1e-3 > abs(WidebandTOAResiduals(toas, f2.model).chi2 - ftc2) > 1e-5 ftc2 = f2.fit_toas(maxiter=10) assert_allclose(WidebandTOAResiduals(toas, f2.model).chi2, ftc2)
def test_fitting_no_full_cov(self): fitter = WidebandTOAFitter([self.toas], self.model, additional_args={}) time_rms_pre = fitter.resids_init.toa.rms_weighted() dm_rms_pre = fitter.resids_init.dm.rms_weighted() fitter.fit_toas() dm_rms_post = fitter.resids.dm.rms_weighted() prefit_pint = fitter.resids_init.toa.time_resids prefit_tempo = self.tempo_res[:, 0] * u.us diff_prefit = (prefit_pint - prefit_tempo).to(u.ns) # 50 ns is the difference of PINT tempo precession and nautation model. assert np.abs(diff_prefit - diff_prefit.mean()).max() < 50 * u.ns postfit_pint = fitter.resids.toa.time_resids postfit_tempo = self.tempo_res[:, 1] * u.us diff_postfit = (postfit_pint - postfit_tempo).to(u.ns) assert np.abs(diff_postfit - diff_postfit.mean()).max() < 50 * u.ns assert np.abs(dm_rms_pre - dm_rms_post) < 3e-8 * dm_rms_pre.unit
def test_wideband_fit_dmjump_all(wb_model, wb_toas_all): wb_model.free_params = ["DMJUMP1"] fitter = WidebandTOAFitter(wb_toas_all, wb_model) fitter.fit_toas() print(fitter.print_summary()) assert_allclose(fitter.model.DMJUMP1.value, -10, atol=1e-3)
def test_wideband_fit_dmjump(wb_model, wb_toas): wb_model.free_params = ["DMJUMP1"] fitter = WidebandTOAFitter(wb_toas, wb_model) fitter.fit_toas() assert_allclose(fitter.model.DMJUMP1.value, -10, atol=1e-3)
# %% toas.table[-1] # %% toas.table["flags"][0] # %% [markdown] # ## Do the fit # # As before, but now we need a fitter adapted to wideband TOAs. # %% fitter = WidebandTOAFitter(toas, model) # %% fitter.fit_toas() # %% [markdown] # ## What is new, compared to narrowband fitting? # %% [markdown] # ### Residual objects combine TOA and time data # %% type(fitter.resids) # %% [markdown] # #### If we look into the resids attribute, it has two independent Residual objects. # %% fitter.resids.toa, fitter.resids.dm
def test_fitting_full_cov(self): fitter = WidebandTOAFitter([self.toas,], self.model, additional_args={}) rms_pre = fitter.resids_init.rms_weighted() fitter.fit_toas(full_cov=True) assert fitter.resids.rms_weighted() - rms_pre < 1e-9