예제 #1
0
    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
예제 #2
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
예제 #3
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 = 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
예제 #4
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
예제 #5
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
예제 #6
0
def FourierBasisCommonGP(
    spectrum, orf, coefficients=False, combine=True, components=20, Tspan=None, modes=None, name="common_fourier"
):

    if coefficients and Tspan is None:
        raise ValueError(
            "With coefficients=True, FourierBasisCommonGP " + "requires that you specify Tspan explicitly."
        )

    basis = utils.createfourierdesignmatrix_red(nmodes=components, Tspan=Tspan, modes=modes)
    BaseClass = BasisCommonGP(spectrum, basis, orf, coefficients=coefficients, combine=combine, name=name)

    class FourierBasisCommonGP(BaseClass):
        _Tmin, _Tmax = [], []

        def __init__(self, psr):
            super(FourierBasisCommonGP, self).__init__(psr)

            if Tspan is None:
                FourierBasisCommonGP._Tmin.append(psr.toas.min())
                FourierBasisCommonGP._Tmax.append(psr.toas.max())

        @signal_base.cache_call("basis_params")
        def _construct_basis(self, params={}):
            span = Tspan if Tspan is not None else max(FourierBasisCommonGP._Tmax) - min(FourierBasisCommonGP._Tmin)
            self._basis, self._labels = self._bases(params=params, Tspan=span)

    return FourierBasisCommonGP
예제 #7
0
def FourierBasisGP(spectrum,
                   coefficients=False,
                   combine=True,
                   components=20,
                   selection=Selection(selections.no_selection),
                   Tspan=None,
                   modes=None,
                   name='red_noise'):
    """Convenience function to return a BasisGP class with a
    fourier basis."""

    basis = utils.createfourierdesignmatrix_red(nmodes=components,
                                                Tspan=Tspan,
                                                modes=modes)
    BaseClass = BasisGP(spectrum,
                        basis,
                        coefficients=coefficients,
                        combine=combine,
                        selection=selection,
                        name=name)

    class FourierBasisGP(BaseClass):
        signal_type = 'basis'
        signal_name = 'red noise'
        signal_id = name

    return FourierBasisGP
예제 #8
0
def FourierBasisCommonGP(spectrum, orf, components=20,
                         Tspan=None, name=''):

    basis = utils.createfourierdesignmatrix_red(nmodes=components)
    BaseClass = BasisCommonGP(spectrum, basis, orf, name=name)

    class FourierBasisCommonGP(BaseClass):
        signal_id = 'common_fourier_' + name if name else 'common_fourier'

        _Tmin, _Tmax = [], []

        def __init__(self, psr):
            super(FourierBasisCommonGP, self).__init__(psr)

            if Tspan is None:
                FourierBasisCommonGP._Tmin.append(psr.toas.min())
                FourierBasisCommonGP._Tmax.append(psr.toas.max())

        @base.cache_call('basis_params')
        def _construct_basis(self, params={}):
            span = (Tspan if Tspan is not None else
                    max(FourierBasisCommonGP._Tmax) -
                    min(FourierBasisCommonGP._Tmin))
            self._basis, self._labels = self._bases(params=params, Tspan=span)

    return FourierBasisCommonGP
예제 #9
0
파일: sw_pta.py 프로젝트: Hazboun6/pta_sim
        def solar_wind_perturb(toas,
                               freqs,
                               planetssb,
                               sunssb,
                               pos_t,
                               n_earth_rho=0,
                               n_mean=5,
                               nmodes=20,
                               Tspan=None,
                               logf=False,
                               fmin=None,
                               fmax=None,
                               modes=None):
            """
            Construct DM-Solar Model fourier design matrix.

            :param toas: vector of time series in seconds
            :param planetssb: solar system bayrcenter positions
            :param pos_t: pulsar position as 3-vector
            :param freqs: radio frequencies of observations [MHz]
            :param n_earth_rho: electron density from the solar wind
                        at 1 AU.
            :param n_earth_bins: Number of binned values of n_earth for which to fit or
                        an array or list of bin edges to use for binned n_Earth values.
                        In the latter case the first and last edges must encompass all
                        TOAs and in all cases it must match the size (number of
                        elements) of log10_n_earth.
            :param t_init: Initial time of earliest TOA in entire dataset, including all
                        pulsar.
            :param t_final: Final time of latest TOA in entire dataset, including all
                        pulsar.

            :return dt_DM: DM due to solar wind
            """
            if modes is not None:
                nmodes = len(modes)

            #print(n_earth_rho)
            if n_earth_rho.size != 2 * nmodes:
                raise ValueError(
                    'Length of n_earth_rho must match 2 x nmodes.')

            F, Ffreqs = utils.createfourierdesignmatrix_red(toas,
                                                            nmodes=nmodes,
                                                            Tspan=Tspan,
                                                            logf=logf,
                                                            fmin=fmin,
                                                            fmax=fmax,
                                                            modes=modes)

            n_Earth = np.einsum('ij,j', F,
                                n_earth_rho)  #np.repeat(10**n_earth_rho,2))
            # if np.any(np.logical_or(n_Earth<0,n_Earth>50)):
            #     dt_sw = np.zeros_like(n_Earth)
            # else:
            theta, R_earth, _, _ = SW.theta_impact(planetssb, sunssb, pos_t)
            dm_sol_wind = SW.dm_solar(1.0, theta, R_earth)
            dt_sw = n_Earth * dm_sol_wind * 4.148808e3 / freqs**2

            return dt_sw
