Exemple #1
0
    def reverse_add_data(self, data_item):
        """
        Adds data from specviz to glue.

        Parameters
        ----------
        data_item : :class:`specviz.core.items.DataItem`
            The data item recently added to model.
        """
        new_data = Data(label=data_item.name)
        new_data.coords = coordinates_from_header(data_item.spectrum.wcs)

        flux_component = Component(data_item.spectrum.flux,
                                   data_item.spectrum.flux.unit)
        new_data.add_component(flux_component, "Flux")

        disp_component = Component(data_item.spectrum.spectral_axis,
                                   data_item.spectrum.spectral_axis.unit)
        new_data.add_component(disp_component, "Dispersion")

        if data_item.spectrum.uncertainty is not None:
            uncert_component = Component(data_item.spectrum.uncertainty.array,
                                         data_item.spectrum.uncertainty.unit)
            new_data.add_component(uncert_component, "Uncertainty")

        self._session.data_collection.append(new_data)
 def cube_to_data(self, cube,
                  output_label=None,
                  output_component_id=None):
     """
     Convert SpectralCube to final output.
     self.output_as_component is checked here.
     if self.output_as_component:
         add new component to self.data
     else:
         create new data and return it.
     :param cube: SpectralCube
     :param output_label: Name of new Data.
     :param output_component_id: label of new component
     :return:
     """
     original_data = self.data
     new_component = Component(cube._data.copy(), self.component_unit)
     if self.output_as_component:
         original_data.add_component(new_component, output_component_id)
         return None
     else:
         new_data = Data(label=output_label)
         new_data.coords = coordinates_from_header(cube.header)
         new_data.add_component(new_component, output_component_id)
         return new_data
Exemple #3
0
def _load_GALFAHI_data_LowRes(filename, **kwargs):
    # Data loader customized for GALFA-HI data cube
    # Resize the data cube into lower resolution in velocity/space

    def _bin_cube(cube, factor, axis_label):
        # resize the cube to lower resolution
        shape = cube.shape
        if axis_label == 'VELO':
            new_shape = (shape[0]/factor, factor, shape[1], shape[2])
            return cube.reshape(new_shape).mean(axis = 1)
        elif axis_label == 'RADEC':
            new_shape = (shape[0], shape[1]/factor, factor, shape[2]/factor, factor)
            return cube.reshape(new_shape).mean(axis = 4).mean(axis = 2)
        else: return cube

    # change the header for those cubes that has been binned into low resolutions
    def _get_new_header(header, factor, axis_label):
        new_header = header
        if axis_label == 'VELO':
            new_header['NAXIS3'] = header['NAXIS3'] / factor
            new_header['CRVAL3'] = header['CRVAL3']
            new_header['CRPIX3'] = float(header['CRPIX3'] / factor)
            new_header['CDELT3'] = header['CDELT3'] * factor
        elif axis_label == 'RADEC':
            for ax in [1, 2]:
                new_header['NAXIS%d'%(ax)] = header['NAXIS%d'%(ax)] / factor
                new_header['CRVAL%d'%(ax)] = header['CRVAL%d'%(ax)]
                new_header['CRPIX%d'%(ax)] = float(header['CRPIX%d'%(ax)] / factor)
                new_header['CDELT%d'%(ax)] = header['CDELT%d'%(ax)] * factor
        else: new_header = header
        # m/s --> km/s
        new_header['CDELT3'] = new_header['CDELT3'] * (10**(-3))
        return new_header

    def _get_cube_center(header, cubeshape):
        ra  = header['CRVAL1'] + header['CDELT1'] * (np.arange(cubeshape[2])+0.5 - header['CRPIX1'])              ## degree
        dec = header['CRVAL2'] + header['CDELT2'] * (np.arange(cubeshape[1])+0.5 - header['CRPIX2'])            ## degree
        return np.mean(ra), np.mean(dec)

    data_list = []
    # add 3 data objects with different resolutions:
    for factor, axis_label in zip([4, 16, 2], ['VELO', 'VELO', 'RADEC']):
        cube = fits.getdata(filename)
        header = fits.getheader(filename)
        cen_ra, cen_dec = _get_cube_center(header, cube.shape)
        new_header = _get_new_header(header, factor, axis_label)
        cube_name = 'G_%d%+.2fradec_%.1fkm/s_%.1fa' % (cen_ra, cen_dec, new_header['CDELT3'], new_header['CDELT2']*60.)

        data = Data()
        data.coords = coordinates_from_header(new_header)
        data.add_component(_bin_cube(cube, factor, axis_label), cube_name)
        data.label  = cube_name
        data_list.append(data)
        del data, cube, header
    return data_list
