def prepOutfile(self,filename,headerChanges=None): outFile = File(filename,"w+") if headerChanges is not None: for key,val in headerChanges: self.modify_header(key,val) outFile.write(self.write_header()) self.reset_header() return outFile
def _readTim(self): """Read time series from .tim file. Currently only works with 32-bit time series. Creates class attribute timBuffer. """ f = File(self.file,"r") f.seek(self.hdrlen) self.timBuffer = Buffer(self.info["nsamples"],C.c_float) f.cread(self.timBuffer)
def __init__(self,filename): """Create Filterbank instance. Args: filename -- string containing name of file to process """ Header.__init__(self,filename) self.f = File(filename,"r",nbits=self.info["nbits"]) infofile = "%s.info"%(self.basename) if os.path.isfile(infofile): try: self.stats = cPickle.load(open(infofile,"r")) except: self.stats = None else: self.stats = None if self.ctype == C.c_float: self.lib = C.CDLL("libSigPyProc32.so") else: self.lib = C.CDLL("libSigPyProc8.so")
class Filterbank(Header): """Class to handle filterbank files in all their glory. Parameters ---------- \tfilename -- name of filterbank file Methods ------- \tcollapse -- Collapse filterbank in frequency and/or time \tdedisperse -- Simple dedispersion algorithm (fixed some sigproc bugs) \tdownsample -- Downsample filterbank in frequency and/or time """ def __init__(self,filename): """Create Filterbank instance. Args: filename -- string containing name of file to process """ Header.__init__(self,filename) self.f = File(filename,"r",nbits=self.info["nbits"]) infofile = "%s.info"%(self.basename) if os.path.isfile(infofile): try: self.stats = cPickle.load(open(infofile,"r")) except: self.stats = None else: self.stats = None if self.ctype == C.c_float: self.lib = C.CDLL("libSigPyProc32.so") else: self.lib = C.CDLL("libSigPyProc8.so") def getDMdelays(self,dm): """For a given dispersion measure return delay for each channel """ chanFreqs = (numpy.arange(self.info["nchans"]) *self.info['foff'])+self.info['fch1'] chanDelays = (dm * 4.148808e3 * ((chanFreqs**-2)-(self.info['fch1']**-2) )/self.info["tsamp"]).round().astype("int32") return chanDelays def collapse(self,blocksize=512): """Collapse a filterbank in frequency. Args: blocksize -- number of samples to read in each gulp Return: TimeSeries instance """ readBuffer = Buffer(blocksize*self.info["nchans"],self.ctype) timBuffer = Buffer(self.info["nsamples"],C.c_float) passPlan = ReadPlan(self,readBuffer) passPlan.readOnce(blocksize) for nsamps,ii in passPlan.makePass(): self.lib.getTim(readBuffer.Cbuffer,timBuffer.Cbuffer, self.info["nchans"],nsamps,ii*blocksize) return TimeSeries(self.info.copy(),timBuffer) def bandpass(self,blocksize=512): """Collapse a filterbank in time. Args: blocksize -- number of samples to read in each gulp Return: BandpassFromBuffer instance """ readBuffer = Buffer(blocksize*self.info["nchans"],self.ctype) bpassBuffer = Buffer(self.info["nchans"],C.c_float) passPlan = ReadPlan(self,readBuffer) passPlan.readOnce(blocksize) for nsamps,ii in passPlan.makePass(): self.lib.getBpass(readBuffer.Cbuffer,bpassBuffer.Cbuffer, self.info["nchans"],blocksize) return BandpassFromBuffer(self.info.copy(),bpassBuffer) def dedisperse(self,dm,gulp=10000): """Dedisperse filterbank to timeseries. Args: dm -- Dispersion measure to dedisperse to gulp -- size of block to read at a time, if chosen gulp is less than maximum dispersion delay gulp is taken as 2 * max delay. Returns: TimeSeries instance """ chanDelays = self.getDMdelays(dm) delayPointer = arrayToPointer(chanDelays) maxDelay = int(chanDelays.max()) gulp = max(2*maxDelay,gulp) timLen = self.info["nsamples"]-maxDelay timBuffer = Buffer(timLen,C.c_float) readBuffer = Buffer(self.info["nchans"]*gulp,self.ctype) passPlan = ReadPlan(self,readBuffer) passPlan.readSkipBack(gulp,maxDelay) for nsamps,ii in passPlan.makePass(): self.lib.dedisperse(readBuffer.Cbuffer,timBuffer.Cbuffer,delayPointer, maxDelay, self.info["nchans"], nsamps, ii*(gulp-maxDelay)) timInfo = self.info.copy() timInfo["nsamples"] = timLen timInfo["refdm"] = dm return TimeSeries(timInfo,timBuffer) def downsample(self,tfactor=1,ffactor=1,filename=None): """Downsample filterbank in frequency and/or time. Args: tfactor -- Factor to downsample in time ffactor -- Factor to downsample in frequecy (must be factor of nchans) filename -- File to write downsampled data to. Returns: Filterbank instance (from output file) """ if filename is None: filename = "%s_f%d_t%d.fil"%(self.basename,ffactor,tfactor) self.f.seek(self.hdrlen) if not self.info["nchans"]%ffactor == 0: raise ValueError,"Bad frequency factor given" self.downsample_header(tfactor=tfactor,ffactor=ffactor) outFile = self.prepOutfile(filename, (("tsamp",self.info["tsamp"]*tfactor), ("nchans",self.info["nchans"]/ffactor), ("foff",self.info["foff"]*ffactor))) readBuffer = Buffer(tfactor*self.info["nchans"],self.ctype) writeBuffer = Buffer(self.info["nchans"]/ffactor,self.ctype) tempBuffer = Buffer(self.info["nchans"]/ffactor,C.c_int) self.lib.downsampleFil(self.f.f, outFile.f, readBuffer.Cbuffer, writeBuffer.Cbuffer,tempBuffer.Cbuffer, tfactor, ffactor, self.info["nchans"], self.info["nsamples"]) return Filterbank(filename) def fold(self,period,dm,nbins=50,nints=32,nbands=32,gulp=10000): """Fold filterbank phase bins, subintegrations and subbands. Args: period -- period in seconds to fold with nbins -- number of phase bins in output nints -- number of subintegrations in output Returns: FoldedData instance """ nbands = min(nbands,self.info["nchans"]) chanDelays = self.getDMdelays(dm) delayPointer = arrayToPointer(chanDelays) maxDelay = int(chanDelays.max()) gulp = max(2*maxDelay,gulp) foldBuffer = Buffer(nbins*nints*nbands,C.c_float) countBuffer = Buffer(nbins*nints*nbands,C.c_int) readBuffer = Buffer(self.info["nchans"]*gulp,self.ctype) passPlan = ReadPlan(self,readBuffer) passPlan.readSkipBack(gulp,maxDelay) for nsamps,ii in passPlan.makePass(): self.lib.foldFil(readBuffer.Cbuffer, foldBuffer.Cbuffer, countBuffer.Cbuffer, delayPointer, maxDelay, C.c_double(self.info["tsamp"]), C.c_double(period), gulp, self.info["nchans"], nbins, nints, nbands, ii*(gulp-maxDelay)) parentInfo = self.info.copy() return FoldedData(parentInfo,foldBuffer,countBuffer, period,dm,nbins,nints,nbands) def dropBits32to8(self,gulp=1024,flag=0,clip=0): if self.stats is None: raise AttributeError,"First run getStatistics()" readBuffer = Buffer(self.info["nchans"]*gulp,self.ctype) writeBuffer = Buffer(self.info["nchans"]*gulp,C.c_ubyte) passPlan = ReadPlan(self,readBuffer) passPlan.readOnce(gulp) if flag is not 0: flagBuffer = Buffer(self.info["nchans"]*gulp,C.c_ubyte) flagMax = flag*self.stats["sigma"].astype("float32") flagMin = -flag*self.stats["sigma"].astype("float32") if clip is not 0: chanMax = numpy.array([min(a,b) for a,b in zip(clip*self.stats["sigma"],self.stats["maxima"])]) chanMin = numpy.array([max(a,b) for a,b in zip(-clip*self.stats["sigma"],self.stats["minima"])]) else: chanMax = self.stats["maxima"] chanMin = self.stats["minima"] chanFactor = ((chanMax-chanMin)/255.) chanPlus = (chanMin/chanFactor) outFile = self.prepOutfile("%s_8bit.fil"%(self.basename),(("nbits",8))) if flag is not 0: changes = (("nbits",8),("source_name","%s_mask"%(self.info["source_name"].split()[0]))) flagFile = self.prepOutfile("%s_8bit_mask.fil"%(self.basename),changes) for nsamps,ii in passPlan.makePass(): self.lib.to8bit(readBuffer.Cbuffer,writeBuffer.Cbuffer, arrayToPointer(chanFactor),arrayToPointer(chanPlus), nsamps,self.info["nchans"]) outFile.cwrite(writeBuffer) if flag is not 0: lib.flagBlock(readBuffer.Cbuffer,flagBuffer.Cbuffer, arrayToPointer(flagMax),arrayToPointer(flagMin), nsamps,self.info["nchans"]) flagFile.cwrite(flagBuffer) if flag is not 0: return(Filterbank(outFile.name),Filterbank(flagFile.name)) else: return Filterbank(outFile.name) def getStatistics(self,window=10001,gulp=30003): if gulp < window: raise ValueError,"gulp must be > window" readBuffer = Buffer(self.info["nchans"]*gulp,self.ctype) writeBuffer = Buffer(self.info["nchans"]*gulp,self.ctype) maximaBuffer = Buffer(self.info["nchans"],C.c_float) minimaBuffer = Buffer(self.info["nchans"],C.c_float) meansBuffer = Buffer(self.info["nchans"],C.c_float) bpassBuffer = Buffer(self.info["nchans"],C.c_float) stdevBuffer = Buffer(self.info["nchans"],C.c_float) outFile = self.prepOutfile("%s_RM.fil"%(self.basename)) passPlan = ReadPlan(self,readBuffer) passPlan.readSkipBack(gulp,window) for nsamps,ii in passPlan.makePass(): self.lib.getStats(readBuffer.Cbuffer, meansBuffer.Cbuffer, bpassBuffer.Cbuffer, stdevBuffer.Cbuffer, writeBuffer.Cbuffer,maximaBuffer.Cbuffer, minimaBuffer.Cbuffer,self.info["nchans"],nsamps,window,ii) if ii == 0: outFile.cwrite(writeBuffer) elif ii == passPlan.nreads-1: outFile.cwrite(writeBuffer, nunits=nsamps*self.info["nchans"], offset=self.info["nchans"]*window) else: outFile.cwrite(writeBuffer, nunits = (gulp-window)*self.info["nchans"], offset = self.info["nchans"]*window) stdevBuffer.Ndarray = numpy.sqrt(stdevBuffer.Ndarray/self.info["nsamples"]) infoFile = open("%s_RM.info"%(self.basename),"w+") info = {"sigma":stdevBuffer.Ndarray, "bandpass":bpassBuffer.Ndarray, "maxima":maximaBuffer.Ndarray, "minima":minimaBuffer.Ndarray} cPickle.dump(info,infoFile) infoFile.close() return Filterbank(outFile.name) def prepOutfile(self,filename,headerChanges=None): outFile = File(filename,"w+") if headerChanges is not None: for key,val in headerChanges: self.modify_header(key,val) outFile.write(self.write_header()) self.reset_header() return outFile