Пример #1
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
Пример #2
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)

        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
Пример #3
0
def get_iers_b_up_to_date(mjd):
    """Update the IERS B table to include MJD if necessary"""
    if Time.now().mjd <= mjd:
        raise ValueError("IERS B data requested for future MJD {}".format(mjd))
    might_be_old = is_url_in_cache(IERS_B_URL)
    iers_b = IERS_B.open(download_file(IERS_B_URL, cache=True))
    if might_be_old and iers_b[-1]["MJD"].to_value(u.d) < mjd:
        # Try wiping the download and re-downloading
        clear_download_cache(IERS_B_URL)
        iers_b = IERS_B.open(download_file(IERS_B_URL, cache=True))
    if iers_b[-1]["MJD"].to_value(u.d) < mjd:
        raise ValueError(
            "IERS B data not yet available for MJD {}".format(mjd))
    return iers_b
Пример #4
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, uses FB90.
                SpacecraftObs will include a topocentric correction term.
            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":
            return self._get_TDB_default(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)
Пример #5
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
Пример #6
0
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
Пример #7
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")
Пример #8
0
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
Пример #9
0
 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
Пример #10
0
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
Пример #11
0
    def fit(self, selected, iters=1):
        """
        Run a fit using the specified fitter
        """
        # Select all the TOAs if none are explicitly set
        if not any(selected):
            selected = ~selected

        if self.fitted:
            self.prefit_model = self.postfit_model
            self.prefit_resids = self.postfit_resids

        if self.fitter == Fitters.POWELL:
            fitter = pint.fitter.PowellFitter(self.selected_toas, self.prefit_model)
        elif self.fitter == Fitters.WLS:
            fitter = pint.fitter.WLSFitter(self.selected_toas, self.prefit_model)
        elif self.fitter == Fitters.GLS:
            fitter = pint.fitter.GLSFitter(self.selected_toas, self.prefit_model)
        chi2 = self.prefit_resids.chi2
        wrms = self.prefit_resids.rms_weighted()
        print("Pre-Fit Chi2:\t\t%.8g" % chi2)
        print("Pre-Fit Weighted RMS:\t%.8g us" % wrms.to(u.us).value)

        fitter.fit_toas(maxiter=1)
        self.postfit_model = fitter.model
        self.postfit_resids = Residuals(self.all_toas, self.postfit_model)
        self.fitted = True
        self.write_fit_summary()

        # TODO: delta_pulse_numbers need some work. They serve both for PHASE and -padd functions from the TOAs
        # as well as for phase jumps added manually in the GUI. They really should not be zeroed out here because
        # that will wipe out preexisting values
        self.all_toas.table["delta_pulse_numbers"] = np.zeros(self.all_toas.ntoas)
        self.selected_toas.table["delta_pulse_number"] = np.zeros(
            self.selected_toas.ntoas
        )

        # plot the prefit without jumps
        pm_no_jumps = copy.deepcopy(self.prefit_model)
        for param in pm_no_jumps.params:
            if param.startswith("JUMP"):
                getattr(pm_no_jumps, param).value = 0.0
                getattr(pm_no_jumps, param).frozen = True
        self.prefit_resids_no_jumps = Residuals(self.selected_toas, pm_no_jumps)

        f = copy.deepcopy(fitter)
        no_jumps = [
            False if "jump" in dict.keys() else True for dict in f.toas.table["flags"]
        ]
        f.toas.select(no_jumps)

        selectedMJDs = self.selected_toas.get_mjds()
        if all(no_jumps):
            q = list(self.all_toas.get_mjds())
            index = q.index(
                [i for i in self.all_toas.get_mjds() if i > selectedMJDs.min()][0]
            )
            rs_mean = (
                Residuals(self.all_toas, f.model)
                .phase_resids[index : index + len(selectedMJDs)]
                .mean()
            )
        else:
            rs_mean = self.prefit_resids_no_jumps.phase_resids[no_jumps].mean()

        # determines how far on either side fake toas go
        # TODO: hard limit on how far fake toas can go --> can get clkcorr
        # errors if go before GBT existed, etc.
        minMJD, maxMJD = selectedMJDs.min(), selectedMJDs.max()
        spanMJDs = maxMJD - minMJD
        if spanMJDs < 30 * u.d:
            redge = ledge = 4
            npoints = 400
        elif spanMJDs < 90 * u.d:
            redge = ledge = 2
            npoints = 300
        elif spanMJDs < 200 * u.d:
            redge = ledge = 1
            npoints = 300
        elif spanMJDs < 400 * u.d:
            redge = ledge = 0.5
            npoints = 200
        else:
            redge = ledge = 1.0
            npoints = 250
        # Check to see if too recent
        nowish = (Time.now().mjd - 40) * u.d
        if maxMJD + spanMJDs * redge > nowish:
            redge = (nowish - maxMJD) / spanMJDs
            if redge < 0.0:
                redge = 0.0
        f_toas = make_fake_toas_uniform(
            minMJD - spanMJDs * ledge, maxMJD + spanMJDs * redge, npoints, f.model
        )
        rs = calculate_random_models(
            f, f_toas, Nmodels=10, keep_models=False, return_time=True
        )

        # subtract the mean residual of each random model from the respective residual set
        # based ONLY on the mean of the random residuals in the real data range
        start_index = np.where(abs(f_toas.get_mjds() - minMJD) < 1 * u.d)
        end_index = np.where(abs(f_toas.get_mjds() - maxMJD) < 1 * u.d)
        for i in range(len(rs)):
            # use start_index[0][0] since np.where returns np.array([], dtype), extract index from list in array
            rs_mean = rs[i][start_index[0][0] : end_index[0][0]].mean()
            rs[i][:] = [resid - rs_mean for resid in rs[i]]

        self.random_resids = rs
        self.fake_toas = f_toas
