Exemplo n.º 1
0
def get_optimal_cuts(data, pred_rate=0.017, usez=False):
    """ Determine rates from analytic prediction for both 0.25 and 0.40 keV
        cuts, and use these to estimate an optimal H test.
    """
    pi_mask = (data[2] > 25) & (data[2] < 100)
    sn, sn0, hs, ph_gti, gti_rts_s, gti_len_s = make_sn(data,
                                                        mask=pi_mask,
                                                        rate=pred_rate,
                                                        usez=usez)
    amax = np.argmax(sn)

    pi_mask = (data[2] > 40) & (data[2] < 100)
    pred_rate *= 3. / 5
    sn_40, sn0_40, hs_40, ph_gti_40, gti_rts_s_40, gti_len_s_40 = make_sn(
        data, mask=pi_mask, rate=pred_rate, usez=usez)
    if usez:
        hsig_40 = sig2sigma(chi2.sf(hs, 4))
    else:
        hsig_40 = local_h2sig(hs)
    exposure = np.cumsum(gti_len_s)
    amax_40 = np.argmax(sn_40)

    # get intersection of 0.25 keV data sets and 0.4 keV data sets
    rate_025_cut = gti_rts_s[amax]
    rate_040_cut = gti_rts_s_40[amax_40]
    mask_025 = gti_rts_s <= rate_025_cut
    mask_040 = ~mask_025 & (gti_rts_s_40 < rate_040_cut)
    ph1 = np.concatenate(np.asarray(ph_gti)[mask_025])
    try:
        ph2 = np.concatenate(np.asarray(ph_gti_40)[mask_040])
    except ValueError:
        ph2 = np.asarray([])

    print('Found %d photons satisfying 0.25 keV cut; exposure = %.1fs' %
          (len(ph1), np.sum(np.asarray(gti_len_s)[mask_025])))
    print('Found %d photons satisfying 0.40 keV cut; exposure = %.1fs' %
          (len(ph2), np.sum(np.asarray(gti_len_s_40)[mask_040])))
    if usez:
        print('Z-test 1: %.2f' % z2m(ph1, m=2)[-1])
        if len(ph2) > 0:
            print('Z-test 2: %.2f' % z2m(ph2, m=2)[-1])
        else:
            print('Z-test 2: no photons!')
        print('Z-test joint: %.2f' % z2m(np.append(ph1, ph2), m=2)[-1])
    else:
        print('H-test 1: %.2f' % hm(ph1))
        if len(ph2) > 0:
            print('H-test 2: %.2f' % hm(ph2))
        else:
            print('H-test 2: no photons!')
        print('H-test joint: %.2f' % hm(np.append(ph1, ph2)))
Exemplo n.º 2
0
 def prof_vs_weights(self, nbins=50, use_weights=False):
     """
     Show binned profiles (and H-test values) as a function
     of the minimum weight used. nbins is only for the plots.
     """
     f, ax = plt.subplots(3, 3, sharex=True)
     phss = self.get_event_phases()
     htests = []
     weights = np.linspace(0.0, 0.95, 20)
     swgts = self.get_weights()
     for ii, minwgt in enumerate(weights):
         good = swgts > minwgt
         nphotons = np.sum(good)
         wgts = swgts[good] if use_weights else None
         if nphotons <= 0:
             hval = 0
         else:
             if use_weights:
                 hval = hmw(phss[good], weights=wgts)
             else:
                 hval = hm(phss[good])
         htests.append(hval)
         if ii > 0 and ii % 2 == 0 and ii < 20:
             r, c = ((ii - 2) / 2) / 3, ((ii - 2) / 2) % 3
             ax[r][c].hist(
                 phss[good],
                 nbins,
                 range=[0, 1],
                 weights=wgts,
                 color="k",
                 histtype="step",
             )
             ax[r][c].set_title("%.1f / %.1f / %.0f" %
                                (minwgt, hval, nphotons),
                                fontsize=11)
             if c == 0:
                 ax[r][c].set_ylabel("Htest")
             if r == 2:
                 ax[r][c].set_xlabel("Phase")
             f.suptitle(
                 "%s:  Minwgt / H-test / Approx # events" %
                 self.model.PSR.value,
                 fontweight="bold",
             )
     if use_weights:
         plt.savefig(self.model.PSR.value + "_profs_v_wgtcut.png")
     else:
         plt.savefig(self.model.PSR.value +
                     "_profs_v_wgtcut_unweighted.png")
     plt.close()
     plt.plot(weights, htests, "k")
     plt.xlabel("Min Weight")
     plt.ylabel("H-test")
     plt.title(self.model.PSR.value)
     if use_weights:
         plt.savefig(self.model.PSR.value + "_htest_v_wgtcut.png")
     else:
         plt.savefig(self.model.PSR.value +
                     "_htest_v_wgtcut_unweighted.png")
     plt.close()
