def test_fourier_red_noise_pshift(self):
        """Test that red noise signal returns correct values."""
        # set up signal parameter
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7))
        rn = gp_signals.FourierBasisGP(spectrum=pl, components=30, pshift=True, pseed=42)
        rnm = rn(self.psr)

        # parameters
        log10_A, gamma = -14.5, 4.33
        params = {"B1855+09_red_noise_log10_A": log10_A, "B1855+09_red_noise_gamma": gamma}

        # basis matrix test
        F, f2 = utils.createfourierdesignmatrix_red(self.psr.toas, nmodes=30, pshift=True, pseed=42)
        msg = "F matrix incorrect for GP Fourier signal."
        assert np.allclose(F, rnm.get_basis(params)), msg

        # spectrum test
        phi = utils.powerlaw(f2, log10_A=log10_A, gamma=gamma)
        msg = "Spectrum incorrect for GP Fourier signal."
        assert np.all(rnm.get_phi(params) == phi), msg

        # inverse spectrum test
        msg = "Spectrum inverse incorrect for GP Fourier signal."
        assert np.all(rnm.get_phiinv(params) == 1 / phi), msg

        # test shape
        msg = "F matrix shape incorrect"
        assert rnm.get_basis(params).shape == F.shape, msg
    def test_fourier_red_user_freq_array(self):
        """Test that red noise signal returns correct values with user defined
        frequency array."""
        # set parameters
        log10_A, gamma = -14.5, 4.33
        params = {"B1855+09_red_noise_log10_A": log10_A, "B1855+09_red_noise_gamma": gamma}

        F, f2 = utils.createfourierdesignmatrix_red(self.psr.toas, nmodes=30)

        # set up signal model. use list of frequencies to make basis
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7))
        rn = gp_signals.FourierBasisGP(spectrum=pl, modes=f2[::2])
        rnm = rn(self.psr)

        # basis matrix test
        msg = "F matrix incorrect for GP Fourier signal."
        assert np.allclose(F, rnm.get_basis(params)), msg

        # spectrum test
        phi = utils.powerlaw(f2, log10_A=log10_A, gamma=gamma)
        msg = "Spectrum incorrect for GP Fourier signal."
        assert np.all(rnm.get_phi(params) == phi), msg

        # inverse spectrum test
        msg = "Spectrum inverse incorrect for GP Fourier signal."
        assert np.all(rnm.get_phiinv(params) == 1 / phi), msg

        # test shape
        msg = "F matrix shape incorrect"
        assert rnm.get_basis(params).shape == F.shape, msg
Beispiel #3
0
    def test_fourier_red_noise(self):
        """Test that red noise signal returns correct values."""
        # set up signal parameter
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(1,7))
        rn = gs.FourierBasisGP(spectrum=pl, components=30)
        rnm = rn(self.psr)

        # parameters
        log10_A, gamma = -14.5, 4.33
        params = {'B1855+09_log10_A': log10_A,
                  'B1855+09_gamma': gamma}

        # basis matrix test
        F, f2 = utils.createfourierdesignmatrix_red(
            self.psr.toas, nmodes=30)
        msg = 'F matrix incorrect for GP Fourier signal.'
        assert np.allclose(F, rnm.get_basis(params)), msg

        # spectrum test
        phi = utils.powerlaw(f2, log10_A=log10_A, gamma=gamma)
        msg = 'Spectrum incorrect for GP Fourier signal.'
        assert np.all(rnm.get_phi(params) == phi), msg

        # inverse spectrum test
        msg = 'Spectrum inverse incorrect for GP Fourier signal.'
        assert np.all(rnm.get_phiinv(params) == 1/phi), msg

        # test shape
        msg = 'F matrix shape incorrect'
        assert rnm.get_basis(params).shape == F.shape, msg
    def test_gp_parameter(self):
        """Test GP basis model with parameterized basis."""

        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12),
                            gamma=parameter.Uniform(0, 7))
        basis_env = utils.createfourierdesignmatrix_env(
            log10_Amp=parameter.Uniform(-10, -5),
            t0=parameter.Uniform(4.3e9, 5e9),
            log10_Q=parameter.Uniform(0, 4))

        basis_red = utils.createfourierdesignmatrix_red()

        rn_env = gp_signals.BasisGP(pl, basis_env, name="env")
        rn = gp_signals.BasisGP(pl, basis_red)
        s = rn_env + rn
        m = s(self.psr)

        # parameters
        log10_A, gamma = -14.5, 4.33
        log10_A_env, gamma_env = -14.0, 2.5
        log10_Amp, log10_Q, t0 = -7.3, np.log10(345), 55000 * 86400
        params = {
            "B1855+09_log10_A": log10_A,
            "B1855+09_gamma": gamma,
            "B1855+09_env_log10_A": log10_A_env,
            "B1855+09_env_gamma": gamma_env,
            "B1855+09_env_log10_Q": log10_Q,
            "B1855+09_env_log10_Amp": log10_Amp,
            "B1855+09_env_t0": t0,
        }

        # get basis
        Fred, f2_red = utils.createfourierdesignmatrix_red(self.psr.toas,
                                                           nmodes=30)
        Fenv, f2_env = utils.createfourierdesignmatrix_env(self.psr.toas,
                                                           nmodes=30,
                                                           log10_Amp=log10_Amp,
                                                           log10_Q=log10_Q,
                                                           t0=t0)
        F = np.hstack((Fenv, Fred))
        phi_env = utils.powerlaw(f2_env, log10_A=log10_A_env, gamma=gamma_env)
        phi_red = utils.powerlaw(f2_red, log10_A=log10_A, gamma=gamma)
        phi = np.concatenate((phi_env, phi_red))

        # basis matrix test
        msg = "F matrix incorrect for GP Fourier signal."
        assert np.allclose(F, m.get_basis(params)), msg

        # spectrum test
        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

        # test shape
        msg = "F matrix shape incorrect"
        assert m.get_basis(params).shape == F.shape, msg
