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 _hist_setup(self): """ Setup binning for a quick chi-squared fit.""" h = hmw(self.phases,self.weights) nbins = 25 if h > 100: nbins = 50 if h > 1000: nbins = 100 bins,counts,errors = weighted_light_curve(nbins, self.phases,self.weights,phase_shift=self.phase_shift) mask = counts > 0 N = counts.sum() self.bg_level = 1-(self.weights**2).sum()/N x = ((bins[1:]+bins[:-1])/2) y = counts / N * nbins yerr = errors / N * nbins self.chistuff = x[mask],y[mask],yerr[mask] # now set up binning for binned likelihood nbins = self.binned_bins bins = np.linspace(0+self.phase_shift,1+self.phase_shift,nbins+1) a = np.argsort(self.phases) self.phases = self.phases[a] self.weights = self.weights[a] self.counts_centers = [] self.slices = [] indices = np.arange(len(self.weights)) for i in xrange(nbins): mask = (self.phases >= bins[i]) & (self.phases < bins[i+1]) if mask.sum() > 0: w = self.weights[mask] if w.sum()==0: continue p = self.phases[mask] self.counts_centers.append((w*p).sum()/w.sum()) self.slices.append(slice(indices[mask].min(),indices[mask].max()+1)) self.counts_centers = np.asarray(self.counts_centers)
def _hist_setup(self): """ Setup binning for a quick chi-squared fit.""" h = hmw(self.phases, self.weights) nbins = 25 if h > 100: nbins = 50 if h > 1000: nbins = 100 bins, counts, errors = weighted_light_curve( nbins, self.phases, self.weights, phase_shift=self.phase_shift) mask = counts > 0 N = counts.sum() self.bg_level = 1 - (self.weights**2).sum() / N x = ((bins[1:] + bins[:-1]) / 2) y = counts / N * nbins yerr = errors / N * nbins self.chistuff = x[mask], y[mask], yerr[mask] # now set up binning for binned likelihood nbins = self.binned_bins bins = np.linspace(0 + self.phase_shift, 1 + self.phase_shift, nbins + 1) a = np.argsort(self.phases) self.phases = self.phases[a] self.weights = self.weights[a] self.counts_centers = [] self.slices = [] indices = np.arange(len(self.weights)) for i in range(nbins): mask = (self.phases >= bins[i]) & (self.phases < bins[i + 1]) if mask.sum() > 0: w = self.weights[mask] if w.sum() == 0: continue p = self.phases[mask] self.counts_centers.append((w * p).sum() / w.sum()) self.slices.append( slice(indices[mask].min(), indices[mask].max() + 1)) self.counts_centers = np.asarray(self.counts_centers)
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 lnposterior(self, theta): """ The log posterior (priors * likelihood) """ global maxpost, numcalls self.set_params(dict(zip(self.fitkeys, theta))) # Make sure parallax is positive if we are fitting for it if 'PX' in self.fitkeys and self.model.PX.value < 0.0: return -np.inf if 'SINI' in self.fitkeys and (self.model.SINI.value > 1.0 or self.model.SINI.value < 0.0): return -np.inf # Do we really need to check both E and ECC or can the model param alias handle that? if 'E' in self.fitkeys and (self.model.E.value < 0.0 or self.model.E.value >= 1.0): return -np.inf if 'ECC' in self.fitkeys and (self.model.ECC.value < 0.0 or self.model.ECC.value >= 1.0): return -np.inf phases = self.get_event_phases() # Here, I need to negate the survival function of H, so I am looking # for the maximum lnlikelihood = -1.0 * sf_hm(hmw(phases, weights=self.weights), logprob=True) numcalls += 1 if numcalls % (nwalkers * nsteps / 100) == 0: print "~%d%% complete" % (numcalls / (nwalkers * nsteps / 100)) lnpost = self.lnprior(theta) + lnlikelihood if lnpost > maxpost: print "New max: ", lnpost for name, val in zip(ftr.fitkeys, theta): print " %8s: %25.15g" % (name, val) maxpost = lnpost self.maxpost_fitvals = theta return lnpost
def scan_F0(self, values, plotfile=None, show=False, par_model=None): # Set the par model to be the same one as stored in the object, # if none is provided. if par_model is None: par_model = self.modelin model = deepcopy(par_model) significance = [] # F0_range = np.arange(start, stop, step) F0_range = values for ii in F0_range: # Change F0 model.F0.quantity = ii * u.Hz # Calculate the phases iphss, phss = model.phase(self.toas) # Should I ensure all phases are positive? I don't think so... # Calculate the significance, and append it to the list significance.append( hmw(phss, np.array(self.toas.get_flag_value('weights')[0]))) if plotfile is not None: plt.plot(F0_range, significance) plt.savefig(plotfile) if show: plt.plot(F0_range, significance) plt.show() return significance
def lnposterior(self, theta): """ The log posterior (priors * likelihood) """ global maxpost, numcalls self.set_params(dict(zip(self.fitkeys, theta))) # Make sure parallax is positive if we are fitting for it if 'PX' in self.fitkeys and self.model.PX.value < 0.0: return -np.inf if 'SINI' in self.fitkeys and (self.model.SINI.value > 1.0 or self.model.SINI.value < 0.0): return -np.inf # Do we really need to check both E and ECC or can the model param alias handle that? if 'E' in self.fitkeys and (self.model.E.value < 0.0 or self.model.E.value>=1.0): return -np.inf if 'ECC' in self.fitkeys and (self.model.ECC.value < 0.0 or self.model.ECC.value>=1.0): return -np.inf phases = self.get_event_phases() # Here, I need to negate the survival function of H, so I am looking # for the maximum lnlikelihood = -1.0*sf_hm(hmw(phases,weights=self.weights),logprob=True) numcalls += 1 if numcalls % (nwalkers * nsteps / 100) == 0: print("~%d%% complete" % (numcalls / (nwalkers * nsteps / 100))) lnpost = self.lnprior(theta) + lnlikelihood if lnpost > maxpost: print("New max: ", lnpost) for name, val in zip(ftr.fitkeys, theta): print(" %8s: %25.15g" % (name, val)) maxpost = lnpost self.maxpost_fitvals = theta return lnpost
def plot(self): iphss, phss = self.modelin.phase(self.toas) # , abs_phase=True) # Ensure all postive phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss) # Pull out the first H-Test htest = hmw(phases, np.array(self.toas.get_flag_value('weights'))) print(htest) phaseogram(self.toas.get_mjds(), phases, weights=np.array(self.toas.get_flag_value('weights')))
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 minimize_func(self, theta): """ Returns -log(likelihood) so that we can use scipy.optimize.minimize """ # first scale the params based on the errors ntheta = (theta * self.fiterrs) + self.fitvals self.set_params(dict(zip(self.fitkeys, ntheta))) if "PX" in self.fitkeys and self.model.PX.value < 0.0: return np.inf phases = self.get_event_phases() # Here I'm using H-test and computing the log of the probability # of getting that value or higher. So this is already a negative # log likelihood, and should be minimized. lnlikelihood = sf_hm(hmw(phases, self.weights), logprob=True) print(lnlikelihood, ntheta) return lnlikelihood
def h_test(self, model): # Compute model phase for each TOA # I believe absolute phase is just a phase offset used to # align data from multiple time perods or instruments. iphss, phss = model.phase(self.toas) # , abs_phase=True) # Ensure all postive phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss) # Pull out the first H-Test htest = hmw(phases, np.array(self.toas.get_flag_value('weights'))) print(htest) return htest
def minimize_func(self, theta): """ Returns -log(likelihood) so that we can use scipy.optimize.minimize """ # first scale the params based on the errors ntheta = (theta * self.fiterrs) + self.fitvals self.set_params(dict(zip(self.fitkeys, ntheta))) if 'PX' in self.fitkeys and self.model.PX.value < 0.0: return np.inf phases = self.get_event_phases() # Here I'm using H-test and computing the log of the probability # of getting that value or higher. So this is already a negative # log likelihood, and should be minimized. lnlikelihood = sf_hm(hmw(phases, self.weights),logprob=True) print(lnlikelihood, ntheta) return lnlikelihood
def plot_Phmw(self): # Calculate the phases iphss, phss = self.modelin.phase(self.toas) # Place to store the H-Test h_vec = [] photons = [] for ii in range(0, len(phss), int(floor(len(phss) / 50))): h_vec.append( hmw(phss[0:ii], np.array(self.toas.get_flag_value('weights')[0:ii]))) photons.append(len(phss[0:ii])) plt.plot(photons, h_vec) plt.show()
def MCMC_htest(self, fitter, params): # Update the fitter with the test parameters fitter.set_parameters(params) # Calcuate phases iphss, phss = fitter.model.phase(self.toas) # Ensure all postive phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss) # Pull out the H-Test htest = hmw(phases, np.array(self.toas.get_flag_value('weights'))) #print(params) #print(htest) return htest
def plot_hmw(self, plotfile=None, sort=False): # Calculate the phases iphss, phss = self.modelin.phase(self.toas) # Pull out the weights weights = np.array(self.toas.get_flag_value('weights')[0]) # Pull out the MJDs photon_mjds = self.toas.get_mjds().value # Sometimes, the data will need to be sorted if sort: zipped = zip(photon_mjds, phss, weights) sorted_data = sorted(zipped) tuples = zip(*sorted_data) photon_mjds, phss, weights = [list(tuple) for tuple in tuples] weights = np.array(weights) # Place to store the H-Test h_vec = [] mjds = [] for ii in range(0, len(phss), int(floor(len(phss) / 50))): # h_vec.append(hmw(phss[0:ii], # np.array(self.toas.get_flag_value('weights')[0:ii]))) # mjds.append(self.toas.get_mjds()[ii].value) h_vec.append(hmw(phss[0:ii], weights[0:ii])) mjds.append(photon_mjds[ii]) print(photon_mjds[ii]) print(mjds) plt.plot(mjds, h_vec) if plotfile is not None: plt.savefig(plotfile) else: plt.show()
def plot_binned(self, plotfile=None): iphss, phss = self.modelin.phase(self.toas) # , abs_phase=True) # Ensure all postive phases = np.where(phss < 0.0, phss + 1.0, phss) # Legacy # phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss) # Pull out the first H-Test htest = hmw(phases, np.array(self.toas.get_flag_value('weights'))) print(htest) phaseogram_binned(self.toas.get_mjds(), phases, weights=np.array( self.toas.get_flag_value('weights')[0]), plotfile=plotfile) return 0
def scan_F0(self, par_model, values): model = deepcopy(par_model) significance = [] # F0_range = np.arange(start, stop, step) F0_range = values for ii in F0_range: # Change F0 model.F0.quantity = ii * u.Hz # Calculate the phases iphss, phss = model.phase(self.toas) # Should I ensure all phases are positive? I don't think so... # Calculate the significance, and append it to the list significance.append( hmw(phss, np.array(self.toas.get_flag_value('weights')))) # plt.plot(F1_range, significance) # plt.show() return significance
def main(argv=None): parser = argparse.ArgumentParser( description= "Use PINT to compute H-test and plot Phaseogram from a Fermi FT1 event file." ) parser.add_argument("eventfile", help="Fermi event FITS file name.") parser.add_argument("parfile", help="par file to construct model from") parser.add_argument( "weightcol", help="Column name for event weights (or 'CALC' to compute them)") parser.add_argument("--ft2", help="Path to FT2 file.", default=None) parser.add_argument( "--addphase", help="Write FT1 file with added phase column", default=False, action="store_true", ) parser.add_argument("--plot", help="Show phaseogram plot.", action="store_true", default=False) parser.add_argument("--plotfile", help="Output figure file name (default=None)", default=None) parser.add_argument("--maxMJD", help="Maximum MJD to include in analysis", default=None) parser.add_argument( "--outfile", help="Output figure file name (default is to overwrite input file)", default=None, ) parser.add_argument( "--planets", help="Use planetary Shapiro delay in calculations (default=False)", default=False, action="store_true", ) parser.add_argument("--ephem", help="Planetary ephemeris to use (default=DE421)", default="DE421") args = parser.parse_args(argv) # If outfile is specified, that implies addphase if args.outfile is not None: args.addphase = True # Read in model modelin = pint.models.get_model(args.parfile) if "ELONG" in modelin.params: tc = SkyCoord( modelin.ELONG.quantity, modelin.ELAT.quantity, frame="barycentrictrueecliptic", ) else: tc = SkyCoord(modelin.RAJ.quantity, modelin.DECJ.quantity, frame="icrs") if args.ft2 is not None: # Instantiate FermiObs once so it gets added to the observatory registry FermiObs(name="Fermi", ft2name=args.ft2) # Read event file and return list of TOA objects tl = load_Fermi_TOAs(args.eventfile, weightcolumn=args.weightcol, targetcoord=tc) # Discard events outside of MJD range if args.maxMJD is not None: tlnew = [] print("pre len : ", len(tl)) maxT = Time(float(args.maxMJD), format="mjd") print("maxT : ", maxT) for tt in tl: if tt.mjd < maxT: tlnew.append(tt) tl = tlnew print("post len : ", len(tlnew)) # Now convert to TOAs object and compute TDBs and posvels # For Fermi, we are not including GPS or TT(BIPM) corrections ts = toa.get_TOAs_list( tl, include_gps=False, include_bipm=False, planets=args.planets, ephem=args.ephem, ) ts.filename = args.eventfile print(ts.get_summary()) mjds = ts.get_mjds() print(mjds.min(), mjds.max()) # Compute model phase for each TOA iphss, phss = modelin.phase(ts, abs_phase=True) # ensure all postive phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss) mjds = ts.get_mjds() weights = np.array([w["weight"] for w in ts.table["flags"]]) h = float(hmw(phases, weights)) print("Htest : {0:.2f} ({1:.2f} sigma)".format(h, h2sig(h))) if args.plot: log.info("Making phaseogram plot with {0} photons".format(len(mjds))) phaseogram(mjds, phases, weights, bins=100, plotfile=args.plotfile) if args.addphase: # Read input FITS file (again). # If overwriting, open in 'update' mode if args.outfile is None: hdulist = pyfits.open(args.eventfile, mode="update") else: hdulist = pyfits.open(args.eventfile) event_hdu = hdulist[1] event_hdr = event_hdu.header event_dat = event_hdu.data if len(event_dat) != len(phases): raise RuntimeError( "Mismatch between length of FITS table ({0}) and length of phase array ({1})!" .format(len(event_dat), len(phases))) if "PULSE_PHASE" in event_hdu.columns.names: log.info("Found existing PULSE_PHASE column, overwriting...") # Overwrite values in existing Column event_dat["PULSE_PHASE"] = phases else: # Construct and append new column, preserving HDU header and name log.info("Adding new PULSE_PHASE column.") phasecol = pyfits.ColDefs( [pyfits.Column(name="PULSE_PHASE", format="D", array=phases)]) bt = pyfits.BinTableHDU.from_columns(event_hdu.columns + phasecol, header=event_hdr, name=event_hdu.name) hdulist[1] = bt if args.outfile is None: # Overwrite the existing file log.info("Overwriting existing FITS file " + args.eventfile) hdulist.flush(verbose=True, output_verify="warn") else: # Write to new output file log.info("Writing output FITS file " + args.outfile) hdulist.writeto(args.outfile, overwrite=True, checksum=True, output_verify="warn") return 0
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()) # Read in model modelin = pint.models.get_model(args.parfile) # Remove the dispersion delay as it is unnecessary modelin.delay_funcs['L1'].remove(modelin.dispersion_delay) # Compute model phase for each TOA phss = modelin.phase(ts.table)[1] # ensure all postive phases = np.where(phss < 0.0, phss + 1.0, phss) mjds = ts.get_mjds() weights = np.array([w['weight'] for w in ts.table['flags']]) h = float(hmw(phases,weights)) print("Htest : {0:.2f} ({1:.2f} sigma)".format(h,h2sig(h))) phaseogram(mjds,phases,weights,bins=100,file = args.outfile)
weights = None print "There are %d events, no weights are being used." % (len(weights)) # Now define the requirements for emcee ftr = emcee_fitter(ts, modelin, weights) # Use this if you want to see the effect of setting minWeight if minWeight == 0.0: print("Checking h-test vs weights") ftr.prof_vs_weights(use_weights=True) ftr.prof_vs_weights(use_weights=False) sys.exit() # Now compute the photon phases and see if we see a pulse phss = ftr.get_event_phases() like_start = -1.0*sf_hm(hmw(phss,weights=ftr.weights),logprob=True) print "Starting pulse likelihood:", like_start ftr.phaseogram(file=ftr.model.PSR.value+"_pre.png") plt.close() ftr.phaseogram() # Write out the starting pulse profile vs, xs = np.histogram(ftr.get_event_phases(), outprof_nbins, \ range=[0,1], weights=ftr.weights) f = open(ftr.model.PSR.value+"_prof_pre.txt", 'w') for x, v in zip(xs, vs): f.write("%.5f %12.5f\n" % (x, v)) f.close() # Try normal optimization first to see how it goes if do_opt_first:
def main(argv=None): if len(argv)==3: eventfile, parfile, weightcol = sys.argv[1:] elif len(argv)==2: eventfile, parfile = sys.argv[1:] weightcol=None else: print("usage: htest_optimize eventfile parfile [weightcol]") sys.exit() # Read in initial model modelin = pint.models.get_model(parfile) # Remove the dispersion delay as it is unnecessary modelin.delay_funcs['L1'].remove(modelin.dispersion_delay) # Set the target coords for automatic weighting if necessary if 'ELONG' in modelin.params: tc = SkyCoord(modelin.ELONG.quantity,modelin.ELAT.quantity, frame='barycentrictrueecliptic') else: tc = SkyCoord(modelin.RAJ.quantity,modelin.DECJ.quantity,frame='icrs') target = tc if weightcol=='CALC' else None # TODO: make this properly handle long double if not (os.path.isfile(eventfile+".pickle") or os.path.isfile(eventfile+".pickle.gz")): # Read event file and return list of TOA objects tl = fermi.load_Fermi_TOAs(eventfile, weightcolumn=weightcol, targetcoord=target, minweight=minWeight) # Limit the TOAs to ones where we have IERS corrections for tl = [tl[ii] for ii in range(len(tl)) if (tl[ii].mjd.value < maxMJD and (weightcol is None or tl[ii].flags['weight'] > minWeight))] print("There are %d events we will use" % len(tl)) # Now convert to TOAs object and compute TDBs and posvels ts = toa.TOAs(toalist=tl) ts.filename = eventfile ts.compute_TDBs() ts.compute_posvels(ephem="DE421", planets=False) ts.pickle() else: # read the events in as a pickle file picklefile = toa._check_pickle(eventfile) if not picklefile: picklefile = eventfile ts = toa.TOAs(picklefile) if weightcol is not None: if weightcol=='CALC': weights = np.asarray([x['weight'] for x in ts.table['flags']]) print("Original weights have min / max weights %.3f / %.3f" % \ (weights.min(), weights.max())) weights **= wgtexp wmx, wmn = weights.max(), weights.min() # make the highest weight = 1, but keep min weight the same weights = wmn + ((weights - wmn) * (1.0 - wmn) / (wmx - wmn)) for ii, x in enumerate(ts.table['flags']): x['weight'] = weights[ii] weights = np.asarray([x['weight'] for x in ts.table['flags']]) print("There are %d events, with min / max weights %.3f / %.3f" % \ (len(weights), weights.min(), weights.max())) else: weights = None print("There are %d events, no weights are being used." % (len(weights))) # Now define the requirements for emcee ftr = emcee_fitter(ts, modelin, weights) # Use this if you want to see the effect of setting minWeight if minWeight == 0.0: print("Checking h-test vs weights") ftr.prof_vs_weights(use_weights=True) ftr.prof_vs_weights(use_weights=False) sys.exit() # Now compute the photon phases and see if we see a pulse phss = ftr.get_event_phases() like_start = -1.0*sf_hm(hmw(phss,weights=ftr.weights),logprob=True) print("Starting pulse likelihood:", like_start) ftr.phaseogram(file=ftr.model.PSR.value+"_pre.png") plt.close() ftr.phaseogram() # Write out the starting pulse profile vs, xs = np.histogram(ftr.get_event_phases(), outprof_nbins, \ range=[0,1], weights=ftr.weights) f = open(ftr.model.PSR.value+"_prof_pre.txt", 'w') for x, v in zip(xs, vs): f.write("%.5f %12.5f\n" % (x, v)) f.close() # Try normal optimization first to see how it goes if do_opt_first: result = op.minimize(ftr.minimize_func, np.zeros_like(ftr.fitvals)) newfitvals = np.asarray(result['x']) * ftr.fiterrs + ftr.fitvals like_optmin = -result['fun'] print("Optimization likelihood:", like_optmin) ftr.set_params(dict(zip(ftr.fitkeys, newfitvals))) ftr.phaseogram() else: like_optmin = -np.inf # Set up the initial conditions for the emcee walkers. Use the # scipy.optimize newfitvals instead if they are better ndim = ftr.n_fit_params if like_start > like_optmin: # Keep the starting deviations small... pos = [ftr.fitvals + ftr.fiterrs/errfact * np.random.randn(ndim) for ii in range(nwalkers)] # Set starting params with uniform priors to uniform in the prior for param in ["GLPH_1", "GLEP_1", "SINI", "M2", "E", "ECC", "PX", "A1"]: if param in ftr.fitkeys: idx = ftr.fitkeys.index(param) if param=="GLPH_1": svals = np.random.uniform(-0.5, 0.5, nwalkers) elif param=="GLEP_1": svals = np.random.uniform(minMJD+100, maxMJD-100, nwalkers) #svals = 55422.0 + np.random.randn(nwalkers) elif param=="SINI": svals = np.random.uniform(0.0, 1.0, nwalkers) elif param=="M2": svals = np.random.uniform(0.1, 0.6, nwalkers) elif param in ["E", "ECC", "PX", "A1"]: # Ensure all positive svals = np.fabs(ftr.fitvals[idx] + ftr.fiterrs[idx] * np.random.randn(nwalkers)) if param in ["E", "ECC"]: svals[svals>1.0] = 1.0 - (svals[svals>1.0] - 1.0) for ii in range(nwalkers): pos[ii][idx] = svals[ii] else: pos = [newfitvals + ftr.fiterrs/errfact*np.random.randn(ndim) for i in range(nwalkers)] # Set the 0th walker to have the initial pre-fit solution # This way, one walker should always be in a good position pos[0] = ftr.fitvals import emcee #sampler = emcee.EnsembleSampler(nwalkers, ndim, ftr.lnposterior, threads=10) sampler = emcee.EnsembleSampler(nwalkers, ndim, ftr.lnposterior) # The number is the number of points in the chain sampler.run_mcmc(pos, nsteps) def chains_to_dict(names, sampler): chains = [sampler.chain[:,:,ii].T for ii in range(len(names))] return dict(zip(names,chains)) def plot_chains(chain_dict, file=False): np = len(chain_dict) fig, axes = plt.subplots(np, 1, sharex=True, figsize=(8, 9)) for ii, name in enumerate(chain_dict.keys()): axes[ii].plot(chain_dict[name], color="k", alpha=0.3) axes[ii].set_ylabel(name) axes[np-1].set_xlabel("Step Number") fig.tight_layout() if file: fig.savefig(file) plt.close() else: plt.show() plt.close() chains = chains_to_dict(ftr.fitkeys, sampler) plot_chains(chains, file=ftr.model.PSR.value+"_chains.png") # Make the triangle plot. try: import corner samples = sampler.chain[:, burnin:, :].reshape((-1, ndim)) fig = corner.corner(samples, labels=ftr.fitkeys, bins=50) fig.savefig(ftr.model.PSR.value+"_triangle.png") plt.close() except: pass # Make a phaseogram with the 50th percentile values #ftr.set_params(dict(zip(ftr.fitkeys, np.percentile(samples, 50, axis=0)))) # Make a phaseogram with the best MCMC result ftr.set_params(dict(zip(ftr.fitkeys, ftr.maxpost_fitvals))) ftr.phaseogram(file=ftr.model.PSR.value+"_post.png") plt.close() # Write out the output pulse profile vs, xs = np.histogram(ftr.get_event_phases(), outprof_nbins, \ range=[0,1], weights=ftr.weights) f = open(ftr.model.PSR.value+"_prof_post.txt", 'w') for x, v in zip(xs, vs): f.write("%.5f %12.5f\n" % (x, v)) f.close() # Write out the par file for the best MCMC parameter est f = open(ftr.model.PSR.value+"_post.par", 'w') f.write(ftr.model.as_parfile()) f.close() # Print the best MCMC values and ranges ranges = map(lambda v: (v[1], v[2]-v[1], v[1]-v[0]), zip(*np.percentile(samples, [16, 50, 84], axis=0))) print("Post-MCMC values (50th percentile +/- (16th/84th percentile):") for name, vals in zip(ftr.fitkeys, ranges): print("%8s:"%name, "%25.15g (+ %12.5g / - %12.5g)"%vals) # Put the same stuff in a file f = open(ftr.model.PSR.value+"_results.txt", 'w') f.write("Post-MCMC values (50th percentile +/- (16th/84th percentile):\n") for name, vals in zip(ftr.fitkeys, ranges): f.write("%8s:"%name + " %25.15g (+ %12.5g / - %12.5g)\n"%vals) f.write("\nMaximum likelihood par file:\n") f.write(ftr.model.as_parfile()) f.close() import cPickle cPickle.dump(samples, open(ftr.model.PSR.value+"_samples.pickle", "wb"))
def main(argv=None): parser = argparse.ArgumentParser(description="Use PINT to compute H-test and plot Phaseogram from a Fermi FT1 event file.") parser.add_argument("eventfile",help="Fermi event FITS file name.") parser.add_argument("parfile",help="par file to construct model from") parser.add_argument("weightcol",help="Column name for event weights (or 'CALC' to compute them)") parser.add_argument("--ft2",help="Path to FT2 file.",default=None) parser.add_argument("--addphase",help="Write FT1 file with added phase column", default=False,action='store_true') parser.add_argument("--plot",help="Show phaseogram plot.", action='store_true', default=False) parser.add_argument("--plotfile",help="Output figure file name (default=None)", default=None) parser.add_argument("--maxMJD",help="Maximum MJD to include in analysis", default=None) parser.add_argument("--outfile",help="Output figure file name (default is to overwrite input file)", default=None) parser.add_argument("--planets",help="Use planetary Shapiro delay in calculations (default=False)", default=False, action="store_true") parser.add_argument("--ephem",help="Planetary ephemeris to use (default=DE421)", default="DE421") args = parser.parse_args(argv) # If outfile is specified, that implies addphase if args.outfile is not None: args.addphase = True # Read in model modelin = pint.models.get_model(args.parfile) if 'ELONG' in modelin.params: tc = SkyCoord(modelin.ELONG.quantity,modelin.ELAT.quantity, frame='barycentrictrueecliptic') else: tc = SkyCoord(modelin.RAJ.quantity,modelin.DECJ.quantity,frame='icrs') if args.ft2 is not None: # Instantiate FermiObs once so it gets added to the observatory registry FermiObs(name='Fermi',ft2name=args.ft2) # Read event file and return list of TOA objects tl = load_Fermi_TOAs(args.eventfile, weightcolumn=args.weightcol, targetcoord=tc) # Discard events outside of MJD range if args.maxMJD is not None: tlnew = [] print("pre len : ",len(tl)) maxT = Time(float(args.maxMJD),format='mjd') print("maxT : ",maxT) for tt in tl: if tt.mjd < maxT: tlnew.append(tt) tl=tlnew print("post len : ",len(tlnew)) # Now convert to TOAs object and compute TDBs and posvels # For Fermi, we are not including GPS or TT(BIPM) corrections ts = toa.get_TOAs_list(tl,include_gps=False,include_bipm=False,planets=args.planets,ephem=args.ephem) ts.filename = args.eventfile print(ts.get_summary()) mjds = ts.get_mjds() print(mjds.min(),mjds.max()) # Compute model phase for each TOA iphss,phss = modelin.phase(ts,abs_phase=True) # ensure all postive phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss) mjds = ts.get_mjds() weights = np.array([w['weight'] for w in ts.table['flags']]) h = float(hmw(phases,weights)) print("Htest : {0:.2f} ({1:.2f} sigma)".format(h,h2sig(h))) if args.plot: log.info("Making phaseogram plot with {0} photons".format(len(mjds))) phaseogram(mjds,phases,weights,bins=100,plotfile = args.plotfile) if args.addphase: # Read input FITS file (again). # If overwriting, open in 'update' mode if args.outfile is None: hdulist = pyfits.open(args.eventfile,mode='update') else: hdulist = pyfits.open(args.eventfile) event_hdu = hdulist[1] event_hdr=event_hdu.header event_dat=event_hdu.data if len(event_dat) != len(phases): raise RuntimeError('Mismatch between length of FITS table ({0}) and length of phase array ({1})!'.format(len(event_dat),len(phases))) if 'PULSE_PHASE' in event_hdu.columns.names: log.info('Found existing PULSE_PHASE column, overwriting...') # Overwrite values in existing Column event_dat['PULSE_PHASE'] = phases else: # Construct and append new column, preserving HDU header and name log.info('Adding new PULSE_PHASE column.') phasecol = pyfits.ColDefs([pyfits.Column(name='PULSE_PHASE', format='D', array=phases)]) bt = pyfits.BinTableHDU.from_columns( event_hdu.columns + phasecol, header=event_hdr,name=event_hdu.name) hdulist[1] = bt if args.outfile is None: # Overwrite the existing file log.info('Overwriting existing FITS file '+args.eventfile) hdulist.flush(verbose=True, output_verify='warn') else: # Write to new output file log.info('Writing output FITS file '+args.outfile) hdulist.writeto(args.outfile,overwrite=True, checksum=True, output_verify='warn') return 0
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()) # Read in model modelin = pint.models.get_model(args.parfile) # Remove the dispersion delay as it is unnecessary modelin.delay_funcs['L1'].remove(modelin.dispersion_delay) # Compute model phase for each TOA phss = modelin.phase(ts.table)[1] # ensure all postive phases = np.where(phss < 0.0, phss + 1.0, phss) mjds = ts.get_mjds() weights = np.array([w['weight'] for w in ts.table['flags']]) h = float(hmw(phases, weights)) print("Htest : {0:.2f} ({1:.2f} sigma)".format(h, h2sig(h))) phaseogram(mjds, phases, weights, bins=100, file=args.outfile)
def main(argv=None): if len(argv) == 3: eventfile, parfile, weightcol = sys.argv[1:] elif len(argv) == 2: eventfile, parfile = sys.argv[1:] weightcol = None else: print("usage: htest_optimize eventfile parfile [weightcol]") sys.exit() # Read in initial model modelin = pint.models.get_model(parfile) # Remove the dispersion delay as it is unnecessary modelin.delay_funcs.remove(modelin.dispersion_delay) # Set the target coords for automatic weighting if necessary if "ELONG" in modelin.params: tc = SkyCoord( modelin.ELONG.quantity, modelin.ELAT.quantity, frame="barycentrictrueecliptic", ) else: tc = SkyCoord(modelin.RAJ.quantity, modelin.DECJ.quantity, frame="icrs") target = tc if weightcol == "CALC" else None # TODO: make this properly handle long double if not ( os.path.isfile(eventfile + ".pickle") or os.path.isfile(eventfile + ".pickle.gz") ): # Read event file and return list of TOA objects tl = fermi.load_Fermi_TOAs( eventfile, weightcolumn=weightcol, targetcoord=target, minweight=minWeight ) # Limit the TOAs to ones where we have IERS corrections for tl = [ tl[ii] for ii in range(len(tl)) if ( tl[ii].mjd.value < maxMJD and (weightcol is None or tl[ii].flags["weight"] > minWeight) ) ] print("There are %d events we will use" % len(tl)) # Now convert to TOAs object and compute TDBs and posvels ts = toa.TOAs(toalist=tl) ts.filename = eventfile ts.compute_TDBs() ts.compute_posvels(ephem="DE421", planets=False) ts.pickle() else: # read the events in as a pickle file picklefile = toa._check_pickle(eventfile) if not picklefile: picklefile = eventfile ts = toa.TOAs(picklefile) if weightcol is not None: if weightcol == "CALC": weights = np.asarray([x["weight"] for x in ts.table["flags"]]) print( "Original weights have min / max weights %.3f / %.3f" % (weights.min(), weights.max()) ) weights **= wgtexp wmx, wmn = weights.max(), weights.min() # make the highest weight = 1, but keep min weight the same weights = wmn + ((weights - wmn) * (1.0 - wmn) / (wmx - wmn)) for ii, x in enumerate(ts.table["flags"]): x["weight"] = weights[ii] weights = np.asarray([x["weight"] for x in ts.table["flags"]]) print( "There are %d events, with min / max weights %.3f / %.3f" % (len(weights), weights.min(), weights.max()) ) else: weights = None print("There are %d events, no weights are being used." % (len(weights))) # Now define the requirements for emcee ftr = emcee_fitter(ts, modelin, weights) # Use this if you want to see the effect of setting minWeight if minWeight == 0.0: print("Checking h-test vs weights") ftr.prof_vs_weights(use_weights=True) ftr.prof_vs_weights(use_weights=False) sys.exit() # Now compute the photon phases and see if we see a pulse phss = ftr.get_event_phases() like_start = -1.0 * sf_hm(hmw(phss, weights=ftr.weights), logprob=True) print("Starting pulse likelihood:", like_start) ftr.phaseogram(file=ftr.model.PSR.value + "_pre.png") plt.close() ftr.phaseogram() # Write out the starting pulse profile vs, xs = np.histogram( ftr.get_event_phases(), outprof_nbins, range=[0, 1], weights=ftr.weights ) f = open(ftr.model.PSR.value + "_prof_pre.txt", "w") for x, v in zip(xs, vs): f.write("%.5f %12.5f\n" % (x, v)) f.close() # Try normal optimization first to see how it goes if do_opt_first: result = op.minimize(ftr.minimize_func, np.zeros_like(ftr.fitvals)) newfitvals = np.asarray(result["x"]) * ftr.fiterrs + ftr.fitvals like_optmin = -result["fun"] print("Optimization likelihood:", like_optmin) ftr.set_params(dict(zip(ftr.fitkeys, newfitvals))) ftr.phaseogram() else: like_optmin = -np.inf # Set up the initial conditions for the emcee walkers. Use the # scipy.optimize newfitvals instead if they are better ndim = ftr.n_fit_params if like_start > like_optmin: # Keep the starting deviations small... pos = [ ftr.fitvals + ftr.fiterrs / errfact * np.random.randn(ndim) for ii in range(nwalkers) ] # Set starting params with uniform priors to uniform in the prior for param in ["GLPH_1", "GLEP_1", "SINI", "M2", "E", "ECC", "PX", "A1"]: if param in ftr.fitkeys: idx = ftr.fitkeys.index(param) if param == "GLPH_1": svals = np.random.uniform(-0.5, 0.5, nwalkers) elif param == "GLEP_1": svals = np.random.uniform(minMJD + 100, maxMJD - 100, nwalkers) # svals = 55422.0 + np.random.randn(nwalkers) elif param == "SINI": svals = np.random.uniform(0.0, 1.0, nwalkers) elif param == "M2": svals = np.random.uniform(0.1, 0.6, nwalkers) elif param in ["E", "ECC", "PX", "A1"]: # Ensure all positive svals = np.fabs( ftr.fitvals[idx] + ftr.fiterrs[idx] * np.random.randn(nwalkers) ) if param in ["E", "ECC"]: svals[svals > 1.0] = 1.0 - (svals[svals > 1.0] - 1.0) for ii in range(nwalkers): pos[ii][idx] = svals[ii] else: pos = [ newfitvals + ftr.fiterrs / errfact * np.random.randn(ndim) for i in range(nwalkers) ] # Set the 0th walker to have the initial pre-fit solution # This way, one walker should always be in a good position pos[0] = ftr.fitvals import emcee # sampler = emcee.EnsembleSampler(nwalkers, ndim, ftr.lnposterior, threads=10) sampler = emcee.EnsembleSampler(nwalkers, ndim, ftr.lnposterior) # The number is the number of points in the chain sampler.run_mcmc(pos, nsteps) def chains_to_dict(names, sampler): chains = [sampler.chain[:, :, ii].T for ii in range(len(names))] return dict(zip(names, chains)) def plot_chains(chain_dict, file=False): np = len(chain_dict) fig, axes = plt.subplots(np, 1, sharex=True, figsize=(8, 9)) for ii, name in enumerate(chain_dict.keys()): axes[ii].plot(chain_dict[name], color="k", alpha=0.3) axes[ii].set_ylabel(name) axes[np - 1].set_xlabel("Step Number") fig.tight_layout() if file: fig.savefig(file) plt.close() else: plt.show() plt.close() chains = chains_to_dict(ftr.fitkeys, sampler) plot_chains(chains, file=ftr.model.PSR.value + "_chains.png") # Make the triangle plot. try: import corner samples = sampler.chain[:, burnin:, :].reshape((-1, ndim)) fig = corner.corner(samples, labels=ftr.fitkeys, bins=50) fig.savefig(ftr.model.PSR.value + "_triangle.png") plt.close() except ImportError: pass # Make a phaseogram with the 50th percentile values # ftr.set_params(dict(zip(ftr.fitkeys, np.percentile(samples, 50, axis=0)))) # Make a phaseogram with the best MCMC result ftr.set_params(dict(zip(ftr.fitkeys, ftr.maxpost_fitvals))) ftr.phaseogram(file=ftr.model.PSR.value + "_post.png") plt.close() # Write out the output pulse profile vs, xs = np.histogram( ftr.get_event_phases(), outprof_nbins, range=[0, 1], weights=ftr.weights ) f = open(ftr.model.PSR.value + "_prof_post.txt", "w") for x, v in zip(xs, vs): f.write("%.5f %12.5f\n" % (x, v)) f.close() # Write out the par file for the best MCMC parameter est f = open(ftr.model.PSR.value + "_post.par", "w") f.write(ftr.model.as_parfile()) f.close() # Print the best MCMC values and ranges ranges = map( lambda v: (v[1], v[2] - v[1], v[1] - v[0]), zip(*np.percentile(samples, [16, 50, 84], axis=0)), ) print("Post-MCMC values (50th percentile +/- (16th/84th percentile):") for name, vals in zip(ftr.fitkeys, ranges): print("%8s:" % name, "%25.15g (+ %12.5g / - %12.5g)" % vals) # Put the same stuff in a file f = open(ftr.model.PSR.value + "_results.txt", "w") f.write("Post-MCMC values (50th percentile +/- (16th/84th percentile):\n") for name, vals in zip(ftr.fitkeys, ranges): f.write("%8s:" % name + " %25.15g (+ %12.5g / - %12.5g)\n" % vals) f.write("\nMaximum likelihood par file:\n") f.write(ftr.model.as_parfile()) f.close() import cPickle cPickle.dump(samples, open(ftr.model.PSR.value + "_samples.pickle", "wb"))
print "There are %d events, no weights are being used." % ( len(weights)) # Now define the requirements for emcee ftr = emcee_fitter(ts, modelin, weights) # Use this if you want to see the effect of setting minWeight if minWeight == 0.0: print("Checking h-test vs weights") ftr.prof_vs_weights(use_weights=True) ftr.prof_vs_weights(use_weights=False) sys.exit() # Now compute the photon phases and see if we see a pulse phss = ftr.get_event_phases() like_start = -1.0 * sf_hm(hmw(phss, weights=ftr.weights), logprob=True) print "Starting pulse likelihood:", like_start ftr.phaseogram(file=ftr.model.PSR.value + "_pre.png") plt.close() ftr.phaseogram() # Write out the starting pulse profile vs, xs = np.histogram(ftr.get_event_phases(), outprof_nbins, \ range=[0,1], weights=ftr.weights) f = open(ftr.model.PSR.value + "_prof_pre.txt", 'w') for x, v in zip(xs, vs): f.write("%.5f %12.5f\n" % (x, v)) f.close() # Try normal optimization first to see how it goes if do_opt_first:
def main(argv=None): parser = argparse.ArgumentParser( description= "Use PINT to compute H-test and plot Phaseogram from a Fermi FT1 event file." ) parser.add_argument("eventfile", help="Fermi event FITS file name.") parser.add_argument("parfile", help="par file to construct model from") parser.add_argument( "weightcol", help="Column name for event weights (or 'CALC' to compute them)") parser.add_argument("--ft2", help="Path to FT2 file.", default=None) parser.add_argument( "--addphase", help="Write FT1 file with added phase column", default=False, action="store_true", ) parser.add_argument("--plot", help="Show phaseogram plot.", action="store_true", default=False) parser.add_argument("--plotfile", help="Output figure file name (default=None)", default=None) parser.add_argument("--maxMJD", help="Maximum MJD to include in analysis", default=None) parser.add_argument("--minMJD", help="Minimum MJD to include in analysis", default=None) parser.add_argument( "--outfile", help="Output figure file name (default is to overwrite input file)", default=None, ) parser.add_argument( "--planets", help="Use planetary Shapiro delay in calculations (default=False)", default=False, action="store_true", ) parser.add_argument("--ephem", help="Planetary ephemeris to use (default=DE421)", default="DE421") args = parser.parse_args(argv) # If outfile is specified, that implies addphase if args.outfile is not None: args.addphase = True # Read in model modelin = pint.models.get_model(args.parfile) if "ELONG" in modelin.params: tc = SkyCoord( modelin.ELONG.quantity, modelin.ELAT.quantity, frame="barycentrictrueecliptic", ) else: tc = SkyCoord(modelin.RAJ.quantity, modelin.DECJ.quantity, frame="icrs") if args.ft2 is not None: # Instantiate Fermi observatory once so it gets added to the observatory registry get_satellite_observatory("Fermi", args.ft2) # Read event file and return list of TOA objects maxmjd = np.inf if (args.maxMJD is None) else float(args.maxMJD) minmjd = 0.0 if (args.minMJD is None) else float(args.minMJD) tl = load_Fermi_TOAs( args.eventfile, maxmjd=maxmjd, minmjd=minmjd, weightcolumn=args.weightcol, targetcoord=tc, ) # Now convert to TOAs object and compute TDBs and posvels # For Fermi, we are not including GPS or TT(BIPM) corrections ts = toa.get_TOAs_list( tl, include_gps=False, include_bipm=False, planets=args.planets, ephem=args.ephem, ) ts.filename = args.eventfile print(ts.get_summary()) mjds = ts.get_mjds() print(mjds.min(), mjds.max()) # Compute model phase for each TOA iphss, phss = modelin.phase(ts, abs_phase=True) phss %= 1 phases = phss.value mjds = ts.get_mjds() weights = np.array([w["weight"] for w in ts.table["flags"]]) h = float(hmw(phases, weights)) print("Htest : {0:.2f} ({1:.2f} sigma)".format(h, h2sig(h))) if args.plot: log.info("Making phaseogram plot with {0} photons".format(len(mjds))) phaseogram(mjds, phases, weights, bins=100, plotfile=args.plotfile) if args.addphase: # Read input FITS file (again). # If overwriting, open in 'update' mode if args.outfile is None: hdulist = pyfits.open(args.eventfile, mode="update") else: hdulist = pyfits.open(args.eventfile) event_hdu = hdulist[1] event_hdr = event_hdu.header event_dat = event_hdu.data event_mjds = read_fits_event_mjds_tuples(event_hdu) mjds_float = np.asarray([r[0] + r[1] for r in event_mjds]) time_mask = np.logical_and((mjds_float > minmjd), (mjds_float < maxmjd)) new_phases = np.full(len(event_dat), -1, dtype=float) new_phases[time_mask] = phases if "PULSE_PHASE" in event_hdu.columns.names: log.info("Found existing PULSE_PHASE column, overwriting...") # Overwrite values in existing Column event_dat["PULSE_PHASE"] = new_phases else: # Construct and append new column, preserving HDU header and name log.info("Adding new PULSE_PHASE column.") phasecol = pyfits.ColDefs([ pyfits.Column(name="PULSE_PHASE", format="D", array=new_phases) ]) bt = pyfits.BinTableHDU.from_columns(event_hdu.columns + phasecol, header=event_hdr, name=event_hdu.name) hdulist[1] = bt if args.outfile is None: # Overwrite the existing file log.info("Overwriting existing FITS file " + args.eventfile) hdulist.flush(verbose=True, output_verify="warn") else: # Write to new output file log.info("Writing output FITS file " + args.outfile) hdulist.writeto(args.outfile, overwrite=True, checksum=True, output_verify="warn") return 0
def main(argv=None): parser = argparse.ArgumentParser( description= "Use PINT to compute H-test and plot Phaseogram from a POLAR event file." ) parser.add_argument("eventfile", help="Polar event root file name.") parser.add_argument("parfile", help="par file to construct model from") parser.add_argument("--wei", help="Branch name for event weights", default="") parser.add_argument("--eng", help="Path to ENG file.", default="$POLAR_AUX/Alleng.root") parser.add_argument("--addphase", help="Add phase tree Friend", default=False, action='store_true') parser.add_argument("--plot", help="Show phaseogram plot.", action='store_true', default=False) parser.add_argument("--plotfile", help="Output figure file name (default=None)", default=None) parser.add_argument("--maxMJD", help="Maximum MJD to include in analysis", default=None) parser.add_argument( "--planets", help="Use planetary Shapiro delay in calculations (default=False)", default=False, action="store_true") parser.add_argument("--ephem", help="Planetary ephemeris to use (default=DE421)", default="DE421") args = parser.parse_args(argv) # Read in model modelin = pint.models.get_model(args.parfile) if 'ELONG' in modelin.params: tc = SkyCoord(modelin.ELONG.quantity, modelin.ELAT.quantity, frame='barycentrictrueecliptic') else: tc = SkyCoord(modelin.RAJ.quantity, modelin.DECJ.quantity, frame='icrs') if args.eng is not None: # Instantiate PolarObs once so it gets added to the observatory registry PolarObs(name='Polar', engname=args.eng) # Read event file and return list of TOA objects tl = load_Polar_TOAs(args.eventfile, weightcolumn=args.wei) # 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 phss = modelin.phase(ts.table)[1] # ensure all postive phases = np.where(phss < 0.0 * u.cycle, phss + 1.0 * u.cycle, phss) mjds = ts.get_mjds() weights = np.array([1] * len(mjds)) h = float(hmw(phases, weights)) print("Htest : {0:.2f} ({1:.2f} sigma)".format(h, h2sig(h))) if args.plot: log.info("Making phaseogram plot with {0} photons".format(len(mjds))) phaseogram(mjds, phases, weights, bins=100, plotfile=args.plotfile) if args.addphase: if len(event_dat) != len(phases): raise RuntimeError( 'Mismatch between length of ROOT tree ({0}) and length of phase array ({1})!' .format(len(event_dat), len(phases))) return 0