Exemplo n.º 3
0
def test_h_and_z():
    phases = np.linspace(0, 1, 101)
    weights = np.zeros(101)
    weights[:50] = 1

    ans = 0.01980198019801975
    res = es.hm(phases)
    assert_allclose(res, ans, atol=1.0e-7)

    ans = 40.54180942257532
    res = es.hmw(phases, weights)
    assert_allclose(res, ans, atol=1.0e-7)

    res = es.z2m(phases, m=4)
    assert len(res) == 4
    ans = 0.0792079207920788
    assert_allclose(res[3], ans, atol=1.0e-7)

    ans = 40.54180942257532
    res = es.hmw(phases, weights)
    assert_allclose(res, ans, atol=1.0e-7)

    res = es.z2mw(phases, weights, m=4)
    assert len(res) == 4
    ans = 45.05833019383544
    assert_allclose(res[3], ans, atol=1.0e-7)
Exemplo n.º 4
0
def pulse_profile(ax, etable, args):
    if (args.orb is None) or (args.par is None):
        log.warning('You did not specify orbfile or parfile')
        log.info('Please input files for orb and par with --orb and --par')
        return
    import pint
    import astropy.io.fits as pyfits
    import pint.toa, pint.models
    from pint.plot_utils import phaseogram_binned
    from pint.observatory.nicer_obs import NICERObs
    from pint.eventstats import hm

    ### Make arguments for parfile and orbfile and only do this if both are present
    log.info('Event file TELESCOPE = {0}, INSTRUMENT = {1}'.format(
        etable.meta['TELESCOP'], etable.meta['INSTRUME']))
    # Instantiate NICERObs once so it gets added to the observatory registry
    log.info('Setting up NICER observatory')
    NICERObs(name='NICER', FPorbname=args.orb, tt2tdb_mode='none')

    # Read event file and return list of TOA objects
    log.info('doing the load_toas thing')
    #tl  = load_NICER_TOAs(pulsefilename[0])

    # Create TOA list
    tl = []
    for t in etable['T']:
        tl.append(pint.toa.TOA(t, obs='NICER'))

    ts = pint.toa.TOAs(toalist=tl)
    ts.compute_TDBs()
    ts.compute_posvels(ephem='DE421', planets=True)

    log.info('Did all the stuff, now to PARFILE')
    # Load PINT model objects
    modelin = pint.models.get_model(args.par)
    log.info(str(modelin))

    # Compute phases
    phss = modelin.phase(ts.table)[1]
    # Strip the units, because PINT may return u.cycle
    phss = np.array(phss)
    # ensure all postive
    phases = np.where(phss < 0.0, phss + 1.0, phss)
    mjds = ts.get_mjds()

    h = hm(phases)
    log.info("H = {0} from {1} phases".format(h, len(phases)))
    ax.hist(phases, bins=32)
    ax.text(0.1, 0.1, 'H = {0:.2f}'.format(h), transform=ax.transAxes)

    #np.savetxt('{0}.phases'.format(args.basename),np.transpose([etable['MET'], etable['PI'],phases]))

    plot.ylabel('Counts')
    plot.xlabel('Pulse Phase')
    plot.title('Pulse Profile')
    return