예제 #10
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
예제 #11
0
    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
예제 #12
0
    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
예제 #13
0
def createfourierdesignmatrix_solar_dm(toas, freqs, planetssb, pos_t,
                                       modes=None, nmodes=30,
                                       Tspan=None, logf=True, fmin=None,
                                       fmax=None):

    """
    Construct DM-Solar Model fourier design matrix.

    :param toas: vector of time series in seconds
    :param planetssb: solar system bayrcenter positions
    :param pos_t: pulsar position as 3-vector
    :param nmodes: number of fourier coefficients to use
    :param freqs: radio frequencies of observations [MHz]
    :param Tspan: option to some other Tspan
    :param logf: use log frequency spacing
    :param fmin: lower sampling frequency
    :param fmax: upper sampling frequency

    :return: F: SW DM-variation fourier design matrix
    :return: f: Sampling frequencies
    """

    # get base fourier design matrix and frequencies
    F, Ffreqs = utils.createfourierdesignmatrix_red(toas, nmodes=nmodes,
                                                    modes=modes,
                                                    Tspan=Tspan, logf=logf,
                                                    fmin=fmin, fmax=fmax)
    theta, R_earth = theta_impact(planetssb,pos_t)
    dm_sol_wind = dm_solar(1.0, theta, R_earth)
    dt_DM = dm_sol_wind * 4.148808e3 /(freqs**2)

    return F * dt_DM[:, None], Ffreqs
예제 #14
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 = 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
예제 #15
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
예제 #16
0
def FourierBasisCommonGP(
    spectrum,
    orf,
    coefficients=False,
    combine=True,
    components=20,
    Tspan=None,
    modes=None,
    name="common_fourier",
    pshift=False,
    pseed=None,
):

    if coefficients and Tspan is None:
        raise ValueError("With coefficients=True, FourierBasisCommonGP " +
                         "requires that you specify Tspan explicitly.")

    basis = utils.createfourierdesignmatrix_red(nmodes=components,
                                                Tspan=Tspan,
                                                modes=modes,
                                                pshift=pshift,
                                                pseed=pseed)
    BaseClass = BasisCommonGP(spectrum,
                              basis,
                              orf,
                              coefficients=coefficients,
                              combine=combine,
                              name=name)

    class FourierBasisCommonGP(BaseClass):
        _Tmin, _Tmax = [], []

        def __init__(self, psr):
            super(FourierBasisCommonGP, self).__init__(psr)

            if Tspan is None:
                FourierBasisCommonGP._Tmin.append(psr.toas.min())
                FourierBasisCommonGP._Tmax.append(psr.toas.max())

        # since this function has side-effects, it can only be cached
        # with limit=1, so it will run again if called with params different
        # than the last time
        @signal_base.cache_call("basis_params", 1)
        def _construct_basis(self, params={}):
            span = Tspan if Tspan is not None else max(
                FourierBasisCommonGP._Tmax) - min(FourierBasisCommonGP._Tmin)
            self._basis, self._labels = self._bases(params=params, Tspan=span)

    return FourierBasisCommonGP
예제 #17
0
def FourierBasisGP(spectrum, components=20,
                   selection=Selection(selections.no_selection),
                   Tspan=None, name=''):
    """Convenience function to return a BasisGP class with a
    fourier basis."""

    basis = utils.createfourierdesignmatrix_red(nmodes=components, Tspan=Tspan)
    BaseClass = BasisGP(spectrum, basis, selection=selection, name=name)

    class FourierBasisGP(BaseClass):
        signal_type = 'basis'
        signal_name = 'red noise'
        signal_id = 'red_noise_' + name if name else 'red_noise'

    return FourierBasisGP
