def __init__(self, psr): # not available for PINT yet if isinstance(psr, enterprise.pulsar.PintPulsar): msg = 'Physical Ephemeris model is not compatible with PINT ' msg += 'at this time.' raise NotImplementedError(msg) super(Dropout_PhysicalEphemerisSignal, self).__init__(psr) if use_epoch_toas: # get quantization matrix and calculate daily average TOAs U, _ = utils.create_quantization_matrix(psr.toas, nmin=1) self.uinds = utils.quant2ind(U) avetoas = np.array([psr.toas[sc].mean() for sc in self.uinds]) self._wf[''].add_kwarg(toas=avetoas) # interpolate ssb planet position vectors to avetoas planetssb = np.zeros((len(avetoas), 9, 3)) for jj in range(9): planetssb[:, jj, :] = np.array([ np.interp(avetoas, psr.toas, psr.planetssb[:, jj, aa]) for aa in range(3) ]).T self._wf[''].add_kwarg(planetssb=planetssb) # Inteprolating the pulsar position vectors onto epoch TOAs pos_t = np.array([ np.interp(avetoas, psr.toas, psr.pos_t[:, aa]) for aa in range(3) ]).T self._wf[''].add_kwarg(pos_t=pos_t) # initialize delay self._delay = np.zeros(len(psr.toas))
def __init__(self, psr): super(EcorrKernelNoise, self).__init__(psr) self.name = self.psrname + "_" + self.signal_id sel = selection(psr) self._params, self._masks = sel("log10_ecorr", log10_ecorr) keys = sorted(self._masks.keys()) masks = [self._masks[key] for key in keys] Umats = [] for key, mask in zip(keys, masks): Umats.append( utils.create_quantization_matrix(psr.toas[mask], nmin=2)[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(psr.toas), nepoch)) self._slices = {} netot = 0 for ct, (key, mask) in enumerate(zip(keys, masks)): nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] self._slices.update( {key: utils.quant2ind(U[:, netot:nn + netot])}) netot += nn # initialize sparse matrix self._setup(psr)
def test_ecorr(self): """Test that ecorr signal returns correct values.""" # set up signal parameter ecorr = parameter.Uniform(-10, -5) ec = gs.EcorrBasisModel(log10_ecorr=ecorr) ecm = ec(self.psr) # parameters ecorr = -6.4 params = {'B1855+09_log10_ecorr': ecorr} # basis matrix test U = utils.create_quantization_matrix(self.psr.toas)[0] msg = 'U matrix incorrect for Basis Ecorr signal.' assert np.allclose(U, ecm.get_basis(params)), msg # Jvec test jvec = 10**(2*ecorr) * np.ones(U.shape[1]) msg = 'Prior vector incorrect for Basis Ecorr signal.' assert np.all(ecm.get_phi(params) == jvec), msg # inverse Jvec test msg = 'Prior vector inverse incorrect for Basis Ecorr signal.' assert np.all(ecm.get_phiinv(params) == 1/jvec), msg # test shape msg = 'U matrix shape incorrect' assert ecm.get_basis(params).shape == U.shape, msg
def test_ecorr(self): """Test that ecorr signal returns correct values.""" # set up signal parameter ecorr = parameter.Uniform(-10, -5) ec = gp_signals.EcorrBasisModel(log10_ecorr=ecorr) ecm = ec(self.psr) # parameters ecorr = -6.4 params = {"B1855+09_basis_ecorr_log10_ecorr": ecorr} # basis matrix test U = utils.create_quantization_matrix(self.psr.toas)[0] msg = "U matrix incorrect for Basis Ecorr signal." assert np.allclose(U, ecm.get_basis(params)), msg # Jvec test jvec = 10 ** (2 * ecorr) * np.ones(U.shape[1]) msg = "Prior vector incorrect for Basis Ecorr signal." assert np.all(ecm.get_phi(params) == jvec), msg # inverse Jvec test msg = "Prior vector inverse incorrect for Basis Ecorr signal." assert np.all(ecm.get_phiinv(params) == 1 / jvec), msg # test shape msg = "U matrix shape incorrect" assert ecm.get_basis(params).shape == U.shape, msg
def __init__(self, psr): # not available for PINT yet if isinstance(psr, enterprise.pulsar.PintPulsar): msg = 'Physical Ephemeris model is not compatible with PINT ' msg += 'at this time.' raise NotImplementedError(msg) super(PhysicalEphemerisSignal, self).__init__(psr) if use_epoch_toas: # get quantization matrix and calculate daily average TOAs U, _ = utils.create_quantization_matrix(psr.toas, nmin=1) self.uinds = utils.quant2ind(U) avetoas = np.array([psr.toas[sc].mean() for sc in self.uinds]) self._wf[''].add_kwarg(toas=avetoas) # interpolate ssb planet position vectors to avetoas planetssb = np.zeros((len(avetoas), 9, 3)) for jj in range(9): planetssb[:, jj, :] = np.array([ np.interp(avetoas, psr.toas, psr.planetssb[:,jj,aa]) for aa in range(3)]).T self._wf[''].add_kwarg(planetssb=planetssb) # Inteprolating the pulsar position vectors onto epoch TOAs pos_t = np.array([np.interp(avetoas, psr.toas, psr.pos_t[:,aa]) for aa in range(3)]).T self._wf[''].add_kwarg(pos_t=pos_t) # initialize delay self._delay = np.zeros(len(psr.toas))
def test_quantization_matrix(self): """Test quantization matrix generation.""" U = utils.create_quantization_matrix(self.psr.toas, dt=1)[0] msg1 = "Quantization matrix shape incorrect." msg2 = "Quantization matrix contains single TOA epochs." assert U.shape == (4005, 235), msg1 assert all(np.sum(U, axis=0) > 1), msg2
def test_quantization_matrix(self): """Test quantization matrix generation.""" U = utils.create_quantization_matrix(self.psr.toas, dt=1)[0] msg1 = 'Quantization matrix shape incorrect.' msg2 = 'Quantization matrix contains single TOA epochs.' assert U.shape == (4005, 235), msg1 assert all(np.sum(U, axis=0) > 1), msg2
def set_Umat_auxiliaries(self): """Set quantization matrix and array of observing epoch start/stop indices for TOAs after filtering out short (<4 TOAs) epochs """ Umat, _ = create_quantization_matrix(self.psr.toas) Uind = quant2ind(Umat) self.Umat, self.Uindslc = ut.set_Uindslc(Umat, Uind)
def get_tf_quantization_matrix(toas, freqs, dt=30 * 86400, df=None, dm=False, dm_idx=2): """ Quantization matrix in time and radio frequency to cut down on the kernel size. """ if df is None: dfs = [(600, 1000), (1000, 1900), (1900, 3000), (3000, 5000)] else: fmin = freqs.min() fmax = freqs.max() fs = np.arange(fmin, fmax + df, df) dfs = [(fs[ii], fs[ii + 1]) for ii in range(len(fs) - 1)] Us, avetoas, avefreqs, masks = [], [], [], [] for rng in dfs: mask = np.logical_and(freqs >= rng[0], freqs < rng[1]) if any(mask): masks.append(mask) U, _ = utils.create_quantization_matrix(toas[mask], dt=dt, nmin=1) avetoa = np.array( [toas[mask][idx.astype(bool)].mean() for idx in U.T]) avefreq = np.array( [freqs[mask][idx.astype(bool)].mean() for idx in U.T]) Us.append(U) avetoas.append(avetoa) avefreqs.append(avefreq) nc = np.sum(U.shape[1] for U in Us) U = np.zeros((len(toas), nc)) avetoas = np.concatenate(avetoas) idx = np.argsort(avetoas) avefreqs = np.concatenate(avefreqs) nctot = 0 for ct, mask in enumerate(masks): Umat = Us[ct] nn = Umat.shape[1] U[mask, nctot:nn + nctot] = Umat nctot += nn if dm: weights = (1400 / freqs)**dm_idx else: weights = np.ones_like(freqs) return U[:, idx] * weights[:, None], { 'avetoas': avetoas[idx], 'avefreqs': avefreqs[idx] }
def test_ecorr_backend(self): """Test that ecorr-backend signal returns correct values.""" # set up signal parameter ecorr = parameter.Uniform(-10, -5) selection = Selection(selections.by_backend) ec = gp_signals.EcorrBasisModel(log10_ecorr=ecorr, selection=selection) ecm = ec(self.psr) # parameters ecorrs = [-6.1, -6.2, -6.3, -6.4] params = { "B1855+09_basis_ecorr_430_ASP_log10_ecorr": ecorrs[0], "B1855+09_basis_ecorr_430_PUPPI_log10_ecorr": ecorrs[1], "B1855+09_basis_ecorr_L-wide_ASP_log10_ecorr": ecorrs[2], "B1855+09_basis_ecorr_L-wide_PUPPI_log10_ecorr": ecorrs[3], } # get the basis bflags = self.psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append( utils.create_quantization_matrix(self.psr.toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ct]) netot += nn # basis matrix test msg = "U matrix incorrect for Basis Ecorr-backend signal." assert np.allclose(U, ecm.get_basis(params)), msg # Jvec test msg = "Prior vector incorrect for Basis Ecorr backend signal." assert np.all(ecm.get_phi(params) == jvec), msg # inverse Jvec test msg = "Prior vector inverse incorrect for Basis Ecorr backend signal." assert np.all(ecm.get_phiinv(params) == 1 / jvec), msg # test shape msg = "U matrix shape incorrect" assert ecm.get_basis(params).shape == U.shape, msg
def test_ecorr_backend(self): """Test that ecorr-backend signal returns correct values.""" # set up signal parameter ecorr = parameter.Uniform(-10, -5) selection = Selection(selections.by_backend) ec = gs.EcorrBasisModel(log10_ecorr=ecorr, selection=selection) ecm = ec(self.psr) # parameters ecorrs = [-6.1, -6.2, -6.3, -6.4] params = {'B1855+09_430_ASP_log10_ecorr': ecorrs[0], 'B1855+09_430_PUPPI_log10_ecorr': ecorrs[1], 'B1855+09_L-wide_ASP_log10_ecorr': ecorrs[2], 'B1855+09_L-wide_PUPPI_log10_ecorr': ecorrs[3]} # get the basis bflags = self.psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append(utils.create_quantization_matrix( self.psr.toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn+netot] = Umats[ct] jvec[netot:nn+netot] = 10**(2*ecorrs[ct]) netot += nn # basis matrix test msg = 'U matrix incorrect for Basis Ecorr-backend signal.' assert np.allclose(U, ecm.get_basis(params)), msg # Jvec test msg = 'Prior vector incorrect for Basis Ecorr backend signal.' assert np.all(ecm.get_phi(params) == jvec), msg # inverse Jvec test msg = 'Prior vector inverse incorrect for Basis Ecorr backend signal.' assert np.all(ecm.get_phiinv(params) == 1/jvec), msg # test shape msg = 'U matrix shape incorrect' assert ecm.get_basis(params).shape == U.shape, msg
def EcorrBasisModel(log10_ecorr=parameter.Uniform(-10, -5), selection=Selection(selections.no_selection), name=''): """Convienience function to return a BasisGP class with a quantized ECORR basis.""" basis = utils.create_quantization_matrix() prior = ecorr_basis_prior(log10_ecorr=log10_ecorr) BaseClass = BasisGP(prior, basis, selection=selection, name=name) class EcorrBasisModel(BaseClass): signal_type = 'basis' signal_name = 'basis ecorr' signal_id = 'basis_ecorr_' + name if name else 'basis_ecorr' return EcorrBasisModel
def EcorrBasisModel( log10_ecorr=parameter.Uniform(-10, -5), coefficients=False, selection=Selection(selections.no_selection), name="basis_ecorr", ): """Convenience function to return a BasisGP class with a quantized ECORR basis.""" basis = utils.create_quantization_matrix() prior = ecorr_basis_prior(log10_ecorr=log10_ecorr) BaseClass = BasisGP(prior, basis, coefficients=coefficients, selection=selection, name=name) class EcorrBasisModel(BaseClass): signal_type = "basis" signal_name = "basis ecorr" signal_id = name return EcorrBasisModel
def _ecorr_test_ipta(self, method='sparse'): """Test of sparse/sherman-morrison ecorr signal and solve methods.""" selection = Selection(selections.nanograv_backends) efac = parameter.Uniform(0.1, 5) ecorr = parameter.Uniform(-10, -5) ef = ws.MeasurementNoise(efac=efac) ec = ws.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection, method=method) tm = gp.TimingModel() s = ef + ec + tm m = s(self.ipsr) # set parameters efacs = [1.3] ecorrs = [-6.1, -6.2, -6.3, -6.4, -7.2, -8.4, -7.1, -7.9] params = {'J1713+0747_efac': efacs[0], 'J1713+0747_ASP-L_log10_ecorr': ecorrs[0], 'J1713+0747_ASP-S_log10_ecorr': ecorrs[1], 'J1713+0747_GASP-8_log10_ecorr': ecorrs[2], 'J1713+0747_GASP-L_log10_ecorr': ecorrs[3], 'J1713+0747_GUPPI-8_log10_ecorr': ecorrs[4], 'J1713+0747_GUPPI-L_log10_ecorr': ecorrs[5], 'J1713+0747_PUPPI-L_log10_ecorr': ecorrs[6], 'J1713+0747_PUPPI-S_log10_ecorr': ecorrs[7]} # get EFAC Nvec nvec0 = efacs[0]**2 * self.ipsr.toaerrs**2 # get the basis flags = ['ASP-L', 'ASP-S', 'GASP-8', 'GASP-L', 'GUPPI-8', 'GUPPI-L', 'PUPPI-L', 'PUPPI-S'] bflags = self.ipsr.backend_flags Umats = [] for flag in np.unique(bflags): if flag in flags: mask = bflags == flag Umats.append(utils.create_quantization_matrix( self.ipsr.toas[mask], nmin=2)[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.ipsr.toas), nepoch)) jvec = np.zeros(nepoch) netot, ct = 0, 0 for flag in np.unique(bflags): if flag in flags: mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn+netot] = Umats[ct] jvec[netot:nn+netot] = 10**(2*ecorrs[ct]) netot += nn ct += 1 # get covariance matrix wd = Woodbury(nvec0, U, jvec) # test msg = 'EFAC/ECORR {} logdet incorrect.'.format(method) N = m.get_ndiag(params) assert np.allclose(N.solve(self.ipsr.residuals, logdet=True)[1], wd.logdet(), rtol=1e-8), msg msg = 'EFAC/ECORR {} D1 solve incorrect.'.format(method) assert np.allclose(N.solve(self.ipsr.residuals), wd.solve(self.ipsr.residuals), rtol=1e-8), msg msg = 'EFAC/ECORR {} 1D1 solve incorrect.'.format(method) assert np.allclose( N.solve(self.ipsr.residuals, left_array=self.ipsr.residuals), np.dot(self.ipsr.residuals, wd.solve(self.ipsr.residuals)), rtol=1e-8), msg msg = 'EFAC/ECORR {} 2D1 solve incorrect.'.format(method) T = m.get_basis() assert np.allclose( N.solve(self.ipsr.residuals, left_array=T), np.dot(T.T, wd.solve(self.ipsr.residuals)), rtol=1e-8), msg msg = 'EFAC/ECORR {} 2D2 solve incorrect.'.format(method) assert np.allclose( N.solve(T, left_array=T), np.dot(T.T, wd.solve(T)), rtol=1e-8), msg
if args.tmin is not None and args.tmax is not None: if args.tmin<tmin: err = "tmin ({:.1f}) BEFORE first TOA ({:.1f})".format(args.tmin, tmin) raise RuntimeError(err) elif args.tmax>tmax: err = "tmax ({:.1f}) AFTER last TOA ({:.1f})".format(args.tmax, tmax) raise RuntimeError(err) elif args.tmin>args.tmax: err = "tmin ({:.1f}) BEFORE last tmax ({:.1f})".format(args.tmin, args.tmax) raise RuntimeError(err) else: t0min = args.tmin t0max = args.tmax else: U,_ = utils.create_quantization_matrix(psr.toas) eps = 9 # clip first and last N observing epochs t0min = np.floor(max(U[:,eps] * psr.toas/const.day)) t0max = np.ceil(max(U[:,-eps] * psr.toas/const.day)) #tclip = (tmax - tmin) * 0.05 #t0min = tmin + tclip*2 # clip first 10% #t0max = tmax - tclip # clip last 5% pta = models.model_bwm([psr], sngl_psr=True, upper_limit=args.UL, bayesephem=False, logmin=logminA, logmax=logmaxA, Tmin_bwm=t0min, Tmax_bwm=t0max) pta.set_default_params(setpars) outfile = args.outdir + '/params.txt'
def test_combine_signals(self): """Test for combining different signals.""" # set up signal parameter ecorr = parameter.Uniform(-10, -5) ec = gs.EcorrBasisModel(log10_ecorr=ecorr) pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12), gamma=parameter.Uniform(1,7)) rn = gs.FourierBasisGP(spectrum=pl, components=30) log10_sigma = parameter.Uniform(-10, -5) log10_lam = parameter.Uniform(np.log10(86400), np.log10(1500*86400)) basis = create_quant_matrix(dt=7*86400) prior = se_kernel(log10_sigma=log10_sigma, log10_lam=log10_lam) se = gs.BasisGP(prior, basis, name='se') ts = gs.TimingModel() s = ec + rn + ts + se m = s(self.psr) # parameters ecorr = -6.4 log10_A, gamma = -14.5, 4.33 log10_lam, log10_sigma = 7.4, -6.4 params = {'B1855+09_log10_ecorr': ecorr, 'B1855+09_log10_A': log10_A, 'B1855+09_gamma': gamma, 'B1855+09_se_log10_lam': log10_lam, 'B1855+09_se_log10_sigma': log10_sigma} # combined basis matrix U = utils.create_quantization_matrix(self.psr.toas)[0] M = self.psr.Mmat.copy() norm = np.sqrt(np.sum(M**2, axis=0)) M /= norm F, f2 = utils.createfourierdesignmatrix_red( self.psr.toas, nmodes=30) U2, avetoas = create_quant_matrix(self.psr.toas, dt=7*86400) T = np.hstack((U, F, M, U2)) # combined prior vector jvec = 10**(2*ecorr) * np.ones(U.shape[1]) phim = np.ones(self.psr.Mmat.shape[1]) * 1e40 phi = utils.powerlaw(f2, log10_A=log10_A, gamma=gamma) K = se_kernel(avetoas, log10_lam=log10_lam, log10_sigma=log10_sigma) phivec = np.concatenate((jvec, phi, phim)) phi = sl.block_diag(np.diag(phivec), K) phiinv = np.linalg.inv(phi) # basis matrix test msg = 'Basis matrix incorrect for combined signal.' assert np.allclose(T, m.get_basis(params)), msg # Kernal test msg = 'Prior matrix incorrect for combined signal.' assert np.allclose(m.get_phi(params), phi), msg # inverse Kernel test msg = 'Prior matrix inverse incorrect for combined signal.' assert np.allclose(m.get_phiinv(params), phiinv), msg # test shape msg = 'Basis matrix shape incorrect size for combined signal.' assert m.get_basis(params).shape == T.shape, msg
def compute_like(self, npsrs=1, inc_corr=False, inc_kernel=False): # get parameters from PAL2 style noise files params = get_noise_from_pal2(datadir + "/B1855+09_noise.txt") params2 = get_noise_from_pal2(datadir + "/J1909-3744_noise.txt") params.update(params2) psrs = self.psrs if npsrs == 2 else [self.psrs[0]] if inc_corr: params.update({"GW_gamma": 4.33, "GW_log10_A": -15.0}) # find the maximum time span to set GW frequency sampling tmin = [p.toas.min() for p in psrs] tmax = [p.toas.max() for p in psrs] Tspan = np.max(tmax) - np.min(tmin) # setup basic model efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() log10_A = parameter.Constant() gamma = parameter.Constant() selection = Selection(selections.by_backend) ef = white_signals.MeasurementNoise(efac=efac, selection=selection) eq = white_signals.EquadNoise(log10_equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(pl) orf = utils.hd_orf() crn = gp_signals.FourierBasisCommonGP(pl, orf, components=20, name="GW", Tspan=Tspan) tm = gp_signals.TimingModel() log10_sigma = parameter.Uniform(-10, -5) log10_lam = parameter.Uniform(np.log10(86400), np.log10(1500 * 86400)) basis = create_quant_matrix(dt=7 * 86400) prior = se_kernel(log10_sigma=log10_sigma, log10_lam=log10_lam) se = gp_signals.BasisGP(prior, basis, name="se") # set up kernel stuff if isinstance(inc_kernel, bool): inc_kernel = [inc_kernel] * npsrs if inc_corr: s = ef + eq + ec + rn + crn + tm else: s = ef + eq + ec + rn + tm models = [] for ik, psr in zip(inc_kernel, psrs): snew = s + se if ik else s models.append(snew(psr)) pta = signal_base.PTA(models) # set parameters pta.set_default_params(params) # SE kernel parameters log10_sigmas, log10_lams = [-7.0, -6.5], [7.0, 6.5] params.update({ "B1855+09_se_log10_lam": log10_lams[0], "B1855+09_se_log10_sigma": log10_sigmas[0], "J1909-3744_se_log10_lam": log10_lams[1], "J1909-3744_se_log10_sigma": log10_sigmas[1], }) # get parameters efacs, equads, ecorrs, log10_A, gamma = [], [], [], [], [] lsig, llam = [], [] for pname in [p.name for p in psrs]: efacs.append([ params[key] for key in sorted(params.keys()) if "efac" in key and pname in key ]) equads.append([ params[key] for key in sorted(params.keys()) if "equad" in key and pname in key ]) ecorrs.append([ params[key] for key in sorted(params.keys()) if "ecorr" in key and pname in key ]) log10_A.append(params["{}_red_noise_log10_A".format(pname)]) gamma.append(params["{}_red_noise_gamma".format(pname)]) lsig.append(params["{}_se_log10_sigma".format(pname)]) llam.append(params["{}_se_log10_lam".format(pname)]) GW_gamma = 4.33 GW_log10_A = -15.0 # correct value tflags = [sorted(list(np.unique(p.backend_flags))) for p in psrs] cfs, logdets, phis, Ts = [], [], [], [] for ii, (ik, psr, flags) in enumerate(zip(inc_kernel, psrs, tflags)): nvec0 = np.zeros_like(psr.toas) for ct, flag in enumerate(flags): ind = psr.backend_flags == flag nvec0[ind] = efacs[ii][ct]**2 * psr.toaerrs[ind]**2 nvec0[ind] += 10**(2 * equads[ii][ct]) * np.ones(np.sum(ind)) # get the basis bflags = psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append( utils.create_quantization_matrix(psr.toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ii][ct]) netot += nn # get covariance matrix cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T) cf = sl.cho_factor(cov) logdet = np.sum(2 * np.log(np.diag(cf[0]))) cfs.append(cf) logdets.append(logdet) F, f2 = utils.createfourierdesignmatrix_red(psr.toas, nmodes=20, Tspan=Tspan) Mmat = psr.Mmat.copy() norm = np.sqrt(np.sum(Mmat**2, axis=0)) Mmat /= norm U2, avetoas = create_quant_matrix(psr.toas, dt=7 * 86400) if ik: T = np.hstack((F, Mmat, U2)) else: T = np.hstack((F, Mmat)) Ts.append(T) phi = utils.powerlaw(f2, log10_A=log10_A[ii], gamma=gamma[ii]) if inc_corr: phigw = utils.powerlaw(f2, log10_A=GW_log10_A, gamma=GW_gamma) else: phigw = np.zeros(40) K = se_kernel(avetoas, log10_sigma=log10_sigmas[ii], log10_lam=log10_lams[ii]) k = np.diag( np.concatenate((phi + phigw, np.ones(Mmat.shape[1]) * 1e40))) if ik: k = sl.block_diag(k, K) phis.append(k) # manually compute loglike loglike = 0 TNrs, TNTs = [], [] for ct, psr in enumerate(psrs): TNrs.append(np.dot(Ts[ct].T, sl.cho_solve(cfs[ct], psr.residuals))) TNTs.append(np.dot(Ts[ct].T, sl.cho_solve(cfs[ct], Ts[ct]))) loglike += -0.5 * ( np.dot(psr.residuals, sl.cho_solve(cfs[ct], psr.residuals)) + logdets[ct]) TNr = np.concatenate(TNrs) phi = sl.block_diag(*phis) if inc_corr: hd = utils.hd_orf(psrs[0].pos, psrs[1].pos) phi[len(phis[0]):len(phis[0]) + 40, :40] = np.diag(phigw * hd) phi[:40, len(phis[0]):len(phis[0]) + 40] = np.diag(phigw * hd) cf = sl.cho_factor(phi) phiinv = sl.cho_solve(cf, np.eye(phi.shape[0])) logdetphi = np.sum(2 * np.log(np.diag(cf[0]))) Sigma = sl.block_diag(*TNTs) + phiinv cf = sl.cho_factor(Sigma) expval = sl.cho_solve(cf, TNr) logdetsigma = np.sum(2 * np.log(np.diag(cf[0]))) loglike -= 0.5 * (logdetphi + logdetsigma) loglike += 0.5 * np.dot(TNr, expval) method = ["partition", "sparse", "cliques"] for mth in method: eloglike = pta.get_lnlikelihood(params, phiinv_method=mth) msg = "Incorrect like for npsr={}, phiinv={}".format(npsrs, mth) assert np.allclose(eloglike, loglike), msg
def _ecorr_test(self, method="sparse"): """Test of sparse/sherman-morrison ecorr signal and solve methods.""" selection = Selection(selections.by_backend) efac = parameter.Uniform(0.1, 5) ecorr = parameter.Uniform(-10, -5) ef = white_signals.MeasurementNoise(efac=efac, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection, method=method) tm = gp_signals.TimingModel() s = ef + ec + tm m = s(self.psr) # set parameters efacs = [1.3, 1.4, 1.5, 1.6] ecorrs = [-6.1, -6.2, -6.3, -6.4] params = { "B1855+09_430_ASP_efac": efacs[0], "B1855+09_430_PUPPI_efac": efacs[1], "B1855+09_L-wide_ASP_efac": efacs[2], "B1855+09_L-wide_PUPPI_efac": efacs[3], "B1855+09_430_ASP_log10_ecorr": ecorrs[0], "B1855+09_430_PUPPI_log10_ecorr": ecorrs[1], "B1855+09_L-wide_ASP_log10_ecorr": ecorrs[2], "B1855+09_L-wide_PUPPI_log10_ecorr": ecorrs[3], } # get EFAC Nvec flags = ["430_ASP", "430_PUPPI", "L-wide_ASP", "L-wide_PUPPI"] nvec0 = np.zeros_like(self.psr.toas) for ct, flag in enumerate(np.unique(flags)): ind = flag == self.psr.backend_flags nvec0[ind] = efacs[ct]**2 * self.psr.toaerrs[ind]**2 # get the basis bflags = self.psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append( utils.create_quantization_matrix(self.psr.toas[mask], nmin=2)[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ct]) netot += nn # get covariance matrix wd = Woodbury(nvec0, U, jvec) # test msg = "EFAC/ECORR {} logdet incorrect.".format(method) N = m.get_ndiag(params) assert np.allclose(N.solve(self.psr.residuals, logdet=True)[1], wd.logdet(), rtol=1e-10), msg msg = "EFAC/ECORR {} D1 solve incorrect.".format(method) assert np.allclose(N.solve(self.psr.residuals), wd.solve(self.psr.residuals), rtol=1e-10), msg msg = "EFAC/ECORR {} 1D1 solve incorrect.".format(method) assert np.allclose( N.solve(self.psr.residuals, left_array=self.psr.residuals), np.dot(self.psr.residuals, wd.solve(self.psr.residuals)), rtol=1e-10, ), msg msg = "EFAC/ECORR {} 2D1 solve incorrect.".format(method) T = m.get_basis() assert np.allclose(N.solve(self.psr.residuals, left_array=T), np.dot(T.T, wd.solve(self.psr.residuals)), rtol=1e-10), msg msg = "EFAC/ECORR {} 2D2 solve incorrect.".format(method) assert np.allclose(N.solve(T, left_array=T), np.dot(T.T, wd.solve(T)), rtol=1e-10), msg
def create_quant_matrix(toas, dt=1): U, _ = utils.create_quantization_matrix(toas, dt=dt, nmin=1) avetoas = np.array([toas[idx.astype(bool)].mean() for idx in U.T]) # return value slightly different than 1 to get around ECORR columns return U*1.0000001, avetoas
def _ecorr_test_ipta(self, method="sparse"): """Test of sparse/sherman-morrison ecorr signal and solve methods.""" selection = Selection(selections.nanograv_backends) efac = parameter.Uniform(0.1, 5) ecorr = parameter.Uniform(-10, -5) ef = white_signals.MeasurementNoise(efac=efac) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection, method=method) tm = gp_signals.TimingModel() s = ef + ec + tm m = s(self.ipsr) # set parameters efacs = [1.3] ecorrs = [-6.1, -6.2, -6.3, -6.4, -7.2, -8.4, -7.1, -7.9] params = { "J1713+0747_efac": efacs[0], "J1713+0747_ASP-L_log10_ecorr": ecorrs[0], "J1713+0747_ASP-S_log10_ecorr": ecorrs[1], "J1713+0747_GASP-8_log10_ecorr": ecorrs[2], "J1713+0747_GASP-L_log10_ecorr": ecorrs[3], "J1713+0747_GUPPI-8_log10_ecorr": ecorrs[4], "J1713+0747_GUPPI-L_log10_ecorr": ecorrs[5], "J1713+0747_PUPPI-L_log10_ecorr": ecorrs[6], "J1713+0747_PUPPI-S_log10_ecorr": ecorrs[7], } # get EFAC Nvec nvec0 = efacs[0]**2 * self.ipsr.toaerrs**2 # get the basis flags = [ "ASP-L", "ASP-S", "GASP-8", "GASP-L", "GUPPI-8", "GUPPI-L", "PUPPI-L", "PUPPI-S" ] bflags = self.ipsr.backend_flags Umats = [] for flag in np.unique(bflags): if flag in flags: mask = bflags == flag Umats.append( utils.create_quantization_matrix(self.ipsr.toas[mask], nmin=2)[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.ipsr.toas), nepoch)) jvec = np.zeros(nepoch) netot, ct = 0, 0 for flag in np.unique(bflags): if flag in flags: mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ct]) netot += nn ct += 1 # get covariance matrix wd = Woodbury(nvec0, U, jvec) # test msg = "EFAC/ECORR {} logdet incorrect.".format(method) N = m.get_ndiag(params) assert np.allclose(N.solve(self.ipsr.residuals, logdet=True)[1], wd.logdet(), rtol=1e-8), msg msg = "EFAC/ECORR {} D1 solve incorrect.".format(method) assert np.allclose(N.solve(self.ipsr.residuals), wd.solve(self.ipsr.residuals), rtol=1e-8), msg msg = "EFAC/ECORR {} 1D1 solve incorrect.".format(method) assert np.allclose( N.solve(self.ipsr.residuals, left_array=self.ipsr.residuals), np.dot(self.ipsr.residuals, wd.solve(self.ipsr.residuals)), rtol=1e-8, ), msg msg = "EFAC/ECORR {} 2D1 solve incorrect.".format(method) T = m.get_basis() assert np.allclose(N.solve(self.ipsr.residuals, left_array=T), np.dot(T.T, wd.solve(self.ipsr.residuals)), rtol=1e-8), msg msg = "EFAC/ECORR {} 2D2 solve incorrect.".format(method) assert np.allclose(N.solve(T, left_array=T), np.dot(T.T, wd.solve(T)), rtol=1e-8), msg
def test_pta(self): # get parameters from PAL2 style noise files params = get_noise_from_pal2(datadir + "/B1855+09_noise.txt") params2 = get_noise_from_pal2(datadir + "/J1909-3744_noise.txt") params.update(params2) # setup basic model efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() log10_A = parameter.Constant() gamma = parameter.Constant() selection = Selection(selections.by_backend) ms = white_signals.MeasurementNoise(efac=efac, log10_t2equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(pl) s = ms + ec + rn pta = s(self.psrs[0]) + s(self.psrs[1]) # set parameters pta.set_default_params(params) # get parameters efacs, equads, ecorrs, log10_A, gamma = [], [], [], [], [] for pname in [p.name for p in self.psrs]: efacs.append([ params[key] for key in sorted(params.keys()) if "efac" in key and pname in key ]) equads.append([ params[key] for key in sorted(params.keys()) if "equad" in key and pname in key ]) ecorrs.append([ params[key] for key in sorted(params.keys()) if "ecorr" in key and pname in key ]) log10_A.append(params["{}_red_noise_log10_A".format(pname)]) gamma.append(params["{}_red_noise_gamma".format(pname)]) # correct value tflags = [sorted(list(np.unique(p.backend_flags))) for p in self.psrs] cfs, logdets, phis = [], [], [] for ii, (psr, flags) in enumerate(zip(self.psrs, tflags)): nvec0 = np.zeros_like(psr.toas) for ct, flag in enumerate(flags): ind = psr.backend_flags == flag nvec0[ind] = efacs[ii][ct]**2 * ( psr.toaerrs[ind]**2 + 10**(2 * equads[ii][ct]) * np.ones(np.sum(ind))) # get the basis bflags = psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append( utils.create_quantization_matrix(psr.toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ii][ct]) netot += nn # get covariance matrix cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T) cf = sl.cho_factor(cov) logdet = np.sum(2 * np.log(np.diag(cf[0]))) cfs.append(cf) logdets.append(logdet) F, f2 = utils.createfourierdesignmatrix_red(psr.toas, nmodes=20) phi = utils.powerlaw(f2, log10_A=log10_A[ii], gamma=gamma[ii]) phis.append(phi) # tests Ns = pta.get_ndiag(params) pphis = pta.get_phi(params) pphiinvs = pta.get_phiinv(params) Ts = pta.get_basis(params) zipped = zip(logdets, cfs, phis, self.psrs, Ns, pphis, pphiinvs, Ts) for logdet, cf, phi, psr, N, pphi, pphiinv, T in zipped: msg = "EFAC/ECORR logdet incorrect." assert np.allclose(N.solve(psr.residuals, logdet=True)[1], logdet, rtol=1e-10), msg msg = "EFAC/ECORR D1 solve incorrect." assert np.allclose(N.solve(psr.residuals), sl.cho_solve(cf, psr.residuals), rtol=1e-10), msg msg = "EFAC/ECORR 1D1 solve incorrect." assert np.allclose( N.solve(psr.residuals, left_array=psr.residuals), np.dot(psr.residuals, sl.cho_solve(cf, psr.residuals)), rtol=1e-10, ), msg msg = "EFAC/ECORR 2D1 solve incorrect." assert np.allclose(N.solve(psr.residuals, left_array=T), np.dot(T.T, sl.cho_solve(cf, psr.residuals)), rtol=1e-10), msg msg = "EFAC/ECORR 2D2 solve incorrect." assert np.allclose(N.solve(T, left_array=T), np.dot(T.T, sl.cho_solve(cf, T)), rtol=1e-10), msg # spectrum test msg = "Spectrum incorrect for GP Fourier signal." assert np.all(pphi == phi), msg # inverse spectrum test msg = "Spectrum inverse incorrect for GP Fourier signal." assert np.all(pphiinv == 1 / phi), msg
def compute_like(self, npsrs=1, inc_corr=False, inc_kernel=False): # get parameters from PAL2 style noise files params = get_noise_from_pal2(datadir+'/B1855+09_noise.txt') params2 = get_noise_from_pal2(datadir+'/J1909-3744_noise.txt') params.update(params2) psrs = self.psrs if npsrs == 2 else [self.psrs[0]] if inc_corr: params.update({'GW_gamma': 4.33, 'GW_log10_A':-15.0}) # find the maximum time span to set GW frequency sampling tmin = [p.toas.min() for p in psrs] tmax = [p.toas.max() for p in psrs] Tspan = np.max(tmax) - np.min(tmin) # setup basic model efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() log10_A = parameter.Constant() gamma = parameter.Constant() selection = Selection(selections.by_backend) ef = white_signals.MeasurementNoise(efac=efac, selection=selection) eq = white_signals.EquadNoise(log10_equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(pl) orf = utils.hd_orf() crn = gp_signals.FourierBasisCommonGP(pl, orf, components=20, name='GW', Tspan=Tspan) tm = gp_signals.TimingModel() log10_sigma = parameter.Uniform(-10, -5) log10_lam = parameter.Uniform(np.log10(86400), np.log10(1500*86400)) basis = create_quant_matrix(dt=7*86400) prior = se_kernel(log10_sigma=log10_sigma, log10_lam=log10_lam) se = gp_signals.BasisGP(prior, basis, name='se') # set up kernel stuff if isinstance(inc_kernel, bool): inc_kernel = [inc_kernel] * npsrs if inc_corr: s = ef + eq + ec + rn + crn + tm else: s = ef + eq + ec + rn + tm models = [] for ik, psr in zip(inc_kernel, psrs): snew = s + se if ik else s models.append(snew(psr)) pta = signal_base.PTA(models) # set parameters pta.set_default_params(params) # SE kernel parameters log10_sigmas, log10_lams = [-7.0, -6.5], [7.0, 6.5] params.update({'B1855+09_se_log10_lam': log10_lams[0], 'B1855+09_se_log10_sigma': log10_sigmas[0], 'J1909-3744_se_log10_lam': log10_lams[1], 'J1909-3744_se_log10_sigma': log10_sigmas[1]}) # get parameters efacs, equads, ecorrs, log10_A, gamma = [], [], [], [], [] lsig, llam = [], [] for pname in [p.name for p in psrs]: efacs.append([params[key] for key in sorted(params.keys()) if 'efac' in key and pname in key]) equads.append([params[key] for key in sorted(params.keys()) if 'equad' in key and pname in key]) ecorrs.append([params[key] for key in sorted(params.keys()) if 'ecorr' in key and pname in key]) log10_A.append(params['{}_log10_A'.format(pname)]) gamma.append(params['{}_gamma'.format(pname)]) lsig.append(params['{}_se_log10_sigma'.format(pname)]) llam.append(params['{}_se_log10_lam'.format(pname)]) GW_gamma = 4.33 GW_log10_A = -15.0 # correct value tflags = [sorted(list(np.unique(p.backend_flags))) for p in psrs] cfs, logdets, phis, Ts = [], [], [], [] for ii, (ik, psr, flags) in enumerate(zip(inc_kernel, psrs, tflags)): nvec0 = np.zeros_like(psr.toas) for ct, flag in enumerate(flags): ind = psr.backend_flags == flag nvec0[ind] = efacs[ii][ct]**2 * psr.toaerrs[ind]**2 nvec0[ind] += 10**(2*equads[ii][ct]) * np.ones(np.sum(ind)) # get the basis bflags = psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append(utils.create_quantization_matrix( psr.toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn+netot] = Umats[ct] jvec[netot:nn+netot] = 10**(2*ecorrs[ii][ct]) netot += nn # get covariance matrix cov = np.diag(nvec0) + np.dot(U*jvec[None, :], U.T) cf = sl.cho_factor(cov) logdet = np.sum(2*np.log(np.diag(cf[0]))) cfs.append(cf) logdets.append(logdet) F, f2 = utils.createfourierdesignmatrix_red(psr.toas, nmodes=20, Tspan=Tspan) Mmat = psr.Mmat.copy() norm = np.sqrt(np.sum(Mmat**2, axis=0)) Mmat /= norm U2, avetoas = create_quant_matrix(psr.toas, dt=7*86400) if ik: T = np.hstack((F, Mmat, U2)) else: T = np.hstack((F, Mmat)) Ts.append(T) phi = utils.powerlaw(f2, log10_A=log10_A[ii], gamma=gamma[ii]) if inc_corr: phigw = utils.powerlaw(f2, log10_A=GW_log10_A, gamma=GW_gamma) else: phigw = np.zeros(40) K = se_kernel(avetoas, log10_sigma=log10_sigmas[ii], log10_lam=log10_lams[ii]) k = np.diag(np.concatenate((phi+phigw, np.ones(Mmat.shape[1])*1e40))) if ik: k = sl.block_diag(k, K) phis.append(k) # manually compute loglike loglike = 0 TNrs, TNTs = [], [] for ct, psr in enumerate(psrs): TNrs.append(np.dot(Ts[ct].T, sl.cho_solve(cfs[ct], psr.residuals))) TNTs.append(np.dot(Ts[ct].T, sl.cho_solve(cfs[ct], Ts[ct]))) loglike += -0.5 * (np.dot(psr.residuals, sl.cho_solve( cfs[ct], psr.residuals)) + logdets[ct]) TNr = np.concatenate(TNrs) phi = sl.block_diag(*phis) if inc_corr: hd = utils.hd_orf(psrs[0].pos, psrs[1].pos) phi[len(phis[0]):len(phis[0])+40, :40] = np.diag(phigw * hd) phi[:40, len(phis[0]):len(phis[0])+40] = np.diag(phigw * hd) cf = sl.cho_factor(phi) phiinv = sl.cho_solve(cf, np.eye(phi.shape[0])) logdetphi = np.sum(2*np.log(np.diag(cf[0]))) Sigma = sl.block_diag(*TNTs) + phiinv cf = sl.cho_factor(Sigma) expval = sl.cho_solve(cf, TNr) logdetsigma = np.sum(2*np.log(np.diag(cf[0]))) loglike -= 0.5 * (logdetphi + logdetsigma) loglike += 0.5 * np.dot(TNr, expval) method = ['partition', 'sparse', 'cliques'] for mth in method: eloglike = pta.get_lnlikelihood(params, phiinv_method=mth) msg = 'Incorrect like for npsr={}, phiinv={}'.format(npsrs, mth) assert np.allclose(eloglike, loglike), msg
def test_single_pulsar(self): # get parameters from PAL2 style noise files params = get_noise_from_pal2(datadir + "/B1855+09_noise.txt") # setup basic model efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() log10_A = parameter.Constant() gamma = parameter.Constant() selection = Selection(selections.by_backend) ms = white_signals.MeasurementNoise(efac=efac, log10_t2equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(pl) s = ms + ec + rn m = s(self.psrs[0]) # set parameters m.set_default_params(params) # get parameters efacs = [params[key] for key in sorted(params.keys()) if "efac" in key] equads = [ params[key] for key in sorted(params.keys()) if "equad" in key ] ecorrs = [ params[key] for key in sorted(params.keys()) if "ecorr" in key ] log10_A = params["B1855+09_red_noise_log10_A"] gamma = params["B1855+09_red_noise_gamma"] # correct value flags = ["430_ASP", "430_PUPPI", "L-wide_ASP", "L-wide_PUPPI"] nvec0 = np.zeros_like(self.psrs[0].toas) for ct, flag in enumerate(np.unique(flags)): ind = flag == self.psrs[0].backend_flags nvec0[ind] = efacs[ct]**2 * ( self.psrs[0].toaerrs[ind]**2 + 10**(2 * equads[ct]) * np.ones(np.sum(ind))) # get the basis bflags = self.psrs[0].backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append( utils.create_quantization_matrix(self.psrs[0].toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.psrs[0].toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ct]) netot += nn # get covariance matrix cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T) cf = sl.cho_factor(cov) logdet = np.sum(2 * np.log(np.diag(cf[0]))) # test msg = "EFAC/ECORR logdet incorrect." N = m.get_ndiag(params) assert np.allclose(N.solve(self.psrs[0].residuals, logdet=True)[1], logdet, rtol=1e-10), msg msg = "EFAC/ECORR D1 solve incorrect." assert np.allclose(N.solve(self.psrs[0].residuals), sl.cho_solve(cf, self.psrs[0].residuals), rtol=1e-10), msg msg = "EFAC/ECORR 1D1 solve incorrect." assert np.allclose( N.solve(self.psrs[0].residuals, left_array=self.psrs[0].residuals), np.dot(self.psrs[0].residuals, sl.cho_solve(cf, self.psrs[0].residuals)), rtol=1e-10, ), msg msg = "EFAC/ECORR 2D1 solve incorrect." T = m.get_basis(params) assert np.allclose( N.solve(self.psrs[0].residuals, left_array=T), np.dot(T.T, sl.cho_solve(cf, self.psrs[0].residuals)), rtol=1e-10, ), msg msg = "EFAC/ECORR 2D2 solve incorrect." assert np.allclose(N.solve(T, left_array=T), np.dot(T.T, sl.cho_solve(cf, T)), rtol=1e-10), msg F, f2 = utils.createfourierdesignmatrix_red(self.psrs[0].toas, nmodes=20) # spectrum test phi = utils.powerlaw(f2, log10_A=log10_A, gamma=gamma) msg = "Spectrum incorrect for GP Fourier signal." assert np.all(m.get_phi(params) == phi), msg # inverse spectrum test msg = "Spectrum inverse incorrect for GP Fourier signal." assert np.all(m.get_phiinv(params) == 1 / phi), msg
def create_quant_matrix(toas, dt=1): U, _ = utils.create_quantization_matrix(toas, dt=dt, nmin=1) avetoas = np.array([toas[idx.astype(bool)].mean() for idx in U.T]) # return value slightly different than 1 to get around ECORR columns return U * 1.0000001, avetoas
def _ecorr_test(self, method='sparse'): """Test of sparse/sherman-morrison ecorr signal and solve methods.""" selection = Selection(selections.by_backend) efac = parameter.Uniform(0.1, 5) ecorr = parameter.Uniform(-10, -5) ef = ws.MeasurementNoise(efac=efac, selection=selection) ec = ws.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection, method=method) tm = gp.TimingModel() s = ef + ec + tm m = s(self.psr) # set parameters efacs = [1.3, 1.4, 1.5, 1.6] ecorrs = [-6.1, -6.2, -6.3, -6.4] params = {'B1855+09_430_ASP_efac': efacs[0], 'B1855+09_430_PUPPI_efac': efacs[1], 'B1855+09_L-wide_ASP_efac': efacs[2], 'B1855+09_L-wide_PUPPI_efac': efacs[3], 'B1855+09_430_ASP_log10_ecorr': ecorrs[0], 'B1855+09_430_PUPPI_log10_ecorr': ecorrs[1], 'B1855+09_L-wide_ASP_log10_ecorr': ecorrs[2], 'B1855+09_L-wide_PUPPI_log10_ecorr': ecorrs[3]} # get EFAC Nvec flags = ['430_ASP', '430_PUPPI', 'L-wide_ASP', 'L-wide_PUPPI'] nvec0 = np.zeros_like(self.psr.toas) for ct, flag in enumerate(np.unique(flags)): ind = flag == self.psr.backend_flags nvec0[ind] = efacs[ct]**2 * self.psr.toaerrs[ind]**2 # get the basis bflags = self.psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append(utils.create_quantization_matrix( self.psr.toas[mask], nmin=2)[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn+netot] = Umats[ct] jvec[netot:nn+netot] = 10**(2*ecorrs[ct]) netot += nn # get covariance matrix wd = Woodbury(nvec0, U, jvec) # test msg = 'EFAC/ECORR {} logdet incorrect.'.format(method) N = m.get_ndiag(params) assert np.allclose(N.solve(self.psr.residuals, logdet=True)[1], wd.logdet(), rtol=1e-10), msg msg = 'EFAC/ECORR {} D1 solve incorrect.'.format(method) assert np.allclose(N.solve(self.psr.residuals), wd.solve(self.psr.residuals), rtol=1e-10), msg msg = 'EFAC/ECORR {} 1D1 solve incorrect.'.format(method) assert np.allclose( N.solve(self.psr.residuals, left_array=self.psr.residuals), np.dot(self.psr.residuals, wd.solve(self.psr.residuals)), rtol=1e-10), msg msg = 'EFAC/ECORR {} 2D1 solve incorrect.'.format(method) T = m.get_basis() assert np.allclose( N.solve(self.psr.residuals, left_array=T), np.dot(T.T, wd.solve(self.psr.residuals)), rtol=1e-10), msg msg = 'EFAC/ECORR {} 2D2 solve incorrect.'.format(method) assert np.allclose( N.solve(T, left_array=T), np.dot(T.T, wd.solve(T)), rtol=1e-10), msg
def test_combine_signals(self): """Test for combining different signals.""" # set up signal parameter ecorr = parameter.Uniform(-10, -5) ec = gp_signals.EcorrBasisModel(log10_ecorr=ecorr) pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7)) rn = gp_signals.FourierBasisGP(spectrum=pl, components=30) log10_sigma = parameter.Uniform(-10, -5) log10_lam = parameter.Uniform(np.log10(86400), np.log10(1500 * 86400)) basis = create_quant_matrix(dt=7 * 86400) prior = se_kernel(log10_sigma=log10_sigma, log10_lam=log10_lam) se = gp_signals.BasisGP(prior, basis, name="se") ts = gp_signals.TimingModel() s = ec + rn + ts + se m = s(self.psr) # parameters ecorr = -6.4 log10_A, gamma = -14.5, 4.33 log10_lam, log10_sigma = 7.4, -6.4 params = { "B1855+09_basis_ecorr_log10_ecorr": ecorr, "B1855+09_red_noise_log10_A": log10_A, "B1855+09_red_noise_gamma": gamma, "B1855+09_se_log10_lam": log10_lam, "B1855+09_se_log10_sigma": log10_sigma, } # combined basis matrix U = utils.create_quantization_matrix(self.psr.toas)[0] M = self.psr.Mmat.copy() norm = np.sqrt(np.sum(M ** 2, axis=0)) M /= norm F, f2 = utils.createfourierdesignmatrix_red(self.psr.toas, nmodes=30) U2, avetoas = create_quant_matrix(self.psr.toas, dt=7 * 86400) T = np.hstack((U, F, M, U2)) # combined prior vector jvec = 10 ** (2 * ecorr) * np.ones(U.shape[1]) phim = np.ones(self.psr.Mmat.shape[1]) * 1e40 phi = utils.powerlaw(f2, log10_A=log10_A, gamma=gamma) K = se_kernel(avetoas, log10_lam=log10_lam, log10_sigma=log10_sigma) phivec = np.concatenate((jvec, phi, phim)) phi = sl.block_diag(np.diag(phivec), K) phiinv = np.linalg.inv(phi) # basis matrix test msg = "Basis matrix incorrect for combined signal." assert np.allclose(T, m.get_basis(params)), msg # Kernal test msg = "Prior matrix incorrect for combined signal." assert np.allclose(m.get_phi(params), phi), msg # inverse Kernel test msg = "Prior matrix inverse incorrect for combined signal." assert np.allclose(m.get_phiinv(params), phiinv), msg # test shape msg = "Basis matrix shape incorrect size for combined signal." assert m.get_basis(params).shape == T.shape, msg
def make_lookup_table(psr, noisefile, outdir, sign): log10_burst_amplitudes = np.linspace( -18, -12, 60, endpoint=True) #grid points for the burst strain burst_amp_spacing = '-18,-12,60' log10_rn_amps = np.linspace( -18, -12, 60, endpoint=True) #grid points for the pulsar red noise rn_amp_spacing = '-18,-12,60' Ngammas = 70 gmin = 0 gmax = 7 gammas = np.linspace(gmin, gmax, Ngammas, endpoint=True) #grid points for gamma' gamma_spacing = '0,7,70' if not os.path.exists(outdir + psr.name): os.mkdir(outdir + psr.name) #now we need to make a pta for this pulsar to look up likelihoods for each amplitude we calculate ################## ##### PTA #### ################## tmin = psr.toas.min() / const.day tmax = psr.toas.max() / const.day U, _ = utils.create_quantization_matrix(psr.toas) eps = 9 # clip first and last N observing epochs t0min = np.floor(max(U[:, eps] * psr.toas / const.day)) t0max = np.ceil(max(U[:, -eps] * psr.toas / const.day)) Ts = np.linspace(t0min, t0max, num=100, endpoint=True) time_spacing = '{},{},100'.format(t0min, t0max) sign_spacing = '-1,1,2' pta = ee_models.model_ramp([psr], LogLikelihood, upper_limit=False, bayesephem=False, Tmin_bwm=t0min, Tmax_bwm=t0max) with open(noisefile, 'rb') as nfile: setpars = json.load(nfile) pta.set_default_params(setpars) with open(outdir + '{}/pars.txt'.format(psr.name), 'w+') as f: f.write( '{}_red_noise_gamma;{}\n{}_red_noise_log10_A;{}\n{};{}\n{};{}\n{};{}' .format(psr.name, gamma_spacing, psr.name, rn_amp_spacing, 'ramp_log10_A', burst_amp_spacing, 'ramp_t0', time_spacing, 'sign', sign_spacing)) with open(outdir + "{}/{}_{}.txt".format(psr.name, psr.name, sign), 'a+') as f: for t0 in Ts: for log10_strain in log10_burst_amplitudes: #set up the sky location of the pulsar #ramp_amp*=sign #print(psr.name + "would see an amplitude of: " + str(ramp_amp)) #Now we need to add the A_red and gamma_red params so that we have in total: #A_red, Gamma_red, A_ramp, t_ramp for log10_rn_amp in log10_rn_amps: for gamma in gammas: #now we have the four parameters, we need to ask the pta to calculate a likelihood #the pta params are in the order: #[sign, psr_gamma, psr_log10_A, ramp_log10_A, ramp_t0] lnlike = pta.get_lnlikelihood( [gamma, log10_rn_amp, log10_strain, t0, sign]) f.write('{0:.12f}\n'.format(float(lnlike)))