Exemplo n.º 5
0
 def prof_vs_weights(self, nbins=50, use_weights=False):
     """
     Show binned profiles (and H-test values) as a function
     of the minimum weight used. nbins is only for the plots.
     """
     global ftr
     f, ax = plt.subplots(3, 3, sharex=True)
     phss = ftr.get_event_phases()
     htests = []
     weights = np.linspace(0.0, 0.95, 20)
     for ii, minwgt in enumerate(weights):
         good = ftr.weights > minwgt
         nphotons = np.sum(good)
         wgts = ftr.weights[good] if use_weights else None
         if nphotons <= 0:
             hval = 0
         else:
             if use_weights:
                 hval = hmw(phss[good], weights=wgts)
             else:
                 hval = hm(phss[good])
         htests.append(hval)
         if ii > 0 and ii%2==0 and ii<20:
             r, c = ((ii-2)/2)/3, ((ii-2)/2)%3
             ax[r][c].hist(phss[good], nbins, range=[0,1],
                           weights=wgts, color='k',
                           histtype='step')
             ax[r][c].set_title("%.1f / %.1f / %.0f" %
                                (minwgt, hval, nphotons),
                                fontsize=11)
             if c==0: ax[r][c].set_ylabel("Htest")
             if r==2: ax[r][c].set_xlabel("Phase")
             f.suptitle("%s:  Minwgt / H-test / Approx # events" %
                        self.model.PSR.value, fontweight='bold')
     if use_weights:
         plt.savefig(ftr.model.PSR.value+"_profs_v_wgtcut.png")
     else:
         plt.savefig(ftr.model.PSR.value+"_profs_v_wgtcut_unweighted.png")
     plt.close()
     plt.plot(weights, htests, 'k')
     plt.xlabel("Min Weight")
     plt.ylabel("H-test")
     plt.title(self.model.PSR.value)
     if use_weights:
         plt.savefig(ftr.model.PSR.value+"_htest_v_wgtcut.png")
     else:
         plt.savefig(ftr.model.PSR.value+"_htest_v_wgtcut_unweighted.png")
     plt.close()
Exemplo n.º 6
0
 def _hist_setup(self):
     """ Setup data for chi-squared and binned likelihood."""
     h = hm(self.phases)
     nbins = 25
     if h > 100: nbins = 50
     if h > 1000: nbins = 100
     ph0,ph1 = 0+self.phase_shift,1+self.phase_shift
     hist = np.histogram(self.phases,bins=np.linspace(ph0,ph1,nbins))
     if len(hist[0])==nbins: raise ValueError,'Histogram too old!'
     x = ((hist[1][1:] + hist[1][:-1])/2.)[hist[0]>0]
     counts = (hist[0][hist[0]>0]).astype(float)
     y    = counts / counts.sum() * nbins
     yerr = counts**0.5  / counts.sum() * nbins
     self.chistuff = x,y,yerr
     # now set up binning for binned likelihood
     nbins = self.binned_bins+1
     hist = np.histogram(self.phases,bins=np.linspace(ph0,ph1,nbins))
     self.counts_centers = ((hist[1][1:] + hist[1][:-1])/2.)[hist[0]>0]
     self.counts = hist[0][hist[0]>0]
Exemplo n.º 7
0
 def _hist_setup(self):
     """ Setup data for chi-squared and binned likelihood."""
     h = hm(self.phases)
     nbins = 25
     if h > 100: nbins = 50
     if h > 1000: nbins = 100
     ph0, ph1 = 0 + self.phase_shift, 1 + self.phase_shift
     hist = np.histogram(self.phases, bins=np.linspace(ph0, ph1, nbins))
     if len(hist[0]) == nbins: raise ValueError('Histogram too old!')
     x = ((hist[1][1:] + hist[1][:-1]) / 2.)[hist[0] > 0]
     counts = (hist[0][hist[0] > 0]).astype(float)
     y = counts / counts.sum() * nbins
     yerr = counts**0.5 / counts.sum() * nbins
     self.chistuff = x, y, yerr
     # now set up binning for binned likelihood
     nbins = self.binned_bins + 1
     hist = np.histogram(self.phases, bins=np.linspace(ph0, ph1, nbins))
     self.counts_centers = ((hist[1][1:] + hist[1][:-1]) / 2.)[hist[0] > 0]
     self.counts = hist[0][hist[0] > 0]
