コード例 #1
0
ファイル: pulsar.py プロジェクト: rossjjennings/PINT
 def dayofyear(self):
     """
     Return the day of the year for all the TOAs of this pulsar
     """
     t = Time(self.all_toas.get_mjds(), format="mjd")
     year = Time(np.floor(t.decimalyear), format="decimalyear")
     return np.asarray(t.mjd - year.mjd) << u.day
コード例 #2
0
def gcrs_posvel_from_itrf(loc, toas, obsname="obs"):
    """Return a list of PosVel instances for the observatory at the TOA times.

    Observatory location should be given in the loc argument as an astropy
    EarthLocation object. This location will be in the ITRF frame (i.e.
    co-rotating with the Earth).

    The optional obsname argument will be used as label in the returned
    PosVel instance.

    This routine returns a list of PosVel instances, containing the
    positions (m) and velocities (m / s) at the times of the toas and
    referenced to the Earth-centered Inertial (ECI, aka GCRS) coordinates.
    This routine is basically SOFA's pvtob() [Position and velocity of
    a terrestrial observing station] with an extra rotation from c2ixys()
    [Form the celestial to intermediate-frame-of-date matrix given the CIP
    X,Y and the CIO locator s].

    This version uses astropy's internal routines, which use IERS A data
    rather than the final IERS B values. These do differ, and yield results
    that are different by ~20 m.
    """
    unpack = False
    # If the input is a single TOA (i.e. a row from the table),
    # then put it into a list
    if type(toas) == table.row.Row:
        ttoas = Time([toas["mjd"]])
        unpack = True
    elif type(toas) == table.table.Table:
        ttoas = toas["mjd"]
    elif isinstance(toas, Time):
        if toas.isscalar:
            ttoas = Time([toas])
            unpack = True
        else:
            ttoas = toas
    else:
        if np.isscalar(toas):
            ttoas = Time([toas], format="mjd")
            unpack = True
        else:
            ttoas = toas
    t = ttoas

    pos, vel = loc.get_gcrs_posvel(t)
    r = PosVel(pos.xyz, vel.xyz, obj=obsname, origin="earth")
    if unpack:
        return r[0]
    else:
        return r
コード例 #3
0
 def fake_year(self):
     """
     Function to support plotting of random models on multiple x-axes.
     Return the decimal year for all the TOAs of this pulsar
     """
     t = Time(self.fake_toas.get_mjds(), format="mjd")
     return (t.decimalyear) * u.year
コード例 #4
0
ファイル: topo_obs.py プロジェクト: dlakaplan/PINT
    def _get_TDB_ephem(self, t, ephem):
        """Read the ephem TDB-TT column.

        This column is provided by DE4XXt version of ephemeris. This function is only
        for the ground-based observatories

        """
        geo_tdb_tt = get_tdb_tt_ephem_geocenter(t.tt, ephem)
        # NOTE The earth velocity is need to compute the time correcion from
        # Topocenter to Geocenter
        # Since earth velocity is not going to change a lot in 3ms. The
        # differences between TT and TDB can be ignored.
        earth_pv = objPosVel_wrt_SSB("earth", t.tdb, ephem)
        obs_geocenter_pv = gcrs_posvel_from_itrf(
            self.earth_location_itrf(), t, obsname=self.name
        )
        # NOTE
        # Moyer (1981) and Murray (1983), with fundamental arguments adapted
        # from Simon et al. 1994.
        topo_time_corr = numpy.sum(
            earth_pv.vel / c.c * obs_geocenter_pv.pos / c.c, axis=0
        )
        topo_tdb_tt = geo_tdb_tt - topo_time_corr
        result = Time(
            t.tt.jd1 - JD_MJD,
            t.tt.jd2 - topo_tdb_tt.to(u.day).value,
            format="pulsar_mjd",
            scale="tdb",
            location=self.earth_location_itrf(),
        )
        return result
コード例 #5
0
ファイル: topo_obs.py プロジェクト: dlakaplan/PINT
 def posvel(self, t, ephem, group=None):
     if t.isscalar:
         t = Time([t])
     earth_pv = objPosVel_wrt_SSB("earth", t, ephem)
     obs_geocenter_pv = gcrs_posvel_from_itrf(
         self.earth_location_itrf(), t, obsname=self.name
     )
     return obs_geocenter_pv + earth_pv
コード例 #6
0
def F0(toa, model):

    dt = toa.get_mjds(high_precision=True) - np.array(
        Time(model.PEPOCH.value, format="pulsar_mjd", scale="utc")
    )
    # Can use dt[n].jd1 and jd2 with mpmath here if necessary
    ph = np.array([x.sec * model.F0.value for x in dt])

    return ph
