def test_ecorr_average(): par = os.path.join(datadir, "J0023+0923_NANOGrav_11yv0.gls.par") tim = os.path.join(datadir, "J0023+0923_NANOGrav_11yv0.tim") m = mb.get_model(par) t = toa.get_TOAs(tim, ephem="DE436") f = GLSFitter(t, m) # Get comparison resids and uncertainties mjd, freq, res, err, ophase, chi2, info = np.genfromtxt(par + ".resavg", unpack=True) resavg_mjd = mjd * u.d # resavg_freq = freq * u.MHz resavg_res = res * u.us resavg_err = err * u.us # resavg_chi2 = chi2 f.fit_toas() avg = f.resids.ecorr_average() # The comparison data always come out time-sorted # so we need to sort here. ii = np.argsort(avg["mjds"]) mjd_diff = avg["mjds"][ii] - resavg_mjd res_diff = avg["time_resids"][ii] - resavg_res err_ratio = avg["errors"][ii] / resavg_err assert np.abs(mjd_diff).max() < 1e-9 * u.d assert np.abs(res_diff).max() < 7 * u.ns assert np.abs(err_ratio - 1.0).max() < 5e-4
def _gen_data(par, tim): t = toa.get_TOAs(tim, ephem="DE436") m = mb.get_model(par) gls = GLSFitter(t, m) gls.fit_toas() mjds = t.get_mjds().to(u.d).value freqs = t.get_freqs().to(u.MHz).value res = gls.resids.time_resids.to(u.us).value err = m.scaled_sigma(t).to(u.us).value info = t.get_flag_value("f") fout = open(par + ".resids", "w") iout = open(par + ".info", "w") for i in range(t.ntoas): line = "%.10f %.4f %+.8e %.3e 0.0 %s" % ( mjds[i], freqs[i], res[i], err[i], info[i], ) fout.write(line + "\n") iout.write(info[i] + "\n") fout.close() iout.close() # Requires res_avg in path cmd = "cat %s.resids | res_avg -r -t0.0001 -E%s -i%s.info > %s.resavg" % ( par, par, par, par, ) print(cmd)
def test_fake_DMfit(): """ fit only for DM with fake TOAs compare the variance of that result against the uncertainties """ parfile = pint.config.examplefile("NGC6440E.par") timfile = pint.config.examplefile("NGC6440E.tim") m, t = get_model_and_toas(parfile, timfile) # pick only data for a DM fit t = t[-8:] m.RAJ.frozen = True m.DECJ.frozen = True m.F0.frozen = True m.F1.frozen = True f = GLSFitter(t, m) f.fit_toas() N = 30 DMs = np.zeros(N) * u.pc / u.cm**3 for iter in range(N): t_fake = pint.simulation.make_fake_toas(t, m, add_noise=True) f_fake = GLSFitter(t_fake, m) f_fake.fit_toas() DMs[iter] = f_fake.model.DM.quantity.astype(np.float64) assert np.isclose(DMs.std(), f.model.DM.uncertainty, rtol=0.5) assert np.abs(DMs.mean() - f.model.DM.quantity) < 5 * f.model.DM.uncertainty
def test_gls_covmatrix(wls): gls = GLSFitter(wls.toas, wls.model_init) gls.fit_toas() assert np.isclose(wls.parameter_covariance_matrix.matrix, gls.parameter_covariance_matrix.matrix).all() uncertainties = gls.model.get_params_dict("free", "uncertainty") for param in uncertainties: # uncertainty based on the diagonals of the covariance matrix matrix_uncertainty = np.sqrt( gls.parameter_covariance_matrix.get_label_matrix([param ]).matrix[0, 0]) assert np.isclose(uncertainties[param], matrix_uncertainty)
def test_gls_chi2_behaviour(): model = get_model( StringIO( """ PSRJ J1234+5678 ELAT 0 ELONG 0 DM 10 F0 1 PEPOCH 58000 TNRedAmp -14.227505410948254 TNRedGam 4.91353 TNRedC 45 """ ) ) model.free_params = ["F0", "ELAT", "ELONG"] toas = make_fake_toas_uniform(57000, 59000, 40, model=model, error=1 * u.us) np.random.seed(0) toas.adjust_TOAs(TimeDelta(np.random.randn(len(toas)) * u.us)) f = GLSFitter(toas, model) initial_chi2 = Residuals(toas, model).calc_chi2() fit_chi2 = f.fit_toas() assert fit_chi2 <= initial_chi2 assert f.resids.calc_chi2() <= initial_chi2 assert initial_chi2 == Residuals(toas, model).calc_chi2()
def test_fake_from_timfile(): m, t = get_model_and_toas( pint.config.examplefile("B1855+09_NANOGrav_9yv1.gls.par"), pint.config.examplefile("B1855+09_NANOGrav_9yv1.tim"), ) # refit the data to get rid of a trend f = GLSFitter(t, m) f.fit_toas() r = pint.residuals.Residuals(t, f.model) t_sim = pint.simulation.make_fake_toas(t, f.model, add_noise=True) r_sim = pint.residuals.Residuals(t_sim, f.model) # need a generous rtol because of the small statistics assert np.isclose(r.calc_time_resids().std(), r_sim.calc_time_resids().std(), rtol=2)
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. """ if self.model.has_correlated_errors: log.debug("Using GLS fitter to compute residual chi2") # Use GLS but don't actually fit from pint.fitter import GLSFitter m = copy.deepcopy(self.model) m.free_params = [] f = GLSFitter(self.toas, m, residuals=self) 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 else: # Residual units are in seconds. Error units are in microseconds. toa_errors = self.get_data_error() if (toa_errors == 0.0).any(): return np.inf else: # The self.time_resids is in the unit of "s", the error "us". # This is more correct way, but it is the slowest. # return (((self.time_resids / self.toas.get_errors()).decompose()**2.0).sum()).value # This method is faster then the method above but not the most correct way # return ((self.time_resids.to(u.s) / self.toas.get_errors().to(u.s)).value**2.0).sum() # This the fastest way, but highly depend on the assumption of time_resids and # error units. # insure only a pure number returned try: return ((self.time_resids / toa_errors.to(u.s)) ** 2.0).sum().value except ValueError: return ((self.time_resids / toa_errors.to(u.s)) ** 2.0).sum()
class TestGLS(unittest.TestCase): """Compare delays from the dd model with tempo and PINT""" @classmethod def setUpClass(self): self.par = 'B1855+09_NANOGrav_9yv1.gls.par' self.tim = 'B1855+09_NANOGrav_9yv1.tim' self.m = mb.get_model(self.par) self.t = toa.get_TOAs(self.tim, ephem='DE436') self.f = GLSFitter(self.t, self.m) # get tempo2 parameter dict with open('B1855+09_tempo2_gls_pars.json', 'r') as fp: self.t2d = json.load(fp) def fit(self, full_cov): self.f.reset_model() self.f.update_resids() self.f.fit_toas(full_cov=full_cov) def test_gls_fitter(self): for full_cov in [True, False]: self.fit(full_cov) for par, val in sorted(self.t2d.items()): if par not in ['F0']: v = (getattr(self.f.model, par).value if par not in [ 'ELONG', 'ELAT' ] else getattr(self.f.model, par).quantity.to(u.rad).value) e = (getattr(self.f.model, par).uncertainty.value if par not in ['ELONG', 'ELAT'] else getattr( self.f.model, par).uncertainty.to(u.rad).value) msg = 'Parameter {} does not match T2 for full_cov={}'.format( par, full_cov) assert np.abs(v - val[0]) <= val[1], msg assert np.abs(v - val[0]) <= e, msg assert np.abs(1 - val[1] / e) < 0.1, msg def test_gls_compare(self): self.fit(full_cov=False) chi21 = self.f.resids.chi2 self.fit(full_cov=True) chi22 = self.f.resids.chi2 assert np.allclose(chi21, chi22)
def test_gls_covmatrix(wls): gls = GLSFitter(wls.toas, wls.model_init) gls.fit_toas() assert np.isclose( wls.parameter_covariance_matrix.matrix, gls.parameter_covariance_matrix.matrix ).all() uncertainties = gls.model.get_params_dict("free", "uncertainty") for param in uncertainties: # uncertainty based on the diagonals of the covariance matrix matrix_uncertainty = np.sqrt( gls.parameter_covariance_matrix.get_label_matrix([param]).matrix[0, 0] ) if param in ["RAJ", "DECJ"]: # then uncertainties are in arcsec, need to convert factor = 3600 else: factor = 1 assert np.isclose(uncertainties[param] / factor, matrix_uncertainty)
class TestGLS(unittest.TestCase): """Compare delays from the dd model with tempo and PINT""" @classmethod def setUpClass(self): self.par = 'B1855+09_NANOGrav_9yv1.gls.par' self.tim = 'B1855+09_NANOGrav_9yv1.tim' self.m = mb.get_model(self.par) self.t = toa.get_TOAs(self.tim, ephem='DE436') self.f = GLSFitter(self.t, self.m) # get tempo2 parameter dict with open('B1855+09_tempo2_gls_pars.json', 'r') as fp: self.t2d = json.load(fp) def fit(self, full_cov): self.f.reset_model() self.f.update_resids() self.f.fit_toas(full_cov=full_cov) def test_gls_fitter(self): for full_cov in [True, False]: self.fit(full_cov) for par, val in sorted(self.t2d.items()): if par not in ['F0']: v = (getattr(self.f.model, par).value if par not in ['ELONG', 'ELAT'] else getattr(self.f.model, par).quantity.to(u.rad).value) e = (getattr(self.f.model, par).uncertainty.value if par not in ['ELONG', 'ELAT'] else getattr(self.f.model, par).uncertainty.to(u.rad).value) msg = 'Parameter {} does not match T2 for full_cov={}'.format(par, full_cov) assert np.abs(v-val[0]) <= val[1], msg assert np.abs(v-val[0]) <= e, msg assert np.abs(1 - val[1]/e) < 0.1, msg def test_gls_compare(self): self.fit(full_cov=False) chi21 = self.f.resids.chi2 self.fit(full_cov=True) chi22 = self.f.resids.chi2 assert np.allclose(chi21, chi22)
def test_residuals_gls_chi2(): model = get_model( StringIO(""" PSRJ J1234+5678 ELAT 0 ELONG 0 DM 10 F0 1 PEPOCH 58000 ECORR mjd 57000 58000 2 """)) toas = make_fake_toas(57000, 59000, 20, model=model, error=1 * u.us) np.random.seed(0) toas.adjust_TOAs(TimeDelta(np.random.randn(len(toas)) * u.us)) r = Residuals(toas, model) f = GLSFitter(toas, model) assert f.fit_toas() == r.chi2
def test_gls_chi2_reasonable(full_cov): model = get_model( StringIO(""" PSRJ J1234+5678 ELAT 0 ELONG 0 DM 10 F0 1 PEPOCH 58000 TNRedAmp -14.227505410948254 TNRedGam 4.91353 TNRedC 45 """)) toas = make_fake_toas(57000, 59000, 40, model=model, error=1 * u.us) np.random.seed(0) toas.adjust_TOAs(TimeDelta(np.random.randn(len(toas)) * u.us)) f = GLSFitter(toas, model) fit_chi2 = f.fit_toas(full_cov=full_cov) assert_allclose(fit_chi2, f.resids.calc_chi2(full_cov=full_cov))
def test_compare_gls(full_cov, wls): gls = GLSFitter(wls.toas, wls.model_init) gls.fit_toas(full_cov=full_cov) assert abs(wls.resids.chi2 - gls.resids.chi2) < 0.01