Exemplo n.º 8
0
def main(argv=None):
    import argparse

    parser = argparse.ArgumentParser(
        description=
        "Use PINT to compute event phases and make plots of photon event files.",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    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("--minMJD",
                        help="Minimum MJD to include in analysis",
                        default=None)
    parser.add_argument("--plotfile",
                        help="Output figure file name",
                        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")
    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(
        "--log-level",
        type=str,
        choices=("TRACE", "DEBUG", "INFO", "WARNING", "ERROR"),
        default="WARNING",
        help="Logging level",
        dest="loglevel",
    )
    #    parser.add_argument("--fix",help="Apply 1.0 second offset for NICER", action='store_true', default=False)
    parser.add_argument(
        "--polycos",
        default=False,
        action="store_true",
        help=
        "Use polycos to calculate phases; use when working with very large event files",
    )
    args = parser.parse_args(argv)
    log.remove()
    log.add(
        sys.stderr,
        level=args.loglevel,
        colorize=True,
        format=pint.logging.format,
        filter=pint.logging.LogFilter(),
    )

    # 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

    # set MJD ranges
    maxmjd = np.inf if (args.maxMJD is None) else float(args.maxMJD)
    minmjd = 0.0 if (args.minMJD is None) else float(args.minMJD)

    # 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"]))

    telescope = hdr["TELESCOP"].lower()

    # Instantiate observatory once so it gets added to the observatory registry
    if args.orbfile is not None:
        log.info(f"Setting up {telescope.upper()} observatory")
        try:
            get_satellite_observatory(telescope, args.orbfile)
        except Exception:
            log.error(
                "The orbit file is not recognized. It is likely that this mission is not supported. "
                "Please barycenter the event file using the official mission tools before processing with PINT"
            )
    # Read event file and return list of TOA objects, if not using polycos
    if args.polycos == False:
        try:
            tl = load_event_TOAs(args.eventfile,
                                 telescope,
                                 minmjd=minmjd,
                                 maxmjd=maxmjd)
        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)

        # 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.")

    # Use polycos to calculate pulse phases
    if args.polycos:
        log.info("Using polycos to get pulse phases.")

        if args.addorbphase:
            raise ValueError("Cannot use orbphase with polycos.")

        # Polycos parameters
        segLength = 120  # in minutes
        ncoeff = 10
        obsfreq = 0

        # Open event file and get start and end mjds
        hdulist = pyfits.open(args.eventfile)
        data = hdulist[1].data
        mjds = read_fits_event_mjds(hdulist[1])
        minmjd = min(mjds)
        maxmjd = max(mjds)

        # Check if event file is barycentered
        if hdulist[1].header["TIMESYS"] != "TDB":
            raise ValueError(
                "The event file has not been barycentered. Polycos can only be used with barycentered data."
            )

        # Create polycos table
        log.debug("Generating polycos")
        telescope_n = "@"
        p = polycos.Polycos()
        ptable = p.generate_polycos(modelin, minmjd, maxmjd, telescope_n,
                                    segLength, ncoeff, obsfreq)

        # Calculate phases
        log.debug("Evaluating polycos")
        phases = p.eval_phase(mjds)
        phases[phases < 0] += 1.0
        h = float(hm(phases))
        print("Htest : {0:.2f} ({1:.2f} sigma)".format(h, h2sig(h)))
    else:  # Normal mode, not polycos
        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)
        phases = phss.value % 1
        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=int)
        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 = {}

        # Handle case where minMJD/maxMJD do not exceed length of events
        mjds_float = read_fits_event_mjds(hdulist[1])
        time_mask = np.logical_and((mjds_float > minmjd),
                                   (mjds_float < maxmjd))
        if args.polycos:
            time_mask = np.logical_and((mjds_float >= minmjd),
                                       (mjds_float <= maxmjd))

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

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

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

        if args.addorbphase:
            if time_mask.sum() != len(orbphases):
                raise RuntimeError(
                    "Mismatch between data selection ({0}) and length of orbital phase array ({1})!"
                    .format(time_mask.sum(), 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][time_mask] = data_to_add[key][0]
            else:
                # Construct and append new column, preserving HDU header and name
                log.info("Adding new %s column." % key)
                new_dat = np.full(time_mask.shape,
                                  -1,
                                  dtype=data_to_add[key][0].dtype)
                new_dat[time_mask] = data_to_add[key][0]
                datacol.append(
                    pyfits.ColDefs([
                        pyfits.Column(name=key,
                                      format=data_to_add[key][1],
                                      array=new_dat)
                    ]))

        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")
Exemplo n.º 9
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("--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("--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")
    parser.add_argument("--plot",help="Show phaseogram plot.", 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='none')
        # 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='none')
        # 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)
    else:
        log.error("FITS file not recognized, TELESCOPE = {0}, INSTRUMENT = {1}".format(
            hdr['TELESCOP'], hdr['INSTRUME']))
        sys.exit(1)

    # Read in model
    modelin = pint.models.get_model(args.parfile)

    # Discard SS Shapiro part if specified in ephemeris and not enabled
    if (not args.planets) and (
            'SolarSystemShapiro' in modelin.components.keys()):
        log.info(
            "Removing SS Shapiro component from model (planets=False).")
        components = modelin.components
        components.pop('SolarSystemShapiro')
        modelin.setup_components(components.values())

    # 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
    ts = toa.TOAs(toalist=tl)
    ts.filename = args.eventfile
    ts.compute_TDBs()
    ts.compute_posvels(ephem=args.ephem,planets=args.planets)

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

    # Compute model phase for each TOA
    iphss,phss = modelin.phase(ts.table)
    # ensure all postive
    negmask = phss < 0.0 * u.cycle
    phases = np.where(negmask, phss + 1.0 * u.cycle, 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)

    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)
        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*u.cycle,'K']
        if args.barytime:
            tdbs = np.asarray([t.mjd for t in ts.table['tdb']])
            data_to_add['BARY_TIME'] = [tdbs,'D']
        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 = pyfits.ColDefs([pyfits.Column(name=key, 
                    format=data_to_add[key][1], array=data_to_add[key][0])])
                bt = pyfits.BinTableHDU.from_columns(
                    hdulist[1].columns + datacol, 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')
Exemplo n.º 10
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")
Exemplo n.º 11
0
)  # TT topocentric MJDs as floats; only used to find the index of the photon time closest to the middle of the MJD range