Beispiel #5
0
    def test_red_noise_add(self):
        """Test that red noise addition only returns independent columns."""
        # set up signals
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(1,7))
        cpl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12)('log10_Agw'),
                             gamma=parameter.Uniform(1,7)('gamma_gw'))

        # parameters
        log10_A, gamma = -14.5, 4.33
        log10_Ac, gammac = -15.5, 1.33
        params = {'B1855+09_log10_A': log10_A,
                  'B1855+09_gamma': gamma,
                  'log10_Agw': log10_Ac,
                  'gamma_gw': gammac}

        Tmax = self.psr.toas.max() - self.psr.toas.min()
        tpars = [(30, 20, Tmax, Tmax), (20, 30, Tmax, Tmax),
                 (30, 30, Tmax, Tmax), (30, 20, Tmax, 1.123*Tmax),
                 (20, 30, Tmax, 1.123*Tmax), (30, 30, 1.123*Tmax, Tmax)]

        for (nf1, nf2, T1, T2) in tpars:

            rn = gs.FourierBasisGP(spectrum=pl, components=nf1, Tspan=T1)
            crn = gs.FourierBasisGP(spectrum=cpl, components=nf2, Tspan=T2)
            s = rn + crn
            rnm = s(self.psr)

            # set up frequencies
            F1, f1 = utils.createfourierdesignmatrix_red(
                self.psr.toas, nmodes=nf1, Tspan=T1)
            F2, f2 = utils.createfourierdesignmatrix_red(
                self.psr.toas, nmodes=nf2, Tspan=T2)

            # test power spectrum
            p1 = utils.powerlaw(f1, log10_A, gamma)
            p2 = utils.powerlaw(f2, log10_Ac, gammac)
            if T1 == T2:
                nf = max(2*nf1, 2*nf2)
                phi = np.zeros(nf)
                F = F1 if nf1 > nf2 else F2
                phi[:2*nf1] = p1
                phi[:2*nf2] += p2
                F[:,]
            else:
                phi = np.concatenate((p1, p2))
                F = np.hstack((F1, F2))

            msg = 'Combined red noise PSD incorrect '
            msg += 'for {} {} {} {}'.format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phi(params) == phi), msg

            msg = 'Combined red noise PSD inverse incorrect '
            msg += 'for {} {} {} {}'.format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phiinv(params) == 1/phi), msg

            msg = 'Combined red noise Fmat incorrect '
            msg += 'for {} {} {} {}'.format(nf1, nf2, T1, T2)
            assert np.allclose(F, rnm.get_basis(params)), msg
    def test_fourier_red_noise_backend(self):
        """Test that red noise-backend signal returns correct values."""
        # set up signal parameter
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12),
                            gamma=parameter.Uniform(1, 7))
        selection = Selection(selections.by_backend)
        rn = gp_signals.FourierBasisGP(spectrum=pl,
                                       components=30,
                                       selection=selection)
        rnm = rn(self.psr)

        # parameters
        log10_As = [-14, -14.4, -15, -14.8]
        gammas = [2.3, 4.4, 1.8, 5.6]
        params = {
            "B1855+09_red_noise_430_ASP_gamma": gammas[0],
            "B1855+09_red_noise_430_PUPPI_gamma": gammas[1],
            "B1855+09_red_noise_L-wide_ASP_gamma": gammas[2],
            "B1855+09_red_noise_L-wide_PUPPI_gamma": gammas[3],
            "B1855+09_red_noise_430_ASP_log10_A": log10_As[0],
            "B1855+09_red_noise_430_PUPPI_log10_A": log10_As[1],
            "B1855+09_red_noise_L-wide_ASP_log10_A": log10_As[2],
            "B1855+09_red_noise_L-wide_PUPPI_log10_A": log10_As[3],
        }

        # get the basis
        bflags = self.psr.backend_flags
        Fmats, fs, phis = [], [], []
        for ct, flag in enumerate(np.unique(bflags)):
            mask = bflags == flag
            F, f = utils.createfourierdesignmatrix_red(self.psr.toas[mask], 30)
            Fmats.append(F)
            fs.append(f)
            phis.append(utils.powerlaw(f, log10_As[ct], gammas[ct]))

        nf = sum(F.shape[1] for F in Fmats)
        F = np.zeros((len(self.psr.toas), nf))
        phi = np.hstack([p for p in phis])
        nftot = 0
        for ct, flag in enumerate(np.unique(bflags)):
            mask = bflags == flag
            nn = Fmats[ct].shape[1]
            F[mask, nftot:nn + nftot] = Fmats[ct]
            nftot += nn

        msg = "F matrix incorrect for GP Fourier backend signal."
        assert np.allclose(F, rnm.get_basis(params)), msg

        # spectrum test
        msg = "Spectrum incorrect for GP Fourier backend signal."
        assert np.all(rnm.get_phi(params) == phi), msg

        # inverse spectrum test
        msg = "Spectrum inverse incorrect for GP Fourier backend signal."
        assert np.all(rnm.get_phiinv(params) == 1 / phi), msg

        # test shape
        msg = "F matrix shape incorrect"
        assert rnm.get_basis(params).shape == F.shape, msg
Beispiel #7
0
    def test_gp_parameter(self):
        """Test GP basis model with parameterized basis."""

        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(0, 7))
        basis_env = utils.createfourierdesignmatrix_env(
            log10_Amp=parameter.Uniform(-10, -5),
            t0=parameter.Uniform(4.3e9, 5e9),
            log10_Q=parameter.Uniform(0,4))

        basis_red = utils.createfourierdesignmatrix_red()

        rn_env = gs.BasisGP(pl, basis_env, name='env')
        rn = gs.BasisGP(pl, basis_red)
        s = rn_env + rn
        m = s(self.psr)

        # parameters
        log10_A, gamma = -14.5, 4.33
        log10_A_env, gamma_env = -14.0, 2.5
        log10_Amp, log10_Q, t0 = -7.3, np.log10(345), 55000*86400
        params = {'B1855+09_log10_A': log10_A,
                  'B1855+09_gamma': gamma,
                  'B1855+09_env_log10_A': log10_A_env,
                  'B1855+09_env_gamma': gamma_env,
                  'B1855+09_env_log10_Q': log10_Q,
                  'B1855+09_env_log10_Amp': log10_Amp,
                  'B1855+09_env_t0': t0}

        # get basis
        Fred, f2_red = utils.createfourierdesignmatrix_red(
            self.psr.toas, nmodes=30)
        Fenv, f2_env = utils.createfourierdesignmatrix_env(
            self.psr.toas, nmodes=30, log10_Amp=log10_Amp,
            log10_Q=log10_Q, t0=t0)
        F = np.hstack((Fenv, Fred))
        phi_env = utils.powerlaw(f2_env, log10_A=log10_A_env,
                                 gamma=gamma_env)
        phi_red = utils.powerlaw(f2_red, log10_A=log10_A,
                                 gamma=gamma)
        phi = np.concatenate((phi_env, phi_red))

        # basis matrix test
        msg = 'F matrix incorrect for GP Fourier signal.'
        assert np.allclose(F, m.get_basis(params)), msg

        # spectrum test
        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

        # test shape
        msg = 'F matrix shape incorrect'
        assert m.get_basis(params).shape == F.shape, msg
Beispiel #8
0
    def test_fourier_red_noise_backend(self):
        """Test that red noise-backend signal returns correct values."""
        # set up signal parameter
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(1,7))
        selection = Selection(selections.by_backend)
        rn = gs.FourierBasisGP(spectrum=pl, components=30, selection=selection)
        rnm = rn(self.psr)

        # parameters
        log10_As = [-14, -14.4, -15, -14.8]
        gammas = [2.3, 4.4, 1.8, 5.6]
        params = {'B1855+09_430_ASP_gamma': gammas[0],
                  'B1855+09_430_PUPPI_gamma': gammas[1],
                  'B1855+09_L-wide_ASP_gamma': gammas[2],
                  'B1855+09_L-wide_PUPPI_gamma': gammas[3],
                  'B1855+09_430_ASP_log10_A': log10_As[0],
                  'B1855+09_430_PUPPI_log10_A': log10_As[1],
                  'B1855+09_L-wide_ASP_log10_A': log10_As[2],
                  'B1855+09_L-wide_PUPPI_log10_A': log10_As[3]}

        # get the basis
        bflags = self.psr.backend_flags
        Fmats, fs, phis = [], [], []
        for ct, flag in enumerate(np.unique(bflags)):
            mask = bflags == flag
            F, f = utils.createfourierdesignmatrix_red(
                self.psr.toas[mask], 30)
            Fmats.append(F)
            fs.append(f)
            phis.append(utils.powerlaw(f, log10_As[ct], gammas[ct]))

        nf = sum(F.shape[1] for F in Fmats)
        F = np.zeros((len(self.psr.toas), nf))
        phi = np.hstack(p for p in phis)
        nftot = 0
        for ct, flag in enumerate(np.unique(bflags)):
            mask = bflags == flag
            nn = Fmats[ct].shape[1]
            F[mask, nftot:nn+nftot] = Fmats[ct]
            nftot += nn

        msg = 'F matrix incorrect for GP Fourier backend signal.'
        assert np.allclose(F, rnm.get_basis(params)), msg

        # spectrum test
        msg = 'Spectrum incorrect for GP Fourier backend signal.'
        assert np.all(rnm.get_phi(params) == phi), msg

        # inverse spectrum test
        msg = 'Spectrum inverse incorrect for GP Fourier backend signal.'
        assert np.all(rnm.get_phiinv(params) == 1/phi), msg

        # test shape
        msg = 'F matrix shape incorrect'
        assert rnm.get_basis(params).shape == F.shape, msg
Beispiel #9
0
    def chromred(self, option="vary"):
        """
    This is an generalization of DM noise, with the dependence of Fourier 
    amplitudes on radio frequency nu as ~ 1/nu^chi, where chi is a free
    parameter.

    Examples of chi:

    - Pulse scattering in the ISM: chi = 4 (Lyne A., Graham-Smith F., 2012,
      Pulsar astronomy)
    - Refractive propagation: chi = 6.4 (Shannon, R. M., and J. M. Cordes.
      MNRAS, 464.2 (2017): 2075-2089).
    """
        log10_A = parameter.Uniform(self.params.dmn_lgA[0],
                                    self.params.dmn_lgA[1])
        gamma = parameter.Uniform(self.params.dmn_gamma[0],
                                  self.params.dmn_gamma[1])
        pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                            components=self.params.red_general_nfouriercomp)
        nfreqs = self.determine_nfreqs(sel_func_name=None)

        if option == "vary":
            idx = parameter.Uniform(self.params.chrom_idx[0], \
                                    self.params.chrom_idx[1])
        else:
            idx = option

        chr_basis = models.createfourierdesignmatrix_chromatic(
            nmodes=nfreqs, Tspan=self.params.Tspan, idx=idx)

        chrn = gp_signals.BasisGP(pl, chr_basis, name='chromatic_gp')

        return chrn
