Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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")
Ejemplo n.º 4
0
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