Пример #12
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
Пример #13
0
    def fit(self, selected, iters=1):
        """
        Run a fit using the specified fitter
        """
        # Select all the TOAs if none are explicitly set
        if not any(selected):
            selected = ~selected
        """JUMP check, TODO: put in fitter?"""
        if "PhaseJump" in self.prefit_model.components:
            # if attempted fit (selected)
            # A) contains only jumps, don't do the fit and return an error
            # B) excludes a jump, turn that jump off
            # C) partially contains a jump, redefine that jump only with the overlap
            fit_jumps = []
            for param in self.prefit_model.params:
                if getattr(self.prefit_model,
                           param).frozen == False and param.startswith("JUMP"):
                    fit_jumps.append(int(param[4:]))

            numjumps = self.prefit_model.components[
                "PhaseJump"].get_number_of_jumps()
            if numjumps == 0:
                log.warn(
                    "There are no jumps (maskParameter objects) in PhaseJump. Please delete the PhaseJump object and try again. "
                )
                return None
            # boolean array to determine if all selected toas are jumped
            jumps = [
                True if "jump" in dict.keys() and dict["jump"] in fit_jumps
                else False for dict in self.all_toas.table["flags"][selected]
            ]
            # check if par file jumps in PhaseJump object
            if not any(jumps):
                # for every jump, set appropriate flag for TOAs it jumps
                for jump_par in self.prefit_model.components[
                        "PhaseJump"].get_jump_param_objects():
                    # find TOAs jump applies to
                    mask = jump_par.select_toa_mask(self.all_toas)
                    # apply to dictionaries for future use
                    for dict in self.all_toas.table["flags"][mask]:
                        dict["jump"] = jump_par.index
                jumps = [
                    True if "jump" in dict.keys() and dict["jump"] in fit_jumps
                    else False
                    for dict in self.all_toas.table["flags"][selected]
                ]
            if all(jumps):
                log.warn(
                    "toas being fit must not all be jumped. Remove or uncheck at least one jump in the selected toas before fitting."
                )
                return None
            # numerical array of selected jump flags
            sel_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.all_toas.table["flags"][selected]
            ]
            # numerical array of all jump flags
            full_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.all_toas.table["flags"]
            ]
            for num in range(1, numjumps + 1):
                num = int(num)
                if num not in sel_jump_nums:
                    getattr(self.prefit_model, "JUMP" + str(num)).frozen = True
                    continue
                jump_select = [num == jump_num for jump_num in full_jump_nums]
                overlap = [a and b for a, b in zip(jump_select, selected)]
                # remove the jump flags for that num
                for dict in self.all_toas.table["flags"]:
                    if "jump" in dict.keys() and dict["jump"] == num:
                        del dict["jump"]
                # re-add the jump using overlap as 'selected'
                for dict in self.all_toas.table["flags"][overlap]:
                    dict["jump"] = num

        if self.fitted:
            self.prefit_model = self.postfit_model
            self.prefit_resids = self.postfit_resids

        if self.fitter == Fitters.POWELL:
            fitter = pint.fitter.PowellFitter(self.selected_toas,
                                              self.prefit_model)
        elif self.fitter == Fitters.WLS:
            fitter = pint.fitter.WLSFitter(self.selected_toas,
                                           self.prefit_model)
        elif self.fitter == Fitters.GLS:
            fitter = pint.fitter.GLSFitter(self.selected_toas,
                                           self.prefit_model)
        chi2 = self.prefit_resids.chi2
        wrms = np.sqrt(chi2 / self.selected_toas.ntoas)
        print("Pre-Fit Chi2:\t\t%.8g us^2" % chi2)
        print("Pre-Fit Weighted RMS:\t%.8g us" % wrms)

        fitter.fit_toas(maxiter=1)
        self.postfit_model = fitter.model
        self.postfit_resids = Residuals(self.all_toas, self.postfit_model)
        self.fitted = True
        self.write_fit_summary()

        # TODO: delta_pulse_numbers need some work. They serve both for PHASE and -padd functions from the TOAs
        # as well as for phase jumps added manually in the GUI. They really should not be zeroed out here because
        # that will wipe out preexisting values
        self.fulltoas.table["delta_pulse_numbers"] = np.zeros(
            self.fulltoas.ntoas)
        self.selected_toas.table["delta_pulse_number"] = np.zeros(
            self.selected_toas.ntoas)

        # plot the prefit without jumps
        pm_no_jumps = copy.deepcopy(self.postfit_model)
        for param in pm_no_jumps.params:
            if param.startswith("JUMP"):
                getattr(pm_no_jumps, param).value = 0.0
                getattr(pm_no_jumps, param).frozen = True
        self.prefit_resids_no_jumps = Residuals(self.selected_toas,
                                                pm_no_jumps)

        f = copy.deepcopy(fitter)
        no_jumps = [
            False if "jump" in dict.keys() else True
            for dict in f.toas.table["flags"]
        ]
        f.toas.select(no_jumps)

        selectedMJDs = self.selected_toas.get_mjds()
        if all(no_jumps):
            q = list(self.all_toas.get_mjds())
            index = q.index([
                i for i in self.all_toas.get_mjds() if i > selectedMJDs.min()
            ][0])
            rs_mean = (Residuals(
                self.all_toas,
                f.model).phase_resids[index:index + len(selectedMJDs)].mean())
        else:
            rs_mean = self.prefit_resids_no_jumps.phase_resids[no_jumps].mean()

        # determines how far on either side fake toas go
        # TODO: hard limit on how far fake toas can go --> can get clkcorr
        # errors if go before GBT existed, etc.
        minMJD, maxMJD = selectedMJDs.min(), selectedMJDs.max()
        spanMJDs = maxMJD - minMJD
        if spanMJDs < 30 * u.d:
            redge = ledge = 4
            npoints = 400
        elif spanMJDs < 90 * u.d:
            redge = ledge = 2
            npoints = 300
        elif spanMJDs < 200 * u.d:
            redge = ledge = 1
            npoints = 300
        elif spanMJDs < 400 * u.d:
            redge = ledge = 0.5
            npoints = 200
        else:
            redge = ledge = 0.2
            npoints = 150
        # Check to see if too recent
        nowish = (Time.now().mjd - 40) * u.d
        if maxMJD + spanMJDs * redge > nowish:
            redge = (nowish - maxMJD) / spanMJDs
            if redge < 0.0:
                redge = 0.0
        f_toas, rs, mrands = random_models(
            f,
            rs_mean=rs_mean,
            redge_multiplier=redge,
            ledge_multiplier=ledge,
            npoints=npoints,
            iter=10,
        )
        self.random_resids = rs
        self.fake_toas = f_toas