コード例 #7
0
ファイル: __init__.py プロジェクト: ben-cassese/PINT
    def get_TDBs(self, t, method="default", ephem=None, options=None):
        """This is a high level function for converting TOAs to TDB time scale.

        Different method can be applied to obtain the result. Current supported
        methods are ['default', 'ephemeris']

        Parameters
        ----------
        t: astropy.time.Time object
            The time need for converting toas
        method: str or callable, optional
            Method of computing TDB

            "default"
                Astropy time.Time object built-in converter, uses FB90.
                SpacecraftObs will include a topocentric correction term.
            "ephemeris"
                JPL ephemeris included TDB-TT correction. Not currently
                implemented.
            callable
                This callable is called with the parameter t as its first
                parameter; additional keyword arguments can be supplied
                in the options argument

        ephem: str, optional
            The ephemeris to get he TDB-TT correction. Required for the
            'ephemeris' method.
        options: dict or None
            Options to pass to a custom callable.
        """

        if t.isscalar:
            t = Time([t])
        if t.scale == "tdb":
            return t
        # Check the method. This pattern is from numpy minize
        if callable(method):
            meth = "_custom"
        else:
            meth = method.lower()
        if options is None:
            options = {}
        if meth == "_custom":
            options = dict(options)
            return method(t, **options)
        if meth == "default":
            return self._get_TDB_default(t, ephem)
        elif meth == "ephemeris":
            if ephem is None:
                raise ValueError(
                    "A ephemeris file should be provided to get"
                    " the TDB-TT corrections."
                )
            return self._get_TDB_ephem(t, ephem)
        else:
            raise ValueError("Unknown method '%s'." % method)
コード例 #8
0
    def test_normal_day(self):
        one_mjd = Time(self.normal_days[0], scale="utc")
        mjds = Time(self.normal_days, scale="utc")
        # convert to pulsar mjd
        p_one_mjd = Time(one_mjd, format="pulsar_mjd")
        p_mjds = Time(mjds, format="pulsar_mjd")

        assert np.isscalar(
            p_one_mjd.value), "Pulsar one mjd did not return the right lenght."
        assert np.isclose(
            np.modf(p_one_mjd.value)[0], 0.5, atol=1e-14
        ), "Pulsar mjd did not give the right fractional day at leapsecond day"
        assert len(p_mjds) == 2, "Pulsar mjds did not return the right lenght."
        assert np.all(
            np.isclose(np.modf(p_mjds.value)[0], 0.5, atol=1e-14)
        ), "Pulsar mjd did not give the right fractional day at leapsecond day"
        assert np.all(np.isclose(
            np.modf(mjds.mjd)[0], 0.5,
            atol=1e-14)), "Astropy time did not have correct leapsecond setup."
コード例 #9
0
 def __init__(self, filename, **kwargs):
     self.filename = filename
     log.debug("Loading {0} observatory clock correction file {1}".format(
         self.format, filename))
     mjd, clk, self.header = self.load_tempo2_clock_file(filename)
     # NOTE Clock correction file has a time far in the future as ending point
     with warnings.catch_warnings():
         warnings.simplefilter("ignore", ErfaWarning)
         self._time = Time(mjd, format="pulsar_mjd", scale="utc")
     self._clock = clk * u.s
コード例 #10
0
    def change_pepoch(self, new_epoch, toas=None, delay=None):
        """Move PEPOCH to a new time and change the related paramters.

        Parameters
        ----------
        new_epoch: float or `astropy.Time` object
            The new PEPOCH value.
        toas: `toa` object, optional.
            If current PEPOCH is not provided, the first pulsar frame toa will
            be treated as PEPOCH.
        delay: `numpy.array` object
            If current PEPOCH is not provided, it is required for computing the
            first pulsar frame toa.
        """
        if isinstance(new_epoch, Time):
            new_epoch = Time(new_epoch, scale="tdb", precision=9)
        else:
            new_epoch = Time(new_epoch, scale="tdb", format="mjd", precision=9)
        # make new_epoch a toa for delay calculation.
        new_epoch_toa = toa.get_TOAs_list([toa.TOA(new_epoch)],
                                          ephem=toas.ephem)

        if self.PEPOCH.value is None:
            if toas is None or delay is None:
                raise ValueError(
                    "`PEPOCH` is not in the model, thus, 'toa' and"
                    " 'delay' shoule be givne.")
            tbl = toas.table
            phsepoch_ld = (tbl["tdb"][0] - delay[0]).tdb.mjd_long
        else:
            phsepoch_ld = self.PEPOCH.quantity.tdb.mjd_long
        dt = (new_epoch.tdb.mjd_long - phsepoch_ld) * u.day
        fterms = [0.0 * u.Unit("")] + self.get_spin_terms()
        # rescale the fterms
        for n in range(len(fterms) - 1):
            f_par = getattr(self, "F{}".format(n))
            f_par.value = taylor_horner_deriv(dt.to(u.second),
                                              fterms,
                                              deriv_order=n + 1)
        self.PEPOCH.value = new_epoch
コード例 #11
0
 def __init__(self, filename, obscode=None, **kwargs):
     self.filename = filename
     self.obscode = obscode
     log.debug(
         "Loading {0} observatory ({1}) clock correction file {2}".format(
             self.format, obscode, filename))
     mjd, clk = self.load_tempo1_clock_file(filename, site=obscode)
     # NOTE Clock correction file has a time far in the future as ending point
     # We are swithing off astropy warning only for gps correction.
     with warnings.catch_warnings():
         warnings.simplefilter("ignore", ErfaWarning)
         try:
             self._time = Time(mjd, format="pulsar_mjd", scale="utc")
         except ValueError:
             log.error("Filename {0}, site {1}: Bad MJD {2}".format(
                 filename, obscode, mjd))
             raise
     self._clock = clk * u.us
