def test_works(self) : fname ='/a_place/in_a_very/deep/directory/with_a_very/long/name.dat' abbr = utils.abbreviate_file_path(fname) self.assertEqual(abbr, 'long/name.dat') abbr = utils.abbreviate_file_path(abbr) self.assertEqual(abbr, 'long/name.dat') fname = 'name' abbr = utils.abbreviate_file_path(fname) self.assertEqual(abbr, fname)
def __init__(self, fname, memmap=False): self.verify_ordering = True self.fname = fname # The passed file name is assumed to be a GBT spectrometer fits file. self.hdulist = pyfits.open(self.fname, 'readonly', memmap=memmap) if len(self.hdulist) < 2: raise DataError("Fits file missing data extension") logger.info("Opened GBT fits file: %s" % abbreviate_file_path(fname)) fits_data = self.hdulist[1].data n_records = len(fits_data) self._fits_data = fits_data try: names = fits_data.names except AttributeError: names = fits_data._names self._field_names = names # Figure out the scan and sub-band content of the file. if 'SCAN' in names: self._scans_all = fits_data.field('SCAN') scans = np.unique(self._scans_all) np.sort(scans) self._scans = scans else: self._scans_all = np.zeros(len(n_records)) self._scans = np.array([0]) # Round the frequencies to nearest 10 kHz as we only need to tell the # difference between one sub-band and the other. self._bands_all = np.round(fits_data.field('CRVAL1'), -4) bands = np.unique(self._bands_all) np.sort(bands) self._bands = bands
def write(self, file_name): """Write stored data to file. Parameters ---------- file_name : string File name to write data to. """ # Add the data Col = pyfits.Column(name='DATA', format=self.data_format, array=self.data) columns = [Col,] # Add all the other stored fields. for field_name in self.field.iterkeys() : Col = pyfits.Column(name=field_name, format=self.formats[field_name], array=np.asarray(self.field[field_name])) columns.append(Col) coldefs = pyfits.ColDefs(columns) # Create fits header data units, one for the table and the mandatory # primary. tbhdu = pyfits.new_table(coldefs) prihdu = pyfits.PrimaryHDU() # Add the write history. fname_abbr = abbreviate_file_path(file_name) self.history.add('Written to file.', ('File name: ' + fname_abbr,)) # Add the history to the header. write_history_header(prihdu.header, self.history) # Combine the HDUs and write to file. hdulist = pyfits.HDUList([prihdu, tbhdu]) hdulist.writeto(file_name, clobber=True) logger.info('Wrote data to file: %s' % fname_abbr)
def read(self, scans=None, bands=None) : """Read in data from the fits file. This method reads data from the fits file including the files history. It is done one scan and one band at a time. Each scan and band is returned as an instance of :class:`SpecBlock` class. Parameters ---------- scans : tuple of integers Which scans in the file to be processed. A list of integers, with 0 corresponding to the lowest numbered scan. Default is all of them. bands : tuple of integers Which intermediate frequencies (also called frequency windows) to process. A list of integers with 0 corresponding to the lowest frequency present. Default is all of them. Returns ------- blocks : list List of :class:`SpecBlock` objects read from file. """ # We want scans and bands to be a sequence of indicies. if scans is None : scans = range(len(self.scans)) elif not hasattr(scans, '__iter__') : scans = (scans, ) elif len(scans) == 0 : scans = range(len(self.scans)) if bands is None : bands = range(len(self.bands)) elif not hasattr(bands, '__iter__') : bands = (bands, ) elif len(bands) == 0 : bands = range(len(self.bands)) logger.info("Reading scans %s and bands %s" % (str(scans), str(bands))) blocks = [] # Sequence of output SpecBlock objects. for scan_ind in scans : for band_ind in bands : # Choose the appropriate records from the file, get that data. records_sb = self.get_scan_band_records(scan_ind, band_ind) block_sb = SpecBlock(records_sb["DATA"]) # Masked data is stored in FITS files as float('nan') block_sb.data[np.logical_not(np.isfinite( block_sb.data))] = ma.masked # Now iterate over the fields and add them # to the data block. for field, field_axes in SPEC_FIELDS.iteritems() : if not field in self._field_names : continue # First get the 'FITS' format string. field_format = self.hdulist[1].columns.formats[ self.hdulist[1].columns.names.index(field)] which_data = [slice(None)] * 2 for ii, single_axis in enumerate(block_sb.axes[:-1]): # For each axis, slice out all the data except the # stuff we need. if single_axis in field_axes : #field_shape.append(block_sb.shape[ii]) pass else : which_data[ii] = 0 field_data = records_sb[tuple(which_data)][field] block_sb.set_field(field, field_data, field_axes, field_format) if not hasattr(self, 'history'): self.history = get_history_header(self.hdulist[0].header) #self.set_history(Data_sb) fname_abbr = abbreviate_file_path(self.fname) self.history.add('Read from file.', ('File name: ' + fname_abbr, )) block_sb._history = History(self.history) block_sb.verify() blocks.append(block_sb) logger.info("Read finished") return blocks