Beispiel #10
0
 def spin_noise(self, option="powerlaw"):
     """
 Achromatic red noise process is called spin noise, although generally
 this model is used to model any unknown red noise. If this model is 
 preferred over chromatic models then the observed noise is really spin
 noise, associated with pulsar rotational irregularities.
 """
     log10_A = parameter.Uniform(self.params.sn_lgA[0],
                                 self.params.sn_lgA[1])
     gamma = parameter.Uniform(self.params.sn_gamma[0],
                               self.params.sn_gamma[1])
     if option == "powerlaw":
         pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                             components=self.params.red_general_nfouriercomp)
     elif option == "turnover":
         fc = parameter.Uniform(self.params.sn_fc[0], self.params.sn_fc[1])
         pl = powerlaw_bpl(log10_A=log10_A,
                           gamma=gamma,
                           fc=fc,
                           components=self.params.red_general_nfouriercomp)
     nfreqs = self.determine_nfreqs(sel_func_name=None)
     sn = gp_signals.FourierBasisGP(spectrum=pl,
                                    Tspan=self.params.Tspan,
                                    name='red_noise',
                                    components=nfreqs)
     return sn
    def paired_ppta_band_noise(self, option=[]):
        """
    Including band noise terms for paired values of the PPTA "-B" flag:
    joint 1020-cm and 4050-cm red processes.
    """
        for ii, paired_band_term in enumerate(option):

            log10_A = parameter.Uniform(self.params.syn_lgA[0],
                                        self.params.syn_lgA[1])
            gamma = parameter.Uniform(self.params.syn_gamma[0],\
                                      self.params.syn_gamma[1])
            pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                                components=self.params.red_general_nfouriercomp)

            setattr(self, paired_band_term, globals()[paired_band_term])
            nfreqs = self.determine_nfreqs(sel_func_name=paired_band_term)

            pbn_term = gp_signals.FourierBasisGP(spectrum=pl, Tspan=self.params.Tspan,
                                              name='band_noise_' + paired_band_term,
                                              selection=selections.Selection( \
                                              self.__dict__[paired_band_term] ),
                                              components=nfreqs)
            if ii == 0:
                pbn = pbn_term
            elif ii > 0:
                pbn += pbn_term

        return pbn
Beispiel #12
0
def red_noise_block(prior='log-uniform', Tspan=None):
    """
    Returns red noise model:
        1. Red noise modeled as a power-law with 30 sampling frequencies
    :param prior:
        Prior on log10_A. Default if "log-uniform". Use "uniform" for
        upper limits.
    :param Tspan:
        Sets frequency sampling f_i = i / Tspan. Default will
        use overall time span for indivicual pulsar.
    """

    # red noise parameters
    if prior == 'uniform':
        log10_A = parameter.LinearExp(-20, -11)
    elif prior == 'log-uniform':
        log10_A = parameter.Uniform(-20, -11)
    else:
        raise ValueError('Unknown prior for red noise amplitude!')

    gamma = parameter.Uniform(0, 7)

    # red noise signal
    pl = utils.powerlaw(log10_A=log10_A, gamma=gamma)
    rn = gp_signals.FourierBasisGP(pl, components=30, Tspan=Tspan)

    return rn
    def test_pshift_fourier(self):
        """Test Fourier basis with prescribed phase shifts."""

        # build a SignalCollection with timing model and red noise with phase shifts

        Tspan = self.psr.toas.max() - self.psr.toas.min()
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(0, 7))

        ts = gp_signals.TimingModel()
        rn = gp_signals.FourierBasisGP(pl, components=5, Tspan=Tspan, pseed=parameter.Uniform(0, 32768))

        s = ts + rn
        m = s(self.psr)

        b1 = m.signals[1].get_basis()
        b2 = utils.createfourierdesignmatrix_red(nmodes=5, Tspan=Tspan)("")(self.psr.toas)[0]
        msg = "Fourier bases incorrect (no phase shifts)"
        assert np.all(b1 == b2), msg

        b1 = m.signals[1].get_basis()
        b2 = utils.createfourierdesignmatrix_red(nmodes=5, Tspan=Tspan, pseed=5)("")(self.psr.toas)[0]
        msg = "Fourier bases incorrect (no-parameter call vs phase shift 5)"
        assert not np.all(b1 == b2), msg

        b1 = m.signals[1].get_basis(params={self.psr.name + "_red_noise_pseed": 5})
        b2 = utils.createfourierdesignmatrix_red(nmodes=5, Tspan=Tspan, pseed=5)("")(self.psr.toas)[0]
        msg = "Fourier bases incorrect (phase shift 5)"
        assert np.all(b1 == b2), msg

        b1 = m.signals[1].get_basis(params={self.psr.name + "_red_noise_pseed": 5})
        b2 = utils.createfourierdesignmatrix_red(nmodes=5, Tspan=Tspan)("")(self.psr.toas)[0]
        msg = "Fourier bases incorrect (phase-shift-5 call vs no phase shift)"
        assert not np.all(b1 == b2), msg
Beispiel #14
0
    def dm_noise(self, option="powerlaw"):
        """
    A term to account for stochastic variations in DM. It is based on spin
    noise model, with Fourier amplitudes depending on radio frequency nu
    as ~ 1/nu^2.
    """
        log10_A = parameter.Uniform(self.params.dmn_lgA[0],
                                    self.params.dmn_lgA[1])
        gamma = parameter.Uniform(self.params.dmn_gamma[0],
                                  self.params.dmn_gamma[1])
        if option == "powerlaw":
            pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                                components=self.params.red_general_nfouriercomp)
        elif option == "turnover":
            fc = parameter.Uniform(self.params.sn_fc[0], self.params.sn_fc[1])
            pl = powerlaw_bpl(log10_A=log10_A,
                              gamma=gamma,
                              fc=fc,
                              components=self.params.red_general_nfouriercomp)
        nfreqs = self.determine_nfreqs(sel_func_name=None)
        dm_basis = utils.createfourierdesignmatrix_dm(nmodes=nfreqs,
                                                      Tspan=self.params.Tspan,
                                                      fref=self.params.fref)
        dmn = gp_signals.BasisGP(pl, dm_basis, name='dm_gp')

        return dmn
Beispiel #15
0
    def test_parameterized_orf(self):
        T1 = 3.16e8
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(1,7))
        orf = hd_orf_generic(a=parameter.Uniform(0,5),
                             b=parameter.Uniform(0,5),
                             c=parameter.Uniform(0,5))
        rn = gp_signals.FourierBasisGP(spectrum=pl, Tspan=T1, components=30)
        crn = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=orf,
                                              components=30, name='gw',
                                              Tspan=T1)

        model = rn + crn
        pta = model(self.psrs[0]) + model(self.psrs[1])

        lA1, gamma1 = -13, 1e-15
        lA2, gamma2 = -13.3, 1e-15
        lAc, gammac = -13.1, 1e-15
        a, b, c = 1.9, 0.4, 0.23

        params = {'gw_log10_A': lAc, 'gw_gamma': gammac,
                  'gw_a': a, 'gw_b':b, 'gw_c':c,
                  'B1855+09_log10_A': lA1, 'B1855+09_gamma': gamma1,
                  'J1909-3744_log10_A': lA2, 'J1909-3744_gamma': gamma2}

        phi = pta.get_phi(params)
        phiinv = pta.get_phiinv(params)

        F1, f1 = utils.createfourierdesignmatrix_red(
            self.psrs[0].toas, nmodes=30, Tspan=T1)
        F2, f2 = utils.createfourierdesignmatrix_red(
            self.psrs[1].toas, nmodes=30, Tspan=T1)

        msg = 'F matrix incorrect'
        assert np.allclose(pta.get_basis(params)[0], F1, rtol=1e-10), msg
        assert np.allclose(pta.get_basis(params)[1], F2, rtol=1e-10), msg

        nftot = 120
        phidiag = np.zeros(nftot)
        phit = np.zeros((nftot, nftot))

        phidiag[:60] = utils.powerlaw(f1, lA1, gamma1)
        phidiag[:60] += utils.powerlaw(f1, lAc, gammac)
        phidiag[60:] = utils.powerlaw(f2, lA2, gamma2)
        phidiag[60:] += utils.powerlaw(f2, lAc, gammac)

        phit[np.diag_indices(nftot)] = phidiag
        orf = hd_orf_generic(self.psrs[0].pos, self.psrs[1].pos, a=a, b=b, c=c)
        spec = utils.powerlaw(f1, log10_A=lAc, gamma=gammac)
        phit[:60, 60:] = np.diag(orf*spec)
        phit[60:, :60] = phit[:60, 60:]

        msg = '{} {}'.format(np.diag(phi), np.diag(phit))
        assert np.allclose(phi, phit, rtol=1e-15, atol=1e-17), msg
        msg = 'PTA Phi inverse is incorrect {}.'.format(params)
        assert np.allclose(phiinv, np.linalg.inv(phit),
                           rtol=1e-15, atol=1e-17), msg