コード例 #12
0
ファイル: pulsar.py プロジェクト: rossjjennings/PINT
 def year(self):
     """
     Return the decimal year for all the TOAs of this pulsar
     """
     t = Time(self.all_toas.get_mjds(), format="mjd")
     return np.asarray(t.decimalyear) << u.year
コード例 #13
0
ファイル: fermiphase.py プロジェクト: hellohancheng/PINT
def main(argv=None):

    parser = argparse.ArgumentParser(
        description=
        "Use PINT to compute H-test and plot Phaseogram from a Fermi FT1 event file."
    )
    parser.add_argument("eventfile", help="Fermi event FITS file name.")
    parser.add_argument("parfile", help="par file to construct model from")
    parser.add_argument(
        "weightcol",
        help="Column name for event weights (or 'CALC' to compute them)")
    parser.add_argument("--ft2", help="Path to FT2 file.", default=None)
    parser.add_argument(
        "--addphase",
        help="Write FT1 file with added phase column",
        default=False,
        action="store_true",
    )
    parser.add_argument("--plot",
                        help="Show phaseogram plot.",
                        action="store_true",
                        default=False)
    parser.add_argument("--plotfile",
                        help="Output figure file name (default=None)",
                        default=None)
    parser.add_argument("--maxMJD",
                        help="Maximum MJD to include in analysis",
                        default=None)
    parser.add_argument(
        "--outfile",
        help="Output figure file name (default is to overwrite input file)",
        default=None,
    )
    parser.add_argument(
        "--planets",
        help="Use planetary Shapiro delay in calculations (default=False)",
        default=False,
        action="store_true",
    )
    parser.add_argument("--ephem",
                        help="Planetary ephemeris to use (default=DE421)",
                        default="DE421")
    args = parser.parse_args(argv)

    # If outfile is specified, that implies addphase
    if args.outfile is not None:
        args.addphase = True

    # Read in model
    modelin = pint.models.get_model(args.parfile)
    if "ELONG" in modelin.params:
        tc = SkyCoord(
            modelin.ELONG.quantity,
            modelin.ELAT.quantity,
            frame="barycentrictrueecliptic",
        )
    else:
        tc = SkyCoord(modelin.RAJ.quantity,
                      modelin.DECJ.quantity,
                      frame="icrs")

    if args.ft2 is not None:
        # Instantiate FermiObs once so it gets added to the observatory registry
        FermiObs(name="Fermi", ft2name=args.ft2)

    # Read event file and return list of TOA objects
    tl = load_Fermi_TOAs(args.eventfile,
                         weightcolumn=args.weightcol,
                         targetcoord=tc)

    # Discard events outside of MJD range
    if args.maxMJD is not None:
        tlnew = []
        print("pre len : ", len(tl))
        maxT = Time(float(args.maxMJD), format="mjd")
        print("maxT : ", maxT)
        for tt in tl:
            if tt.mjd < maxT:
                tlnew.append(tt)
        tl = tlnew
        print("post len : ", len(tlnew))

    # Now convert to TOAs object and compute TDBs and posvels
    # For Fermi, we are not including GPS or TT(BIPM) corrections
    ts = toa.get_TOAs_list(
        tl,
        include_gps=False,
        include_bipm=False,
        planets=args.planets,
        ephem=args.ephem,
    )
    ts.filename = args.eventfile

    print(ts.get_summary())
    mjds = ts.get_mjds()
    print(mjds.min(), mjds.max())

    # Compute model phase for each TOA
    iphss, phss = modelin.phase(ts, abs_phase=True)
    # ensure all postive
    phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss)
    mjds = ts.get_mjds()
    weights = np.array([w["weight"] for w in ts.table["flags"]])
    h = float(hmw(phases, weights))
    print("Htest : {0:.2f} ({1:.2f} sigma)".format(h, h2sig(h)))
    if args.plot:
        log.info("Making phaseogram plot with {0} photons".format(len(mjds)))
        phaseogram(mjds, phases, weights, bins=100, plotfile=args.plotfile)

    if args.addphase:
        # Read input FITS file (again).
        # If overwriting, open in 'update' mode
        if args.outfile is None:
            hdulist = pyfits.open(args.eventfile, mode="update")
        else:
            hdulist = pyfits.open(args.eventfile)
        event_hdu = hdulist[1]
        event_hdr = event_hdu.header
        event_dat = event_hdu.data
        if len(event_dat) != len(phases):
            raise RuntimeError(
                "Mismatch between length of FITS table ({0}) and length of phase array ({1})!"
                .format(len(event_dat), len(phases)))
        if "PULSE_PHASE" in event_hdu.columns.names:
            log.info("Found existing PULSE_PHASE column, overwriting...")
            # Overwrite values in existing Column
            event_dat["PULSE_PHASE"] = phases
        else:
            # Construct and append new column, preserving HDU header and name
            log.info("Adding new PULSE_PHASE column.")
            phasecol = pyfits.ColDefs(
                [pyfits.Column(name="PULSE_PHASE", format="D", array=phases)])
            bt = pyfits.BinTableHDU.from_columns(event_hdu.columns + phasecol,
                                                 header=event_hdr,
                                                 name=event_hdu.name)
            hdulist[1] = bt
        if args.outfile is None:
            # Overwrite the existing file
            log.info("Overwriting existing FITS file " + args.eventfile)
            hdulist.flush(verbose=True, output_verify="warn")
        else:
            # Write to new output file
            log.info("Writing output FITS file " + args.outfile)
            hdulist.writeto(args.outfile,
                            overwrite=True,
                            checksum=True,
                            output_verify="warn")

    return 0