Пример #14
0
 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")
Пример #15
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
Пример #16
0
    def fit(self, selected, iters=1):
        """
        Run a fit using the specified fitter
        """
        # Select all the TOAs if none are explicitly set
        if not any(selected):
            selected = ~selected
        """JUMP check, TODO: put in fitter?"""
        if "PhaseJump" in self.prefit_model.components:
            # if attempted fit (selected)
            # A) contains only jumps, don't do the fit and return an error
            # B) excludes a jump, turn that jump off
            # C) partially contains a jump, redefine that jump only with the overlap
            fit_jumps = []
            for param in self.prefit_model.params:
                if getattr(self.prefit_model,
                           param).frozen == False and param.startswith("JUMP"):
                    fit_jumps.append(int(param[4:]))
            jumps = [
                True if "jump" in dict.keys() and dict["jump"] in fit_jumps
                else False for dict in self.selected_toas.table["flags"]
            ]
            if all(jumps):
                log.warn(
                    "toas being fit must not all be jumped. Remove or uncheck at least one jump in the selected toas before fitting."
                )
                return None
            sel_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.selected_toas.table["flags"]
            ]
            full_jump_nums = [
                dict["jump"] if "jump" in dict.keys() else np.nan
                for dict in self.all_toas.table["flags"]
            ]
            for num in range(1, int(np.nanmax(full_jump_nums) + 1)):
                num = int(num)
                if num not in sel_jump_nums:
                    getattr(self.prefit_model, "JUMP" + str(num)).frozen = True
                    continue
                jump_select = [num == jump_num for jump_num in full_jump_nums]
                overlap = [a and b for a, b in zip(jump_select, selected)]
                # remove the jump flags for that num
                for dict in self.all_toas.table["flags"]:
                    if "jump" in dict.keys() and dict["jump"] == num:
                        del dict["jump"]
                # re-add the jump using overlap as 'selected'
                for dict in self.all_toas.table["flags"][overlap]:
                    dict["jump"] = num

        if self.fitted:
            self.prefit_model = self.postfit_model
            self.prefit_resids = self.postfit_resids

        if self.fitter == Fitters.POWELL:
            fitter = pint.fitter.PowellFitter(self.selected_toas,
                                              self.prefit_model)
        elif self.fitter == Fitters.WLS:
            fitter = pint.fitter.WLSFitter(self.selected_toas,
                                           self.prefit_model)
        elif self.fitter == Fitters.GLS:
            fitter = pint.fitter.GLSFitter(self.selected_toas,
                                           self.prefit_model)
        chi2 = self.prefit_resids.chi2
        wrms = np.sqrt(chi2 / self.selected_toas.ntoas)
        print("Pre-Fit Chi2:\t\t%.8g us^2" % chi2)
        print("Pre-Fit Weighted RMS:\t%.8g us" % wrms)

        fitter.fit_toas(maxiter=1)
        self.postfit_model = fitter.model
        self.postfit_resids = Residuals(self.all_toas,
                                        self.postfit_model,
                                        set_pulse_nums=True)
        self.fitted = True
        self.write_fit_summary()

        # TODO: set pulse nums above not working to reset delta pulse nums, have to force it here
        # self.fulltoas.table['delta_pulse_numbers'] = np.zeros(self.fulltoas.ntoas)
        self.selected_toas.table["delta_pulse_number"] = np.zeros(
            self.selected_toas.ntoas)

        # plot the prefit without jumps
        pm_no_jumps = copy.deepcopy(self.postfit_model)
        for param in pm_no_jumps.params:
            if param.startswith("JUMP"):
                getattr(pm_no_jumps, param).value = 0.0
                getattr(pm_no_jumps, param).frozen = True
        self.prefit_resids_no_jumps = Residuals(self.all_toas,
                                                pm_no_jumps,
                                                set_pulse_nums=True)

        f = copy.deepcopy(fitter)
        no_jumps = [
            False if "jump" in dict.keys() else True
            for dict in f.toas.table["flags"]
        ]
        f.toas.select(no_jumps)

        selectedMJDs = self.selected_toas.get_mjds()
        if all(no_jumps):
            q = list(self.all_toas.get_mjds())
            index = q.index([
                i for i in self.all_toas.get_mjds() if i > selectedMJDs.min()
            ][0])
            rs_mean = (Residuals(
                self.all_toas, f.model,
                set_pulse_nums=True).phase_resids[index:index +
                                                  len(selectedMJDs)].mean())
        else:
            rs_mean = self.prefit_resids_no_jumps.phase_resids[no_jumps].mean()

        # determines how far on either side fake toas go
        # TODO: hard limit on how far fake toas can go --> can get clkcorr
        # errors if go before GBT existed, etc.
        minMJD, maxMJD = selectedMJDs.min(), selectedMJDs.max()
        spanMJDs = maxMJD - minMJD
        if spanMJDs < 30 * u.d:
            redge = ledge = 4
            npoints = 400
        elif spanMJDs < 90 * u.d:
            redge = ledge = 2
            npoints = 300
        elif spanMJDs < 200 * u.d:
            redge = ledge = 1
            npoints = 300
        elif spanMJDs < 400 * u.d:
            redge = ledge = 0.5
            npoints = 200
        else:
            redge = ledge = 0.2
            npoints = 150
        # Check to see if too recent
        nowish = (Time.now().mjd - 40) * u.d
        if maxMJD + spanMJDs * redge > nowish:
            redge = (nowish - maxMJD) / spanMJDs
            if redge < 0.0:
                redge = 0.0
        f_toas, rs = random_models(
            f,
            rs_mean=rs_mean,
            redge_multiplier=redge,
            ledge_multiplier=ledge,
            npoints=npoints,
            iter=10,
        )
        self.random_resids = rs
        self.fake_toas = f_toas