Beispiel #16
0
  def gwb(self,option="hd_vary_gamma"):
    """
    Spatially-correlated quadrupole signal from the nanohertz stochastic
    gravitational-wave background.
    """
    name = 'gw'

    if "_nfreqs" in option:
      split_idx_nfreqs = option.split('_').index('nfreqs') - 1
      nfreqs = int(option.split('_')[split_idx_nfreqs])
    else:
      nfreqs = self.determine_nfreqs(sel_func_name=None, common_signal=True)

    if "_gamma" in option:
      amp_name = '{}_log10_A'.format(name)
      if self.params.gwb_lgA_prior == "uniform":
        gwb_log10_A = parameter.Uniform(self.params.gwb_lgA[0],
                                        self.params.gwb_lgA[1])(amp_name)
      elif self.params.gwb_lgA_prior == "linexp":
        gwb_log10_A = parameter.LinearExp(self.params.gwb_lgA[0],
                                          self.params.gwb_lgA[1])(amp_name)

      gam_name = '{}_gamma'.format(name)
      if "vary_gamma" in option:
        gwb_gamma = parameter.Uniform(self.params.gwb_gamma[0],
                                      self.params.gwb_gamma[1])(gam_name)
      elif "fixed_gamma" in option:
        gwb_gamma = parameter.Constant(4.33)(gam_name)
      else:
        split_idx_gamma = option.split('_').index('gamma') - 1
        gamma_val = float(option.split('_')[split_idx_gamma])
        gwb_gamma = parameter.Constant(gamma_val)(gam_name)
      gwb_pl = utils.powerlaw(log10_A=gwb_log10_A, gamma=gwb_gamma)
    elif "freesp" in option:
      amp_name = '{}_log10_rho'.format(name)
      log10_rho = parameter.Uniform(self.params.gwb_lgrho[0], 
                                    self.params.gwb_lgrho[1], 
                                    size=nfreqs)(amp_name)
      gwb_pl = gp_priors.free_spectrum(log10_rho=log10_rho)

    if "hd" in option:
      orf = utils.hd_orf()
      gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs,
                                            name='gwb', Tspan=self.params.Tspan)
    else:
      gwb = gp_signals.FourierBasisGP(gwb_pl, components=nfreqs,
                                      name='gwb', Tspan=self.params.Tspan)

    return gwb
        def test_formalism(self):
            # create marginalized model
            ef = white_signals.MeasurementNoise(
                efac=parameter.Uniform(0.1, 5.0))
            tm = gp_signals.TimingModel()
            ec = gp_signals.EcorrBasisModel(
                log10_ecorr=parameter.Uniform(-10, -5))
            pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12),
                                gamma=parameter.Uniform(1, 7))
            rn = gp_signals.FourierBasisGP(spectrum=pl, components=10)
            model = ef + tm + ec + rn
            pta = signal_base.PTA([model(self.psr)])

            # create hierarchical model
            tmc = gp_signals.TimingModel(coefficients=True)
            ecc = gp_signals.EcorrBasisModel(log10_ecorr=parameter.Uniform(
                -10, -5),
                                             coefficients=True)
            rnc = gp_signals.FourierBasisGP(spectrum=pl,
                                            components=10,
                                            coefficients=True)
            modelc = ef + tmc + ecc + rnc
            ptac = signal_base.PTA([modelc(self.psr)])

            ps = {
                "B1855+09_efac": 1,
                "B1855+09_basis_ecorr_log10_ecorr": -6,
                "B1855+09_red_noise_log10_A": -14,
                "B1855+09_red_noise_gamma": 3,
            }
            psc = utils.get_coefficients(pta, ps)

            d1 = ptac.get_delay(psc)[0]
            d2 = (np.dot(pta.pulsarmodels[0].signals[1].get_basis(ps),
                         psc["B1855+09_linear_timing_model_coefficients"]) +
                  np.dot(pta.pulsarmodels[0].signals[2].get_basis(ps),
                         psc["B1855+09_basis_ecorr_coefficients"]) +
                  np.dot(pta.pulsarmodels[0].signals[3].get_basis(ps),
                         psc["B1855+09_red_noise_coefficients"]))

            msg = "Implicit and explicit PTA delays are different."
            assert np.allclose(d1, d2), msg

            l1 = pta.get_lnlikelihood(ps)
            l2 = ptac.get_lnlikelihood(psc)

            # I don't know how to integrate l2 to match l1...
            msg = "Marginal and hierarchical likelihoods should be different."
            assert l1 != l2, msg
 def gwb(self,option="common_pl"):
   """
   Spatially-correlated quadrupole signal from the nanohertz stochastic
   gravitational-wave background.
   """
   gwb_log10_A = parameter.Uniform(params.gwb_lgA[0],params.gwb_lgA[1])
   if option=="common_pl":
     gwb_gamma = parameter.Uniform(params.gwb_gamma[0],params.gwb_gamma[1])
   elif option=="fixed_gamma":
     gwb_gamma = parameter.Constant(4.33)
   gwb_pl = utils.powerlaw(log10_A=gwb_log10_A, gamma=gwb_gamma)
   nfreqs = self.determine_nfreqs(sel_func_name=None)
   orf = utils.hd_orf()
   gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, \
                                         name='gwb', Tspan=self.params.Tspan)
   return gwb
Beispiel #19
0
    def test_summary(self):
        """ Test summary table."""
        T1, T3 = 3.16e8, 3.16e8
        nf1 = 30

        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(1,7))
        orf = utils.hd_orf()
        rn = gp_signals.FourierBasisGP(spectrum=pl, components=nf1, Tspan=T1)
        crn = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=orf,
                                              components=1, name='gw',
                                              Tspan=T3)

        model = rn + crn
        pta = model(self.psrs[0]) + model(self.psrs[1])
        pta.summary()
Beispiel #20
0
  def ppta_band_noise(self,option=[]):
    """
    Including red noise terms by the PPTA "-B" flag, only with flagvals in
    noise model file. It is considered a derivative of system noise in our code.

    See Lentati, Lindley, et al. MNRAS 458.2 (2016): 2161-2187.
    """
    for ii, band_term in enumerate(option):
      log10_A = parameter.Uniform(self.params.syn_lgA[0],self.params.syn_lgA[1])
      gamma = parameter.Uniform(self.params.syn_gamma[0],\
                                self.params.syn_gamma[1])
      selection_function_name = 'band_noise_selection_' + \
                                str(self.sys_noise_count)
      setattr(self, selection_function_name,
              selection_factory(selection_function_name))
      band_term, nfreqs = self.option_nfreqs(band_term, \
                                      selection_flag='B', \
                                      sel_func_name=selection_function_name)
      if "turnover" in band_term:
        fc = parameter.Uniform(self.params.sn_fc[0],self.params.sn_fc[1])
        pl = powerlaw_bpl(log10_A=log10_A, gamma=gamma, fc=fc,
                          components=self.params.red_general_nfouriercomp)
        option_split = band_term.split("_")
        del option_split[option_split.index("turnover")]
        band_term = "_".join(option_split)
      else:
        pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                            components=self.params.red_general_nfouriercomp)

      tspan = self.determine_tspan(sel_func_name=selection_function_name)

      syn_term = gp_signals.FourierBasisGP(spectrum=pl, Tspan=tspan,
                                      name='band_noise_' + \
                                      str(self.sys_noise_count),
                                      selection=selections.Selection( \
                                      self.__dict__[selection_function_name] ),
                                      components=nfreqs)
      if ii == 0:
        syn = syn_term
      elif ii > 0:
        syn += syn_term

      self.sys_noise_count += 1

    return syn