コード例 #14
0
def old_gcrs_posvel_from_itrf(loc, toas, obsname="obs"):
    """Return a list of PosVel instances for the observatory at the TOA times.

    Observatory location should be given in the loc argument as an astropy
    EarthLocation object. This location will be in the ITRF frame (i.e.
    co-rotating with the Earth).

    The optional obsname argument will be used as label in the returned
    PosVel instance.

    This routine returns a list of PosVel instances, containing the
    positions (m) and velocities (m / s) at the times of the toas and
    referenced to the Earth-centered Inertial (ECI, aka GCRS) coordinates.
    This routine is basically SOFA's pvtob() [Position and velocity of
    a terrestrial observing station] with an extra rotation from c2ixys()
    [Form the celestial to intermediate-frame-of-date matrix given the CIP
    X,Y and the CIO locator s].
    """
    unpack = False
    # If the input is a single TOA (i.e. a row from the table),
    # then put it into a list
    if type(toas) == table.row.Row:
        ttoas = Time([toas["mjd"]])
        unpack = True
    elif type(toas) == table.table.Table:
        ttoas = toas["mjd"]
    elif isinstance(toas, Time):
        if toas.isscalar:
            ttoas = Time([toas])
            unpack = True
        else:
            ttoas = toas
    else:
        if np.isscalar(toas):
            ttoas = Time([toas], format="mjd")
            unpack = True
        else:
            ttoas = toas
    N = len(ttoas)
    if len(ttoas.shape) != 1:
        raise ValueError("At most one-dimensional array of times possible, "
                         "shape was {}".format(ttoas.shape))

    # Get various times from the TOAs as arrays
    tts = np.asarray([(t.jd1, t.jd2) for t in ttoas.tt]).T
    ut1s = np.asarray([(t.jd1, t.jd2) for t in ttoas.ut1]).T
    mjds = np.asarray(ttoas.mjd)

    iers_b = get_iers_b_up_to_date(mjds.max())

    # Get x, y coords of Celestial Intermediate Pole and CIO locator s
    X, Y, S = erfa.xys00a(*tts)

    # Get dX and dY from IERS A in arcsec and convert to radians
    # dX = np.interp(mjds, iers_tab['MJD'], iers_tab['dX_2000A_B']) * asec2rad
    # dY = np.interp(mjds, iers_tab['MJD'], iers_tab['dY_2000A_B']) * asec2rad
    # Get dX and dY from IERS B in arcsec and convert to radians
    dX = np.interp(mjds, iers_b["MJD"].to_value(u.d),
                   iers_b["dX_2000A"].to_value(u.rad))
    dY = np.interp(mjds, iers_b["MJD"].to_value(u.d),
                   iers_b["dY_2000A"].to_value(u.rad))

    # Get GCRS to CIRS matrices
    rc2i = erfa.c2ixys(X + dX, Y + dY, S)

    # Gets the TIO locator s'
    sp = erfa.sp00(*tts)

    # Get X and Y from IERS A in arcsec and convert to radians
    # xp = np.interp(mjds, iers_tab['MJD'], iers_tab['PM_X_B']) * asec2rad
    # yp = np.interp(mjds, iers_tab['MJD'], iers_tab['PM_Y_B']) * asec2rad
    # Get X and Y from IERS B in arcsec and convert to radians
    xp = np.interp(mjds, iers_b["MJD"].to_value(u.d),
                   iers_b["PM_x"].to_value(u.rad))
    yp = np.interp(mjds, iers_b["MJD"].to_value(u.d),
                   iers_b["PM_y"].to_value(u.rad))

    # Get the polar motion matrices
    rpm = erfa.pom00(xp, yp, sp)

    # Observatory geocentric coords in m
    xyzm = np.array([a.to_value(u.m) for a in loc.geocentric])
    x, y, z = np.dot(xyzm, rpm).T

    # Functions of Earth Rotation Angle
    theta = erfa.era00(*ut1s)
    s, c = np.sin(theta), np.cos(theta)
    sx, cx = s * x, c * x
    sy, cy = s * y, c * y

    # Initial positions and velocities
    iposs = np.asarray([cx - sy, sx + cy, z]).T
    ivels = np.asarray([OM * (-sx - cy), OM * (cx - sy), np.zeros_like(x)]).T
    # There is probably a way to do this with np.einsum or something...
    # and here it is .
    poss = np.empty((N, 3), dtype=np.float64)
    vels = np.empty((N, 3), dtype=np.float64)
    poss = np.einsum("ij,ijk->ik", iposs, rc2i)
    vels = np.einsum("ij,ijk->ik", ivels, rc2i)
    r = PosVel(poss.T * u.m, vels.T * u.m / u.s, obj=obsname, origin="earth")
    if unpack:
        return r[0]
    else:
        return r