예제 #18
0
    def setUpClass(cls):
        """Setup the Pulsar object."""

        # initialize Pulsar class
        cls.psr = Pulsar(datadir + "/B1855+09_NANOGrav_9yv1.gls.par",
                         datadir + "/B1855+09_NANOGrav_9yv1.tim")

        cls.F, _ = utils.createfourierdesignmatrix_red(cls.psr.toas, nmodes=30)

        cls.Fdm, _ = utils.createfourierdesignmatrix_dm(cls.psr.toas,
                                                        freqs=cls.psr.freqs,
                                                        nmodes=30)

        cls.Feph, cls.feph = utils.createfourierdesignmatrix_ephem(
            cls.psr.toas, cls.psr.pos, nmodes=30)

        cls.Mm = utils.create_stabletimingdesignmatrix(cls.psr.Mmat)
예제 #19
0
    def setUpClass(cls):
        """Setup the Pulsar object."""

        # initialize Pulsar class
        cls.psr = Pulsar(datadir + '/B1855+09_NANOGrav_9yv1.gls.par',
                         datadir + '/B1855+09_NANOGrav_9yv1.tim')
        cls.F, _ = utils.createfourierdesignmatrix_red(
            cls.psr.toas, nmodes=30)
        cls.Fdm, _ = utils.createfourierdesignmatrix_dm(
            cls.psr.toas,freqs=cls.psr.freqs, nmodes=30)
        tmp = utils.createfourierdesignmatrix_eph(t=cls.psr.toas,
                                                  phi=cls.psr.phi,
                                                  theta=cls.psr.theta,
                                                  nmodes=30)
        cls.Fx, cls.Fy, cls.Fz = tmp

        cls.Mm = utils.create_stabletimingdesignmatrix(cls.psr.Mmat)
예제 #20
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
예제 #21
0
    ch_b = ['ASP', 'GASP', 'GUPPI', 'PUPPI', 'NUPPI']
    flagvals = filter(lambda x: any(map(lambda y: y in x, ch_b)), flagvals)
    return {flagval: backend_flags == flagval for flagval in flagvals}


selection_ch = selections.Selection(channelized_backends)
selection = selections.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_ch)

# red noise (powerlaw with 5 frequencies)
pl = utils.powerlaw(log10_A=log10_A, gamma=gamma)
basis = utils.createfourierdesignmatrix_red(Tspan=Tspan,
                                            nmodes=args.nfreqs,
                                            logf=args.logf)
rn = gp_signals.BasisGP(priorFunction=pl,
                        name='red_noise',
                        basisFunction=basis)

# timing model
tm = gp_signals.TimingModel(use_svd=False)

model = tm + ef + eq + ec + rn