Beispiel #21
0
    def test_summary(self):
        """ Test summary table."""
        T1, T3 = 3.16e8, 3.16e8
        nf1 = 30

        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12),
                            gamma=parameter.Uniform(1, 7))
        orf = utils.hd_orf()
        rn = gp_signals.FourierBasisGP(spectrum=pl, components=nf1, Tspan=T1)
        crn = gp_signals.FourierBasisCommonGP(spectrum=pl,
                                              orf=orf,
                                              components=1,
                                              name='gw',
                                              Tspan=T3)

        model = rn + crn
        pta = model(self.psrs[0]) + model(self.psrs[1])
        pta.summary(to_stdout=True)
Beispiel #22
0
def initialize_pta_sim(psrs, fgw,
                       inc_efac=True, inc_equad=False, inc_ecorr=False,
                       selection=None,
                       inc_red_noise=False, noisedict=None):
    
    # continuous GW signal
    s = models.cw_block_circ(log10_fgw=np.log10(fgw), psrTerm=True)
    
    # linearized timing model
    s += gp_signals.TimingModel(use_svd=True)

    # white noise
    if selection == 'backend':
        selection = selections.Selection(selections.by_backend)

    if inc_efac:
        efac = parameter.Constant()
        s += white_signals.MeasurementNoise(efac=efac, selection=selection)
    
    if inc_equad:
        equad = parameter.Constant()
        s += white_signals.EquadNoise(log10_equad=equad,
                                      selection=selection)
    if inc_ecorr:
        ecorr = parameter.Constant()
        s += gp_signals.EcorrBasisModel(log10_ecorr=ecorr,
                                        selection=selection)

    if inc_red_noise:
        log10_A = parameter.Constant()
        gamma = parameter.Constant()
        pl = utils.powerlaw(log10_A=log10_A, gamma=gamma)
        s += gp_signals.FourierBasisGP(pl, components=30)

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

    # set white noise parameters
    if noisedict is None:
        print('No noise dictionary provided!...')
    else:
        pta.set_default_params(noisedict)
    
    return pta
Beispiel #23
0
    def test_psd(self):
        """Test PSD functions."""
        Tmax = self.psr.toas.max() - self.psr.toas.min()
        f = np.linspace(1 / Tmax, 10 / Tmax, 10)
        log10_A = -15
        gamma = 4.33
        lf0 = -8.5
        kappa = 10 / 3
        beta = 0.5
        pl = (10**log10_A)**2 / 12.0 / np.pi**2 * const.fyr**(gamma - 3) * f**(
            -gamma) * f[0]
        hcf = 10**log10_A * (f / const.fyr)**(
            (3 - gamma) / 2) / (1 + (10**lf0 / f)**kappa)**beta
        pt = hcf**2 / 12 / np.pi**2 / f**3 * f[0]

        msg = "PSD calculation incorrect"
        assert np.allclose(utils.powerlaw(f, log10_A, gamma), pl), msg
        assert np.allclose(utils.turnover(f, log10_A, gamma, lf0, kappa, beta),
                           pt), msg
Beispiel #24
0
def pta_pshift(dmx_psrs, caplog):
    Tspan = model_utils.get_tspan(dmx_psrs)
    tm = gp_signals.TimingModel()
    wn = blocks.white_noise_block(inc_ecorr=True, tnequad=True)
    rn = blocks.red_noise_block(Tspan=Tspan)
    pseed = parameter.Uniform(0, 10000)('gw_pseed')
    gw_log10_A = parameter.Uniform(-18, -14)('gw_log10_A')
    gw_gamma = parameter.Constant(13. / 3)('gw_gamma')
    gw_pl = utils.powerlaw(log10_A=gw_log10_A, gamma=gw_gamma)
    gw_pshift = gp_signals.FourierBasisGP(spectrum=gw_pl,
                                          components=5,
                                          Tspan=Tspan,
                                          name='gw',
                                          pshift=True,
                                          pseed=pseed)
    model = tm + wn + rn + gw_pshift
    pta_pshift = signal_base.PTA([model(p) for p in dmx_psrs])
    pta_pshift.set_default_params(noise_dict)
    return pta_pshift
Beispiel #25
0
    def test_psd(self):
        """Test PSD functions."""
        Tmax = self.psr.toas.max() - self.psr.toas.min()
        f = np.linspace(1/Tmax, 10/Tmax, 10)
        log10_A = -15
        gamma = 4.33
        lf0 = -8.5
        kappa = 10/3
        beta = 0.5
        pl = ((10**log10_A)**2 / 12.0 / np.pi**2 *
              const.fyr**(gamma-3) * f**(-gamma)*f[0])
        hcf = (10**log10_A * (f / const.fyr) ** ((3-gamma) / 2) /
               (1 + (10**lf0 / f) ** kappa) ** beta)
        pt = hcf**2/12/np.pi**2/f**3 * f[0]

        msg = 'PSD calculation incorrect'
        assert np.allclose(utils.powerlaw(f, log10_A, gamma), pl), msg
        assert np.allclose(utils.turnover(f, log10_A, gamma,
                                          lf0, kappa, beta),pt), msg
Beispiel #26
0
  def chromred(self,option="vary"):
    """
    This is an generalization of DM noise, with the dependence of Fourier
    amplitudes on radio frequency nu as ~ 1/nu^chi, where chi is a free
    parameter.

    Examples of chi:

    - Pulse scattering in the ISM: chi = 4 (Lyne A., Graham-Smith F., 2012,
      Pulsar astronomy)
    - Refractive propagation: chi = 6.4 (Shannon, R. M., and J. M. Cordes.
      MNRAS, 464.2 (2017): 2075-2089).
    """
    log10_A = parameter.Uniform(self.params.dmn_lgA[0],self.params.dmn_lgA[1])
    gamma = parameter.Uniform(self.params.dmn_gamma[0],self.params.dmn_gamma[1])
    option, nfreqs = self.option_nfreqs(option, sel_func_name=None)
    if type(option) is str and "turnover" in option:
      fc = parameter.Uniform(self.params.sn_fc[0],self.params.sn_fc[1])
      pl = powerlaw_bpl(log10_A=log10_A, gamma=gamma, fc=fc,
                        components=self.params.red_general_nfouriercomp)
      option_split = option.split("_")
      del option_split[option_split.index("turnover")]
      option = "_".join(option_split)
      if option.isdigit(): option = float(option)
    else:
      pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                          components=self.params.red_general_nfouriercomp)

    #idx_code = option.split"_").index("idx") + 1
    if option=="vary":
      idx = parameter.Uniform(self.params.chrom_idx[0], \
                              self.params.chrom_idx[1])
    else:
      idx = option

    chr_basis = gp_bases.createfourierdesignmatrix_chromatic(nmodes=nfreqs,
                                                   Tspan=self.params.Tspan,
                                                   idx=idx)

    chrn = gp_signals.BasisGP(pl, chr_basis, name='chromatic_gp')

    return chrn
  def paired_ppta_band_noise(self, option=[]):
    """
    Including band noise terms for paired values of the PPTA "-B" flag:
    joint 1020-cm and 4050-cm red processes.
    """
    for ii, paired_band_term in enumerate(option):

      log10_A = parameter.Uniform(self.params.syn_lgA[0],self.params.syn_lgA[1])
      gamma = parameter.Uniform(self.params.syn_gamma[0],\
                                self.params.syn_gamma[1])

      if "turnover" in paired_band_term:
        fc = parameter.Uniform(self.params.sn_fc[0],self.params.sn_fc[1])
        pl = powerlaw_bpl(log10_A=log10_A, gamma=gamma, fc=fc,
                          components=self.params.red_general_nfouriercomp)
        option_split = paired_band_term.split("_")
        del option_split[option_split.index("turnover")]
        paired_band_term = "_".join(option_split)
      else:
        pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                          components=self.params.red_general_nfouriercomp)

      if "nfreqs" not in paired_band_term:
        setattr(self, paired_band_term, globals()[paired_band_term])
      paired_band_term, nfreqs = self.option_nfreqs(paired_band_term, \
                                      sel_func_name=paired_band_term)
      setattr(self, paired_band_term, globals()[paired_band_term])

      tspan = self.determine_tspan(sel_func_name=paired_band_term)
  
      pbn_term = gp_signals.FourierBasisGP(spectrum=pl, Tspan=tspan,
                                        name='band_noise_' + paired_band_term,
                                        selection=selections.Selection( \
                                        self.__dict__[paired_band_term] ),
                                        components=nfreqs)
      if ii == 0:
        pbn = pbn_term
      elif ii > 0:
        pbn += pbn_term

    return pbn
        def test_fourier_red_noise(self):
            """Test that implicit and explicit GP delays are the same."""
            # set up signal parameter
            pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12),
                                gamma=parameter.Uniform(1, 7))
            rn = gp_signals.FourierBasisGP(spectrum=pl, components=20)
            rnm = rn(self.psr)

            rnc = gp_signals.FourierBasisGP(spectrum=pl,
                                            components=20,
                                            coefficients=True)
            rnmc = rnc(self.psr)

            # parameters
            log10_A, gamma = -14.5, 4.33
            params = {
                "B1855+09_red_noise_log10_A": log10_A,
                "B1855+09_red_noise_gamma": gamma
            }

            # get the GP delays in two different ways
            cf = np.random.randn(40)
            d1 = np.dot(rnm.get_basis(params), cf)

            params.update({"B1855+09_red_noise_coefficients": cf})
            d2 = rnmc.get_delay(params)

            msg = "Implicit and explicit GP delays are different."
            assert np.allclose(d1, d2), msg

            # np.array cast is needed because we get a KernelArray
            phimat = np.array(rnm.get_phi(params))
            pr1 = (-0.5 * np.sum(cf * cf / phimat) -
                   0.5 * np.sum(np.log(phimat)) -
                   0.5 * len(phimat) * np.log(2 * math.pi))

            cpar = [p for p in rnmc.params if "coefficients" in p.name][0]
            pr2 = cpar.get_logpdf(params=params)

            msg = "Implicit and explicit GP priors are different."
            assert np.allclose(pr1, pr2), msg