Exemple #4
0
def acs_cutout_image_reader(file_name):
    """
    Data loader for the ACS cut-outs for the DEIMOS spectra.

    The cutouts contain only the image.
    """

    hdulist = fits.open(file_name)
    data = Data(label='ACS Cutout Image')
    data.coords = coordinates_from_header(hdulist[0].header)
    data.header = hdulist[0].header
    data.add_component(hdulist[0].data, 'Flux')

    return data
Exemple #5
0
def _load_fits_generic(filename, **kwargs):
    hdulist = fits.open(filename)
    groups = dict()
    label_base = basename(filename).rpartition('.')[0]

    if not label_base:
        label_base = basename(filename)

    for extnum, hdu in enumerate(hdulist):
        if hdu.data is not None:
            hdu_name = hdu.name if hdu.name else str(extnum)
            if is_image_hdu(hdu):
                shape = hdu.data.shape
                try:
                    data = groups[shape]
                except KeyError:
                    label = '{}[{}]'.format(
                        label_base,
                        'x'.join(str(x) for x in shape)
                    )
                    data = Data(label=label)
                    data.coords = coordinates_from_header(hdu.header)
                    groups[shape] = data
                data.add_component(component=hdu.data,
                                   label=hdu_name)
            elif is_table_hdu(hdu):
                # Loop through columns and make component list
                table = Table(hdu.data)
                table_name = '{}[{}]'.format(
                    label_base,
                    hdu_name
                )
                for column_name in table.columns:
                    column = table[column_name]
                    shape = column.shape
                    data_label = '{}[{}]'.format(
                        table_name,
                        'x'.join(str(x) for x in shape)
                    )
                    try:
                        data = groups[data_label]
                    except KeyError:
                        data = Data(label=data_label)
                        groups[data_label] = data
                    component = Component.autotyped(column, units=column.unit)
                    data.add_component(component=component,
                                       label=column_name)
    return [data for data in groups.itervalues()]
Exemple #6
0
def casalike_cube(filename, **kwargs):
    """
    This provides special support for 4D CASA FITS - like cubes,
    which have 2 spatial axes, a spectral axis, and a stokes axis
    in that order.

    Each stokes cube is split out as a separate component
    """
    from astropy.io import fits

    result = Data()
    with fits.open(filename, **kwargs) as hdulist:
        array = hdulist[0].data
        header = hdulist[0].header
    result.coords = coordinates_from_header(header)
    for i in range(array.shape[0]):
        result.add_component(array[[i]], label='STOKES %i' % i)
    return result
Exemple #7
0
def nirspec_spectrum2d_reader(file_name):
    """
    Data loader for simulated NIRSpec 2D spectrum.

    This function extracts the DATA, QUALITY, and VAR
    extensions and returns them as a glue Data object.

    It then uses the header keywords of the DATA extension
    to detemine the wavelengths.
    """

    hdulist = fits.open(file_name)
    data = Data(label='2D Spectrum')
    data.header = hdulist['DATA'].header
    data.coords = coordinates_from_header(hdulist[1].header)
    data.add_component(hdulist['DATA'].data, 'Flux')
    data.add_component(hdulist['VAR'].data, 'Uncertainty')

    return data
Exemple #8
0
def _load_fits_generic(filename, **kwargs):
    hdulist = fits.open(filename)
    groups = defaultdict(Data)
    for extnum, hdu in enumerate(hdulist):
        if not isinstance(hdu, fits.TableHDU) and\
           hdu.data is not None:
            shape = hdu.data.shape
            if shape not in groups:
                label = '{}[{}]'.format(
                    basename(filename).split('.', 1)[0],
                    'x'.join((str(x) for x in shape))
                )
                data = Data(label=label)
                data.coords = coordinates_from_header(hdu.header)
                groups[shape] = data
            else:
                data = groups[shape]
            data.add_component(component=hdu.data,
                               label=hdu.header.get('EXTNAME', 'EXT[{}]'.format(str(extnum))))
    return [data for data in groups.itervalues()]
    def to_glue(self, label="yt", data_collection=None):
        """
        Takes the data in the FITSImageData instance and exports it to
        Glue (http://www.glueviz.org) for interactive analysis. Optionally 
        add a *label*. If you are already within the Glue environment, you 
        can pass a *data_collection* object, otherwise Glue will be started.
        """
        from glue.core import DataCollection, Data
        from glue.core.coordinates import coordinates_from_header
        from glue.qt.glue_application import GlueApplication

        image = Data(label=label)
        image.coords = coordinates_from_header(self.wcs.to_header())
        for k,f in self.items():
            image.add_component(f.data, k)
        if data_collection is None:
            dc = DataCollection([image])
            app = GlueApplication(dc)
            app.start()
        else:
            data_collection.append(image)
