예제 #1
0
    def test_compare_ecorr_likelihood(self):
        """Compare basis and kernel ecorr methods."""

        selection = Selection(selections.nanograv_backends)
        ef = white_signals.MeasurementNoise()
        ec = white_signals.EcorrKernelNoise(selection=selection)
        ec2 = gp_signals.EcorrBasisModel(selection=selection)
        tm = gp_signals.TimingModel()
        m = ef + ec + tm
        m2 = ef + ec2 + tm

        pta1 = signal_base.PTA([m(p) for p in self.psrs])
        pta2 = signal_base.PTA([m2(p) for p in self.psrs])

        params = parameter.sample(pta1.params)
        l1 = pta1.get_lnlikelihood(params)

        # need to translate some names for EcorrBasis
        basis_params = {}
        for parname, parval in params.items():
            if "log10_ecorr" in parname:
                toks = parname.split("_")
                basisname = toks[0] + "_basis_ecorr_" + "_".join(toks[1:])
                basis_params[basisname] = parval
        params.update(basis_params)
        l2 = pta2.get_lnlikelihood(params)

        msg = "Likelihood mismatch between ECORR methods"
        assert np.allclose(l1, l2), msg
예제 #2
0
    def test_pta_phiinv_methods(self):
        ef = white_signals.MeasurementNoise(efac=parameter.Uniform(0.1, 5))

        span = np.max(self.psrs[0].toas) - np.min(self.psrs[0].toas)

        pl = utils.powerlaw(log10_A=parameter.Uniform(-16, -13),
                            gamma=parameter.Uniform(1, 7))

        orf = utils.hd_orf()
        vrf = utils.dipole_orf()

        rn = gp_signals.FourierBasisGP(spectrum=pl, components=30, Tspan=span)

        hdrn = gp_signals.FourierBasisCommonGP(spectrum=pl,
                                               orf=orf,
                                               components=20,
                                               Tspan=span,
                                               name='gw')

        vrn = gp_signals.FourierBasisCommonGP(spectrum=pl,
                                              orf=vrf,
                                              components=20,
                                              Tspan=span,
                                              name='vec')

        vrn2 = gp_signals.FourierBasisCommonGP(spectrum=pl,
                                               orf=vrf,
                                               components=20,
                                               Tspan=span * 1.234,
                                               name='vec2')

        # two common processes, sharing basis partially

        model = ef + rn + hdrn  # + vrn

        pta = signal_base.PTA([model(psr) for psr in self.psrs])

        ps = parameter.sample(pta.params)

        phi = pta.get_phi(ps)
        ldp = np.linalg.slogdet(phi)[1]

        inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True)
        inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True)
        inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True)
        if not isinstance(inv3, np.ndarray):
            inv3 = inv3.toarray()

        for ld in [ld1, ld2, ld3]:
            msg = "Wrong phi log determinant for two common processes"
            assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg

        for inv in [inv1, inv2, inv3]:
            msg = "Wrong phi inverse for two common processes"
            assert np.allclose(np.dot(phi, inv),
                               np.eye(phi.shape[0]),
                               rtol=1e-15,
                               atol=1e-6), msg

        for inva, invb in itertools.combinations([inv1, inv2, inv3], 2):
            assert np.allclose(inva, invb)

        # two common processes, no sharing basis

        model = ef + rn + vrn2

        pta = signal_base.PTA([model(psr) for psr in self.psrs])

        ps = parameter.sample(pta.params)

        phi = pta.get_phi(ps)
        ldp = np.linalg.slogdet(phi)[1]

        inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True)
        inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True)
        inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True)
        if not isinstance(inv3, np.ndarray):
            inv3 = inv3.toarray()

        for ld in [ld1, ld2, ld3]:
            msg = "Wrong phi log determinant for two common processes"
            assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg

        for inv in [inv1, inv2, inv3]:
            msg = "Wrong phi inverse for two processes"
            assert np.allclose(np.dot(phi, inv),
                               np.eye(phi.shape[0]),
                               rtol=1e-15,
                               atol=1e-6), msg

        for inva, invb in itertools.combinations([inv1, inv2, inv3], 2):
            assert np.allclose(inva, invb)

        # three common processes, sharing basis partially

        model = ef + rn + hdrn + vrn

        pta = signal_base.PTA([model(psr) for psr in self.psrs])

        ps = parameter.sample(pta.params)

        phi = pta.get_phi(ps)
        ldp = np.linalg.slogdet(phi)[1]

        inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True)
        inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True)
        inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True)
        if not isinstance(inv3, np.ndarray):
            inv3 = inv3.toarray()

        for ld in [ld1, ld3]:
            msg = "Wrong phi log determinant for two common processes"
            assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg

        for inv in [inv1, inv3]:
            msg = "Wrong phi inverse for three common processes"
            assert np.allclose(np.dot(phi, inv),
                               np.eye(phi.shape[0]),
                               rtol=1e-15,
                               atol=1e-6), msg

        for inva, invb in itertools.combinations([inv1, inv3], 2):
            assert np.allclose(inva, invb)

        # four common processes, three sharing basis partially

        model = ef + rn + hdrn + vrn + vrn2

        pta = signal_base.PTA([model(psr) for psr in self.psrs])

        ps = parameter.sample(pta.params)

        phi = pta.get_phi(ps)
        ldp = np.linalg.slogdet(phi)[1]

        inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True)
        inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True)
        inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True)
        if not isinstance(inv3, np.ndarray):
            inv3 = inv3.toarray()

        for ld in [ld1, ld3]:
            msg = "Wrong phi log determinant for two common processes"
            assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg

        for inv in [inv1, inv3]:
            msg = "Wrong phi inverse for four processes"
            assert np.allclose(np.dot(phi, inv),
                               np.eye(phi.shape[0]),
                               rtol=1e-15,
                               atol=1e-6), msg

        for inva, invb in itertools.combinations([inv1, inv3], 2):
            assert np.allclose(inva, invb)