Beispiel #29
0
    def ppta_band_noise(self, option=[]):
        """
    Including red noise terms by the PPTA "-B" flag, only with flagvals in
    noise model file. It is considered a derivative of system noise in our code.

    See Lentati, Lindley, et al. MNRAS 458.2 (2016): 2161-2187.
    """
        for ii, band_term in enumerate(option):
            log10_A = parameter.Uniform(self.params.syn_lgA[0],
                                        self.params.syn_lgA[1])
            gamma = parameter.Uniform(self.params.syn_gamma[0],\
                                      self.params.syn_gamma[1])
            pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                                components=self.params.red_general_nfouriercomp)

            selection_function_name = 'band_noise_selection_' + \
                                      str(self.sys_noise_count)
            setattr(self, selection_function_name,
                    selection_factory(selection_function_name))
            self.psr.sys_flags.append('B')
            self.psr.sys_flagvals.append(band_term)

            nfreqs = self.determine_nfreqs(
                sel_func_name=selection_function_name)
            tspan = self.determine_tspan(sel_func_name=selection_function_name)

            syn_term = gp_signals.FourierBasisGP(spectrum=pl, Tspan=tspan,
                                            name='band_noise_' + \
                                            str(self.sys_noise_count),
                                            selection=selections.Selection( \
                                            self.__dict__[selection_function_name] ),
                                            components=nfreqs)
            if ii == 0:
                syn = syn_term
            elif ii > 0:
                syn += syn_term

            self.sys_noise_count += 1

        return syn
Beispiel #30
0
  def system_noise(self,option=[]):
    """
    Including red noise terms by "-group" flag, only with flagvals in noise
    model file.

    See Lentati, Lindley, et al. MNRAS 458.2 (2016): 2161-2187.
    """
    for ii, sys_noise_term in enumerate(option):
      log10_A = parameter.Uniform(self.params.syn_lgA[0],self.params.syn_lgA[1])
      gamma = parameter.Uniform(self.params.syn_gamma[0],\
                                self.params.syn_gamma[1])
      pl = utils.powerlaw(log10_A=log10_A, gamma=gamma, \
                          components=self.params.red_general_nfouriercomp)

      selection_function_name = 'sys_noise_selection_'+str(self.sys_noise_count)
      setattr(self, selection_function_name,
              selection_factory(selection_function_name))
      sys_noise_term, nfreqs = self.option_nfreqs(sys_noise_term, \
                                    selection_flag='group', \
                                    sel_func_name=selection_function_name)

      tspan = self.determine_tspan(sel_func_name=selection_function_name)

      syn_term = gp_signals.FourierBasisGP(spectrum=pl, Tspan=tspan,
                                      name='system_noise_' + \
                                      str(self.sys_noise_count),
                                      selection=selections.Selection( \
                                      self.__dict__[selection_function_name] ),
                                      components=nfreqs)
      if ii == 0:
        syn = syn_term
      elif ii > 0:
        syn += syn_term

      self.sys_noise_count += 1

    return syn
    def add_rn(self):
        """Return dictionary containing red noise power-law signal attributes

        :return: OrderedDict of red noise signal
        """
        log10_A = parameter.Uniform(-20.0, -10.0)
        gamma = parameter.Uniform(0.02, 6.98)
        pl = utils.powerlaw(log10_A=log10_A, gamma=gamma)
        rn = gp_signals.FourierBasisGP(pl,
                                       components=self.nfreqcomps,
                                       name='rn')
        newsignal = OrderedDict({
            'type':
            'rn',
            'name': [self.pname + '_rn_log10_A', self.pname + '_rn_gamma'],
            'pmin': [-20.0, 0.02],
            'pmax': [-10.0, 6.98],
            'pstart': [-14.5, 3.51],
            'interval': [True, True],
            'numpars':
            2
        })
        self.rn_sig = rn(self.psr)
        return {'rn': newsignal}