# Compute model phase for each TOA;
phss = modelin.phase(ts, abs_phase=True)[1].value  # discard units

# Note that you can compute barycentric TOAs from topocentric data, so
# just because topo is False does NOT mean that data are barycentered!
if barydata:
    ph_times = ts.table["tdb"]
else:
    ph_times = ts.table["mjd"]

# ensure all positive
phases = np.where(phss < 0.0, 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)

# get exposure information
try:
    f = pyfits.open(args.eventname)
    exposure = f[1].header["exposure"]
    f.close()
except:
    exposure = 0

if args.grid > 0.0:
    mets = np.asarray([t.met for t in tl])
    dT = args.grid
Exemplo n.º 12
0
#print(ts.get_summary())
mjds = ts.get_mjds(
)  # TT topocentric MJDs as floats; only used to find the index of the photon time closest to the middle of the MJD range

# Compute model phase for each TOA;
#(TODO--'tdbs' var. needs to be renamed since it's TT and not TDB for the topocentric photon times in the if block)
phss = modelin.phase(ts, abs_phase=True)[1].value  # discard units
if args.topo:
    tdbs = ts.table['mjd']
else:
    tdbs = ts.table['tdb']

# ensure all positive
phases = np.where(phss < 0.0, 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)

# get exposure information
try:
    f = pyfits.open(args.eventname)
    exposure = f[1].header['exposure']
    f.close()
except:
    exposure = 0


def estimate_toa(mjds, phases, tdbs, topo, obs):
    """ Return a pint TOA object for the provided times and phases."""