Exemple #10
0
def nirspec_level2_reader(file_name):
    """
    Data Loader for level2 products.
    Uses extension information to index
    fits hdu list. The ext info is included
    in the file_name as follows: <file_path>[<ext>]
    """
    file_name, ext = split_file_name(file_name, default_ext=1)

    hdulist = fits.open(file_name)

    data = Data(label="2D Spectra")
    data.header = hdulist[ext].header
    data.coords = coordinates_from_header(hdulist[ext].header)
    data.add_component(hdulist[ext].data, 'Level2 Flux')

    # TODO: update uncertainty once data model becomes clear
    data.add_component(np.sqrt(hdulist[ext + 2].data), 'Level2 Uncertainty')

    hdulist.close()

    return data
Exemple #11
0
def gridded_data(filename, format='auto', **kwargs):

    result = Data()

    # Try and automatically find the format if not specified
    if format == 'auto':
        format = file_format(filename)

    # Read in the data
    if is_fits(filename):
        from astropy.io import fits
        arrays = extract_data_fits(filename, **kwargs)
        header = fits.getheader(filename)
        result.coords = coordinates_from_header(header)
    elif is_hdf5(filename):
        arrays = extract_data_hdf5(filename, **kwargs)
    else:
        raise Exception("Unkonwn format: %s" % format)

    for component_name in arrays:
        comp = Component.autotyped(arrays[component_name])
        result.add_component(comp, component_name)

    return result
Exemple #12
0
def casalike_cube(filename, **kwargs):
    """
    This provides special support for 4D CASA FITS - like cubes,
    which have 2 spatial axes, a spectral axis, and a stokes axis
    in that order.

    Each stokes cube is split out as a separate component
    """
    from astropy.io import fits

    result = Data()

    if 'ignore_missing_end' not in kwargs:
        kwargs['ignore_missing_end'] = True

    with fits.open(filename, mode='denywrite', **kwargs) as hdulist:
        array = hdulist[0].data
        header = hdulist[0].header
    result.coords = coordinates_from_header(header)
    for i in range(array.shape[0]):
        units = header.get('BUNIT')
        component = Component.autotyped(array[[i]], units=units)
        result.add_component(component, label='STOKES %i' % i)
    return result
Exemple #13
0
def _load_GALFAHI_data(filename, **kwargs):
    def _get_cube_center(header, cubeshape):
        ra  = header['CRVAL1'] + header['CDELT1'] * (np.arange(cubeshape[2])+0.5 - header['CRPIX1'])              ## degree
        dec = header['CRVAL2'] + header['CDELT2'] * (np.arange(cubeshape[1])+0.5 - header['CRPIX2'])            ## degree
        return np.mean(ra), np.mean(dec)

    # add the primary components
    cube = fits.getdata(filename)
    header = fits.getheader(filename)
    header['CDELT3'] = header['CDELT3'] * (10**(-3))        # m/s --> km/s
    cen_ra, cen_dec = _get_cube_center(header, cube.shape)
    nn = filename.split('/')[-1]
    # cube_name = '%s_RA%dDEC%d' % (nn[0:3], cen_ra, cen_dec)
    cube_name = 'G_%d%+.2fradec_%.1fkm/s_%.1fa' % (cen_ra, cen_dec, header['CDELT3'], header['CDELT2']*60.)

    data = Data()
    data.coords = coordinates_from_header(header)
    data.add_component(cube, cube_name)
    data.label  = cube_name

    data_list = []
    data_list.append(data)
    data_list.append(data)
    return data_list