コード例 #15
0
ファイル: test_times.py プロジェクト: hellohancheng/PINT
def test_times_against_tempo2():
    log.setLevel("ERROR")
    # for nice output info, set the following instead
    # log.setLevel('INFO')

    ls = u.def_unit("ls", const.c * 1.0 * u.s)

    log.info("Reading TOAs into PINT")
    ts = toa.get_TOAs(datadir + "/testtimes.tim",
                      include_bipm=False,
                      usepickle=False)
    if log.level < 25:
        ts.print_summary()
    ts.table.sort("index")

    log.info("Calling TEMPO2")
    # cmd = 'tempo2 -output general2 -f tests/testtimes.par tests/testtimes.tim -s "XXX {clock0} {clock1} {clock2} {clock3} {tt} {t2tb} {telSSB} {telVel} {Ttt}\n"'
    # cmd = 'tempo2 -output general2 -f ' + datadir+'/testtimes.par ' + datadir + \
    #       '/testtimes.tim -s "XXX {clock0} {clock1} {clock2} {clock3} {tt} {t2tb} {earth_ssb1} {earth_ssb2} {earth_ssb3} {earth_ssb4} {earth_ssb5} {earth_ssb6} {telEpos} {telEVel} {Ttt}\n"'
    # args = shlex.split(cmd)
    #
    # tout = subprocess.check_output(args)
    # goodlines = [x for x in tout.split("\n") if x.startswith("XXX")]
    #
    # assert(len(goodlines)==len(ts.table))
    # t2result = numpy.genfromtxt('datafile/testtimes.par' + '.tempo2_test', names=True, comments = '#')

    f = open(datadir + "/testtimes.par" + ".tempo2_test")
    lines = f.readlines()
    goodlines = lines[1:]
    # Get the output lines from the TOAs
    for line, TOA in zip(goodlines, ts.table):
        assert (len(line.split()) == 19
                ), "tempo2 general2 does not support all needed outputs"
        (
            oclk,
            gps_utc,
            tai_utc,
            tt_tai,
            ttcorr,
            tt2tb,
            ep0,
            ep1,
            ep2,
            ev0,
            ev1,
            ev2,
            tp0,
            tp1,
            tp2,
            tv0,
            tv1,
            tv2,
            Ttt,
        ) = (float(x) for x in line.split())

        t2_epv = PosVel(
            numpy.asarray([ep0, ep1, ep2]) * ls,
            numpy.asarray([ev0, ev1, ev2]) * ls / u.s,
        )
        t2_opv = PosVel(
            numpy.asarray([tp0, tp1, tp2]) * ls,
            numpy.asarray([tv0, tv1, tv2]) * ls / u.s,
        )

        t2_ssb2obs = t2_epv + t2_opv
        # print time_to_mjd_string(TOA.mjd.tt), line.split()[-1]
        tempo_tt = Time(line.split()[-1], format="mjd_string", scale="tt")
        # Ensure that the clock corrections are accurate to better than 0.1 ns
        assert (math.fabs(
            (oclk * u.s + gps_utc * u.s - TOA["flags"]["clkcorr"]).to(
                u.ns).value) < 0.1)

        log.info("TOA in tt difference is: %.2f ns" %
                 ((TOA["mjd"].tt - tempo_tt.tt).sec * u.s).to(u.ns).value)

        pint_opv = erfautils.gcrs_posvel_from_itrf(Observatory.get(
            TOA["obs"]).earth_location_itrf(),
                                                   TOA,
                                                   obsname=TOA["obs"])
        pint_opv = PosVel(pint_opv.pos, pint_opv.vel)
        # print " obs  T2:", t2_opv.pos.to(u.m).value, t2_opv.vel.to(u.m/u.s)
        # print " obs PINT:", pint_opv.pos.to(u.m), pint_opv.vel.to(u.m/u.s)
        dopv = pint_opv - t2_opv
        dpos = numpy.sqrt(numpy.dot(dopv.pos.to(u.m), dopv.pos.to(u.m)))
        dvel = numpy.sqrt(
            numpy.dot(dopv.vel.to(u.mm / u.s), dopv.vel.to(u.mm / u.s)))
        log.info(" obs diff: %.2f m, %.3f mm/s" % (dpos, dvel))
        assert dpos < 2.0 and dvel < 0.02

        pint_ssb2obs = PosVel(
            numpy.asarray(TOA["ssb_obs_pos"]) * u.km,
            numpy.asarray(TOA["ssb_obs_vel"]) * u.km / u.s,
            origin="SSB",
            obj="OBS",
        )
        # print " topo  T2:", t2_ssb2obs.pos.to(u.km), t2_ssb2obs.vel.to(u.km/u.s)
        # print " topo PINT:", pint_ssb2obs.pos.to(u.km), pint_ssb2obs.vel.to(u.km/u.s)
        dtopo = pint_ssb2obs - t2_ssb2obs
        dpos = numpy.sqrt(numpy.dot(dtopo.pos.to(u.m), dtopo.pos.to(u.m)))
        dvel = numpy.sqrt(
            numpy.dot(dtopo.vel.to(u.mm / u.s), dtopo.vel.to(u.mm / u.s)))
        log.info(" topo diff: %.2f m, %.3f m/s" % (dpos, dvel))
        assert dpos < 2.0 and dvel < 0.02
