def read_data_fits(input, hdu=None, **kwargs): """ Read an array and header from an FITS file. Parameters ---------- input : str or compatible `astropy.io.fits` HDU object If a string, the filename to read the table from. The following `astropy.io.fits` HDU objects can be used as input: - :class:`~astropy.io.fits.hdu.table.PrimaryHDU` - :class:`~astropy.io.fits.hdu.table.ImageHDU` - :class:`~astropy.io.fits.hdu.hdulist.HDUList` hdu : int or str, optional The HDU to read the table from. """ if isinstance(input, fits.HDUList): # Parse all array objects arrays = OrderedDict() for ihdu, hdu_item in enumerate(input): if isinstance(hdu_item, (fits.PrimaryHDU, fits.ImageHDU)): arrays[ihdu] = hdu_item if len(arrays) > 1: if hdu is None: hdu = first(arrays) warnings.warn("hdu= was not specified but multiple arrays" " are present, reading in first available" " array (hdu={0})".format(hdu)) # hdu might not be an integer, so we first need to convert it # to the correct HDU index hdu = input.index_of(hdu) if hdu in arrays: array_hdu = arrays[hdu] else: raise ValueError("No array found in hdu={0}".format(hdu)) elif len(arrays) == 1: array_hdu = arrays[first(arrays)] else: raise ValueError("No table found") elif isinstance(input, (fits.PrimaryHDU, fits.ImageHDU)): array_hdu = input else: hdulist = fits_open(input, **kwargs) try: return read_data_fits(hdulist, hdu=hdu) finally: hdulist.close() return array_hdu.data, array_hdu.header
def read_data_fits(input, hdu=None, mode='denywrite', **kwargs): """ Read an array and header from an FITS file. Parameters ---------- input : str or compatible `astropy.io.fits` HDU object If a string, the filename to read the table from. The following `astropy.io.fits` HDU objects can be used as input: - :class:`~astropy.io.fits.hdu.table.PrimaryHDU` - :class:`~astropy.io.fits.hdu.table.ImageHDU` - :class:`~astropy.io.fits.hdu.hdulist.HDUList` hdu : int or str, optional The HDU to read the table from. mode : str One of the FITS file reading modes; see `~astropy.io.fits.open`. ``denywrite`` is used by default since this prevents the system from checking that the entire cube will fit into swap, which can prevent the file from being opened at all. """ beam_table = None if isinstance(input, fits.HDUList): # Parse all array objects arrays = OrderedDict() for ihdu, hdu_item in enumerate(input): if isinstance(hdu_item, (fits.PrimaryHDU, fits.ImageHDU)): arrays[ihdu] = hdu_item elif isinstance(hdu_item, fits.BinTableHDU): if 'BPA' in hdu_item.data.names: beam_table = hdu_item.data if len(arrays) > 1: if hdu is None: hdu = first(arrays) warnings.warn("hdu= was not specified but multiple arrays" " are present, reading in first available" " array (hdu={0})".format(hdu)) # hdu might not be an integer, so we first need to convert it # to the correct HDU index hdu = input.index_of(hdu) if hdu in arrays: array_hdu = arrays[hdu] else: raise ValueError("No array found in hdu={0}".format(hdu)) elif len(arrays) == 1: array_hdu = arrays[first(arrays)] else: raise ValueError("No arrays found") elif isinstance(input, (fits.PrimaryHDU, fits.ImageHDU)): array_hdu = input else: hdulist = fits_open(input, mode=mode, **kwargs) try: return read_data_fits(hdulist, hdu=hdu) finally: hdulist.close() return array_hdu.data, array_hdu.header, beam_table
def read_data_fits(input, hdu=None, mode='denywrite', **kwargs): """ Read an array and header from an FITS file. Parameters ---------- input : str or compatible `astropy.io.fits` HDU object If a string, the filename to read the table from. The following `astropy.io.fits` HDU objects can be used as input: - :class:`~astropy.io.fits.hdu.table.PrimaryHDU` - :class:`~astropy.io.fits.hdu.table.ImageHDU` - :class:`~astropy.io.fits.hdu.hdulist.HDUList` hdu : int or str, optional The HDU to read the table from. mode : str One of the FITS file reading modes; see `~astropy.io.fits.open`. ``denywrite`` is used by default since this prevents the system from checking that the entire cube will fit into swap, which can prevent the file from being opened at all. """ beam_table = None if isinstance(input, fits.HDUList): # Parse all array objects arrays = OrderedDict() for ihdu, hdu_item in enumerate(input): if isinstance(hdu_item, (fits.PrimaryHDU, fits.ImageHDU)): arrays[ihdu] = hdu_item elif isinstance(hdu_item, fits.BinTableHDU): if 'BPA' in hdu_item.data.names: beam_table = hdu_item.data if len(arrays) > 1: if hdu is None: hdu = first(arrays) warnings.warn( "hdu= was not specified but multiple arrays" " are present, reading in first available" " array (hdu={0})".format(hdu), FITSWarning) # hdu might not be an integer, so we first need to convert it # to the correct HDU index hdu = input.index_of(hdu) if hdu in arrays: array_hdu = arrays[hdu] else: raise ValueError("No array found in hdu={0}".format(hdu)) elif len(arrays) == 1: array_hdu = arrays[first(arrays)] else: raise ValueError("No arrays found") elif isinstance(input, (fits.PrimaryHDU, fits.ImageHDU)): array_hdu = input else: hdulist = fits_open(input, mode=mode, **kwargs) try: return read_data_fits(hdulist, hdu=hdu) finally: hdulist.close() return array_hdu.data, array_hdu.header, beam_table
def read_table_fits(input, hdu=None): """ Read a Table object from an FITS file Parameters ---------- input : str or file-like object or compatible `astropy.io.fits` HDU object If a string, the filename to read the table from. If a file object, or a compatible HDU object, the object to extract the table from. The following `astropy.io.fits` HDU objects can be used as input: - :class:`~astropy.io.fits.hdu.table.TableHDU` - :class:`~astropy.io.fits.hdu.table.BinTableHDU` - :class:`~astropy.io.fits.hdu.table.GroupsHDU` - :class:`~astropy.io.fits.hdu.hdulist.HDUList` hdu : int or str, optional The HDU to read the table from. """ if isinstance(input, basestring): input = fits_open(input) to_close = input else: to_close = None if hasattr(input, 'read'): input = fits_open(input) try: # Parse all table objects tables = OrderedDict() if isinstance(input, HDUList): for ihdu, hdu_item in enumerate(input): if isinstance(hdu_item, (TableHDU, BinTableHDU, GroupsHDU)): tables[ihdu] = hdu_item if len(tables) > 1: if hdu is None: warnings.warn("hdu= was not specified but multiple tables" " are present, reading in first available" " table (hdu={0})".format(tables.keys()[0])) hdu = tables.keys()[0] # hdu might not be an integer, so we first need to convert it # to the correct HDU index hdu = input.index_of(hdu) if hdu in tables: table = tables[hdu] else: raise ValueError("No table found in hdu={0}".format(hdu)) elif len(tables) == 1: table = tables[tables.keys()[0]] else: raise ValueError("No table found") elif isinstance(input, (TableHDU, BinTableHDU, GroupsHDU)): table = input else: raise ValueError("Input should be a string, a file-like object, " "an HDUList, TableHDU, BinTableHDU, or " "GroupsHDU instance") # Check if table is masked masked = False for col in table.columns: if col.null is not None: masked = True break # Convert to an astropy.table.Table object t = Table(table.data, masked=masked) # Copy over null values if needed if masked: for col in table.columns: t[col.name].set_fill_value(col.null) t[col.name].mask[t[col.name] == col.null] = True # Copy over units for col in table.columns: if col.unit is not None: try: t[col.name].units = u.Unit(col.unit, format='fits') except ValueError: t[col.name].units = u.UnrecognizedUnit(col.unit) # TODO: deal properly with unsigned integers for key, value, comment in table.header.cards: if key in ['COMMENT', 'HISTORY']: if key in t.meta: t.meta[key].append(value) else: t.meta[key] = [value] elif key in t.meta: # key is duplicate if isinstance(t.meta[key], list): t.meta[key].append(value) else: t.meta[key] = [t.meta[key], value] elif (is_column_keyword(key.upper()) or key.upper() in REMOVE_KEYWORDS): pass else: t.meta[key] = value # TODO: implement masking finally: if to_close is not None: to_close.close() return t
def read_table_fits(input, hdu=None): """ Read a Table object from an FITS file Parameters ---------- input : str or file-like object or compatible `astropy.io.fits` HDU object If a string, the filename to read the table from. If a file object, or a compatible HDU object, the object to extract the table from. The following `astropy.io.fits` HDU objects can be used as input: - :class:`~astropy.io.fits.hdu.table.TableHDU` - :class:`~astropy.io.fits.hdu.table.BinTableHDU` - :class:`~astropy.io.fits.hdu.table.GroupsHDU` - :class:`~astropy.io.fits.hdu.hdulist.HDUList` hdu : int or str, optional The HDU to read the table from. """ if isinstance(input, six.string_types): input = fits_open(input) to_close = input else: to_close = None if hasattr(input, 'read'): input = fits_open(input) try: # Parse all table objects tables = OrderedDict() if isinstance(input, HDUList): for ihdu, hdu_item in enumerate(input): if isinstance(hdu_item, (TableHDU, BinTableHDU, GroupsHDU)): tables[ihdu] = hdu_item if len(tables) > 1: if hdu is None: warnings.warn("hdu= was not specified but multiple tables" " are present, reading in first available" " table (hdu={0})".format( list(tables.keys())[0])) hdu = list(tables.keys())[0] # hdu might not be an integer, so we first need to convert it # to the correct HDU index hdu = input.index_of(hdu) if hdu in tables: table = tables[hdu] else: raise ValueError("No table found in hdu={0}".format(hdu)) elif len(tables) == 1: table = tables[list(tables.keys())[0]] else: raise ValueError("No table found") elif isinstance(input, (TableHDU, BinTableHDU, GroupsHDU)): table = input else: raise ValueError("Input should be a string, a file-like object, " "an HDUList, TableHDU, BinTableHDU, or " "GroupsHDU instance") # Check if table is masked masked = False for col in table.columns: if col.null is not None: masked = True break # Convert to an astropy.table.Table object t = Table(table.data, masked=masked) # Copy over null values if needed if masked: for col in table.columns: t[col.name].set_fill_value(col.null) t[col.name].mask[t[col.name] == col.null] = True # Copy over units for col in table.columns: if col.unit is not None: try: t[col.name].units = u.Unit(col.unit, format='fits') except ValueError: t[col.name].units = u.UnrecognizedUnit(col.unit) # TODO: deal properly with unsigned integers for key, value, comment in table.header.cards: if key in ['COMMENT', 'HISTORY']: if key in t.meta: t.meta[key].append(value) else: t.meta[key] = [value] elif key in t.meta: # key is duplicate if isinstance(t.meta[key], list): t.meta[key].append(value) else: t.meta[key] = [t.meta[key], value] elif (is_column_keyword(key.upper()) or key.upper() in REMOVE_KEYWORDS): pass else: t.meta[key] = value # TODO: implement masking finally: if to_close is not None: to_close.close() return t