Exemple #14
0
    def to_glue(self, label="yt", data_collection=None):
        """
        Takes the data in the FITSImageData instance and exports it to
        Glue (http://glueviz.org) for interactive analysis. Optionally 
        add a *label*. If you are already within the Glue environment, you 
        can pass a *data_collection* object, otherwise Glue will be started.
        """
        from glue.core import DataCollection, Data
        from glue.core.coordinates import coordinates_from_header
        try:
            from glue.app.qt.application import GlueApplication
        except ImportError:
            from glue.qt.glue_application import GlueApplication

        image = Data(label=label)
        image.coords = coordinates_from_header(self.wcs.to_header())
        for k in self.fields:
            image.add_component(self[k].data, k)
        if data_collection is None:
            dc = DataCollection([image])
            app = GlueApplication(dc)
            app.start()
        else:
            data_collection.append(image)
Exemple #15
0
def nirspec_spectrum2d_reader(file_name):
    """
    Data loader for simulated NIRSpec 2D spectrum.

    This function extracts the DATA, QUALITY, and VAR
    extensions and returns them as a glue Data object.

    It then uses the header keywords of the DATA extension
    to detemine the wavelengths.
    """

    file_name, ext = split_file_name(file_name, default_ext=1)

    hdulist = fits.open(file_name)

    data = Data(label="2D Spectrum")
    data.header = hdulist['PRIMARY'].header
    data.coords = coordinates_from_header(hdulist[ext].header)
    data.add_component(hdulist[ext].data, 'Flux')
    data.add_component(np.sqrt(hdulist[ext + 2].data), 'Uncertainty')

    hdulist.close()

    return data
Exemple #16
0
def nirspec_spectrum2d_reader(file_name):
    """
    Data loader for simulated NIRSpec 2D spectrum.

    This function extracts the DATA, QUALITY, and VAR
    extensions and returns them as a glue Data object.

    It then uses the header keywords of the DATA extension
    to detemine the wavelengths.
    """

    file_name, ext = split_file_name(file_name, default_ext=1)

    hdulist = fits.open(file_name)

    data = Data(label="2D Spectrum")
    data.header = hdulist['PRIMARY'].header
    data.coords = coordinates_from_header(hdulist[ext].header)
    data.add_component(hdulist[ext].data, 'Flux')
    data.add_component(np.sqrt(hdulist[ext + 2].data), 'Uncertainty')

    hdulist.close()

    return data
Exemple #17
0
    def to_glue(self, label="yt", data_collection=None):
        """
        Takes the data in the FITSImageBuffer and exports it to
        Glue (http://www.glueviz.org) for interactive
        analysis. Optionally add a *label*. If you are already within
        the Glue environment, you can pass a *data_collection* object,
        otherwise Glue will be started.
        """
        from glue.core import DataCollection, Data
        from glue.core.coordinates import coordinates_from_header
        from glue.qt.glue_application import GlueApplication

        field_dict = dict((key, self[key].data) for key in self.keys())

        image = Data(label=label)
        image.coords = coordinates_from_header(self.wcs.to_header())
        for k, v in field_dict.items():
            image.add_component(v, k)
        if data_collection is None:
            dc = DataCollection([image])
            app = GlueApplication(dc)
            app.start()
        else:
            data_collection.append(image)
Exemple #18
0
def casalike_cube(filename, **kwargs):
    """
    This provides special support for 4D CASA FITS - like cubes,
    which have 2 spatial axes, a spectral axis, and a stokes axis
    in that order.

    Each stokes cube is split out as a separate component
    """
    from astropy.io import fits

    result = Data()

    if 'ignore_missing_end' not in kwargs:
        kwargs['ignore_missing_end'] = True

    with fits.open(filename, **kwargs) as hdulist:
        array = hdulist[0].data
        header = hdulist[0].header
    result.coords = coordinates_from_header(header)
    for i in range(array.shape[0]):
        units = header.get('BUNIT')
        component = Component.autotyped(array[[i]], units=units)
        result.add_component(component, label='STOKES %i' % i)
    return result