コード例 #16
0
ファイル: test_observatory.py プロジェクト: tcromartie/PINT
 def setUpClass(cls):
     os.chdir(datadir)
     cls.test_obs = ["aro", "ao", "chime", "drao"]
     cls.test_time = Time(np.linspace(55000, 58000, num=100),
                          scale="utc",
                          format="pulsar_mjd")
コード例 #17
0
    def get_TDBs(self,
                 t,
                 method="default",
                 ephem=None,
                 options=None,
                 grp=None):
        """This is a high level function for converting TOAs to TDB time scale.

        Different method can be applied to obtain the result. Current supported
        methods are ['astropy', 'ephemeris']

        Parameters
        ----------
        t: astropy.time.Time object
            The time need for converting toas
        method: str or callable, optional
            Method of computing TDB

            default
                Astropy time.Time object built-in converter, use FB90.
                Also uses topocentric correction term if self.tt2tdbmethod is
                pint.
            ephemeris
                JPL ephemeris included TDB-TT correction.

        ephem: str, optional
            The ephemeris to get he TDB-TT correction. Required for the
            'ephemeris' method.
        """

        if t.isscalar:
            t = Time([t])
        if t.scale == "tdb":
            return t
        # Check the method. This pattern is from numpy minize
        if callable(method):
            meth = "_custom"
        else:
            meth = method.lower()
        if options is None:
            options = {}
        if meth == "_custom":
            options = dict(options)
            return method(t, **options)
        if meth == "default":
            if self.tt2tdb_mode.lower().startswith("astropy"):
                log.info("Doing astropy mode TDB conversion")
                return self._get_TDB_astropy(t)
            elif self.tt2tdb_mode.lower().startswith("pint"):
                log.info("Doing PINT mode TDB conversion")
                if ephem is None:
                    raise ValueError(
                        "A ephemeris file should be provided to get"
                        " the TDB-TT corrections, or use tt2tdb_mode=astropy")
                return self._get_TDB_PINT(t, ephem, grp)
        elif meth == "ephemeris":
            if ephem is None:
                raise ValueError("A ephemeris file should be provided to get"
                                 " the TDB-TT corrections.")
            return self._get_TDB_ephem(t, ephem)
        else:
            raise ValueError("Unknown method '%s'." % method)
