Example #1
0
    def to_fits(self, npsub=-1):
        """
        Writes out a PSRFITS file

        Args:
            npsub (int): number of spectra per subint

        """

        tsamp = self.your_object.your_header.tsamp

        if npsub == -1:
            npsub = int(1.0 / tsamp)
        else:
            pass

        if self.nsamp:
            if self.nsamp < npsub:
                npsub = self.nsamp

        outfile = self.outdir + "/" + self.outname + ".fits"

        initialize_psrfits(
            outfile=outfile,
            your_object=self.your_object,
            npsub=npsub,
            nstart=self.nstart,
            nsamp=self.nsamp,
            chan_freqs=self.chan_freqs,
        )

        nifs = self.your_object.your_header.npol

        logger.info("Filling PSRFITS file with data")

        # Open PSRFITS file
        hdulist = fits.open(outfile, mode="update")
        hdu = hdulist[1]
        nsubints = len(hdu.data[:]["data"])

        # Loop through chunks of data to write to PSRFITS
        n_read_subints = 10
        logger.info(f"Number of subints to write {nsubints}")

        st = self.nstart
        with Progress() as progress:
            if not self.progress:
                task = progress.add_task(
                    "[green]Writing...", total=nsubints, visible=False
                )
            else:
                task = progress.add_task("[green]Writing...", total=nsubints)

            for istart in np.arange(0, nsubints, n_read_subints):
                istop = istart + n_read_subints
                if istop > nsubints:
                    istop = nsubints
                else:
                    pass
                isub = istop - istart

                logger.info(
                    f"Writing data to {outfile} from subint = {istart} to {istop}."
                )

                # Read in nread samples from filfile
                nread = isub * npsub
                self.get_data_to_write(st, nread)
                progress.update(task, advance=n_read_subints)
                data = self.data
                st += nread

                nvals = isub * npsub * nifs
                if data.shape[0] < nvals:
                    logger.debug(
                        f"nspectra in this chunk ({data.shape[0]}) < nsubints * npsub * nifs ({nvals})"
                    )
                    logger.debug(f"Appending zeros at the end to fill the subint")
                    pad_back = np.zeros((nvals - data.shape[0], data.shape[1]))
                    data = np.vstack((data, pad_back))
                else:
                    pass

                data = np.reshape(data, (isub, npsub, nifs, self.nchans))

                # Put data in hdu data array
                logger.debug(f"Writing data of shape {data.shape} to {outfile}.")
                hdu.data[istart:istop]["data"][:, :, :, :] = data[:].astype(
                    self.your_object.your_header.dtype
                )

            # Write to file
            hdulist.flush()

        logger.info(f"All spectra written to {outfile}")
        # Close open FITS file
        hdulist.close()
Example #2
0
    def to_fits(self,
                nstart=None,
                c=None,
                nsamp=None,
                npsub=-1,
                outdir=None,
                outname=None,
                progress=None,
                flag_rfi=False,
                sk_sig=4,
                sg_fw=15,
                sg_sig=4,
                zero_dm_subt=False):
        """
        Writes out a PSRFITS file

        Args:

            nstart: Start sample number to read from

            nsamp: Number of samples to read/write

            c: Required frequency channel range [min_chan, max_chan] (excludes the higher channel number)

            npsub: Number of spectra per subint

            outdir: Output directory for Filterbank file

            outname: Name of the PSRFITS file to write to

            progress: Turn on/off progress bar

            flag_rfi: To turn on RFI flagging

            sk_sig: Sigma for spectral kurtosis filter

            sg_fw: Filter window for savgol filter

            sg_sig: Sigma for savgol filter

            zero_dm_subt: Enable zero-DM RFI excision

        """

        tsamp = self.your_obj.your_header.tsamp

        if npsub == -1:
            npsub = int(1.0 / tsamp)
        else:
            pass

        if nsamp:
            if nsamp < npsub:
                npsub = nsamp

        if not outname:
            original_dir, orig_basename = os.path.split(
                self.your_obj.your_header.filename)
            name, ext = os.path.splitext(orig_basename)
            if ext == '.fits':
                temp = name.split('_')
                if len(temp) > 1:
                    outname = '_'.join(temp[:-1]) + '_converted.fits'
                else:
                    outname = name + '_converted.fits'
            else:
                outname = name + '_converted.fits'

        if not outdir:
            outdir = os.getcwd()

        outfile = outdir + '/' + outname

        if c:
            min_c = int(np.min(c))
            max_c = int(np.max(c))
        else:
            min_c = 0
            max_c = len(self.your_obj.chan_freqs)

        chan_freqs = self.your_obj.chan_freqs[min_c:max_c]
        nchans = len(chan_freqs)

        initialize_psrfits(outfile=outfile,
                           y=self.your_obj,
                           npsub=npsub,
                           nstart=nstart,
                           nsamp=nsamp,
                           chan_freqs=chan_freqs)

        nifs = self.your_obj.your_header.npol

        logger.info("Filling PSRFITS file with data")

        # Open PSRFITS file
        hdulist = fits.open(outfile, mode='update')
        hdu = hdulist[1]
        nsubints = len(hdu.data[:]['data'])

        # Loop through chunks of data to write to PSRFITS
        n_read_subints = 10
        if not nstart:
            nstart = 0
        logger.info(f'Number of subints to write {nsubints}')

        for istart in tqdm.tqdm(np.arange(0, nsubints, n_read_subints),
                                disable=progress):
            istop = istart + n_read_subints
            if istop > nsubints:
                istop = nsubints
            else:
                pass
            isub = istop - istart

            logger.info(
                f"Writing data to {outfile} from subint = {istart} to {istop}."
            )

            # Read in nread samples from filfile
            nread = isub * npsub
            data = self.your_obj.get_data(nstart=nstart, nsamp=nread)
            data = data[:, min_c:max_c]
            if flag_rfi:
                mask = sk_sg_filter(data, self.your_obj, sk_sig, nchans, sg_fw,
                                    sg_sig)

                if self.your_obj.your_header.dtype == np.uint8:
                    data[:, mask] = np.around(np.mean(data[:, ~mask]))
                else:
                    data[:, mask] = np.mean(data[:, ~mask])

            if zero_dm_subt:
                logger.debug('Subtracting 0-DM time series from the data')
                data = data - data.mean(1)[:, None]

            logger.debug(f'Shape of data array after get_data is {data.shape}')
            nstart += nread

            nvals = isub * npsub * nifs
            if data.shape[0] < nvals:
                logger.debug(
                    f'nspectra in this chunk ({data.shape[0]}) < nsubints * npsub * nifs ({nvals})'
                )
                logger.debug(f'Appending zeros at the end to fill the subint')
                pad_back = np.zeros((nvals - data.shape[0], data.shape[1]))
                data = np.vstack((data, pad_back))
            else:
                pass

            data = np.reshape(data, (isub, npsub, nifs, nchans))

            # If foff is negative, we need to flip the freq axis
            #            if foff < 0:
            #                logger.debug(f"Flipping band as {foff} < 0")
            #                data = data[:, :, :, ::-1]
            #            else:
            #                pass

            # Put data in hdu data array
            logger.debug(f'Writing data of shape {data.shape} to {outfile}.')
            hdu.data[istart:istop]['data'][:, :, :, :] = data[:].astype(
                self.your_obj.your_header.dtype)

            # Write to file
            hdulist.flush()

        logger.info(f'All spectra written to {outfile}')
        # Close open FITS file
        hdulist.close()