Exemple #19
0
def fits_reader(source, auto_merge=False, exclude_exts=None, label=None):
    """
    Read in all extensions from a FITS file.

    Parameters
    ----------
    source: str or HDUList
        The pathname to the FITS file.
        If an HDUList is passed in, simply use that.

    auto_merge: bool
        Merge extensions that have the same shape
        and only one has a defined WCS.

    exclude_exts: [hdu, ] or [index, ]
        List of HDU's to exclude from reading.
        This can be a list of HDU's or a list
        of HDU indexes.
    """

    from astropy.io import fits
    from astropy.table import Table

    exclude_exts = exclude_exts or []
    if not isinstance(source, fits.hdu.hdulist.HDUList):
        hdulist = fits.open(source)
        hdulist.verify('fix')
    else:
        hdulist = source
    groups = OrderedDict()
    extension_by_shape = OrderedDict()

    if label is not None:

        label_base = label

    else:

        hdulist_name = hdulist.filename()
        if hdulist_name is None:
            hdulist_name = "HDUList"

        label_base = basename(hdulist_name).rpartition('.')[0]

        if not label_base:
            label_base = basename(hdulist_name)

    # Create a new image Data.
    def new_data():
        label = '{0}[{1}]'.format(label_base, hdu_name)
        data = Data(label=label)
        data.coords = coords
        groups[hdu_name] = data
        extension_by_shape[shape] = hdu_name
        return data

    for extnum, hdu in enumerate(hdulist):
        hdu_name = hdu.name if hdu.name else "HDU{0}".format(extnum)
        if (hdu.data is not None and hdu.data.size > 0
                and hdu_name not in exclude_exts
                and extnum not in exclude_exts):
            if is_image_hdu(hdu):
                shape = hdu.data.shape
                coords = coordinates_from_header(hdu.header)
                if not auto_merge or has_wcs(coords):
                    data = new_data()
                else:
                    try:
                        data = groups[extension_by_shape[shape]]
                    except KeyError:
                        data = new_data()
                data.add_component(component=hdu.data, label=hdu_name)
            elif is_table_hdu(hdu):
                # Loop through columns and make component list
                table = Table(hdu.data)
                label = '{0}[{1}]'.format(label_base, hdu_name)
                data = Data(label=label)
                groups[hdu_name] = data
                for column_name in table.columns:
                    column = table[column_name]
                    component = Component(column, units=column.unit)
                    data.add_component(component=component, label=column_name)
    return [groups[idx] for idx in groups]
Exemple #20
0
    def load_data(self, data_filenames):
        """
        Load the data based on the extensions defined in the matching YAML file.  THen
        create the datacube and return it.

        :param data_filename:
        :return:
        """

        label = None
        data = None

        ifucube = IFUCube()

        for data_filename in data_filenames.split(','):

            hdulist = ifucube.open(data_filename, fix=self._check_ifu_valid)

            # Good in this case means the file has 3D data and can be loaded by SpectralCube.read
            if self._check_ifu_valid and not ifucube.get_good():
                # Popup takes precedence and accepting continues operation and canceling closes the program
                self.popup_ui.ifucube_log.setText(ifucube.get_log_output())
                self.popup_ui.setModal(True)
                self.popup_ui.show()

                self.popup_ui.button_accept.clicked.connect(self._accept_button_click)
                self.popup_ui.button_cancel.clicked.connect(self._reject_button_click)

            if not label:
                label = "{}: {}".format(self._name, splitext(basename(data_filename))[0])
                data = Data(label=label)

                # this attribute is used to indicate to the cubeviz layout that
                # this is a cubeviz-specific data component.
                data.meta[CUBEVIZ_LAYOUT] = self._name

            data_coords_set = False
            for ii, hdu in enumerate(hdulist):
                if 'NAXIS' in hdu.header and hdu.header['NAXIS'] == 3:

                    # Set the coords based on the first 3D HDU
                    if not data_coords_set:
                        data.coords = coordinates_from_header(hdu.header)
                        data_coords_set = True

                    component_name = str(ii)
                    if 'EXTNAME' in hdu.header:
                        component_name = hdu.header['EXTNAME']

                        # The data must be floating point as spectralcube is expecting floating point data
                        data.add_component(component=hdu.data.astype(np.float), label=component_name)

                        if 'BUNIT' in hdu.header:
                            c = data.get_component(component_name)
                            c.units = self.get_units(hdu.header)
                    else:
                        # Creates a unique component name
                        component_name = str(ii)
                        data.add_component(component=hdu.data.astype(np.float), label=component_name)

            # For the purposes of exporting, we keep a reference to the original HDUList object
            data._cubeviz_hdulist = hdulist

        return data