コード例 #18
0
def main(argv=None):
    import argparse

    parser = argparse.ArgumentParser(
        description=
        "Use PINT to compute event phases and make plots of photon event files."
    )
    parser.add_argument(
        "eventfile",
        help=
        "Photon event FITS file name (e.g. from NICER, RXTE, XMM, Chandra).",
    )
    parser.add_argument("parfile", help="par file to construct model from")
    parser.add_argument("--orbfile", help="Name of orbit file", default=None)
    parser.add_argument("--maxMJD",
                        help="Maximum MJD to include in analysis",
                        default=None)
    parser.add_argument("--plotfile",
                        help="Output figure file name (default=None)",
                        default=None)
    parser.add_argument(
        "--addphase",
        help="Write FITS file with added phase column",
        default=False,
        action="store_true",
    )
    parser.add_argument(
        "--addorbphase",
        help="Write FITS file with added orbital phase column",
        default=False,
        action="store_true",
    )
    parser.add_argument(
        "--absphase",
        help="Write FITS file with integral portion of pulse phase (ABS_PHASE)",
        default=False,
        action="store_true",
    )
    parser.add_argument(
        "--barytime",
        help=
        "Write FITS file with a column containing the barycentric time as double precision MJD.",
        default=False,
        action="store_true",
    )
    parser.add_argument(
        "--outfile",
        help="Output FITS file name (default=same as eventfile)",
        default=None,
    )
    parser.add_argument("--ephem",
                        help="Planetary ephemeris to use (default=DE421)",
                        default="DE421")
    parser.add_argument(
        "--tdbmethod",
        help="Method for computing TT to TDB (default=astropy)",
        default="default",
    )
    parser.add_argument("--plot",
                        help="Show phaseogram plot.",
                        action="store_true",
                        default=False)
    parser.add_argument(
        "--use_gps",
        default=False,
        action="store_true",
        help="Apply GPS to UTC clock corrections",
    )
    parser.add_argument(
        "--use_bipm",
        default=False,
        action="store_true",
        help="Use TT(BIPM) instead of TT(TAI)",
    )
    #    parser.add_argument("--fix",help="Apply 1.0 second offset for NICER", action='store_true', default=False)
    args = parser.parse_args(argv)

    # If outfile is specified, that implies addphase
    if args.outfile is not None:
        args.addphase = True

    # If plotfile is specified, that implies plot
    if args.plotfile is not None:
        args.plot = True

    # Read event file header to figure out what instrument is is from
    hdr = pyfits.getheader(args.eventfile, ext=1)

    log.info("Event file TELESCOPE = {0}, INSTRUMENT = {1}".format(
        hdr["TELESCOP"], hdr["INSTRUME"]))

    if hdr["TELESCOP"] == "NICER":

        # Instantiate NICERObs once so it gets added to the observatory registry
        if args.orbfile is not None:
            log.info("Setting up NICER observatory")
            NICERObs(name="NICER", FPorbname=args.orbfile, tt2tdb_mode="pint")
        # Read event file and return list of TOA objects
        try:
            tl = load_NICER_TOAs(args.eventfile)
        except KeyError:
            log.error(
                "Observatory not recognized.  This probably means you need to provide an orbit file or barycenter the event file."
            )
            sys.exit(1)
    elif hdr["TELESCOP"] == "XTE":

        # Instantiate RXTEObs once so it gets added to the observatory registry
        if args.orbfile is not None:
            # Determine what observatory type is.
            log.info("Setting up RXTE observatory")
            RXTEObs(name="RXTE", FPorbname=args.orbfile, tt2tdb_mode="pint")
        # Read event file and return list of TOA objects
        tl = load_RXTE_TOAs(args.eventfile)
    elif hdr["TELESCOP"].startswith("XMM"):
        # Not loading orbit file here, since that is not yet supported.
        tl = load_XMM_TOAs(args.eventfile)
    elif hdr["TELESCOP"].lower().startswith("nustar"):
        if args.orbfile is not None:
            log.info("Setting up NuSTAR observatory")
            NuSTARObs(name="NuSTAR",
                      FPorbname=args.orbfile,
                      tt2tdb_mode="pint")
        tl = load_NuSTAR_TOAs(args.eventfile)
    else:
        log.error(
            "FITS file not recognized, TELESCOPE = {0}, INSTRUMENT = {1}".
            format(hdr["TELESCOP"], hdr["INSTRUME"]))
        sys.exit(1)

    # Now convert to TOAs object and compute TDBs and posvels
    if len(tl) == 0:
        log.error("No TOAs, exiting!")
        sys.exit(0)

    # Read in model
    modelin = pint.models.get_model(args.parfile)
    use_planets = False
    if "PLANET_SHAPIRO" in modelin.params:
        if modelin.PLANET_SHAPIRO.value:
            use_planets = True
    if "AbsPhase" not in modelin.components:
        log.error(
            "TimingModel does not include AbsPhase component, which is required "
            "for computing phases. Make sure you have TZR* parameters in your par file!"
        )
        raise ValueError("Model missing AbsPhase component.")

    if args.addorbphase and (not hasattr(modelin, "binary_model_name")):
        log.error(
            "TimingModel does not include a binary model, which is required for "
            "computing orbital phases. Make sure you have BINARY and associated "
            "model parameters in your par file!")
        raise ValueError("Model missing BINARY component.")

    # Discard events outside of MJD range
    if args.maxMJD is not None:
        tlnew = []
        print("pre len : ", len(tl))
        maxT = Time(float(args.maxMJD), format="mjd")
        print("maxT : ", maxT)
        for tt in tl:
            if tt.mjd < maxT:
                tlnew.append(tt)
        tl = tlnew
        print("post len : ", len(tlnew))

    ts = toa.get_TOAs_list(
        tl,
        ephem=args.ephem,
        include_bipm=args.use_bipm,
        include_gps=args.use_gps,
        planets=use_planets,
        tdb_method=args.tdbmethod,
    )
    ts.filename = args.eventfile
    #    if args.fix:
    #        ts.adjust_TOAs(TimeDelta(np.ones(len(ts.table))*-1.0*u.s,scale='tt'))

    print(ts.get_summary())
    mjds = ts.get_mjds()
    print(mjds.min(), mjds.max())

    # Compute model phase for each TOA
    iphss, phss = modelin.phase(ts, abs_phase=True)
    # ensure all postive
    negmask = phss < 0.0
    phases = np.where(negmask, phss + 1.0, phss)
    h = float(hm(phases))
    print("Htest : {0:.2f} ({1:.2f} sigma)".format(h, h2sig(h)))
    if args.plot:
        phaseogram_binned(mjds, phases, bins=100, plotfile=args.plotfile)

    # Compute orbital phases for each photon TOA
    if args.addorbphase:
        delay = modelin.delay(ts)
        orbits = modelin.binary_instance.orbits()
        # These lines are already in orbits.orbit_phase() in binary_orbits.py.
        # What is the correct syntax is to call this function here?
        norbits = np.array(np.floor(orbits), dtype=np.long)
        orbphases = orbits - norbits  # fractional phase

    if args.addphase or args.addorbphase:
        # Read input FITS file (again).
        # If overwriting, open in 'update' mode
        if args.outfile is None:
            hdulist = pyfits.open(args.eventfile, mode="update")
        else:
            hdulist = pyfits.open(args.eventfile)

        datacol = []
        data_to_add = {}

        if args.addphase:
            if len(hdulist[1].data) != len(phases):
                raise RuntimeError(
                    "Mismatch between length of FITS table ({0}) and length of phase array ({1})!"
                    .format(len(hdulist[1].data), len(phases)))
            data_to_add["PULSE_PHASE"] = [phases, "D"]

        if args.absphase:
            data_to_add["ABS_PHASE"] = [iphss - negmask, "K"]

        if args.barytime:
            bats = modelin.get_barycentric_toas(ts)
            data_to_add["BARY_TIME"] = [bats, "D"]

        if args.addorbphase:
            if len(hdulist[1].data) != len(orbphases):
                raise RuntimeError(
                    "Mismatch between length of FITS table ({0}) and length of orbital phase array ({1})!"
                    .format(len(hdulist[1].data), len(orbphases)))
            data_to_add["ORBIT_PHASE"] = [orbphases, "D"]
        # End if args.addorbphase

        for key in data_to_add.keys():
            if key in hdulist[1].columns.names:
                log.info("Found existing %s column, overwriting..." % key)
                # Overwrite values in existing Column
                hdulist[1].data[key] = data_to_add[key][0]
            else:
                # Construct and append new column, preserving HDU header and name
                log.info("Adding new %s column." % key)
                datacol.append(
                    pyfits.ColDefs([
                        pyfits.Column(
                            name=key,
                            format=data_to_add[key][1],
                            array=data_to_add[key][0],
                        )
                    ]))

        if len(datacol) > 0:
            cols = hdulist[1].columns
            for c in datacol:
                cols = cols + c
            bt = pyfits.BinTableHDU.from_columns(cols,
                                                 header=hdulist[1].header,
                                                 name=hdulist[1].name)
            hdulist[1] = bt

        if args.outfile is None:
            # Overwrite the existing file
            log.info("Overwriting existing FITS file " + args.eventfile)
            hdulist.flush(verbose=True, output_verify="warn")
        else:
            # Write to new output file
            log.info("Writing output FITS file " + args.outfile)
            hdulist.writeto(args.outfile,
                            overwrite=True,
                            checksum=True,
                            output_verify="warn")
