def parse_eph(filenm): global period, time suffix = filenm.split(".")[-1] if suffix == "bestprof": x = bestprof.bestprof(filenm) fs = pu.p_to_f(x.p0_bary, x.p1_bary, x.p2_bary) epoch = x.epochi_bary + x.epochf_bary T = x.T elif suffix == "par": x = parfile.psr_par(filenm) # Try to see how many freq derivs we have fs = [x.F0] for ii in range(1, 20): # hopefully 20 is an upper limit! attrib = "F%d" % ii if hasattr(x, attrib): fs.append(getattr(x, attrib)) else: break epoch = x.PEPOCH T = (x.FINISH - x.START) * 86400.0 else: print("I don't recognize the file type for", filenm) sys.exit() newts = epoch + num.arange(int(T / 10.0 + 0.5), dtype=num.float) / 8640.0 time = num.concatenate((time, newts)) newps = 1.0 / pu.calc_freq(newts, epoch, *fs) period = num.concatenate((period, newps)) print("%13.7f (%0.1f sec): " % (epoch, T), fs)
def __init__(self, filename): self.pfd_filename = filename infile = open(filename, "rb") # See if the .bestprof file is around try: self.bestprof = bestprof(filename + ".bestprof") except IOError: self.bestprof = 0 swapchar = '<' # this is little-endian data = infile.read(5 * 4) testswap = struct.unpack(swapchar + "i" * 5, data) # This is a hack to try and test the endianness of the data. # None of the 5 values should be a large positive number. if (Num.fabs(Num.asarray(testswap))).max() > 100000: swapchar = '>' # this is big-endian (self.numdms, self.numperiods, self.numpdots, self.nsub, self.npart) = \ struct.unpack(swapchar+"i"*5, data) (self.proflen, self.numchan, self.pstep, self.pdstep, self.dmstep, \ self.ndmfact, self.npfact) = struct.unpack(swapchar+"i"*7, infile.read(7*4)) self.filenm = infile.read( struct.unpack(swapchar + "i", infile.read(4))[0]) self.candnm = infile.read( struct.unpack(swapchar + "i", infile.read(4))[0]).decode("utf-8") self.telescope = infile.read( struct.unpack(swapchar + "i", infile.read(4))[0]).decode("utf-8") self.pgdev = infile.read( struct.unpack(swapchar + "i", infile.read(4))[0]) test = infile.read(16) if not test[:8] == b"Unknown" and b':' in test: self.rastr = test[:test.find(b'\0')] test = infile.read(16) self.decstr = test[:test.find(b'\0')] else: self.rastr = "Unknown" self.decstr = "Unknown" if ':' not in test: infile.seek(-16, 1) # rewind the file before the bad read (self.dt, self.startT) = struct.unpack(swapchar + "dd", infile.read(2 * 8)) (self.endT, self.tepoch, self.bepoch, self.avgvoverc, self.lofreq, \ self.chan_wid, self.bestdm) = struct.unpack(swapchar+"d"*7, infile.read(7*8)) # The following "fixes" (we think) the observing frequency of the Spigot # based on tests done by Ingrid on 0737 (comparing it to GASP) # The same sorts of corrections should be made to WAPP data as well... # The tepoch corrections are empirically determined timing corrections # Note that epoch is only double precision and so the floating # point accuracy is ~1 us! if self.telescope == 'GBT': if (Num.fabs(Num.fmod(self.dt, 8.192e-05) < 1e-12) and \ ("spigot" in filename.lower() or "guppi" not in filename.lower()) and \ (self.tepoch < 54832.0)): sys.stderr.write("Assuming SPIGOT data...\n") if self.chan_wid == 800.0 / 1024: # Spigot 800 MHz mode 2 self.lofreq -= 0.5 * self.chan_wid # original values #if self.tepoch > 0.0: self.tepoch += 0.039334/86400.0 #if self.bestprof: self.bestprof.epochf += 0.039334/86400.0 # values measured with 1713+0747 wrt BCPM2 on 13 Sept 2007 if self.tepoch > 0.0: self.tepoch += 0.039365 / 86400.0 if self.bestprof: self.bestprof.epochf += 0.039365 / 86400.0 elif self.chan_wid == 800.0 / 2048: self.lofreq -= 0.5 * self.chan_wid if self.tepoch < 53700.0: # Spigot 800 MHz mode 16 (downsampled) if self.tepoch > 0.0: self.tepoch += 0.039352 / 86400.0 if self.bestprof: self.bestprof.epochf += 0.039352 / 86400.0 else: # Spigot 800 MHz mode 14 # values measured with 1713+0747 wrt BCPM2 on 13 Sept 2007 if self.tepoch > 0.0: self.tepoch += 0.039365 / 86400.0 if self.bestprof: self.bestprof.epochf += 0.039365 / 86400.0 elif self.chan_wid == 50.0 / 1024 or self.chan_wid == 50.0 / 2048: # Spigot 50 MHz modes self.lofreq += 0.5 * self.chan_wid # Note: the offset has _not_ been measured for the 2048-lag mode if self.tepoch > 0.0: self.tepoch += 0.039450 / 86400.0 if self.bestprof: self.bestprof.epochf += 0.039450 / 86400.0 (self.topo_pow, tmp) = struct.unpack(swapchar + "f" * 2, infile.read(2 * 4)) (self.topo_p1, self.topo_p2, self.topo_p3) = struct.unpack(swapchar+"d"*3, \ infile.read(3*8)) (self.bary_pow, tmp) = struct.unpack(swapchar + "f" * 2, infile.read(2 * 4)) (self.bary_p1, self.bary_p2, self.bary_p3) = struct.unpack(swapchar+"d"*3, \ infile.read(3*8)) (self.fold_pow, tmp) = struct.unpack(swapchar + "f" * 2, infile.read(2 * 4)) (self.fold_p1, self.fold_p2, self.fold_p3) = struct.unpack(swapchar+"d"*3, \ infile.read(3*8)) # Save current p, pd, pdd # NOTE: Fold values are actually frequencies! self.curr_p1, self.curr_p2, self.curr_p3 = \ psr_utils.p_to_f(self.fold_p1, self.fold_p2, self.fold_p3) self.pdelays_bins = Num.zeros(self.npart, dtype='d') (self.orb_p, self.orb_e, self.orb_x, self.orb_w, self.orb_t, self.orb_pd, \ self.orb_wd) = struct.unpack(swapchar+"d"*7, infile.read(7*8)) self.dms = Num.asarray(struct.unpack(swapchar+"d"*self.numdms, \ infile.read(self.numdms*8))) if self.numdms == 1: self.dms = self.dms[0] self.periods = Num.asarray(struct.unpack(swapchar+"d"*self.numperiods, \ infile.read(self.numperiods*8))) self.pdots = Num.asarray(struct.unpack(swapchar+"d"*self.numpdots, \ infile.read(self.numpdots*8))) self.numprofs = self.nsub * self.npart if (swapchar == '<'): # little endian self.profs = Num.zeros((self.npart, self.nsub, self.proflen), dtype='d') for ii in range(self.npart): for jj in range(self.nsub): self.profs[ii, jj, :] = Num.fromfile(infile, Num.float64, self.proflen) else: self.profs = Num.asarray(struct.unpack(swapchar+"d"*self.numprofs*self.proflen, \ infile.read(self.numprofs*self.proflen*8))) self.profs = Num.reshape(self.profs, (self.npart, self.nsub, self.proflen)) if (self.numchan == 1): try: idata = infodata.infodata( self.filenm[:self.filenm.rfind(b'.')] + b".inf") try: if idata.waveband == "Radio": self.bestdm = idata.DM self.numchan = idata.numchan except: self.bestdm = 0.0 self.numchan = 1 except IOError: print("Warning! Can't open the .inf file for " + filename + "!") self.binspersec = self.fold_p1 * self.proflen self.chanpersub = self.numchan // self.nsub self.subdeltafreq = self.chan_wid * self.chanpersub self.hifreq = self.lofreq + (self.numchan - 1) * self.chan_wid self.losubfreq = self.lofreq + self.subdeltafreq - self.chan_wid self.subfreqs = Num.arange(self.nsub, dtype='d')*self.subdeltafreq + \ self.losubfreq self.subdelays_bins = Num.zeros(self.nsub, dtype='d') # Save current DM self.currdm = 0 self.killed_subbands = [] self.killed_intervals = [] self.pts_per_fold = [] # Note: a foldstats struct is read in as a group of 7 doubles # the correspond to, in order: # numdata, data_avg, data_var, numprof, prof_avg, prof_var, redchi self.stats = Num.zeros((self.npart, self.nsub, 7), dtype='d') for ii in range(self.npart): currentstats = self.stats[ii] for jj in range(self.nsub): if (swapchar == '<'): # little endian currentstats[jj] = Num.fromfile(infile, Num.float64, 7) else: currentstats[jj] = Num.asarray(struct.unpack(swapchar+"d"*7, \ infile.read(7*8))) self.pts_per_fold.append( self.stats[ii][0][0]) # numdata from foldstats self.start_secs = Num.add.accumulate([0] + self.pts_per_fold[:-1]) * self.dt self.pts_per_fold = Num.asarray(self.pts_per_fold) self.mid_secs = self.start_secs + 0.5 * self.dt * self.pts_per_fold if (not self.tepoch == 0.0): self.start_topo_MJDs = self.start_secs / 86400.0 + self.tepoch self.mid_topo_MJDs = self.mid_secs / 86400.0 + self.tepoch if (not self.bepoch == 0.0): self.start_bary_MJDs = self.start_secs / 86400.0 + self.bepoch self.mid_bary_MJDs = self.mid_secs / 86400.0 + self.bepoch self.Nfolded = Num.add.reduce(self.pts_per_fold) self.T = self.Nfolded * self.dt self.avgprof = (self.profs / self.proflen).sum() self.varprof = self.calc_varprof() # nominal number of degrees of freedom for reduced chi^2 calculation self.DOFnom = float(self.proflen) - 1.0 # corrected number of degrees of freedom due to inter-bin correlations self.dt_per_bin = self.curr_p1 / self.proflen / self.dt self.DOFcor = self.DOFnom * self.DOF_corr() infile.close() self.barysubfreqs = None if self.avgvoverc == 0: if self.candnm.startswith("PSR_"): # If this doesn't work, we should try to use the barycentering calcs # in the presto module. try: psrname = self.candnm[4:] self.polycos = polycos.polycos(psrname, filenm=self.pfd_filename + ".polycos") midMJD = self.tepoch + 0.5 * self.T / 86400.0 self.avgvoverc = self.polycos.get_voverc( int(midMJD), midMJD - int(midMJD)) #sys.stderr.write("Approximate Doppler velocity (in c) is: %.4g\n"%self.avgvoverc) # Make the Doppler correction self.barysubfreqs = self.subfreqs * (1.0 + self.avgvoverc) except IOError: self.polycos = 0 if self.barysubfreqs is None: self.barysubfreqs = self.subfreqs
else: if sys.argv[1].endswith(".pfd"): print("Input is PFD") # Input is pfd file pfdfn = sys.argv[1] # Check for bestprof if not os.path.exists(pfdfn+".bestprof"): print("Creating bestprof file") # Create bestprof file with show_pfd devnull = open(os.devnull, 'w') subprocess.call(['show_pfd', '-noxwin', pfdfn], stdout=devnull) devnull.close() filenm = pfdfn+".bestprof" else: filenm = sys.argv[1] prof = read_profile(filenm, normalize=0) if len(sys.argv)>=3: noise_stdev = float(sys.argv[2]) else: try: bprof = bestprof(sys.argv[1]) noise_stdev = bprof.prof_std except: noise_stdev = 1.0 fig = plt.figure() dataplot = fig.add_subplot(211) interactor = GaussianSelector(dataplot, prof, noise_stdev, filenm) plt.show()
def __init__(self, filenames, master=None, input_parfile=None): super().__init__(master) self.master = master self.data = Data() if filenames: suffix = '.bestprof' for fn in filenames: if fn.endswith(suffix): prof = bestprof.bestprof(fn) for minute in np.arange(int(prof.T / 60.0 + 0.5)): t = minute * 60. time = prof.epochi + prof.epochf + minute / 1440.0 period = prof.p0 + t * (prof.p1 + 0.5 * t * prof.p2) self.data.add(time, period, ptype='s') try: mjds, periods, uncertainties = np.loadtxt(filenames[0], usecols=(0, 1, 2), unpack=True) self.data.set_mjd(mjds) self.data.set_period(periods) self.data.set_unc(uncertainties) #print (self.data.get_mjd(), self.data.get_period(), self.data.get_unc()) except: print("Input format not recognized") raise # Variables Init self.ra_str = "00:00:00" self.dec_str = "+00:00:00" self.init_parameters() # Build Main window self.create_ui() self.draw_options() self.draw_param() self.set_entries() if input_parfile: self.read_parfile(input_parfile) self.set_entries() #if len(self.data.mjds): # self.plot_model() # Add graphic box and display Label self.plot_orbital = False self.xlabel = "MJD" self.ylabel = "Period (ms)" self.fig = Figure(facecolor='white') #self.fig.canvas.mpl_connect('key_press_event', self.key_press_menu) self.master.bind('<KeyPress>', self.key_press_menu) self.master.bind('<Return>', self.onReturn) self.ax1 = self.fig.add_subplot(3, 1, (1, 2)) self.ax2 = self.fig.add_subplot(3, 1, 3) self.ax1.format_coord = lambda x, y: "" self.ax2.format_coord = lambda x, y: "" ########### #left, width = 0.1, 0.8 #rect1 = [left, 0.1, width, 0.7] #rect2 = [left, 0.8, width, 0.1] self.ax1.set_xlabel(self.xlabel) self.ax1.set_ylabel(self.ylabel) self.ax1.xaxis.set_major_formatter(ScalarFormatter(useOffset=False)) self.ax1.yaxis.set_major_formatter(ScalarFormatter(useOffset=False)) self.ax2.set_xlabel(self.xlabel) self.ax2.set_ylabel("Residuals (mP0)") self.ax2.xaxis.set_major_formatter(ScalarFormatter(useOffset=False)) self.ax2.yaxis.set_major_formatter(ScalarFormatter(useOffset=False)) self.canvas = FigureCanvas(self.fig, master=master) #self.canvas.grid(row=8) #self.canvas.draw() #self.box_param.pack_start(self.canvas, True, True, 0) # Add Toolbar box #toolbar = NavigationToolbar(self.canvas, self) #self.box_param.pack_start(toolbar, False, False) # plot #print ("Have Unc?", self.data.get_unc()) if len(self.data.get_unc()): self.ax1.errorbar(self.data.get_mjd(), self.data.get_period(), yerr=self.data.get_unc(), color='r', fmt='o', zorder=10) else: self.ax1.scatter(self.data.get_mjd(), self.data.get_period(), color='r', s=20, edgecolor='r', marker='o', zorder=10) self.canvas.get_tk_widget().grid(row=6, columnspan=6, sticky=N + S + E + W) toolbarFrame = Frame(master=root) toolbarFrame.grid(row=7, columnspan=6) toolbar = NavigationToolbar(self.canvas, toolbarFrame) self.connect() self.cidAx1 = self.ax1.callbacks.connect('xlim_changed', self.on_xlims_change) #self.ax1.callbacks.connect('ylim_changed', self.on_ylims_change) self.cidAx2 = self.ax2.callbacks.connect('xlim_changed', self.on_xlims_change) #self.ax2.callbacks.connect('ylim_changed', self.on_ylims_change) xmin, xmax = self.ax1.get_xlim() self.oxmin, self.oxmax = self.ax1.get_xlim() self.ax2.set_xlim(xmin, xmax) self.canvas.draw()