Exemplo n.º 13
0
def pulse_profile(ax, etable, args):
    if (args.orb is None) or (args.par is None):
        log.warning('You did not specify orbfile or parfile')
        log.info('Please input files for orb and par with --orb and --par')
        return
    import pint
    import astropy.io.fits as pyfits
    from astropy.time import TimeDelta
    import pint.toa, pint.models
    from pint.plot_utils import phaseogram_binned
    from pint.observatory.nicer_obs import NICERObs
    from pint.eventstats import hm

    ### Make arguments for parfile and orbfile and only do this if both are present
    log.info('Event file TELESCOPE = {0}, INSTRUMENT = {1}'.format(
        etable.meta['TELESCOP'], etable.meta['INSTRUME']))
    # Instantiate NICERObs once so it gets added to the observatory registry
    log.info('Setting up NICER observatory')
    NICERObs(name='NICER', FPorbname=args.orb)

    log.info('Reading model from PARFILE')
    # Load PINT model objects
    modelin = pint.models.get_model(args.par)
    log.info(str(modelin))

    # Read event file and return list of TOA objects
    log.info('doing the load_toas thing')
    #tl  = load_NICER_TOAs(pulsefilename[0])

    # Create TOA list
    tl = []
    for t in etable['T']:
        tl.append(pint.toa.TOA(t, obs='NICER'))

    planets = False
    if 'PLANET_SHAPIRO' in modelin.params:
        if modelin.PLANET_SHAPIRO.value:
            planets = True
    ts = pint.toa.get_TOAs_list(tl,
                                planets=planets,
                                include_bipm=False,
                                include_gps=False)
    # No longer needed, since Feb 28 reprocessing
    #    log.warning('Applying -1.0s time correction to event time TOAs for pulse phase plot')
    #    ts.adjust_TOAs(TimeDelta(np.ones(len(ts.table))*-1.0*u.s,scale='tt'))
    # Note: adjust_TOAs recomputes TDBs and posvels so no need to do again.
    #    ts.compute_TDBs()
    #    ts.compute_posvels(ephem='DE421',planets=True)

    # Compute phases
    phss = modelin.phase(ts, abs_phase=True)[1]
    # Strip the units, because PINT may return u.cycle
    phss = np.array(phss)
    # ensure all postive
    phases = np.where(phss < 0.0, phss + 1.0, phss)
    mjds = ts.get_mjds()

    h = hm(phases)
    if not np.isfinite(h):
        log.error("H not finite, using {0} phases!".format(len(phases)))
        print("Phases from {0} to {1}\n".format(h.min(), h.max()))
    else:
        log.info("H = {0} from {1} phases".format(h, len(phases)))
    ax.hist(phases, bins=32)
    ax.text(0.1, 0.1, 'H = {0:.2f}'.format(h), transform=ax.transAxes)

    #np.savetxt('{0}.phases'.format(args.basename),np.transpose([etable['MET'], etable['PI'],phases]))

    plot.ylabel('Counts')
    plot.xlabel('Pulse Phase')
    plot.title('Pulse Profile')
    return
Exemplo n.º 14
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("--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

    # 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 * u.cycle
    phases = np.where(negmask, phss + 1.0 * u.cycle, 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)

    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)
        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*u.cycle,'K']
        if args.barytime:
            bats = modelin.get_barycentric_toas(ts)
            data_to_add['BARY_TIME'] = [bats,'D']
        datacol = []
        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')
Exemplo n.º 15
0
for ef in args.evfiles:

    tlist = []
    for fn in args.evfiles:
        log.info('Reading file {0}'.format(fn))
        tlist.append(Table.read(fn, hdu=1))
    log.info('Concatenating files')
    if len(tlist) == 1:
        etable = tlist[0]
    else:
        etable = vstack(tlist, metadata_conflicts='silent')
    del tlist

    phasesinitial = etable['PULSE_PHASE']
    hbest = hm(phasesinitial)
    eminbest = 0.0
    emaxbest = 100.0
    print("Initial Htest = {0}".format(hbest))

    emins = np.arange(0.4, 4.0, 0.1)
    for emin in emins:
        emaxs = np.arange(emin, 12.0, 0.1)
        for emax in emaxs:
            idx = np.where(
                np.logical_and(etable['PI'] * PI_TO_KEV > emin,
                               etable['PI'] * PI_TO_KEV < emax))[0]
            phases = etable['PULSE_PHASE'][idx]
            if len(phases) == 0:
                continue
            h = hm(phases)