Exemple #21
0
def fits_reader(source, auto_merge=False, exclude_exts=None, label=None):
    """
    Read in all extensions from a FITS file.

    Parameters
    ----------
    source: str or HDUList
        The pathname to the FITS file.
        If an HDUList is passed in, simply use that.

    auto_merge: bool
        Merge extensions that have the same shape
        and only one has a defined WCS.

    exclude_exts: [hdu, ] or [index, ]
        List of HDU's to exclude from reading.
        This can be a list of HDU's or a list
        of HDU indexes.
    """

    from astropy.io import fits
    from astropy.table import Table

    exclude_exts = exclude_exts or []

    if isinstance(source, fits.hdu.hdulist.HDUList):
        hdulist = source
        close_hdulist = False
    else:
        hdulist = fits.open(source, ignore_missing_end=True)
        hdulist.verify('fix')
        close_hdulist = True

    groups = OrderedDict()
    extension_by_shape = OrderedDict()

    if label is not None:

        label_base = label

    else:

        hdulist_name = hdulist.filename()
        if hdulist_name is None:
            hdulist_name = "HDUList"

        label_base = basename(hdulist_name).rpartition('.')[0]

        if not label_base:
            label_base = basename(hdulist_name)

    # Create a new image Data.
    def new_data(suffix=True):
        if suffix:
            label = '{0}[{1}]'.format(label_base, hdu_name)
        else:
            label = label_base
        data = Data(label=label)
        data.coords = coords

        # We need to be careful here because some header values are special
        # objects that we should convert to strings
        for key, value in hdu.header.items():
            if (key == 'COMMENT' or key == 'HISTORY'):
                if key not in data.meta:
                    data.meta[key] = [str(value)]
                else:
                    data.meta[key].append(str(value))
            elif isinstance(value, string_types) or isinstance(value, (int, float, bool)):
                data.meta[key] = value
            else:
                data.meta[key] = str(value)

        groups[hdu_name] = data
        extension_by_shape[shape] = hdu_name
        return data

    for extnum, hdu in enumerate(hdulist):
        hdu_name = hdu.name if hdu.name else "HDU{0}".format(extnum)
        if (hdu.data is not None and
                hdu.data.size > 0 and
                hdu_name not in exclude_exts and
                extnum not in exclude_exts):
            if is_image_hdu(hdu):
                shape = hdu.data.shape
                coords = coordinates_from_header(hdu.header)
                if not auto_merge or has_wcs(coords):
                    data = new_data(suffix=len(hdulist) > 1)
                else:
                    try:
                        data = groups[extension_by_shape[shape]]
                    except KeyError:
                        data = new_data(suffix=len(hdulist) > 1)
                data.add_component(component=hdu.data,
                                   label=hdu_name)
            elif is_table_hdu(hdu):
                # Loop through columns and make component list
                table = Table.read(hdu, format='fits')
                label = '{0}[{1}]'.format(label_base, hdu_name)
                data = Data(label=label)
                groups[hdu_name] = data
                for column_name in table.columns:
                    column = table[column_name]
                    if column.ndim != 1:
                        warnings.warn("Dropping column '{0}' since it is not 1-dimensional".format(column_name))
                        continue
                    component = Component.autotyped(column, units=column.unit)
                    data.add_component(component=component,
                                       label=column_name)

    if close_hdulist:
        hdulist.close()

    return [groups[idx] for idx in groups]