Beispiel #32
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 = {p.name: float(p.sample()) for p in 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)
        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 = {p.name: float(p.sample()) for p in 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)
        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 = {p.name: float(p.sample()) for p in 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)
        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 = {p.name: float(p.sample()) for p in 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)
        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)
    def test_red_noise_add_backend(self):
        """Test that red noise with backend addition only returns
        independent columns."""
        # set up signals
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7))
        selection = Selection(selections.by_backend)
        cpl = utils.powerlaw(
            log10_A=parameter.Uniform(-18, -12)("log10_Agw"), gamma=parameter.Uniform(1, 7)("gamma_gw")
        )

        # parameters
        log10_As = [-14, -14.4, -15, -14.8]
        gammas = [2.3, 4.4, 1.8, 5.6]
        log10_Ac, gammac = -15.5, 1.33
        params = {
            "B1855+09_red_noise_430_ASP_gamma": gammas[0],
            "B1855+09_red_noise_430_PUPPI_gamma": gammas[1],
            "B1855+09_red_noise_L-wide_ASP_gamma": gammas[2],
            "B1855+09_red_noise_L-wide_PUPPI_gamma": gammas[3],
            "B1855+09_red_noise_430_ASP_log10_A": log10_As[0],
            "B1855+09_red_noise_430_PUPPI_log10_A": log10_As[1],
            "B1855+09_red_noise_L-wide_ASP_log10_A": log10_As[2],
            "B1855+09_red_noise_L-wide_PUPPI_log10_A": log10_As[3],
            "log10_Agw": log10_Ac,
            "gamma_gw": gammac,
        }

        Tmax = self.psr.toas.max() - self.psr.toas.min()
        tpars = [
            (30, 20, Tmax, Tmax),
            (20, 30, Tmax, Tmax),
            (30, 30, Tmax, Tmax),
            (30, 20, Tmax, 1.123 * Tmax),
            (20, 30, Tmax, 1.123 * Tmax),
            (30, 30, 1.123 * Tmax, Tmax),
            (30, 20, None, Tmax),
        ]

        for (nf1, nf2, T1, T2) in tpars:

            rn = gp_signals.FourierBasisGP(spectrum=pl, components=nf1, Tspan=T1, selection=selection)
            crn = gp_signals.FourierBasisGP(spectrum=cpl, components=nf2, Tspan=T2)
            s = rn + crn
            rnm = s(self.psr)

            # get the basis
            bflags = self.psr.backend_flags
            Fmats, fs, phis = [], [], []
            F2, f2 = utils.createfourierdesignmatrix_red(self.psr.toas, nf2, Tspan=T2)
            p2 = utils.powerlaw(f2, log10_Ac, gammac)
            for ct, flag in enumerate(np.unique(bflags)):
                mask = bflags == flag
                F1, f1 = utils.createfourierdesignmatrix_red(self.psr.toas[mask], nf1, Tspan=T1)
                Fmats.append(F1)
                fs.append(f1)
                phis.append(utils.powerlaw(f1, log10_As[ct], gammas[ct]))

            Fmats.append(F2)
            phis.append(p2)
            nf = sum(F.shape[1] for F in Fmats)
            F = np.zeros((len(self.psr.toas), nf))
            phi = np.hstack([p for p in phis])
            nftot = 0
            for ct, flag in enumerate(np.unique(bflags)):
                mask = bflags == flag
                nn = Fmats[ct].shape[1]
                F[mask, nftot : nn + nftot] = Fmats[ct]
                nftot += nn
            F[:, -2 * nf2 :] = F2

            msg = "Combined red noise PSD incorrect "
            msg += "for {} {} {} {}".format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phi(params) == phi), msg

            msg = "Combined red noise PSD inverse incorrect "
            msg += "for {} {} {} {}".format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phiinv(params) == 1 / phi), msg

            msg = "Combined red noise Fmat incorrect "
            msg += "for {} {} {} {}".format(nf1, nf2, T1, T2)
            assert np.allclose(F, rnm.get_basis(params)), msg
    def test_red_noise_add(self):
        """Test that red noise addition only returns independent columns."""
        # set up signals
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7))
        cpl = utils.powerlaw(
            log10_A=parameter.Uniform(-18, -12)("log10_Agw"), gamma=parameter.Uniform(1, 7)("gamma_gw")
        )

        # parameters
        log10_A, gamma = -14.5, 4.33
        log10_Ac, gammac = -15.5, 1.33
        params = {
            "B1855+09_red_noise_log10_A": log10_A,
            "B1855+09_red_noise_gamma": gamma,
            "log10_Agw": log10_Ac,
            "gamma_gw": gammac,
        }

        Tmax = self.psr.toas.max() - self.psr.toas.min()
        tpars = [
            (30, 20, Tmax, Tmax),
            (20, 30, Tmax, Tmax),
            (30, 30, Tmax, Tmax),
            (30, 20, Tmax, 1.123 * Tmax),
            (20, 30, Tmax, 1.123 * Tmax),
            (30, 30, 1.123 * Tmax, Tmax),
        ]

        for (nf1, nf2, T1, T2) in tpars:

            rn = gp_signals.FourierBasisGP(spectrum=pl, components=nf1, Tspan=T1)
            crn = gp_signals.FourierBasisGP(spectrum=cpl, components=nf2, Tspan=T2)
            s = rn + crn
            rnm = s(self.psr)

            # set up frequencies
            F1, f1 = utils.createfourierdesignmatrix_red(self.psr.toas, nmodes=nf1, Tspan=T1)
            F2, f2 = utils.createfourierdesignmatrix_red(self.psr.toas, nmodes=nf2, Tspan=T2)

            # test power spectrum
            p1 = utils.powerlaw(f1, log10_A, gamma)
            p2 = utils.powerlaw(f2, log10_Ac, gammac)
            if T1 == T2:
                nf = max(2 * nf1, 2 * nf2)
                phi = np.zeros(nf)
                F = F1 if nf1 > nf2 else F2
                phi[: 2 * nf1] = p1
                phi[: 2 * nf2] += p2
                F[
                    :,
                ]  # noqa: E231
            else:
                phi = np.concatenate((p1, p2))
                F = np.hstack((F1, F2))

            msg = "Combined red noise PSD incorrect "
            msg += "for {} {} {} {}".format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phi(params) == phi), msg

            msg = "Combined red noise PSD inverse incorrect "
            msg += "for {} {} {} {}".format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phiinv(params) == 1 / phi), msg

            msg = "Combined red noise Fmat incorrect "
            msg += "for {} {} {} {}".format(nf1, nf2, T1, T2)
            assert np.allclose(F, rnm.get_basis(params)), msg
Beispiel #35
0
    def test_pta_phi(self):
        T1, T2, T3 = 3.16e8, 3.16e8, 3.16e8
        nf1, nf2, nf3 = 2, 2, 1

        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(1,7))
        orf = utils.hd_orf()
        rn = gp_signals.FourierBasisGP(spectrum=pl, components=nf1, Tspan=T1)
        crn = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=orf,
                                              components=1, name='gw',
                                              Tspan=T3)

        model = rn + crn
        pta = model(self.psrs[0]) + model(self.psrs[1])

        lA1, gamma1 = -13, 1e-15
        lA2, gamma2 = -13.3, 1e-15
        lAc, gammac = -13.1, 1e-15

        params = {'gw_log10_A': lAc, 'gw_gamma': gammac,
                  'B1855+09_log10_A': lA1, 'B1855+09_gamma': gamma1,
                  'J1909-3744_log10_A': lA2, 'J1909-3744_gamma': gamma2}

        phi = pta.get_phi(params)
        phiinv = pta.get_phiinv(params)

        T1, T2, T3 = 3.16e8, 3.16e8, 3.16e8
        nf1, nf2, nf3 = 2, 2, 1

        F1, f1 = utils.createfourierdesignmatrix_red(
            self.psrs[0].toas, nf1, Tspan=T1)
        F2, f2 = utils.createfourierdesignmatrix_red(
            self.psrs[1].toas, nf2, Tspan=T2)
        F1c, fc = utils.createfourierdesignmatrix_red(
            self.psrs[0].toas, nf3, Tspan=T3)
        F2c, fc = utils.createfourierdesignmatrix_red(
            self.psrs[1].toas, nf3, Tspan=T3)

        nftot = 2 * 2 * nf1
        phidiag = np.zeros(nftot)
        phit = np.zeros((nftot, nftot))

        phidiag[:4] = utils.powerlaw(f1, lA1, gamma1)
        phidiag[:2] += utils.powerlaw(fc, lAc, gammac)
        phidiag[4:] = utils.powerlaw(f2, lA2, gamma2)
        phidiag[4:6] += utils.powerlaw(fc, lAc, gammac)

        phit[np.diag_indices(nftot)] = phidiag

        phit[:2, 4:6] = np.diag(hd_powerlaw(fc, self.psrs[0].pos,
                                            self.psrs[1].pos, lAc,
                                            gammac))
        phit[4:6, :2] = np.diag(hd_powerlaw(fc, self.psrs[0].pos,
                                            self.psrs[1].pos, lAc,
                                            gammac))

        msg = '{} {}'.format(np.diag(phi), np.diag(phit))
        assert np.allclose(phi, phit, rtol=1e-15, atol=1e-17), msg

        msg = 'PTA Phi inverse is incorrect {}.'.format(params)
        assert np.allclose(phiinv, np.linalg.inv(phit),
                           rtol=1e-15, atol=1e-17), msg
Beispiel #36
0
def hd_powerlaw(f, pos1, pos2, log10_A=-15, gamma=4.3):
    return utils.powerlaw(f, log10_A, gamma) * utils.hd_orf(pos1, pos2)
log10_A_gw_2 = parameter.Uniform(-18, -13)('zlog10_A_other_gw')
gamma_gw_2 = parameter.Constant(7 / 3)('zgamma_other_gw')

##### Set up signals #####

# timing model
tm = gp_signals.TimingModel()

# white noise
ef = white_signals.MeasurementNoise(efac=efac, selection=selection)
eq = white_signals.EquadNoise(log10_equad=log10_equad, selection=selection)
ec = white_signals.EcorrKernelNoise(log10_ecorr=log10_ecorr,
                                    selection=selection)

# red noise (powerlaw with 30 frequencies)
pl = utils.powerlaw(log10_A=red_noise_log10_A, gamma=red_noise_gamma)
rn = gp_signals.FourierBasisGP(spectrum=pl, components=30, Tspan=Tspan)

cpl_1 = utils.powerlaw(log10_A=log10_A_gw_1, gamma=gamma_gw_1)
cpl_2 = utils.powerlaw(log10_A=log10_A_gw_2, gamma=gamma_gw_2)

#Common red noise process with no correlations
crn_1 = gp_signals.FourierBasisGP(spectrum=cpl_1,
                                  components=30,
                                  Tspan=Tspan,
                                  name='gw')
