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