Exemple #22
0
def fits_reader(source, auto_merge=False, exclude_exts=None, label=None):
    """
    Read in all extensions from a FITS file.

    Parameters
    ----------
    source: str or HDUList
        The pathname to the FITS file.
        If an HDUList is passed in, simply use that.

    auto_merge: bool
        Merge extensions that have the same shape
        and only one has a defined WCS.

    exclude_exts: [hdu, ] or [index, ]
        List of HDU's to exclude from reading.
        This can be a list of HDU's or a list
        of HDU indexes.
    """

    from astropy.io import fits
    from astropy.table import Table

    exclude_exts = exclude_exts or []

    if isinstance(source, fits.hdu.hdulist.HDUList):
        hdulist = source
        close_hdulist = False
    else:
        hdulist = fits.open(source, ignore_missing_end=True)
        hdulist.verify('fix')
        close_hdulist = True

    groups = OrderedDict()
    extension_by_shape = OrderedDict()

    if label is not None:

        label_base = label

    else:

        hdulist_name = hdulist.filename()
        if hdulist_name is None:
            hdulist_name = "HDUList"

        label_base = basename(hdulist_name).rpartition('.')[0]

        if not label_base:
            label_base = basename(hdulist_name)

    # Create a new image Data.
    def new_data(suffix=True):
        if suffix:
            label = '{0}[{1}]'.format(label_base, hdu_name)
        else:
            label = label_base
        data = Data(label=label)
        data.coords = coords

        # We need to be careful here because some header values are special
        # objects that we should convert to strings
        for key, value in hdu.header.items():
            if (key == 'COMMENT' or key == 'HISTORY'):
                if key not in data.meta:
                    data.meta[key] = [str(value)]
                else:
                    data.meta[key].append(str(value))
            elif isinstance(value, string_types) or isinstance(value, (int, float, bool)):
                data.meta[key] = value
            else:
                data.meta[key] = str(value)

        groups[hdu_name] = data
        extension_by_shape[shape] = hdu_name
        return data

    for extnum, hdu in enumerate(hdulist):
        hdu_name = hdu.name if hdu.name else "HDU{0}".format(extnum)
        if (hdu.data is not None and
                hdu.data.size > 0 and
                hdu_name not in exclude_exts and
                extnum not in exclude_exts):
            if is_image_hdu(hdu):
                shape = hdu.data.shape
                coords = coordinates_from_header(hdu.header)
                units = hdu.header.get('BUNIT')
                if not auto_merge or has_wcs(coords):
                    data = new_data(suffix=len(hdulist) > 1)
                else:
                    try:
                        data = groups[extension_by_shape[shape]]
                    except KeyError:
                        data = new_data(suffix=len(hdulist) > 1)
                component = Component.autotyped(hdu.data, units=units)
                data.add_component(component=component,
                                   label=hdu_name)
            elif is_table_hdu(hdu):
                # Loop through columns and make component list
                table = Table.read(hdu, format='fits')
                label = '{0}[{1}]'.format(label_base, hdu_name)
                data = Data(label=label)
                groups[hdu_name] = data
                for column_name in table.columns:
                    column = table[column_name]
                    if column.ndim != 1:
                        warnings.warn("Dropping column '{0}' since it is not 1-dimensional".format(column_name))
                        continue
                    component = Component.autotyped(column, units=column.unit)
                    data.add_component(component=component,
                                       label=column_name)

    if close_hdulist:
        hdulist.close()

    return [groups[idx] for idx in groups]
Exemple #23
0
def fits_reader(source, auto_merge=False, exclude_exts=None, label=None):
    """
    Read in all extensions from a FITS file.

    Parameters
    ----------
    source: str or HDUList
        The pathname to the FITS file.
        If an HDUList is passed in, simply use that.

    auto_merge: bool
        Merge extensions that have the same shape
        and only one has a defined WCS.

    exclude_exts: [hdu, ] or [index, ]
        List of HDU's to exclude from reading.
        This can be a list of HDU's or a list
        of HDU indexes.
    """

    from astropy.io import fits
    from astropy.table import Table

    exclude_exts = exclude_exts or []
    if not isinstance(source, fits.hdu.hdulist.HDUList):
        hdulist = fits.open(source, ignore_missing_end=True)
        hdulist.verify('fix')
    else:
        hdulist = source
    groups = OrderedDict()
    extension_by_shape = OrderedDict()

    if label is not None:

        label_base = label

    else:

        hdulist_name = hdulist.filename()
        if hdulist_name is None:
            hdulist_name = "HDUList"

        label_base = basename(hdulist_name).rpartition('.')[0]

        if not label_base:
            label_base = basename(hdulist_name)

    # Create a new image Data.
    def new_data():
        label = '{0}[{1}]'.format(
            label_base,
            hdu_name
        )
        data = Data(label=label)
        data.coords = coords
        groups[hdu_name] = data
        extension_by_shape[shape] = hdu_name
        return data

    for extnum, hdu in enumerate(hdulist):
        hdu_name = hdu.name if hdu.name else "HDU{0}".format(extnum)
        if (hdu.data is not None and
                hdu.data.size > 0 and
                hdu_name not in exclude_exts and
                extnum not in exclude_exts):
            if is_image_hdu(hdu):
                shape = hdu.data.shape
                coords = coordinates_from_header(hdu.header)
                if not auto_merge or has_wcs(coords):
                    data = new_data()
                else:
                    try:
                        data = groups[extension_by_shape[shape]]
                    except KeyError:
                        data = new_data()
                data.add_component(component=hdu.data,
                                   label=hdu_name)
            elif is_table_hdu(hdu):
                # Loop through columns and make component list
                table = Table.read(hdu, format='fits')
                label = '{0}[{1}]'.format(
                    label_base,
                    hdu_name
                )
                data = Data(label=label)
                groups[hdu_name] = data
                for column_name in table.columns:
                    column = table[column_name]
                    if column.ndim != 1:
                        warnings.warn("Dropping column '{0}' since it is not 1-dimensional".format(column_name))
                        continue
                    component = Component.autotyped(column, units=column.unit)
                    data.add_component(component=component,
                                       label=column_name)
    return [groups[idx] for idx in groups]