if args.dm_gp_psrs[0] == args.psr:
    dm_basis = utils.createfourierdesignmatrix_dm(Tspan=Tspan,
                                                  nmodes=args.nfreqs,
                                                  logf=args.logf)
    dm_gp = gp_signals.BasisGP(priorFunction=pl,
예제 #22
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["{}_red_noise_log10_A".format(pname)])
            gamma.append(params["{}_red_noise_gamma".format(pname)])
            lsig.append(params["{}_se_log10_sigma".format(pname)])
            llam.append(params["{}_se_log10_lam".format(pname)])
        GW_gamma = 4.33
        GW_log10_A = -15.0

        # correct value
        tflags = [sorted(list(np.unique(p.backend_flags))) for p in psrs]
        cfs, logdets, phis, Ts = [], [], [], []
        for ii, (ik, psr, flags) in enumerate(zip(inc_kernel, psrs, tflags)):
            nvec0 = np.zeros_like(psr.toas)
            for ct, flag in enumerate(flags):
                ind = psr.backend_flags == flag
                nvec0[ind] = efacs[ii][ct]**2 * psr.toaerrs[ind]**2
                nvec0[ind] += 10**(2 * equads[ii][ct]) * np.ones(np.sum(ind))

            # get the basis
            bflags = psr.backend_flags
            Umats = []
            for flag in np.unique(bflags):
                mask = bflags == flag
                Umats.append(
                    utils.create_quantization_matrix(psr.toas[mask])[0])
            nepoch = sum(U.shape[1] for U in Umats)
            U = np.zeros((len(psr.toas), nepoch))
            jvec = np.zeros(nepoch)
            netot = 0
            for ct, flag in enumerate(np.unique(bflags)):
                mask = bflags == flag
                nn = Umats[ct].shape[1]
                U[mask, netot:nn + netot] = Umats[ct]
                jvec[netot:nn + netot] = 10**(2 * ecorrs[ii][ct])
                netot += nn

            # get covariance matrix
            cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T)
            cf = sl.cho_factor(cov)
            logdet = np.sum(2 * np.log(np.diag(cf[0])))
            cfs.append(cf)
            logdets.append(logdet)

            F, f2 = utils.createfourierdesignmatrix_red(psr.toas,
                                                        nmodes=20,
                                                        Tspan=Tspan)
            Mmat = psr.Mmat.copy()
            norm = np.sqrt(np.sum(Mmat**2, axis=0))
            Mmat /= norm
            U2, avetoas = create_quant_matrix(psr.toas, dt=7 * 86400)
            if ik:
                T = np.hstack((F, Mmat, U2))
            else:
                T = np.hstack((F, Mmat))
            Ts.append(T)
            phi = utils.powerlaw(f2, log10_A=log10_A[ii], gamma=gamma[ii])
            if inc_corr:
                phigw = utils.powerlaw(f2, log10_A=GW_log10_A, gamma=GW_gamma)
            else:
                phigw = np.zeros(40)
            K = se_kernel(avetoas,
                          log10_sigma=log10_sigmas[ii],
                          log10_lam=log10_lams[ii])
            k = np.diag(
                np.concatenate((phi + phigw, np.ones(Mmat.shape[1]) * 1e40)))
            if ik:
                k = sl.block_diag(k, K)
            phis.append(k)

        # manually compute loglike
        loglike = 0
        TNrs, TNTs = [], []
        for ct, psr in enumerate(psrs):
            TNrs.append(np.dot(Ts[ct].T, sl.cho_solve(cfs[ct], psr.residuals)))
            TNTs.append(np.dot(Ts[ct].T, sl.cho_solve(cfs[ct], Ts[ct])))
            loglike += -0.5 * (
                np.dot(psr.residuals, sl.cho_solve(cfs[ct], psr.residuals)) +
                logdets[ct])

        TNr = np.concatenate(TNrs)
        phi = sl.block_diag(*phis)

        if inc_corr:
            hd = utils.hd_orf(psrs[0].pos, psrs[1].pos)
            phi[len(phis[0]):len(phis[0]) + 40, :40] = np.diag(phigw * hd)
            phi[:40, len(phis[0]):len(phis[0]) + 40] = np.diag(phigw * hd)

        cf = sl.cho_factor(phi)
        phiinv = sl.cho_solve(cf, np.eye(phi.shape[0]))
        logdetphi = np.sum(2 * np.log(np.diag(cf[0])))
        Sigma = sl.block_diag(*TNTs) + phiinv

        cf = sl.cho_factor(Sigma)
        expval = sl.cho_solve(cf, TNr)
        logdetsigma = np.sum(2 * np.log(np.diag(cf[0])))

        loglike -= 0.5 * (logdetphi + logdetsigma)
        loglike += 0.5 * np.dot(TNr, expval)

        method = ["partition", "sparse", "cliques"]
        for mth in method:
            eloglike = pta.get_lnlikelihood(params, phiinv_method=mth)
            msg = "Incorrect like for npsr={}, phiinv={}".format(npsrs, mth)
            assert np.allclose(eloglike, loglike), msg