crn_2 = gp_signals.FourierBasisGP(spectrum=cpl_2,
                                  components=30,
                                  Tspan=Tspan,
                                  name='other_gw')
Beispiel #38
0
    def test_red_noise_add_backend(self):
        """Test that red noise with backend addition only returns
        independent columns."""
        # set up signals
        pl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12),
                            gamma=parameter.Uniform(1,7))
        selection = Selection(selections.by_backend)
        cpl = utils.powerlaw(log10_A=parameter.Uniform(-18,-12)('log10_Agw'),
                             gamma=parameter.Uniform(1,7)('gamma_gw'))

        # parameters
        log10_As = [-14, -14.4, -15, -14.8]
        gammas = [2.3, 4.4, 1.8, 5.6]
        log10_Ac, gammac = -15.5, 1.33
        params = {'B1855+09_430_ASP_gamma': gammas[0],
                  'B1855+09_430_PUPPI_gamma': gammas[1],
                  'B1855+09_L-wide_ASP_gamma': gammas[2],
                  'B1855+09_L-wide_PUPPI_gamma': gammas[3],
                  'B1855+09_430_ASP_log10_A': log10_As[0],
                  'B1855+09_430_PUPPI_log10_A': log10_As[1],
                  'B1855+09_L-wide_ASP_log10_A': log10_As[2],
                  'B1855+09_L-wide_PUPPI_log10_A': log10_As[3],
                  'log10_Agw': log10_Ac,
                  'gamma_gw': gammac}

        Tmax = self.psr.toas.max() - self.psr.toas.min()
        tpars = [(30, 20, Tmax, Tmax), (20, 30, Tmax, Tmax),
                 (30, 30, Tmax, Tmax), (30, 20, Tmax, 1.123*Tmax),
                 (20, 30, Tmax, 1.123*Tmax), (30, 30, 1.123*Tmax, Tmax),
                 (30, 20, None, Tmax)]

        for (nf1, nf2, T1, T2) in tpars:

            rn = gs.FourierBasisGP(spectrum=pl, components=nf1, Tspan=T1,
                                   selection=selection)
            crn = gs.FourierBasisGP(spectrum=cpl, components=nf2, Tspan=T2)
            s = rn + crn
            rnm = s(self.psr)

            # get the basis
            bflags = self.psr.backend_flags
            Fmats, fs, phis = [], [], []
            F2, f2 = utils.createfourierdesignmatrix_red(
                self.psr.toas, nf2, Tspan=T2)
            p2 = utils.powerlaw(f2, log10_Ac, gammac)
            for ct, flag in enumerate(np.unique(bflags)):
                mask = bflags == flag
                F1, f1 = utils.createfourierdesignmatrix_red(
                    self.psr.toas[mask], nf1, Tspan=T1)
                Fmats.append(F1)
                fs.append(f1)
                phis.append(utils.powerlaw(f1, log10_As[ct], gammas[ct]))

            Fmats.append(F2)
            phis.append(p2)
            nf = sum(F.shape[1] for F in Fmats)
            F = np.zeros((len(self.psr.toas), nf))
            phi = np.hstack(p for p in phis)
            nftot = 0
            for ct, flag in enumerate(np.unique(bflags)):
                mask = bflags == flag
                nn = Fmats[ct].shape[1]
                F[mask, nftot:nn+nftot] = Fmats[ct]
                nftot += nn
            F[:, -2*nf2:] = F2

            msg = 'Combined red noise PSD incorrect '
            msg += 'for {} {} {} {}'.format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phi(params) == phi), msg

            msg = 'Combined red noise PSD inverse incorrect '
            msg += 'for {} {} {} {}'.format(nf1, nf2, T1, T2)
            assert np.all(rnm.get_phiinv(params) == 1/phi), msg

            msg = 'Combined red noise Fmat incorrect '
            msg += 'for {} {} {} {}'.format(nf1, nf2, T1, T2)
            assert np.allclose(F, rnm.get_basis(params)), msg
Beispiel #39
0
    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
Beispiel #40
0
def common_red_noise_block(psd='powerlaw',
                           prior='log-uniform',
                           Tspan=None,
                           gamma_val=None,
                           orf=None,
                           name='gwb'):
    """
    Returns common red noise model:
        1. Red noise modeled with user defined PSD with
        30 sampling frequencies. Available PSDs are
        ['powerlaw', 'turnover' 'spectrum']
    :param psd:
        PSD to use for common red noise signal. Available options
        are ['powerlaw', 'turnover' 'spectrum']
    :param prior:
        Prior on log10_A. Default if "log-uniform". Use "uniform" for
        upper limits.
    :param Tspan:
        Sets frequency sampling f_i = i / Tspan. Default will
        use overall time span for indivicual pulsar.
    :param gamma_val:
        Value of spectral index for power-law and turnover
        models. By default spectral index is varied of range [0,7]
    :param orf:
        String representing which overlap reduction function to use.
        By default we do not use any spatial correlations. Permitted
        values are ['hd', 'dipole', 'monopole'].
    :param name: Name of common red process
    """

    orfs = {
        'hd': utils.hd_orf(),
        'dipole': utils.dipole_orf(),
        'monopole': utils.monopole_orf()
    }

    # common red noise parameters
    if psd in ['powerlaw', 'turnover']:
        amp_name = '{}_log10_A'.format(name)
        if prior == 'uniform':
            log10_Agw = parameter.LinearExp(-18, -11)(amp_name)
        elif prior == 'log-uniform' and gamma_val is not None:
            if np.abs(gamma_val - 4.33) < 0.1:
                log10_Agw = parameter.Uniform(-18, -14)(amp_name)
            else:
                log10_Agw = parameter.Uniform(-18, -11)(amp_name)
        else:
            log10_Agw = parameter.Uniform(-18, -11)(amp_name)

        gam_name = '{}_gamma'.format(name)
        if gamma_val is not None:
            gamma_gw = parameter.Constant(gamma_val)(gam_name)
        else:
            gamma_gw = parameter.Uniform(0, 7)(gam_name)

        # common red noise PSD
        if psd == 'powerlaw':
            cpl = utils.powerlaw(log10_A=log10_Agw, gamma=gamma_gw)
        elif psd == 'turnover':
            kappa_name = '{}_kappa'.format(name)
            lf0_name = '{}_log10_fbend'.format(name)
            kappa_gw = parameter.Uniform(0, 7)(kappa_name)
            lf0_gw = parameter.Uniform(-9, -7)(lf0_name)
            cpl = utils.turnover(log10_A=log10_Agw,
                                 gamma=gamma_gw,
                                 lf0=lf0_gw,
                                 kappa=kappa_gw)

    if orf is None:
        crn = gp_signals.FourierBasisGP(cpl, components=30, Tspan=Tspan)
    elif orf in orfs.keys():
        crn = gp_signals.FourierBasisCommonGP(cpl,
                                              orfs[orf],
                                              components=30,
                                              Tspan=Tspan)
    else:
        raise ValueError('ORF {} not recognized'.format(orf))

    return crn
    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
    for p, t in zip(parfiles, timfiles):
        psr = Pulsar(p, t)
        psrs.append(psr)

    save1 = np.load('noisepars.npy')
    save2 = np.load('noisepardict.npy')
    save3 = np.load('dpdmpars-maxposprob.npy')
    save4 = np.load('dpdmpardict.npy')
    Dict = {save2[i]: save1[i] for i in range(len(save2))}
    Dict.update({save4[i]: save3[i] for i in range(len(save4))})

    # The Big Model
    # dm noise
    log10_A_dm = parameter.Constant()
    gamma_dm = parameter.Constant()
    pl_dm = utils.powerlaw(log10_A=log10_A_dm, gamma=gamma_dm)
    dm_basis = utils.createfourierdesignmatrix_dm(nmodes=50, Tspan=None)
    dmn = gp_signals.BasisGP(pl_dm, dm_basis, name='dm_gp', coefficients=False)
    # spin noise
    log10_A = parameter.Constant()
    gamma = parameter.Constant()
    pl = utils.powerlaw(log10_A=log10_A, gamma=gamma)
    selection = selections.Selection(selections.no_selection)
    spn = gp_signals.FourierBasisGP(pl,
                                    components=50,
                                    Tspan=None,
                                    coefficients=False,
                                    selection=selection,
                                    modes=None)

    dp = DPDM.dpdm_block(type_='Bayes')
Beispiel #43
0
    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