Exemple #24
0
def _load_fits_generic(source, exclude_exts=None, **kwargs):
    """Read in all extensions from a FITS file.

    Parameters
    ----------
    source: str or HDUList
        The pathname to the FITS file.
        If and HDUList is passed in, simply use that.

    exclude_exts: [hdu, ] or [index, ]
        List of HDU's to exclude from reading.
        This can be a list of HDU's or a list
        of HDU indexes.
    """
    exclude_exts = exclude_exts or []
    if not isinstance(source, fits.hdu.hdulist.HDUList):
        hdulist = fits.open(source)
    else:
        hdulist = source
    groups = dict()
    label_base = basename(hdulist.filename()).rpartition('.')[0]

    if not label_base:
        label_base = basename(hdulist.filename())

    for extnum, hdu in enumerate(hdulist):
        hdu_name = hdu.name if hdu.name else str(extnum)
        if hdu.data is not None and \
           hdu_name not in exclude_exts and \
           extnum not in exclude_exts:
            if is_image_hdu(hdu):
                shape = hdu.data.shape
                try:
                    data = groups[shape]
                except KeyError:
                    label = '{}[{}]'.format(
                        label_base,
                        'x'.join(str(x) for x in shape)
                    )
                    data = Data(label=label)
                    data.coords = coordinates_from_header(hdu.header)
                    groups[shape] = data
                data.add_component(component=hdu.data,
                                   label=hdu_name)
            elif is_table_hdu(hdu):
                # Loop through columns and make component list
                table = Table(hdu.data)
                table_name = '{}[{}]'.format(
                    label_base,
                    hdu_name
                )
                for column_name in table.columns:
                    column = table[column_name]
                    shape = column.shape
                    data_label = '{}[{}]'.format(
                        table_name,
                        'x'.join(str(x) for x in shape)
                    )
                    try:
                        data = groups[data_label]
                    except KeyError:
                        data = Data(label=data_label)
                        groups[data_label] = data
                    component = Component(column, units=column.unit)
                    data.add_component(component=component,
                                       label=column_name)
    return [data for data in six.itervalues(groups)]
Exemple #25
0
    def load_data(self, data_filenames):
        """
        Load the data based on the extensions defined in the matching YAML file.  THen
        create the datacube and return it.

        :param data_filename:
        :return:
        """

        label = None
        data = None

        ifucube = IFUCube()

        for data_filename in data_filenames.split(','):

            hdulist = ifucube.open(data_filename, fix=self._check_ifu_valid)

            # Good in this case means the file has 3D data and can be loaded by SpectralCube.read
            if self._check_ifu_valid and not ifucube.get_good():
                # Popup takes precedence and accepting continues operation and canceling closes the program
                self.popup_ui.ifucube_log.setText(ifucube.get_log_output())
                self.popup_ui.setModal(True)
                self.popup_ui.show()

                self.popup_ui.button_accept.clicked.connect(
                    self._accept_button_click)
                self.popup_ui.button_cancel.clicked.connect(
                    self._reject_button_click)

            if not label:
                label = "{}: {}".format(self._name,
                                        splitext(basename(data_filename))[0])
                data = Data(label=label)

                # this attribute is used to indicate to the cubeviz layout that
                # this is a cubeviz-specific data component.
                data.meta[CUBEVIZ_LAYOUT] = self._name

            data_coords_set = False
            for ii, hdu in enumerate(hdulist):
                if 'NAXIS' in hdu.header and hdu.header['NAXIS'] == 3:

                    # Set the coords based on the first 3D HDU
                    if not data_coords_set:
                        data.coords = coordinates_from_header(hdu.header)
                        data_coords_set = True

                    component_name = str(ii)
                    if 'EXTNAME' in hdu.header:
                        component_name = hdu.header['EXTNAME']

                        # The data must be floating point as spectralcube is expecting floating point data
                        data.add_component(component=hdu.data.astype(np.float),
                                           label=component_name)

                        if 'BUNIT' in hdu.header:
                            c = data.get_component(component_name)
                            c.units = self.get_units(hdu.header)
                    else:
                        # Creates a unique component name
                        component_name = str(ii)
                        data.add_component(component=hdu.data.astype(np.float),
                                           label=component_name)

            # For the purposes of exporting, we keep a reference to the original HDUList object
            data._cubeviz_hdulist = hdulist

        return data