예제 #23
0
    def test_pta(self):

        # get parameters from PAL2 style noise files
        params = get_noise_from_pal2(datadir + "/B1855+09_noise.txt")
        params2 = get_noise_from_pal2(datadir + "/J1909-3744_noise.txt")
        params.update(params2)

        # setup basic model
        efac = parameter.Constant()
        equad = parameter.Constant()
        ecorr = parameter.Constant()
        log10_A = parameter.Constant()
        gamma = parameter.Constant()

        selection = Selection(selections.by_backend)

        ms = white_signals.MeasurementNoise(efac=efac,
                                            log10_t2equad=equad,
                                            selection=selection)
        ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr,
                                            selection=selection)

        pl = utils.powerlaw(log10_A=log10_A, gamma=gamma)
        rn = gp_signals.FourierBasisGP(pl)

        s = ms + ec + rn
        pta = s(self.psrs[0]) + s(self.psrs[1])

        # set parameters
        pta.set_default_params(params)

        # get parameters
        efacs, equads, ecorrs, log10_A, gamma = [], [], [], [], []
        for pname in [p.name for p in self.psrs]:
            efacs.append([
                params[key] for key in sorted(params.keys())
                if "efac" in key and pname in key
            ])
            equads.append([
                params[key] for key in sorted(params.keys())
                if "equad" in key and pname in key
            ])
            ecorrs.append([
                params[key] for key in sorted(params.keys())
                if "ecorr" in key and pname in key
            ])
            log10_A.append(params["{}_red_noise_log10_A".format(pname)])
            gamma.append(params["{}_red_noise_gamma".format(pname)])

        # correct value
        tflags = [sorted(list(np.unique(p.backend_flags))) for p in self.psrs]
        cfs, logdets, phis = [], [], []
        for ii, (psr, flags) in enumerate(zip(self.psrs, tflags)):
            nvec0 = np.zeros_like(psr.toas)
            for ct, flag in enumerate(flags):
                ind = psr.backend_flags == flag
                nvec0[ind] = efacs[ii][ct]**2 * (
                    psr.toaerrs[ind]**2 +
                    10**(2 * equads[ii][ct]) * np.ones(np.sum(ind)))

            # get the basis
            bflags = psr.backend_flags
            Umats = []
            for flag in np.unique(bflags):
                mask = bflags == flag
                Umats.append(
                    utils.create_quantization_matrix(psr.toas[mask])[0])
            nepoch = sum(U.shape[1] for U in Umats)
            U = np.zeros((len(psr.toas), nepoch))
            jvec = np.zeros(nepoch)
            netot = 0
            for ct, flag in enumerate(np.unique(bflags)):
                mask = bflags == flag
                nn = Umats[ct].shape[1]
                U[mask, netot:nn + netot] = Umats[ct]
                jvec[netot:nn + netot] = 10**(2 * ecorrs[ii][ct])
                netot += nn

            # get covariance matrix
            cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T)
            cf = sl.cho_factor(cov)
            logdet = np.sum(2 * np.log(np.diag(cf[0])))
            cfs.append(cf)
            logdets.append(logdet)

            F, f2 = utils.createfourierdesignmatrix_red(psr.toas, nmodes=20)
            phi = utils.powerlaw(f2, log10_A=log10_A[ii], gamma=gamma[ii])
            phis.append(phi)

        # tests
        Ns = pta.get_ndiag(params)
        pphis = pta.get_phi(params)
        pphiinvs = pta.get_phiinv(params)
        Ts = pta.get_basis(params)
        zipped = zip(logdets, cfs, phis, self.psrs, Ns, pphis, pphiinvs, Ts)
        for logdet, cf, phi, psr, N, pphi, pphiinv, T in zipped:
            msg = "EFAC/ECORR logdet incorrect."
            assert np.allclose(N.solve(psr.residuals, logdet=True)[1],
                               logdet,
                               rtol=1e-10), msg

            msg = "EFAC/ECORR D1 solve incorrect."
            assert np.allclose(N.solve(psr.residuals),
                               sl.cho_solve(cf, psr.residuals),
                               rtol=1e-10), msg

            msg = "EFAC/ECORR 1D1 solve incorrect."
            assert np.allclose(
                N.solve(psr.residuals, left_array=psr.residuals),
                np.dot(psr.residuals, sl.cho_solve(cf, psr.residuals)),
                rtol=1e-10,
            ), msg

            msg = "EFAC/ECORR 2D1 solve incorrect."
            assert np.allclose(N.solve(psr.residuals, left_array=T),
                               np.dot(T.T, sl.cho_solve(cf, psr.residuals)),
                               rtol=1e-10), msg

            msg = "EFAC/ECORR 2D2 solve incorrect."
            assert np.allclose(N.solve(T, left_array=T),
                               np.dot(T.T, sl.cho_solve(cf, T)),
                               rtol=1e-10), msg

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

            # inverse spectrum test
            msg = "Spectrum inverse incorrect for GP Fourier signal."
            assert np.all(pphiinv == 1 / phi), msg
예제 #24
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_red_noise_log10_A': lA1,
            'B1855+09_red_noise_gamma': gamma1,
            'J1909-3744_red_noise_log10_A': lA2,
            'J1909-3744_red_noise_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
