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]) self.telescope = infile.read(struct.unpack(swapchar+"i", infile.read(4))[0]) self.pgdev = infile.read(struct.unpack(swapchar+"i", infile.read(4))[0]) test = infile.read(16) if not test[:8]=="Unknown": self.rastr = test[:test.find('\0')] test = infile.read(16) self.decstr = test[:test.find('\0')] else: self.rastr = "Unknown" self.decstr = "Unknown" (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('.')]+".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: self.polycos = polycos.polycos(self.candnm[4:], 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
#plotxy(template) #closeplot() # Determine the Telescope used if (not fold.topo): obs = '@' # Solarsystem Barycenter else: try: obs = scopes[fold_pfd.telescope.split()[0]] except KeyError: print "Unknown telescope!!!" # Read the polyco file (if required) if (fold.psr and fold.topo): if (fold_pfd.__dict__.has_key("polycos") and not fold_pfd.polycos==0): pcs = fold_pfd.polycos else: pcs = polycos(fold.psr, sys.argv[-1]+".polycos") (fold.phs0, fold.f0) = pcs.get_phs_and_freq(fold.epochi, fold.epochf) fold.f1 = fold.f2 = 0.0 else: pcs = None fold.phs0 = 0.0 (fold.f0, fold.f1, fold.f2) = psr_utils.p_to_f(fold.p0, fold.p1, fold.p2) # # Calculate the TOAs # for ii in range(numtoas): # The .pfd file was generated using -nosearch and a specified # folding period, p-dot, and p-dotdot (or f, f-dot, and f-dotdot).
else: try: if t2format: obs = scopes2[fold_pfd.telescope.split()[0]] else: obs = scopes[fold_pfd.telescope.split()[0]] except KeyError: sys.stderr.write("Unknown telescope!!! : " + fold_pfd.telescope) # Read the polyco file (if required) if (fold.psr and fold.topo): if (fold_pfd.__dict__.has_key("polycos") and not fold_pfd.polycos == 0): pcs = fold_pfd.polycos else: pcs = polycos(fold.psr, sys.argv[-1] + ".polycos") (fold.phs0, fold.f0) = pcs.get_phs_and_freq(fold.epochi, fold.epochf) fold.f1 = fold.f2 = 0.0 else: pcs = None fold.phs0 = 0.0 (fold.f0, fold.f1, fold.f2) = psr_utils.p_to_f(fold.p0, fold.p1, fold.p2) # # Calculate the TOAs # if t2format: print "FORMAT 1"
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]) self.telescope = infile.read(struct.unpack(swapchar+"i", infile.read(4))[0]) self.pgdev = infile.read(struct.unpack(swapchar+"i", infile.read(4))[0]) test = infile.read(16) has_posn = 1 for ii in range(16): if test[ii] not in '0123456789:.-\0': has_posn = 0 break if has_posn: self.rastr = test[:test.find('\0')] test = infile.read(16) self.decstr = test[:test.find('\0')] (self.dt, self.startT) = struct.unpack(swapchar+"dd", infile.read(2*8)) else: self.rastr = "Unknown" self.decstr = "Unknown" (self.dt, self.startT) = struct.unpack(swapchar+"dd", test) (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('.')]+".inf") if idata.waveband=="Radio": self.bestdm = idata.DM self.numchan = idata.numchan else: # i.e. for events 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() 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: self.polycos = polycos.polycos(self.candnm[4:], 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
cfreq = id.lofreq totbw = id.BW chanbw = id.chan_width freq = cfreq + totbw - chanbw # central freq of the highest channel # prepdata is dedispersing to higher freq (the highest freq channel gets zero delay) # reading .singlepulse file dm, sigma, secs = np.loadtxt(spfile, usecols=(0,1,2), comments='#', dtype=float, unpack=True) offset, downfact = np.loadtxt(spfile, usecols=(3,4), comments='#', dtype=int, unpack=True) if is_col6: col6 = np.loadtxt(spfile, usecols=(5,5), comments='#', dtype=str, unpack=True)[0] toa = ["%.13f" % (startmjd + (offset[i] * tres)/86400.,) for i in np.arange(np.size(offset))] # calculating the phases of pulses if is_phase == True: pid=poly.polycos(source, polycofile) phase=[pid.get_phs_and_freq(float(t.split(".")[0]), float("0." + t.split(".")[1]))[0] for t in toa] # writing the tim-file # Princeton format (+ additional extra field is for sigma) timfile=inffile.split(".inf")[0] + ".tim" if is_tempo2: # output tim-file is in Tempo2 format if is_phase == True: if extra != "" or is_col6: if not is_col6: lines=["%s,%d,%f,%s %8.3f %s %s %s" % (str(sigma[i]), downfact[i], phase[i], extra, freq, str(toa[i]), str(unc), obscode) for i in np.arange(np.size(offset))] else: if extra == "": lines=["%s,%d,%f,%s %8.3f %s %s %s" % (str(sigma[i]), downfact[i], phase[i], col6[i], freq, str(toa[i]), str(unc), obscode) for i in np.arange(np.size(offset))] else: lines=["%s,%d,%f,%s,%s %8.3f %s %s %s" % (str(sigma[i]), downfact[i], phase[i], col6[i], extra, freq, str(toa[i]), str(unc), obscode) for i in np.arange(np.size(offset))]
infile = open(datfile, "rb") except: print("Error: Can't read the dat-file '%s'!" % (datfile,)) sys.exit(1) dataptr = ar.array('f') # 'f' - for float infile.seek(headersize + 4 * start_sample) # position to the first byte to read; '4' - is the size of float else: data = events / 86400. # converting events to days data += startmjd # converting to MJD events -= events[0] # converting events' time relative to the start of observation # Folding the profile if not opts.is_timeseries: if opts.period == -1: # Period is not given in the cmdline, so will use polyco file pid=poly.polycos(source, opts.polycofile) try: if not opts.is_events: fold_period = get_period (pid, startmjd) else: fold_period = get_period (pid, data[0]) except: print("Check the name of the pulsar in polyco file '%s' and inf-file '%s'!" % (opts.polycofile, inffile)) print("If different, try --pulsar option to set the name of pulsar the same as in polyco file.") sys.exit(1) is_update_period = True if fold_period <= 0: print("Computed fold period is bad: %f. Check your polyco and/or MJD!" % (float(fold_period))) sys.exit(1) else: # period is given fold_period = opts.period / 1000.