コード例 #19
0
ファイル: pintbary.py プロジェクト: paulray/PINT
def main(argv=None):
    parser = argparse.ArgumentParser(
        description="PINT tool for command-line barycentering calculations.")

    parser.add_argument("time", help="MJD (UTC, by default)")
    parser.add_argument(
        "--timescale",
        default="utc",
        help="Time scale for MJD argument ('utc', 'tt', 'tdb'), default=utc",
    )
    parser.add_argument(
        "--format",
        help=
        ("Format for time argument ('mjd' or any astropy.Time format "
         "(e.g. 'isot'), see <http://docs.astropy.org/en/stable/time/#time-format>)"
         ),
        default="mjd",
    )
    parser.add_argument("--freq",
                        type=float,
                        default=np.inf,
                        help="Frequency to use, MHz")
    parser.add_argument("--obs",
                        default="Geocenter",
                        help="Observatory code (default = Geocenter)")
    parser.add_argument("--parfile",
                        help="par file to read model from",
                        default=None)
    parser.add_argument(
        "--ra",
        help="RA to use (e.g. '12h22m33.2s' if not read from par file)")
    parser.add_argument(
        "--dec",
        help="Decl. to use (e.g. '19d21m44.2s' if not read from par file)")
    parser.add_argument("--dm",
                        help="DM to use (if not read from par file)",
                        type=float,
                        default=0.0)
    parser.add_argument("--ephem", default="DE421", help="Ephemeris to use")
    parser.add_argument(
        "--use_gps",
        default=False,
        action="store_true",
        help="Apply GPS to UTC clock corrections",
    )
    parser.add_argument(
        "--use_bipm",
        default=False,
        action="store_true",
        help="Use TT(BIPM) instead of TT(TAI)",
    )

    args = parser.parse_args(argv)

    if args.format in ("mjd", "jd", "unix"):
        # These formats require conversion from string to long double first
        fmt = args.format
        # Never allow format == 'mjd' because it fails when scale is 'utc'
        # Change 'mjd' to 'pulsar_mjd' to deal with this.
        if fmt == "mjd":
            fmt = "pulsar_mjd"
        t = Time(np.longdouble(args.time),
                 scale=args.timescale,
                 format=fmt,
                 precision=9)
        print(t)
    else:
        t = Time(args.time,
                 scale=args.timescale,
                 format=args.format,
                 precision=9)
    log.debug(t.iso)

    t = toa.TOA(t, freq=args.freq, obs=args.obs)
    # Build TOAs and compute TDBs and positions from ephemeris
    ts = toa.get_TOAs_list(
        [t],
        ephem=args.ephem,
        include_bipm=args.use_bipm,
        include_gps=args.use_gps,
        planets=False,
    )

    if args.parfile is not None:
        m = pint.models.get_model(args.parfile)
    else:
        # Construct model by hand
        m = pint.models.StandardTimingModel
        # Should check if 12:13:14.2 syntax is used and support that as well!
        m.RAJ.quantity = Angle(args.ra)
        m.DECJ.quantity = Angle(args.dec)
        m.DM.quantity = args.dm * u.parsec / u.cm**3

    tdbtimes = m.get_barycentric_toas(ts)

    print("{0:.16f}".format(tdbtimes[0].value))
    return
コード例 #20
0
 def year(self):
     """
     Return the decimal year for all the TOAs of this pulsar
     """
     t = Time(self.selected_toas.get_mjds(), format="mjd")
     return (t.decimalyear) * u.year