Exemplo n.º 16
0
            print('Ignoring file {0} with good time {1:0.2f}.'.format(
                fn, good_time))
            continue
    tlist.append(t)

log.info('Concatenating files')
if len(tlist) == 1:
    etable = tlist[0]
else:
    etable = vstack(tlist, metadata_conflicts='silent')
del tlist

m = args.maxharm
ts_func = cached_zm if args.ztest else cached_hm
phasesinitial = etable['PULSE_PHASE'].astype(np.float32)
hbest = z2m(phasesinitial, m=m)[-1] if args.ztest else hm(phasesinitial, m=m)
eminbest = 0.0
emaxbest = 100.0
ts_name = "Ztest" if args.ztest else "Htest"
if args.ztest:
    print("Initial {0} = {1}".format(ts_name, np.round(hbest, 3)))
else:
    print("Initial {0} = {1} ({2} sigma)".format(ts_name, np.round(hbest, 3),
                                                 np.round(h2sig(hbest), 3)))

# assemble cache
cache = np.empty([m, 2, len(phasesinitial)], dtype=np.float32)
for i in xrange(m):
    cache[i, 0] = np.cos(phasesinitial * (2 * np.pi * (i + 1)))
    cache[i, 1] = np.sin(phasesinitial * (2 * np.pi * (i + 1)))
cached_hm._cache = cached_zm._cache = cache
Exemplo n.º 17
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(
        "--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'].startswith('NuSTAR'):
        # Not loading orbit file here, since that is not yet supported.
        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

    # 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 * u.cycle
    phases = np.where(negmask, phss + 1.0 * u.cycle, 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)

    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)
        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 * u.cycle, 'K']
        if args.barytime:
            bats = modelin.get_barycentric_toas(ts)
            data_to_add['BARY_TIME'] = [bats, 'D']
        datacol = []
        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')
Exemplo n.º 18
0
#print(ts.get_summary())
mjds = ts.get_mjds(
)  # TT topocentric MJDs as floats; only used to find the index of the photon time closest to the middle of the MJD range

# Compute model phase for each TOA;
#(TODO--'tdbs' var. needs to be renamed since it's TT and not TDB for the topocentric photon times in the if block)
phss = modelin.phase(ts, abs_phase=True)[1].value  # discard units
if args.topo:
    tdbs = ts.table['mjd']
else:
    tdbs = ts.table['tdb']

# ensure all positive
phases = np.where(phss < 0.0, 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)

# get exposure information
try:
    f = pyfits.open(args.eventname)
    exposure = f[1].header['exposure']
    f.close()
except:
    exposure = 0


def estimate_toa(mjds, phases, tdbs, topo, obs):
    """ Return a pint TOA object for the provided times and phases."""
Exemplo n.º 19
0
                    help="Output file for plot (type determined by extension)",
                    default=None)
args = parser.parse_args()

hdulist = pyfits.open(args.evtfile)
dat = hdulist[1].data
hdr = hdulist[1].header

ph = dat['PULSE_PHASE']

try:
    print("Z test = {} ({} sig)".format(
        z2m(ph)[-1], sig2sigma(sf_z2m(z2m(ph)[-1], lo))))
except:
    pass
print("H test = {} ({} sig)".format(hm(ph), h2sig(hm(ph))))

fig, ax = plt.subplots(figsize=(8, 4.5))

h, edges = np.histogram(ph,
                        bins=np.linspace(0.0, 1.0, args.nbins, endpoint=True))
try:
    if hdr['EXPOSURE'] > 0:
        h = np.array(h,
                     dtype=np.float) / (np.float(hdr['EXPOSURE']) / args.nbins)
        rates = True
except:
    rates = False
ax.step(np.concatenate((edges[:-1], 1.0 + edges)),
        np.concatenate((h, h, np.array(h[-1:]))),
        where='post')