예제 #25
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_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
예제 #26
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
예제 #27
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
예제 #28
0
    def test_single_pulsar(self):

        # get parameters from PAL2 style noise files
        params = get_noise_from_pal2(datadir + "/B1855+09_noise.txt")

        # setup basic model
        efac = parameter.Constant()
        equad = parameter.Constant()
        ecorr = parameter.Constant()
        log10_A = parameter.Constant()
        gamma = parameter.Constant()

        selection = Selection(selections.by_backend)

        ms = white_signals.MeasurementNoise(efac=efac,
                                            log10_t2equad=equad,
                                            selection=selection)
        ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr,
                                            selection=selection)

        pl = utils.powerlaw(log10_A=log10_A, gamma=gamma)
        rn = gp_signals.FourierBasisGP(pl)

        s = ms + ec + rn
        m = s(self.psrs[0])

        # set parameters
        m.set_default_params(params)

        # get parameters
        efacs = [params[key] for key in sorted(params.keys()) if "efac" in key]
        equads = [
            params[key] for key in sorted(params.keys()) if "equad" in key
        ]
        ecorrs = [
            params[key] for key in sorted(params.keys()) if "ecorr" in key
        ]
        log10_A = params["B1855+09_red_noise_log10_A"]
        gamma = params["B1855+09_red_noise_gamma"]

        # correct value
        flags = ["430_ASP", "430_PUPPI", "L-wide_ASP", "L-wide_PUPPI"]
        nvec0 = np.zeros_like(self.psrs[0].toas)
        for ct, flag in enumerate(np.unique(flags)):
            ind = flag == self.psrs[0].backend_flags
            nvec0[ind] = efacs[ct]**2 * (
                self.psrs[0].toaerrs[ind]**2 +
                10**(2 * equads[ct]) * np.ones(np.sum(ind)))

        # get the basis
        bflags = self.psrs[0].backend_flags
        Umats = []
        for flag in np.unique(bflags):
            mask = bflags == flag
            Umats.append(
                utils.create_quantization_matrix(self.psrs[0].toas[mask])[0])
        nepoch = sum(U.shape[1] for U in Umats)
        U = np.zeros((len(self.psrs[0].toas), nepoch))
        jvec = np.zeros(nepoch)
        netot = 0
        for ct, flag in enumerate(np.unique(bflags)):
            mask = bflags == flag
            nn = Umats[ct].shape[1]
            U[mask, netot:nn + netot] = Umats[ct]
            jvec[netot:nn + netot] = 10**(2 * ecorrs[ct])
            netot += nn

        # get covariance matrix
        cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T)
        cf = sl.cho_factor(cov)
        logdet = np.sum(2 * np.log(np.diag(cf[0])))

        # test
        msg = "EFAC/ECORR logdet incorrect."
        N = m.get_ndiag(params)
        assert np.allclose(N.solve(self.psrs[0].residuals, logdet=True)[1],
                           logdet,
                           rtol=1e-10), msg

        msg = "EFAC/ECORR D1 solve incorrect."
        assert np.allclose(N.solve(self.psrs[0].residuals),
                           sl.cho_solve(cf, self.psrs[0].residuals),
                           rtol=1e-10), msg

        msg = "EFAC/ECORR 1D1 solve incorrect."
        assert np.allclose(
            N.solve(self.psrs[0].residuals, left_array=self.psrs[0].residuals),
            np.dot(self.psrs[0].residuals,
                   sl.cho_solve(cf, self.psrs[0].residuals)),
            rtol=1e-10,
        ), msg

        msg = "EFAC/ECORR 2D1 solve incorrect."
        T = m.get_basis(params)
        assert np.allclose(
            N.solve(self.psrs[0].residuals, left_array=T),
            np.dot(T.T, sl.cho_solve(cf, self.psrs[0].residuals)),
            rtol=1e-10,
        ), msg

        msg = "EFAC/ECORR 2D2 solve incorrect."
        assert np.allclose(N.solve(T, left_array=T),
                           np.dot(T.T, sl.cho_solve(cf, T)),
                           rtol=1e-10), msg

        F, f2 = utils.createfourierdesignmatrix_red(self.psrs[0].toas,
                                                    nmodes=20)

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

        # inverse spectrum test
        msg = "Spectrum inverse incorrect for GP Fourier signal."
        assert np.all(m.get_phiinv(params) == 1 / phi), msg
예제 #29
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_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
예제 #30
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_red_noise_log10_A': lA1,
            'B1855+09_red_noise_gamma': gamma1,
            'J1909-3744_red_noise_log10_A': lA2,
            'J1909-3744_red_noise_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
예제 #31
0
    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
예제 #32
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