예제 #3
0
    def test_wideband(self):
        ms = white_signals.MeasurementNoise(selection=Selection(selections.by_backend))

        dm = gp_signals.WidebandTimingModel(
            dmefac=parameter.Uniform(0.9, 1.1),
            dmefac_selection=Selection(selections.by_backend),
            dmjump=parameter.Normal(0, 1),
            dmjump_selection=Selection(selections.by_frontend),
        )

        model = ms + dm

        pta = signal_base.PTA([model(self.psr)])

        ps = parameter.sample(pta.params)

        pta.get_lnlikelihood(ps)

        dmtiming = pta.pulsarmodels[0].signals[1]

        msg = "DMEFAC masks do not cover the data."
        assert np.all(sum(dmtiming._dmefac_masks) == 1), msg

        msg = "DMJUMP masks do not cover the data."
        assert np.all(sum(dmtiming._dmjump_masks) == 1), msg

        # start with zero DMEFAC and DMJUMP
        p0 = {par.name: (1 if "dmefac" in par.name else 0) for par in dmtiming.params}

        pta.get_lnlikelihood(params=p0)

        phi0 = dmtiming.get_phi(params=p0)
        dl0 = dmtiming.get_delay(params=p0)

        dm_flags, dme_flags = np.array(self.psr.flags["pp_dm"], "d"), np.array(self.psr.flags["pp_dme"], "d")

        delays = np.zeros_like(self.psr.toas)

        check = 0
        for index, par in enumerate(self.psr.fitpars):
            if "DMX" not in par:
                msg = "Problem with unbound timing parameters"
                assert phi0[index] == 1e40, msg
            else:
                dmx = self.psr.dmx[par]
                which = (dmx["DMXR1"] <= (self.psr.stoas / 86400)) & ((self.psr.stoas / 86400) < dmx["DMXR2"])
                check += which

                avgdm = np.sum(dm_flags[which] / dme_flags[which] ** 2) / np.sum(1.0 / dme_flags[which] ** 2)
                vardm = 1.0 / np.sum(1.0 / dme_flags[which] ** 2)

                msg = "Priors do not match"
                assert np.allclose(vardm, phi0[index]), msg

                delays[which] = (avgdm - self.psr.dm - dmx["DMX"]) / (2.41e-4 * self.psr.freqs[which] ** 2)

        msg = "Not all TOAs are covered by DMX"
        assert np.all(check == 1)

        msg = "Delays do not match"
        assert np.allclose(dl0, delays), msg

        # sample DMEFACs randomly
        p1 = {par.name: (parameter.sample(par)[par.name] if "dmefac" in par.name else 0) for par in dmtiming.params}

        pta.get_lnlikelihood(params=p1)

        phi1 = dmtiming.get_phi(params=p1)
        dl1 = dmtiming.get_delay(params=p1)

        sel = Selection(selections.by_backend)(self.psr)
        msg = "Problem making selection"
        assert np.all(sum(m for m in sel.masks.values()) == 1), msg

        dme_flags_var = dme_flags.copy()

        for key, mask in sel.masks.items():
            dmefac = p1["J1832-0836_" + key + "_dmefac"]
            dme_flags_var[mask] *= dmefac

        for index, par in enumerate(self.psr.fitpars):
            if "DMX" not in par:
                msg = "Problem with unbound timing parameters"
                assert phi1[index] == 1e40, msg
            else:
                dmx = self.psr.dmx[par]
                which = (dmx["DMXR1"] <= (self.psr.stoas / 86400)) & ((self.psr.stoas / 86400) < dmx["DMXR2"])

                avgdm = np.sum(dm_flags[which] / dme_flags_var[which] ** 2) / np.sum(1.0 / dme_flags_var[which] ** 2)
                vardm = 1.0 / np.sum(1.0 / dme_flags_var[which] ** 2)

                msg = "Priors do not match"
                assert np.allclose(vardm, phi1[index]), msg

                delays[which] = (avgdm - self.psr.dm - dmx["DMX"]) / (2.41e-4 * self.psr.freqs[which] ** 2)

        msg = "Delays do not match"
        assert np.allclose(dl1, delays), msg