Esempio n. 1
0
    def getflat(self, chip, flat_file=None, flat_ext=None):
        """
        Method for retrieving a detector's flat field.

        Parameters
        ----------
        chip : int
            Chip number. Same as FITS ``EXTVER``.

        flat_file : str, None
            Flat field file name. If not specified, it will be determined
            automatically from image header.

        flat_ext : str, None
            Flat field extension name (same as FITS ``EXTNAME``). Specifies
            extension name containing flat field data.

        Returns
        -------
        flat : numpy.ndarray
            The flat-field array in the same shape as the input image.

        """
        # For the WFPC2 flat we need to invert
        # for use in Multidrizzle
        if flat_file is None:
            filename = fileutil.osfn(
                self._image["PRIMARY"].header[self.flatkey])
            if filename in WFPC2InputImage.flat_file_map:
                flat_file, mef_flat_ext = WFPC2InputImage.flat_file_map[
                    filename]
            else:
                h = fileutil.openImage(filename, mode='readonly', memmap=False)
                flat_file = h.filename()
                mef_flat_ext = h[0].header.get('FILETYPE', '')
                mef_flat_ext = h[1].header.get('EXTNAME', mef_flat_ext)
                h.close()
                WFPC2InputImage.flat_file_map[filename] = (flat_file,
                                                           mef_flat_ext)
            if flat_ext is None:
                flat_ext = mef_flat_ext

        elif flat_ext is None:
            h = fileutil.openImage(flat_file,
                                   mode='readonly',
                                   memmap=False,
                                   writefits=False)
            flat_ext = h[0].header.get('FILETYPE', '')
            flat_ext = h[1].header.get('EXTNAME', flat_ext)
            h.close()

        flat = 1.0 / super().getflat(chip, flat_file, flat_ext)
        return flat
Esempio n. 2
0
    def getHeaderHandle(self):
        """ Sets up the PyFITS image handle and Primary header
            as self.image_handle and self.header.

            When Pattern being used for output product, filename will be
            set to None and this returns None for header and image_handle.
        """

        _numsci = 0
        if self.name:
            _handle = fileutil.openImage(self.name,mode='readonly',memmap=self.pars['memmap'])
            _fname,_extn = fileutil.parseFilename(self.name)
            _hdr = _handle['PRIMARY'].header.copy()
            # Count number of SCI extensions
            for _fext in _handle:
                if 'extname' in _fext.header and _fext.header['extname'] == 'SCI':
                    _numsci += 1

            if _extn and _extn > 0:
                # Append correct extension/chip/group header to PRIMARY...
                for _card in fileutil.getExtn(_handle,_extn).header.ascard:
                    _hdr.ascard.append(_card)
        else:
            # Default to None
            _handle = None
            _hdr = None

        # Set attribute to point to these products
        self.image_handle = None
        self.header = _hdr
        self.nmembers = _numsci

        return _handle
Esempio n. 3
0
    def getdarkimg(self, chip):
        """
        Return an array representing the dark image for the detector.

        Returns
        -------
        dark: array
            Dark image array in the same shape as the input image with **units of cps**

        """
        sci_chip = self._image[self.scienceExt, chip]

        # First attempt to get the dark image specified by the "DARKFILE"
        # keyword in the primary keyword of the science data.
        try:
            filename = self.header["DARKFILE"]
            handle = fileutil.openImage(filename,
                                        mode='readonly',
                                        memmap=False)
            hdu = fileutil.getExtn(handle, extn="sci,1")
            darkobj = hdu.data[sci_chip.ltv2:sci_chip.size2,
                               sci_chip.ltv1:sci_chip.size1]

        # If the darkfile cannot be located, create the dark image from
        # what we know about the detector dark current and assume a
        # constant dark current for the whole image.
        except:
            darkobj = (
                np.ones(sci_chip.image_shape, dtype=sci_chip.image_dtype) *
                self.getdarkcurrent())
        return darkobj
Esempio n. 4
0
def isSupportedFilter(hdr):
    idc = hdr['idctab']
    idcname = fileutil.osfn(idc)
    filter1 = hdr['FILTNAM1']
    filter2 = hdr['FILTNAM2']

    try:
        idctab = fileutil.openImage(idcname)
    except:
        raise IOError

    if idctab[1].columns.names.count(
            'FILTER1') > 0 and idctab[1].columns.names.count('FILTER2') > 0:
        # 2 filter IDCTAB, all filter modes should be supported
        val = True
    else:
        # 1 filter IDCTAB, check to see whether it is a supported filter and
        # that input is not a 2 filter observation
        filters = idctab[1].data.field('FILTER')

        if filter1 not in filters or filter2.strip():
            val = False
        else:
            val = True

    idctab.close()

    return val
Esempio n. 5
0
    def getData(self,exten=None):
        """ Return just the data array from the specified extension
            fileutil is used instead of fits to account for non-
            FITS input images. openImage returns a fits object.
        """
        if exten.lower().find('sci') > -1:
            # For SCI extensions, the current file will have the data
            fname = self._filename
        else:
            # otherwise, the data being requested may need to come from a
            # separate file, as is the case with WFPC2 DQ data.
            #
            # convert exten to 'sci',extver to get the DQ info for that chip
            extn = exten.split(',')
            sci_chip = self._image[self.scienceExt,int(extn[1])]
            fname = sci_chip.dqfile

        extnum = self._interpretExten(exten)
        if self._image[extnum].data is None:
            if os.path.exists(fname):
                _image=fileutil.openImage(fname,clobber=False,memmap=0)
                _data=fileutil.getExtn(_image,extn=exten).data
                _image.close()
                del _image
                self._image[extnum].data = _data
            else:
                _data = None
        else:
            _data = self._image[extnum].data

        return _data
Esempio n. 6
0
    def getdarkimg(self,chip):
        """
        Return an array representing the dark image for the detector.

        Returns
        -------
        dark: array
            Dark image array in the same shape as the input image with **units of cps**

        """
        sci_chip = self._image[self.scienceExt,chip]

        # First attempt to get the dark image specified by the "DARKFILE"
        # keyword in the primary keyword of the science data.
        try:
            filename = self.header["DARKFILE"]
            handle = fileutil.openImage(filename, mode='readonly', memmap=False)
            hdu = fileutil.getExtn(handle,extn="sci,1")
            darkobj = hdu.data[sci_chip.ltv2:sci_chip.size2,sci_chip.ltv1:sci_chip.size1]

        # If the darkfile cannot be located, create the dark image from
        # what we know about the detector dark current and assume a
        # constant dark current for the whole image.
        except:
            darkobj = np.ones(sci_chip.image_shape,dtype=sci_chip.image_dtype)*self.getdarkcurrent()


        return darkobj
Esempio n. 7
0
def _addDefaultSkyKW(imageObjList):
    """Add MDRIZSKY keyword to "commanded" SCI headers of all input images,
        if that keyword does not already exist.
    """
    skyKW = "MDRIZSKY"
    Value = 0.0
    for imageSet in imageObjList:
        fname = imageSet._filename
        numchips = imageSet._numchips
        sciExt = imageSet.scienceExt
        fobj = fileutil.openImage(fname, mode='update', memmap=False)
        for chip in range(1, numchips + 1, 1):
            ext = (sciExt, chip)
            if not imageSet[ext].group_member:
                # skip over extensions not used in processing
                continue
            if skyKW not in fobj[ext].header:
                fobj[ext].header[skyKW] = (
                    Value, 'Sky value computed by AstroDrizzle')
                log.info(
                    "MDRIZSKY keyword not found in the %s[%s,%d] header." %
                    (fname, sciExt, chip))
                log.info(
                    "    Adding MDRIZSKY to header with default value of 0.")
        fobj.close()
Esempio n. 8
0
    def doUnitConversions(self):
        """Convert the data to electrons.

        This converts all science data extensions and saves
        the results back to disk. We need to make sure
        the data inside the chips already in memory is altered as well.

        """
         # Image information
        #_handle = fileutil.openImage(self._filename,mode='update',memmap=0)
        _handle = fileutil.openImage(self._filename,mode='readonly')

        for det in range(1,self._numchips+1,1):

            chip=self._image[self.scienceExt,det]
            if chip._gain != None:

                conversionFactor = chip._gain
                chip._effGain = chip._gain #1.
                chip._conversionFactor = conversionFactor #1.

            else:
                msg = "Invalid gain value for data, no conversion done"
                print(msg)
                raise ValueError(msg)

        # Close the files and clean-up
        _handle.close()

        self._effGain = conversionFactor # 1.0
Esempio n. 9
0
    def doUnitConversions(self):
        """Convert the data to electrons.

        This converts all science data extensions and saves
        the results back to disk. We need to make sure
        the data inside the chips already in memory is altered as well.

        """
        # Image information
        _handle = fileutil.openImage(self._filename,
                                     mode='readonly',
                                     memmap=False)

        for det in range(1, self._numchips + 1, 1):

            chip = self._image[self.scienceExt, det]
            if chip._gain is not None:

                conversionFactor = chip._gain
                chip._effGain = chip._gain  #1.
                chip._conversionFactor = conversionFactor  #1.

            else:
                msg = "Invalid gain value for data, no conversion done"
                print(msg)
                raise ValueError(msg)

        # Close the files and clean-up
        _handle.close()

        self._effGain = conversionFactor  # 1.0
Esempio n. 10
0
def fromcalfile(filename):
    """
    fromcalfile: function that returns a darkobject instance given the
    name of a cal.fits file as input.  If there is no TEMPFILE keyword
    in the primary header of the cal.fits file or if the file specified
    by TEMPFILE cannot be found, a None object is returned.
    """
    hdulist = fileutil.openImage(filename)

    if 'TEMPFILE' in hdulist[0].header:
        if tddfile == 'N/A':
            return None
        else:
            tddfile = hdulist[0].header['TEMPFILE']
            tddhdulist = fileutil.openImage(tddfile)
            return darkobject(tddhdulist)
    else:
        return None
Esempio n. 11
0
    def doUnitConversions(self):
        """Convert the data to electrons

        This converts all science data extensions and saves
        the results back to disk. We need to make sure
        the data inside the chips already in memory is altered as well.

        """

        # Image information
        _handle = fileutil.openImage(self._filename,
                                     mode='readonly',
                                     memmap=False)

        for det in range(1, self._numchips + 1, 1):

            chip = self._image[self.scienceExt, det]

            if chip._gain is not None:

                #conversionFactor = (self.getExpTime() * self.getGain())
                conversionFactor = chip._gain
                if self.isCountRate():
                    conversionFactor *= chip._exptime
                    counts_str = 'COUNTS/S'
                else:
                    counts_str = 'COUNTS'

                # Multiply the values of the sci extension pixels by the gain.
                print("Converting %s[%s,%d] from %s to ELECTRONS" %
                      (self._filename, self.scienceExt, det, counts_str))
                """
                # If the exptime is 0 the science image will be zeroed out.
                np.multiply(_handle[self.scienceExt,det].data,conversionFactor,_handle[self.scienceExt,det].data)
                #chip.data=_handle[self.scienceExt,det].data.copy()

                # Set the BUNIT keyword to 'electrons'
                chip.header.update('BUNIT','ELECTRONS')
                _handle[0].header.update('BUNIT','ELECTRONS')

                # Update the PHOTFLAM value
                photflam = _handle[0].header['PHOTFLAM']
                _handle[0].header.update('PHOTFLAM',(photflam/chip._gain))

                chip._effGain = 1.0
                """
                chip._effGain = chip._gain
                chip._conversionFactor = conversionFactor
            else:
                msg = "Invalid gain value for data, no conversion done"
                print(msg)
                raise ValueError(msg)

        # Close the files and clean-up
        _handle.close()

        self._effGain = conversionFactor  #1.0
Esempio n. 12
0
def fromcalfile(filename):
    """
    fromcalfile: function that returns a darkobject instance given the
    name of a cal.fits file as input.  If there is no TEMPFILE keyword
    in the primary header of the cal.fits file or if the file specified
    by TEMPFILE cannot be found, a None object is returned.
    """
    hdulist = openImage(filename)
    
    if 'TEMPFILE' in hdulist[0].header:
        if tddfile == 'N/A':
            return None
        else:
            tddfile = hdulist[0].header['TEMPFILE']
            tddhdulist = openImage(tddfile)
            return darkobject(tddhdulist)
    else:
        return None
Esempio n. 13
0
 def updateData(self,exten,data):
     """ Write out updated data and header to
         the original input file for this object.
     """
     _extnum=self._interpretExten(exten)
     fimg = fileutil.openImage(self._filename,mode='update')
     fimg[_extnum].data = data
     fimg[_extnum].header = self._image[_extnum].header
     fimg.close()
Esempio n. 14
0
 def getHeader(self,exten=None):
     """ Return just the specified header extension fileutil
         is used instead of fits to account for non-FITS
         input images. openImage returns a fits object.
     """
     _image=fileutil.openImage(self._filename,clobber=False,memmap=0)
     _header=fileutil.getExtn(_image,extn=exten).header
     _image.close()
     del _image
     return _header
Esempio n. 15
0
 def convert(file):
     newfilename = fileutil.buildNewRootname(file, extn='_c0h.fits')
     try:
         newimage = fileutil.openImage(file,writefits=True,
                                       fitsname=newfilename,clobber=True)
         del newimage
         return newfilename
     except IOError:
         print 'Warning: File %s could not be found' % file
         return None
Esempio n. 16
0
 def convert(file):
     newfilename = fileutil.buildFITSName(file)
     try:
         newimage = fileutil.openImage(file,writefits=True,
             fitsname=newfilename, clobber=True)
         del newimage
         return newfilename
     except IOError:
         print('Warning: File %s could not be found' % file)
         return None
Esempio n. 17
0
    def getflat(self, chip):
        """
        Method for retrieving a detector's flat field. For STIS there are three.
        This method will return an array the same shape as the image.

        """
        sci_chip = self._image[self.scienceExt, chip]
        exten = self.errExt + ',' + str(chip)

        # The keyword for STIS flat fields in the primary header of the flt

        lflatfile = fileutil.osfn(self._image["PRIMARY"].header['LFLTFILE'])
        pflatfile = fileutil.osfn(self._image["PRIMARY"].header['PFLTFILE'])

        # Try to open the file in the location specified by LFLTFILE.
        try:
            handle = fileutil.openImage(lflatfile,
                                        mode='readonly',
                                        memmap=False)
            hdu = fileutil.getExtn(handle, extn=exten)
            lfltdata = hdu.data
            if lfltdata.shape != self.full_shape:
                lfltdata = interp2d.expand2d(lfltdata, self.full_shape)
        except IOError:
            lfltdata = np.ones(self.full_shape, dtype=sci_chip.data.dtype)
            print("Cannot find file '{:s}'. Treating flatfield constant value "
                  "of '1'.\n".format(lflatfile))

        # Try to open the file in the location specified by PFLTFILE.
        try:
            handle = fileutil.openImage(pflatfile,
                                        mode='readonly',
                                        memmap=False)
            hdu = fileutil.getExtn(handle, extn=exten)
            pfltdata = hdu.data
        except IOError:
            pfltdata = np.ones(self.full_shape, dtype=sci_chip.data.dtype)
            print("Cannot find file '{:s}'. Treating flatfield constant value "
                  "of '1'.\n".format(pflatfile))

        flat = lfltdata * pfltdata

        return flat
Esempio n. 18
0
def update_wfpc2_d2geofile(filename, fhdu=None):
    """
    Creates a D2IMFILE from the DGEOFILE for a WFPC2 image (input), and
    modifies the header to reflect the new usage.

    Parameters
    ----------
    filename: string
        Name of WFPC2 file to be processed.  This file will be updated
        to delete any reference to a DGEOFILE and add a D2IMFILE to replace
        that correction when running updatewcs.
    fhdu: object
        FITS object for WFPC2 image.  If user has already opened the WFPC2
        file, they can simply pass that FITS object in for direct processing.

    Returns
    -------
    d2imfile: string
        Name of D2IMFILE created from DGEOFILE.  The D2IMFILE keyword in the
        image header will be updated/added to point to this newly created file.

    """
    if isinstance(filename, fits.HDUList):
        fhdu = filename
        filename = fhdu.filename()
        close_fhdu = False
    else:
        fhdu = fileutil.openImage(filename, mode='update')
        close_fhdu = True

    dgeofile = fhdu['PRIMARY'].header.get('DGEOFILE', None)
    already_converted = dgeofile not in [None, "N/A", "", " "]
    if already_converted or 'ODGEOFIL' in fhdu['PRIMARY'].header:
        if not already_converted:
            dgeofile = fhdu['PRIMARY'].header.get('ODGEOFIL', None)
        logger.info('Converting DGEOFILE %s into D2IMFILE...' % dgeofile)
        rootname = filename[:filename.find('.fits')]
        d2imfile = convert_dgeo_to_d2im(dgeofile, rootname)
        fhdu['PRIMARY'].header['ODGEOFIL'] = dgeofile
        fhdu['PRIMARY'].header['DGEOFILE'] = 'N/A'
        fhdu['PRIMARY'].header['D2IMFILE'] = d2imfile
    else:
        d2imfile = None
        fhdu['PRIMARY'].header['DGEOFILE'] = 'N/A'
        if 'D2IMFILE' not in fhdu['PRIMARY'].header:
            fhdu['PRIMARY'].header['D2IMFILE'] = 'N/A'

    # Only close the file handle if opened in this function
    if close_fhdu:
        fhdu.close()

    # return the d2imfile name so that calling routine can keep
    # track of the new file created and delete it later if necessary
    # (multidrizzle clean=True mode of operation)
    return d2imfile
Esempio n. 19
0
def update_wfpc2_d2geofile(filename, fhdu=None):
    """
    Creates a D2IMFILE from the DGEOFILE for a WFPC2 image (input), and
    modifies the header to reflect the new usage.

    Parameters
    ----------
    filename: string
        Name of WFPC2 file to be processed.  This file will be updated
        to delete any reference to a DGEOFILE and add a D2IMFILE to replace
        that correction when running updatewcs.
    fhdu: object
        FITS object for WFPC2 image.  If user has already opened the WFPC2
        file, they can simply pass that FITS object in for direct processing.

    Returns
    -------
    d2imfile: string
        Name of D2IMFILE created from DGEOFILE.  The D2IMFILE keyword in the
        image header will be updated/added to point to this newly created file.

    """
    if isinstance(filename, fits.HDUList):
        fhdu = filename
        filename = fhdu.filename()
        close_fhdu = False
    else:
        fhdu = fileutil.openImage(filename, mode='update')
        close_fhdu = True

    dgeofile = fhdu['PRIMARY'].header.get('DGEOFILE', None)
    already_converted = dgeofile not in [None, "N/A", "", " "]
    if already_converted or 'ODGEOFIL' in fhdu['PRIMARY'].header:
        if not already_converted:
            dgeofile = fhdu['PRIMARY'].header.get('ODGEOFIL', None)
        logger.info('Converting DGEOFILE %s into D2IMFILE...' % dgeofile)
        rootname = filename[:filename.find('.fits')]
        d2imfile = convert_dgeo_to_d2im(dgeofile, rootname)
        fhdu['PRIMARY'].header['ODGEOFIL'] = dgeofile
        fhdu['PRIMARY'].header['DGEOFILE'] = 'N/A'
        fhdu['PRIMARY'].header['D2IMFILE'] = d2imfile
    else:
        d2imfile = None
        fhdu['PRIMARY'].header['DGEOFILE'] = 'N/A'
        if 'D2IMFILE' not in fhdu['PRIMARY'].header:
            fhdu['PRIMARY'].header['D2IMFILE'] = 'N/A'

    # Only close the file handle if opened in this function
    if close_fhdu:
        fhdu.close()

    # return the d2imfile name so that calling routine can keep
    # track of the new file created and delete it later if necessary
    # (multidrizzle clean=True mode of operation)
    return d2imfile
Esempio n. 20
0
    def doUnitConversions(self):
        """Convert the data to electrons

        This converts all science data extensions and saves
        the results back to disk. We need to make sure
        the data inside the chips already in memory is altered as well.

        """

         # Image information
        #_handle = fileutil.openImage(self._filename,mode='update',memmap=0)
        _handle = fileutil.openImage(self._filename,mode='readonly')

        for det in range(1,self._numchips+1,1):

            chip=self._image[self.scienceExt,det]

            if chip._gain != None:

                #conversionFactor = (self.getExpTime() * self.getGain())
                conversionFactor = chip._gain
                if self.isCountRate():
                    conversionFactor *= chip._exptime
                    counts_str = 'COUNTS/S'
                else:
                    counts_str = 'COUNTS'

                # Multiply the values of the sci extension pixels by the gain.
                print("Converting %s[%s,%d] from %s to ELECTRONS"%(self._filename,self.scienceExt,det,counts_str))
                """
                # If the exptime is 0 the science image will be zeroed out.
                np.multiply(_handle[self.scienceExt,det].data,conversionFactor,_handle[self.scienceExt,det].data)
                #chip.data=_handle[self.scienceExt,det].data.copy()

                # Set the BUNIT keyword to 'electrons'
                chip.header.update('BUNIT','ELECTRONS')
                _handle[0].header.update('BUNIT','ELECTRONS')

                # Update the PHOTFLAM value
                photflam = _handle[0].header['PHOTFLAM']
                _handle[0].header.update('PHOTFLAM',(photflam/chip._gain))

                chip._effGain = 1.0
                """
                chip._effGain = chip._gain
                chip._conversionFactor = conversionFactor
            else:
                msg = "Invalid gain value for data, no conversion done"
                print(msg)
                raise ValueError(msg)

        # Close the files and clean-up
        _handle.close()

        self._effGain = conversionFactor #1.0
Esempio n. 21
0
def updateInputDQArray(dqfile,dq_extn,chip, crmaskname,cr_bits_value):
    if not isinstance(crmaskname, fits.HDUList) and not os.path.exists(crmaskname):
        log.warning('No CR mask file found! Input DQ array not updated.')
        return
    if cr_bits_value is None:
        log.warning('Input DQ array not updated!')
        return
    if isinstance(crmaskname, fits.HDUList):
        # in_memory case
        crmask = crmaskname
    else:
        crmask = fileutil.openImage(crmaskname, memmap=False)

    if os.path.exists(dqfile):
        fullext=dqfile+"["+dq_extn+str(chip)+"]"
        infile = fileutil.openImage(fullext, mode='update', memmap=False)
        __bitarray = np.logical_not(crmask[0].data).astype(np.int16) * cr_bits_value
        np.bitwise_or(infile[dq_extn,chip].data,__bitarray,infile[dq_extn,chip].data)
        infile.close()
        crmask.close()
Esempio n. 22
0
def get_data(filename):
    fileroot,extn = fileutil.parseFilename(filename)
    extname = fileutil.parseExtn(extn)
    if extname[0] == '': extname = "PRIMARY"
    if os.path.exists(fileroot):
        handle = fileutil.openImage(filename)
        data = handle[extname].data
        handle.close()
    else:
        data = None
    return data
Esempio n. 23
0
def updateInputDQArray(dqfile,dq_extn,chip, crmaskname,cr_bits_value):
    if not isinstance(crmaskname, fits.HDUList) and not os.path.exists(crmaskname):
        log.warning('No CR mask file found! Input DQ array not updated.')
        return
    if cr_bits_value == None:
        log.warning('Input DQ array not updated!')
        return
    if isinstance(crmaskname, fits.HDUList):
        # in_memory case
        crmask = crmaskname
    else:
        crmask = fileutil.openImage(crmaskname)

    if os.path.exists(dqfile):
        fullext=dqfile+"["+dq_extn+str(chip)+"]"
        infile = fileutil.openImage(fullext,mode='update')
        __bitarray = np.logical_not(crmask[0].data).astype(np.int16) * cr_bits_value
        np.bitwise_or(infile[dq_extn,chip].data,__bitarray,infile[dq_extn,chip].data)
        infile.close()
        crmask.close()
Esempio n. 24
0
def get_data(filename):
    fileroot, extn = fileutil.parseFilename(filename)
    extname = fileutil.parseExtn(extn)
    if extname[0] == '': extname = "PRIMARY"
    if os.path.exists(fileroot):
        handle = fileutil.openImage(filename, memmap=False)
        data = handle[extname].data
        handle.close()
    else:
        data = None
    return data
Esempio n. 25
0
    def getflat(self,chip):
        """
        Method for retrieving a detector's flat field. For STIS there are three.
        This method will return an array the same shape as the image.

        """
        sci_chip = self._image[self.scienceExt,chip]
        exten = self.errExt+','+str(chip)

        # The keyword for STIS flat fields in the primary header of the flt

        lflatfile = fileutil.osfn(self._image["PRIMARY"].header['LFLTFILE'])
        pflatfile = fileutil.osfn(self._image["PRIMARY"].header['PFLTFILE'])

        # Try to open the file in the location specified by LFLTFILE.
        try:
            handle = fileutil.openImage(lflatfile,mode='readonly',memmap=0)
            hdu = fileutil.getExtn(handle,extn=exten)
            lfltdata = hdu.data
            if lfltdata.shape != self.full_shape:
                lfltdata = interp2d.expand2d(lfltdata,self.full_shape)
        except:
            lfltdata = np.ones(self.full_shape,dtype=sci_chip.image_dtype)
            str = "Cannot find file "+filename+".  Treating flatfield constant value of '1'.\n"
            print(str)

        # Try to open the file in the location specified by PFLTFILE.
        try:
            handle = fileutil.openImage(pflatfile,mode='readonly',memmap=0)
            hdu = fileutil.getExtn(handle,extn=exten)
            pfltdata = hdu.data
        except:
            pfltdata = np.ones(self.image_shape,dtype=sci_chip.image_dtype)
            str = "Cannot find file "+filename+".  Treating flatfield constant value of '1'.\n"
            print(str)

        print("lfltdata shape: ",lfltdata.shape)
        print("pfltdata shape: ",pfltdata.shape)
        flat = lfltdata * pfltdata

        return flat
Esempio n. 26
0
 def convert(file):
     newfilename = fileutil.buildFITSName(file)
     try:
         newimage = fileutil.openImage(file,
                                       writefits=True,
                                       fitsname=newfilename,
                                       clobber=True)
         del newimage
         return newfilename
     except IOError:
         print('Warning: File %s could not be found' % file)
         return None
Esempio n. 27
0
def count_sci_extensions(filename):
    """ Return the number of SCI extensions and the EXTNAME from a input MEF file.
    """
    num_sci = 0
    extname = 'SCI'
    for extn in fileutil.openImage(filename):
        if 'extname' in extn.header and extn.header['extname'] == extname:
            num_sci += 1
    if num_sci == 0:
        extname = 'PRIMARY'
        num_sci = 1

    return num_sci, extname
Esempio n. 28
0
def get_numsci(image):
    """ Find the number of SCI extensions in the image.
        Input:
            image - name of single input image
    """
    handle = fileutil.openImage(image)
    num_sci = 0
    for extn in handle:
        if 'extname' in extn.header:
            if extn.header['extname'].lower() == 'sci':
                num_sci += 1
    handle.close()
    return num_sci
Esempio n. 29
0
    def doUnitConversions(self):
        """ Apply unit conversions to all the chips, ignoring the group parameter.
            This insures that all the chips get the same conversions when this
            gets done, even if only 1 chip was specified to be processed.
        """
        # Image information
        _handle = fileutil.openImage(self._filename,
                                     mode='readonly',
                                     memmap=False)

        # Now convert the SCI array(s) units
        for det in range(1, self._numchips + 1):

            chip = self._image[self.scienceExt, det]
            conversionFactor = 1.0
            # add D2IMFILE to outputNames for removal by 'clean()' method later
            if 'D2IMFILE' in _handle[0].header and _handle[0].header[
                    'D2IMFILE'] not in ["", "N/A"]:
                chip.outputNames['d2imfile'] = _handle[0].header['D2IMFILE']

            if chip._gain is not None:
                """
                # Multiply the values of the sci extension pixels by the gain.
                print "Converting %s[%d] from COUNTS to ELECTRONS"%(self._filename,det)

                # If the exptime is 0 the science image will be zeroed out.
                np.multiply(_handle[self.scienceExt,det].data,chip._gain,_handle[self.scienceExt,det].data)
                chip.data=_handle[self.scienceExt,det].data

                # Set the BUNIT keyword to 'electrons'
                chip._bunit = 'ELECTRONS'
                chip.header.update('BUNIT','ELECTRONS')
                _handle[self.scienceExt,det].header.update('BUNIT','ELECTRONS')

                # Update the PHOTFLAM value
                photflam = _handle[self.scienceExt,det].header['PHOTFLAM']
                _handle[self.scienceExt,det].header.update('PHOTFLAM',(photflam/chip._gain))
                """
                conversionFactor = chip._gain
                chip._effGain = chip._gain  #1.
                chip._conversionFactor = conversionFactor  #1.

            else:
                msg = "Invalid gain value for data, no conversion done"
                print(msg)
                raise ValueError(msg)

        # Close the files and clean-up
        _handle.close()

        self._effGain = conversionFactor  # 1.
Esempio n. 30
0
def convert_dgeo_to_d2im(dgeofile, output, clobber=True):
    """ Routine that converts the WFPC2 DGEOFILE into a D2IMFILE.
    """
    dgeo = fileutil.openImage(dgeofile)
    outname = output + '_d2im.fits'

    removeFileSafely(outname)
    data = np.array([dgeo['dy', 1].data[:, 0]])
    scihdu = fits.ImageHDU(data=data)
    dgeo.close()
    # add required keywords for D2IM header
    scihdu.header['EXTNAME'] = ('DY', 'Extension name')
    scihdu.header['EXTVER'] = (1, 'Extension version')
    fits_str = 'PYFITS Version ' + str(astropy.__version__)
    scihdu.header['ORIGIN'] = (fits_str, 'FITS file originator')
    scihdu.header['INHERIT'] = (False, 'Inherits global header')

    dnow = datetime.datetime.now()
    scihdu.header['DATE'] = (str(dnow).replace(' ', 'T'),
                             'Date FITS file was generated')

    scihdu.header['CRPIX1'] = (0, 'Distortion array reference pixel')
    scihdu.header['CDELT1'] = (1, 'Grid step size in first coordinate')
    scihdu.header['CRVAL1'] = (0, 'Image array pixel coordinate')
    scihdu.header['CRPIX2'] = (0, 'Distortion array reference pixel')
    scihdu.header['CDELT2'] = (1, 'Grid step size in second coordinate')
    scihdu.header['CRVAL2'] = (0, 'Image array pixel coordinate')

    phdu = fits.PrimaryHDU()
    phdu.header['INSTRUME'] = 'WFPC2'
    d2imhdu = fits.HDUList()
    d2imhdu.append(phdu)
    scihdu.header['DETECTOR'] = (1,
                                 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    scihdu.header['EXTVER'] = (2, 'Extension version')
    scihdu.header['DETECTOR'] = (2,
                                 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    scihdu.header['EXTVER'] = (3, 'Extension version')
    scihdu.header['DETECTOR'] = (3,
                                 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    scihdu.header['EXTVER'] = (4, 'Extension version')
    scihdu.header['DETECTOR'] = (4,
                                 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    d2imhdu.writeto(outname)
    d2imhdu.close()

    return outname
Esempio n. 31
0
    def getflat(self, chip):
        """
        Method for retrieving a detector's flat field.

        Returns
        -------
        flat: array
            This method will return an array the same shape as the image in
            **units of electrons**.

        """
        sci_chip = self._image[self.scienceExt, chip]
        # The keyword for ACS flat fields in the primary header of the flt
        # file is pfltfile.  This flat file is already in the required
        # units of electrons.

        # The use of fileutil.osfn interprets any environment variable, such as
        # jref$, used in the specification of the reference filename
        filename = fileutil.osfn(self._image["PRIMARY"].header[self.flatkey])
        hdulist = None
        try:
            hdulist = fileutil.openImage(filename,
                                         mode='readonly',
                                         memmap=False)
            data = hdulist[(self.scienceExt, chip)].data

            if data.shape[0] != sci_chip.image_shape[0]:
                ltv2 = int(np.round(sci_chip.ltv2))
            else:
                ltv2 = 0
            size2 = sci_chip.image_shape[0] + ltv2

            if data.shape[1] != sci_chip.image_shape[1]:
                ltv1 = int(np.round(sci_chip.ltv1))
            else:
                ltv1 = 0
            size1 = sci_chip.image_shape[1] + ltv1

            flat = data[ltv2:size2, ltv1:size1]

        except FileNotFoundError:
            flat = np.ones(sci_chip.image_shape, dtype=sci_chip.image_dtype)
            log.warning("Cannot find flat field file '{}'".format(filename))
            log.warning("Treating flatfield as a constant value of '1'.")

        finally:
            if hdulist is not None:
                hdulist.close()

        return flat
Esempio n. 32
0
def _updateKW(image, filename, exten, skyKW, Value):
    """update the header with the kw,value"""
    # Update the value in memory
    image.header[skyKW] = Value

    # Now update the value on disk
    if isinstance(exten,tuple):
        strexten = '[%s,%s]'%(exten[0],str(exten[1]))
    else:
        strexten = '[%s]'%(exten)
    log.info('Updating keyword %s in %s' % (skyKW, filename + strexten))
    fobj = fileutil.openImage(filename, mode='update')
    fobj[exten].header[skyKW] = (Value, 'Sky value computed by AstroDrizzle')
    fobj.close()
Esempio n. 33
0
def _updateKW(image, filename, exten, skyKW, Value):
    """update the header with the kw,value"""
    # Update the value in memory
    image.header[skyKW] = Value

    # Now update the value on disk
    if isinstance(exten, tuple):
        strexten = '[%s,%s]' % (exten[0], str(exten[1]))
    else:
        strexten = '[%s]' % (exten)
    log.info('Updating keyword %s in %s' % (skyKW, filename + strexten))
    fobj = fileutil.openImage(filename, mode='update', memmap=False)
    fobj[exten].header[skyKW] = (Value, 'Sky value computed by AstroDrizzle')
    fobj.close()
Esempio n. 34
0
    def getflat(self, chip):
        """
        Method for retrieving a detector's flat field.

        Returns
        -------
        flat: array
            This method will return an array the same shape as the image in
            **units of electrons**.

        """
        sci_chip = self._image[self.scienceExt, chip]
        # The keyword for ACS flat fields in the primary header of the flt
        # file is pfltfile.  This flat file is already in the required
        # units of electrons.

        # The use of fileutil.osfn interprets any environment variable, such as
        # jref$, used in the specification of the reference filename
        filename = fileutil.osfn(self._image["PRIMARY"].header[self.flatkey])
        hdulist = None
        try:
            hdulist = fileutil.openImage(filename, mode='readonly',
                                         memmap=False)
            data = hdulist[(self.scienceExt, chip)].data

            if data.shape[0] != sci_chip.image_shape[0]:
                ltv2 = int(np.round(sci_chip.ltv2))
            else:
                ltv2 = 0
            size2 = sci_chip.image_shape[0] + ltv2

            if data.shape[1] != sci_chip.image_shape[1]:
                ltv1 = int(np.round(sci_chip.ltv1))
            else:
                ltv1 = 0
            size1 = sci_chip.image_shape[1] + ltv1

            flat = data[ltv2:size2, ltv1:size1]

        except FileNotFoundError:
            flat = np.ones(sci_chip.image_shape, dtype=sci_chip.image_dtype)
            log.warning("Cannot find flat field file '{}'".format(filename))
            log.warning("Treating flatfield as a constant value of '1'.")

        finally:
            if hdulist is not None:
                hdulist.close()

        return flat
Esempio n. 35
0
    def doUnitConversions(self):
        """ Apply unit conversions to all the chips, ignoring the group parameter.
            This insures that all the chips get the same conversions when this
            gets done, even if only 1 chip was specified to be processed.
        """
         # Image information
        #_handle = fileutil.openImage(self._filename,mode='update',memmap=0)
        _handle = fileutil.openImage(self._filename,mode='readonly')

        # Now convert the SCI array(s) units
        for det in range(1,self._numchips+1):

            chip=self._image[self.scienceExt,det]
            conversionFactor = 1.0
            # add D2IMFILE to outputNames for removal by 'clean()' method later
            if 'D2IMFILE' in _handle[0].header and _handle[0].header['D2IMFILE'] not in ["","N/A"]:
                chip.outputNames['d2imfile'] = _handle[0].header['D2IMFILE']

            if chip._gain != None:
                """
                # Multiply the values of the sci extension pixels by the gain.
                print "Converting %s[%d] from COUNTS to ELECTRONS"%(self._filename,det)

                # If the exptime is 0 the science image will be zeroed out.
                np.multiply(_handle[self.scienceExt,det].data,chip._gain,_handle[self.scienceExt,det].data)
                chip.data=_handle[self.scienceExt,det].data

                # Set the BUNIT keyword to 'electrons'
                chip._bunit = 'ELECTRONS'
                chip.header.update('BUNIT','ELECTRONS')
                _handle[self.scienceExt,det].header.update('BUNIT','ELECTRONS')

                # Update the PHOTFLAM value
                photflam = _handle[self.scienceExt,det].header['PHOTFLAM']
                _handle[self.scienceExt,det].header.update('PHOTFLAM',(photflam/chip._gain))
                """
                conversionFactor = chip._gain
                chip._effGain = chip._gain #1.
                chip._conversionFactor = conversionFactor #1.

            else:
                msg = "Invalid gain value for data, no conversion done"
                print(msg)
                raise ValueError(msg)

        # Close the files and clean-up
        _handle.close()

        self._effGain = conversionFactor # 1.
Esempio n. 36
0
    def buildIVMmask(self,chip,dqarr,scale):
        """ Builds a weight mask from an input DQ array and either an IVM array
        provided by the user or a self-generated IVM array derived from the
        flat-field reference file associated with the input image.
        """
        sci_chip = self._image[self.scienceExt,chip]
        ivmname = self.outputNames['ivmFile']

        if ivmname != None:
            log.info("Applying user supplied IVM files for chip %s" % chip)
            #Parse the input file name to get the extension we are working on
            extn = "IVM,{}".format(chip)

            #Open the mask image for updating and the IVM image
            ivm =  fileutil.openImage(ivmname, mode='readonly')
            ivmfile = fileutil.getExtn(ivm, extn)

            # Multiply the IVM file by the input mask in place.
            ivmarr = ivmfile.data * dqarr

            ivm.close()

        else:

            log.info("Automatically creating IVM files for chip %s" % chip)
            # If no IVM files were provided by the user we will
            # need to automatically generate them based upon
            # instrument specific information.

            flat = self.getflat(chip)
            RN = self.getReadNoiseImage(chip)
            darkimg = self.getdarkimg(chip)
            skyimg = self.getskyimg(chip)

            #exptime = self.getexptimeimg(chip)
            #exptime = sci_chip._exptime
            #ivm = (flat*exptime)**2/(darkimg+(skyimg*flat)+RN**2)
            ivm = (flat)**2/(darkimg+(skyimg*flat)+RN**2)

           # Multiply the IVM file by the input mask in place.
            ivmarr = ivm * dqarr

        # Update 'wt_scl' parameter to match use of IVM file
        sci_chip._wtscl = pow(sci_chip._exptime,2)/pow(scale,4)
        #sci_chip._wtscl = 1.0/pow(scale,4)

        return ivmarr.astype(np.float32)
Esempio n. 37
0
def convert_dgeo_to_d2im(dgeofile, output, clobber=True):
    """ Routine that converts the WFPC2 DGEOFILE into a D2IMFILE.
    """
    dgeo = fileutil.openImage(dgeofile)
    outname = output + '_d2im.fits'

    removeFileSafely(outname)
    data = np.array([dgeo['dy', 1].data[:, 0]])
    scihdu = fits.ImageHDU(data=data)
    dgeo.close()
    # add required keywords for D2IM header
    scihdu.header['EXTNAME'] = ('DY', 'Extension name')
    scihdu.header['EXTVER'] = (1, 'Extension version')
    fits_str = 'PYFITS Version ' + str(astropy.__version__)
    scihdu.header['ORIGIN'] = (fits_str, 'FITS file originator')
    scihdu.header['INHERIT'] = (False, 'Inherits global header')

    dnow = datetime.datetime.now()
    scihdu.header['DATE'] = (str(dnow).replace(' ', 'T'),
                             'Date FITS file was generated')

    scihdu.header['CRPIX1'] = (0, 'Distortion array reference pixel')
    scihdu.header['CDELT1'] = (1, 'Grid step size in first coordinate')
    scihdu.header['CRVAL1'] = (0, 'Image array pixel coordinate')
    scihdu.header['CRPIX2'] = (0, 'Distortion array reference pixel')
    scihdu.header['CDELT2'] = (1, 'Grid step size in second coordinate')
    scihdu.header['CRVAL2'] = (0, 'Image array pixel coordinate')

    phdu = fits.PrimaryHDU()
    phdu.header['INSTRUME'] = 'WFPC2'
    d2imhdu = fits.HDUList()
    d2imhdu.append(phdu)
    scihdu.header['DETECTOR'] = (1, 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    scihdu.header['EXTVER'] = (2, 'Extension version')
    scihdu.header['DETECTOR'] = (2, 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    scihdu.header['EXTVER'] = (3, 'Extension version')
    scihdu.header['DETECTOR'] = (3, 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    scihdu.header['EXTVER'] = (4, 'Extension version')
    scihdu.header['DETECTOR'] = (4, 'CCD number of the detector: PC 1, WFC 2-4 ')
    d2imhdu.append(scihdu.copy())
    d2imhdu.writeto(outname)
    d2imhdu.close()

    return outname
Esempio n. 38
0
def convertImageToSFITS(fname):
    """ Convert the input filename (possibly with
        extensions already specified) into a separate
        simple FITS file for each SCI extension.
        
        If fname refers to a simple FITS file already,
        list will only contain fname. 
    """
    flist = []

    # Extract any extension specifications
    rootname, extn = fileutil.parseFilename(fname)
    if extn == None:
        # Check to see if file is multi-extension
        fimg = fileutil.openImage(fname)
        if len(fimg) > 1:
            # We have multiextension FITS, so write out
            # each SCI extension as a separate simple
            # FITS file.
            for hdu in fimg:
                if 'extname' in hdu.header and hdu.header['extname'] == 'SCI':
                    extname = hdu.header['extname'].lower() + str(
                        hdu.header['extver'])
                    new_fname = rootname[:rootname.rfind(
                        '.fits')] + '_extract_' + extname + '.fits'
                    removeFile(new_fname)
                    flist.append([new_fname, fname])
                    phdu = pyfits.PrimaryHDU(header=hdu.header, data=hdu.data)
                    phdu.writeto(new_fname)
                    del phdu
        else:
            # We already have a simple FITS, just record its name
            flist.append([None, fname])
        fimg.close()
        del fimg
    else:
        # We have an image with a SCI extension specified
        split_extn = extn.split(',')
        extname = str(split_extn[0]) + str(split_extn[1])
        new_fname = rootname[:rootname.
                             rfind('.fits')] + '_extract_' + extname + '.fits'
        removeFile(new_fname)
        iraf.imcopy(fname, new_fname, verbose=no)
        flist.append([new_fname, fname])

    return flist
Esempio n. 39
0
    def getflat(self, chip):
        """
        Method for retrieving a detector's flat field.

        Returns
        -------
        flat: array
            This method will return an array the same shape as the image in
            **units of electrons**.

        """

        sci_chip = self._image[self.scienceExt, chip]
        exten = '%s,%d' % (self.scienceExt, chip)
        # The keyword for ACS flat fields in the primary header of the flt
        # file is pfltfile.  This flat file is already in the required
        # units of electrons.

        # The use of fileutil.osfn interprets any environment variable, such as jref$,
        # used in the specification of the reference filename
        filename = fileutil.osfn(self._image["PRIMARY"].header[self.flatkey])

        try:
            handle = fileutil.openImage(filename,
                                        mode='readonly',
                                        memmap=False)
            hdu = fileutil.getExtn(handle, extn=exten)
            if hdu.data.shape[0] != sci_chip.image_shape[0]:
                _ltv2 = np.round(sci_chip.ltv2)
            else:
                _ltv2 = 0
            _size2 = sci_chip.image_shape[0] + _ltv2
            if hdu.data.shape[1] != sci_chip.image_shape[1]:
                _ltv1 = np.round(sci_chip.ltv1)
            else:
                _ltv1 = 0
            _size1 = sci_chip.image_shape[1] + _ltv1

            data = hdu.data[_ltv2:_size2, _ltv1:_size1]
            handle.close()
        except:
            data = np.ones(sci_chip.image_shape, dtype=sci_chip.image_dtype)
            log.warning("Cannot find file %s.\n    Treating flatfield "
                        "constant value of '1'." % filename)
        flat = data
        return flat
Esempio n. 40
0
    def getflat(self, chip):
        """
        Method for retrieving a detector's flat field.

        Returns
        -------
        flat: array
            This method will return an array the same shape as the image in
            **units of electrons**.

        """

        sci_chip = self._image[self.scienceExt, chip]
        exten = '%s,%d' % (self.scienceExt, chip)
        # The keyword for ACS flat fields in the primary header of the flt
        # file is pfltfile.  This flat file is already in the required
        # units of electrons.

        # The use of fileutil.osfn interprets any environment variable, such as jref$,
        # used in the specification of the reference filename
        filename = fileutil.osfn(self._image["PRIMARY"].header[self.flatkey])

        try:
            handle = fileutil.openImage(filename, mode='readonly', memmap=0)
            hdu = fileutil.getExtn(handle,extn=exten)
            if hdu.data.shape[0] != sci_chip.image_shape[0]:
                _ltv2 = np.round(sci_chip.ltv2)
            else:
                _ltv2 = 0
            _size2 = sci_chip.image_shape[0]+_ltv2
            if hdu.data.shape[1] != sci_chip.image_shape[1]:
                _ltv1 = np.round(sci_chip.ltv1)
            else:
                _ltv1 = 0
            _size1 = sci_chip.image_shape[1]+_ltv1

            data = hdu.data[_ltv2:_size2, _ltv1:_size1]
            handle.close()
        except:
            data = np.ones(sci_chip.image_shape, dtype=sci_chip.image_dtype)
            log.warning("Cannot find file %s.\n    Treating flatfield "
                        "constant value of '1'." % filename)
        flat = data
        return flat
Esempio n. 41
0
    def getDGEOArrays(self):
        """ Return numpy objects for the distortion correction
            image arrays.

            If no DGEOFILE is specified, it will return
            empty 2x2 arrays.
        """

        # Instantiate array objects for distortion correction image arrays
        if self.xgeoim == '':
            # No distortion image specified.
            # Defaulting to empty 2x2 array.
            xgdim = ygdim = 2
            _pxg = np.zeros((ygdim,xgdim),dtype=np.float32)
            _pyg = np.zeros((ygdim,xgdim),dtype=np.float32)
        else:
            # Open distortion correction FITS file
            _xgfile = fileutil.openImage(self.xgeoim)
            #_xgfile.info()

            # Access the extensions which correspond to this Exposure
            _xgname,_xgext = fileutil.parseFilename(self.xgeoim)
            _ygname,_ygext = fileutil.parseFilename(self.ygeoim)

            _pxgext = fileutil.getExtn(_xgfile,extn=_xgext)
            _pygext = fileutil.getExtn(_xgfile,extn=_ygext)

            # Copy out the numpy objects for output
            _ltv1 = int(self.geometry.wcs.offset_x)
            _ltv2 = int(self.geometry.wcs.offset_y)
            if _ltv1 != 0. or _ltv2 != 0.:
                # subarray section only
                _pxg = _pxgext.data[_ltv2:_ltv2+self.naxis2,_ltv1:_ltv1+self.naxis1].copy()
                _pyg = _pygext.data[_ltv2:_ltv2+self.naxis2,_ltv1:_ltv1+self.naxis1].copy()
            else:
                # full array
                _pxg = _pxgext.data.copy()
                _pyg = _pygext.data.copy()

            # Close file handles now...
            _xgfile.close()
            del _xgfile

        return _pxg,_pyg
Esempio n. 42
0
def count_sci_extensions(filename):
    """ Return the number of SCI extensions and the EXTNAME from a input MEF file.
    """
    num_sci = 0
    extname = 'SCI'

    hdu_list = fileutil.openImage(filename, memmap=False)

    for extn in hdu_list:
        if 'extname' in extn.header and extn.header['extname'] == extname:
            num_sci += 1

    if num_sci == 0:
        extname = 'PRIMARY'
        num_sci = 1

    hdu_list.close()

    return num_sci, extname
Esempio n. 43
0
def count_sci_extensions(filename):
    """ Return the number of SCI extensions and the EXTNAME from a input MEF file.
    """
    num_sci = 0
    extname = 'SCI'

    hdu_list = fileutil.openImage(filename, memmap=False)

    for extn in hdu_list:
        if 'extname' in extn.header and extn.header['extname'] == extname:
            num_sci += 1

    if num_sci == 0:
        extname = 'PRIMARY'
        num_sci = 1

    hdu_list.close()

    return num_sci,extname
Esempio n. 44
0
    def doUnitConversions(self):
        """WF3 IR data come out in electrons, and I imagine  the
         photometry keywords will be calculated as such, so no image
         manipulation needs be done between native and electrons """
         # Image information
        _handle = fileutil.openImage(self._filename, mode='readonly', memmap=False)

        for chip in self.returnAllChips(extname=self.scienceExt):
            conversionFactor = 1.0
            if '/S' in chip._bunit:
                conversionFactor = chip._exptime
            else:
                print("Input %s[%s,%d] already in units of ELECTRONS"
                      %(self._filename,self.scienceExt,chip._chip))

            chip._effGain = 1.0# chip._gain #1.
            chip._conversionFactor = conversionFactor #1.

        _handle.close()
        self._effGain= 1.0 #conversionFactor #1.0
Esempio n. 45
0
def mergeDQarray(maskname, dqarr):
    """ Merge static or CR mask with mask created from DQ array on-the-fly here.
    """
    maskarr = None
    if maskname is not None:
        if isinstance(maskname, str):
            # working with file on disk (default case)
            if os.path.exists(maskname):
                mask = fileutil.openImage(maskname, memmap=False)
                maskarr = mask[0].data.astype(bool)
                mask.close()
        else:
            if isinstance(maskname, fits.HDUList):
                # working with a virtual input file
                maskarr = maskname[0].data.astype(bool)
            else:
                maskarr = maskname.data.astype(bool)

        if maskarr is not None:
            # merge array with dqarr now
            np.bitwise_and(dqarr, maskarr, dqarr)
Esempio n. 46
0
def getNrefchip(image,instrument='WFPC2'):
    """
    This handles the fact that WFPC2 subarray observations
    may not include chip 3 which is the default reference chip for
    full observations. Also for subarrays chip 3  may not be the third
    extension in a MEF file. It is a kludge but this whole module is
    one big kludge. ND
    """
    hdu = fileutil.openImage(image)
    if instrument == 'WFPC2':
        detectors = [img.header['DETECTOR'] for img in hdu[1:]]

    if 3 not in detectors:
        Nrefchip=detectors[0]
        Nrefext = 1
    else:
        Nrefchip = 3
        Nrefext = detectors.index(3) + 1

    hdu.close()
    return Nrefchip, Nrefext
Esempio n. 47
0
def mergeDQarray(maskname,dqarr):
    """ Merge static or CR mask with mask created from DQ array on-the-fly here.
    """
    maskarr = None
    if maskname is not None:
        if isinstance(maskname, str):
            # working with file on disk (default case)
            if os.path.exists(maskname):
                mask = fileutil.openImage(maskname)
                maskarr = mask[0].data.astype(np.bool)
                mask.close()
        else:
            if isinstance(maskname, fits.HDUList):
                # working with a virtual input file
                maskarr = maskname[0].data.astype(np.bool)
            else:
                maskarr = maskname.data.astype(np.bool)

        if maskarr is not None:
            # merge array with dqarr now
            np.bitwise_and(dqarr,maskarr,dqarr)
Esempio n. 48
0
    def doUnitConversions(self):
        """WF3 IR data come out in electrons, and I imagine  the
         photometry keywords will be calculated as such, so no image
         manipulation needs be done between native and electrons """
         # Image information
        _handle = fileutil.openImage(self._filename, mode='readonly', memmap=False)

        for chip in self.returnAllChips(extname=self.scienceExt):
            conversionFactor = 1.0
            if '/S' in chip._bunit:
                conversionFactor = chip._exptime
            else:
                print("Input %s[%s,%d] already in units of ELECTRONS"
                      %(self._filename,self.scienceExt,chip._chip))

            chip._effGain = 1.0# chip._gain #1.
            chip._conversionFactor = conversionFactor #1.

        _handle.close()

        self._effGain= 1.0 #conversionFactor #1.0
Esempio n. 49
0
    def getDGEOExtn(self):
        """ Builds filename with extension to access distortion
            correction image extension appropriate to each chip.
        """
        # If no DGEOFILE has been given, then simply return blanks
        # and 'drizzle' will not use any.
        if not self.dgeoname or self.dgeoname == 'N/A':
            return '',''

        # Open file for introspection.
        fimg = fileutil.openImage(self.dgeoname)
        dx_extver = None
        dy_extver = None
        # Find which extensions match this chip ID
        # We need to identify both a DX and DY EXTNAME extension
        for hdu in fimg:
            hdr = hdu.header
            if 'CCDCHIP' not in hdr:
                _chip = 1
            else:
                _chip = int(hdr['CCDCHIP'])

            if 'EXTNAME' in hdr:
                _extname = hdr['EXTNAME'].lower()

                if _chip == int(self.chip):
                    if _extname == 'dx':
                        dx_extver = hdr['EXTVER']

                    if _extname == 'dy':
                        dy_extver = hdr['EXTVER']

        fimg.close()
        del fimg

        # Set the name for each extension here...
        _dxgeo = self.dgeoname+'[DX,'+str(dx_extver)+']'
        _dygeo = self.dgeoname+'[DY,'+str(dy_extver)+']'

        return _dxgeo,_dygeo
Esempio n. 50
0
def _addDefaultSkyKW(imageObjList):
    """Add MDRIZSKY keyword to "commanded" SCI headers of all input images,
        if that keyword does not already exist.
    """
    skyKW = "MDRIZSKY"
    Value = 0.0
    for imageSet in imageObjList:
        fname = imageSet._filename
        numchips=imageSet._numchips
        sciExt=imageSet.scienceExt
        fobj = fileutil.openImage(fname, mode='update')
        for chip in range(1,numchips+1,1):
            ext = (sciExt,chip)
            if not imageSet[ext].group_member:
                # skip over extensions not used in processing
                continue
            if skyKW not in fobj[ext].header:
                fobj[ext].header[skyKW] = (Value, 'Sky value computed by AstroDrizzle')
                log.info("MDRIZSKY keyword not found in the %s[%s,%d] header."%(
                            fname,sciExt,chip))
                log.info("    Adding MDRIZSKY to header with default value of 0.")
        fobj.close()
Esempio n. 51
0
def checkNGOODPIX(filelist):
    """
    Only for ACS, and STIS, check NGOODPIX
    If all pixels are 'bad' on all chips, exclude this image
    from further processing.
    Similar checks requiring comparing 'driz_sep_bits' against
    WFPC2 c1f.fits arrays and NICMOS DQ arrays will need to be
    done separately (and later).
    """
    removed_files = []
    for inputfile in filelist:
        if (fileutil.getKeyword(inputfile,'instrume') == 'ACS') \
           or fileutil.getKeyword(inputfile,'instrume') == 'STIS':
            _file = fileutil.openImage(inputfile)
            _ngood = 0
            for extn in _file:
                if 'EXTNAME' in extn.header and extn.header['EXTNAME'] == 'SCI':
                    _ngood += extn.header['NGOODPIX']
            _file.close()

            if (_ngood == 0):
                removed_files.append(inputfile)
    return removed_files
Esempio n. 52
0
    def __init__(self,filename,group=None,inmemory=False):
        baseImageObject.__init__(self,filename)

        #filutil open returns a fits object
        try:
            self._image=fileutil.openImage(filename,clobber=False,memmap=0)

        except IOError:
            raise IOError("Unable to open file: %s" % filename)

        #populate the global attributes which are good for all the chips in the file
        #self._rootname=self._image['PRIMARY'].header["ROOTNAME"]
        self._rootname=fileutil.buildNewRootname(filename)
        self.outputNames=self._setOutputNames(self._rootname)

        # flag to indicate whether or not to write out intermediate products
        # to disk (default) or keep everything in memory
        self.inmemory = inmemory
        self._initVirtualOutputs()

        #self._exptime=self._image["PRIMARY"].header["EXPTIME"]
        #exptime should be set in the image subclass code since it's kept in different places
#        if(self._exptime == 0):
        self._exptime =1. #to avoid divide by zero
 #           print "Setting exposure time to 1. to avoid div/0!"

        #this is the number of science chips to be processed in the file
        self._numchips=self._countEXT(extname=self.scienceExt)

        self.proc_unit = None

        #self._nextend=self._image["PRIMARY"].header["NEXTEND"]
        self._nextend = self._countEXT(extname=None)

        if (self._numchips == 0):
            #the simple fits image contains the data in the primary extension,
            #this will help us deal with the rest of the code that looks
            #and acts on chips :)
            #self._nextend=1
            self._numchips=1
            self.scienceExt="PRIMARY"
            self.maskExt=None
            self._image["PRIMARY"].header["EXTNAME"] = "PRIMARY"
            self._image["PRIMARY"].header["EXTVER"] = 1
            self._image["PRIMARY"].extnum = 0

        self._isSimpleFits = False

        # Clean out any stray MDRIZSKY keywords from PRIMARY headers
        fimg = fileutil.openImage(filename,mode='update')
        if 'MDRIZSKY' in fimg['PRIMARY'].header:
            del fimg['PRIMARY'].header['MDRIZSKY']
        fimg.close()
        del fimg

        if group not in [None,'']:
            # Only use selected chip
            if ',' in group:
                group_id = group.split(',')
                if group_id[0].isalpha(): # user specified a specific extname,extver
                    self.group = [int(group_id[1])]
                else: # user specified a list of extension numbers to process
                    self.group = []
                    for grp in group_id:
                        # find extname/extver which corresponds to this extension number
                        group_extname = self._image[int(grp)].header['EXTNAME']
                        group_extver = self._image[int(grp)].header['EXTVER']
                        self.group.append(group_extver)
            else:
                # find extname/extver which corresponds to this extension number
                group_extver = self._image[int(group)].header['EXTVER']
                self.group = [int(group_extver)]
        else:
            # Use all chips
            self.group = None

        if not self._isSimpleFits:

            #assign chip specific information
            for chip in range(1,self._numchips+1,1):

                self._assignRootname(chip)
                sci_chip = self._image[self.scienceExt,chip]

                # Set a flag to indicate whether this chip should be included
                # or not, based on user input from the 'group' parameter.
                if self.group is None or (self.group is not None and chip in self.group):
                    sci_chip.group_member = True
                    self._nmembers += 1
                else:
                    sci_chip.group_member = False

                sci_chip.signature = None

                sci_chip.dqname = None
                sci_chip.dqmaskname = None

                sci_chip.dqfile,sci_chip.dq_extn = self.find_DQ_extension()
                #self.maskExt = sci_chip.dq_extn
                if(sci_chip.dqfile != None):
                    sci_chip.dqname = sci_chip.dqfile +'['+sci_chip.dq_extn+','+str(chip)+']'

                # build up HSTWCS object for each chip, which will be necessary for drizzling operations
                sci_chip.wcs=wcs_functions.get_hstwcs(self._filename,self._image,sci_chip.extnum)
                sci_chip.detnum,sci_chip.binned = util.get_detnum(sci_chip.wcs,self._filename,chip)
                sci_chip.wcslin_pscale = 1.0

                #assuming all the chips don't have the same dimensions in the file
                sci_chip._naxis1=sci_chip.header["NAXIS1"]
                sci_chip._naxis2=sci_chip.header["NAXIS2"]

                # record the exptime values for this chip so that it can be
                # easily used to generate the composite value for the final output image
                sci_chip._expstart,sci_chip._expend = util.get_expstart(sci_chip.header,self._image['PRIMARY'].header)

                sci_chip.outputNames=self._setChipOutputNames(sci_chip.rootname,chip).copy() #this is a dictionary
                # Set the units: both bunit and in_units
                self.set_units(chip)

                #initialize gain, readnoise, and exptime attributes
                # the actual values will be set by each instrument based on
                # keyword names specific to that instrument by 'setInstrumentParamters()'
                sci_chip._headergain = 1 # gain value read from header
                sci_chip._gain = 1.0     # calibrated gain value
                sci_chip._rdnoise = 1.0  # calibrated readnoise
                sci_chip._exptime = 1.0
                sci_chip._effGain = 1.0
                sci_chip._conversionFactor = 1.0
                sci_chip._wtscl = 1.0

                # Keep track of the sky value that should be subtracted from this chip
                # Read in value from image header, in case user has already
                # determined the sky level
                if "MDRIZSKY" in sci_chip.header:
                    subsky = sci_chip.header['MDRIZSKY']
                    log.info('Reading in MDRIZSKY of %s' % subsky)
                else:
                    subsky = 0.0
                # .computedSky:   value to be applied by the
                #                 adrizzle/ablot steps.
                # .subtractedSky: value already (or will be by adrizzle/ablot)
                #                 subtracted from the image
                sci_chip.subtractedSky = subsky
                sci_chip.computedSky = subsky

                sci_chip.darkcurrent = 0.0

                # The following attributes are used when working with sub-arrays
                # and get reference file arrays for auto-generation of IVM masks
                try:
                    sci_chip.ltv1 = sci_chip.header['LTV1'] * -1
                    sci_chip.ltv2 = sci_chip.header['LTV2'] * -1
                except KeyError:
                    sci_chip.ltv1 = 0
                    sci_chip.ltv2 = 0
                if sci_chip.ltv1 < 0:
                    sci_chip.ltv1 = 0
                if sci_chip.ltv2 < 0:
                    sci_chip.ltv2 = 0
                sci_chip.size1 = sci_chip.header['NAXIS1'] + np.round(sci_chip.ltv1)
                sci_chip.size2 = sci_chip.header['NAXIS2'] + np.round(sci_chip.ltv2)
                #sci_chip.image_shape = (sci_chip.size2,sci_chip.size1)
                sci_chip.image_shape = (sci_chip.header['NAXIS2'],sci_chip.header['NAXIS1'])

                # Interpret the array dtype by translating the IRAF BITPIX value
                for dtype in IRAF_DTYPES.keys():
                    if sci_chip.header['BITPIX'] == IRAF_DTYPES[dtype]:
                        sci_chip.image_dtype = dtype
                        break

                if self.inmemory:
                    # read image data array into memory
                    shape = sci_chip.data.shape
Esempio n. 53
0
def run_blot(imageObjectList,
             output_wcs,
             paramDict,
             wcsmap=wcs_functions.WCSMap):
    """
    run_blot(imageObjectList, output_wcs, paramDict, wcsmap=wcs_functions.WCSMap)

    Perform the blot operation on the list of images.
    """
    # Insure that input imageObject is a list
    if not isinstance(imageObjectList, list):
        imageObjectList = [imageObjectList]
    #
    # Setup the versions info dictionary for output to PRIMARY header
    # The keys will be used as the name reported in the header, as-is
    #
    _versions = {
        'AstroDrizzle': __version__,
        'PyFITS': util.__fits_version__,
        'Numpy': util.__numpy_version__
    }

    _hdrlist = []

    for img in imageObjectList:

        for chip in img.returnAllChips(extname=img.scienceExt):

            print('    Blot: creating blotted image: ',
                  chip.outputNames['data'])

            #### Check to see what names need to be included here for use in _hdrlist
            chip.outputNames['driz_version'] = _versions['AstroDrizzle']
            outputvals = chip.outputNames.copy()
            outputvals.update(img.outputValues)
            outputvals['blotnx'] = chip.wcs.naxis1
            outputvals['blotny'] = chip.wcs.naxis2
            _hdrlist.append(outputvals)

            plist = outputvals.copy()
            plist.update(paramDict)

            # PyFITS can be used here as it will always operate on
            # output from PyDrizzle (which will always be a FITS file)
            # Open the input science file
            medianPar = 'outMedian'
            outMedianObj = img.getOutputName(medianPar)
            if img.inmemory:
                outMedian = img.outputNames[medianPar]
                _fname, _sciextn = fileutil.parseFilename(outMedian)
                _inimg = outMedianObj
            else:
                outMedian = outMedianObj
                _fname, _sciextn = fileutil.parseFilename(outMedian)
                _inimg = fileutil.openImage(_fname, memmap=False)

            # Return the PyFITS HDU corresponding to the named extension
            _scihdu = fileutil.getExtn(_inimg, _sciextn)
            _insci = _scihdu.data.copy()
            _inimg.close()
            del _inimg, _scihdu

            _outsci = do_blot(_insci,
                              output_wcs,
                              chip.wcs,
                              chip._exptime,
                              coeffs=paramDict['coeffs'],
                              interp=paramDict['blot_interp'],
                              sinscl=paramDict['blot_sinscl'],
                              wcsmap=wcsmap)
            # Apply sky subtraction and unit conversion to blotted array to
            # match un-modified input array
            if paramDict['blot_addsky']:
                skyval = chip.computedSky
            else:
                skyval = paramDict['blot_skyval']
            _outsci /= chip._conversionFactor
            if skyval is not None:
                _outsci += skyval
                log.info('Applying sky value of %0.6f to blotted image %s' %
                         (skyval, chip.outputNames['data']))

            # Write output Numpy objects to a PyFITS file
            # Blotting only occurs from a drizzled SCI extension
            # to a blotted SCI extension...

            _outimg = outputimage.OutputImage(_hdrlist,
                                              paramDict,
                                              build=False,
                                              wcs=chip.wcs,
                                              blot=True)
            _outimg.outweight = None
            _outimg.outcontext = None
            outimgs = _outimg.writeFITS(plist['data'],
                                        _outsci,
                                        None,
                                        versions=_versions,
                                        blend=False,
                                        virtual=img.inmemory)

            img.saveVirtualOutputs(outimgs)
            #_buildOutputFits(_outsci,None,plist['outblot'])
            _hdrlist = []

            del _outsci

        del _outimg
Esempio n. 54
0
def run(configObj, wcsmap=None):
    """
    Run the blot task based on parameters provided interactively by the user.

    """

    # Insure all output filenames specified have .fits extensions
    if configObj['outdata'][-5:] != '.fits': configObj['outdata'] += '.fits'

    scale_pars = configObj['Data Scaling Parameters']
    user_wcs_pars = configObj['User WCS Parameters']

    # PyFITS can be used here as it will always operate on
    # output from PyDrizzle (which will always be a FITS file)
    # Open the input (drizzled?) image
    _fname, _sciextn = fileutil.parseFilename(configObj['data'])
    _inimg = fileutil.openImage(_fname, memmap=False)
    _expin = fileutil.getKeyword(configObj['data'],
                                 scale_pars['expkey'],
                                 handle=_inimg)

    # Return the PyFITS HDU corresponding to the named extension
    _scihdu = fileutil.getExtn(_inimg, _sciextn)
    _insci = _scihdu.data.copy()

    _inexptime = 1.0
    if scale_pars['in_units'] == 'counts':
        if scale_pars['expkey'] in _inimg['PRIMARY'].header:
            _inexptime = _inimg['PRIMARY'].header[scale_pars['expkey']]
        elif 'DRIZEXPT' in _inimg['PRIMARY'].header:
            # Try keyword written out by new 'drizzle' if no valid 'expkey' was given
            _inexptime = _inimg['PRIMARY'].header['DRIZEXPT']
        else:
            raise ValueError('No valid exposure time keyword could be found '
                             'for input %s' % configObj['data'])
    # always convert input to 'cps' for blot() algorithm
    if _inexptime != 0.0 or _inexptime != 1.0:
        np.divide(_insci, _inexptime, _insci)

    _inimg.close()
    del _inimg

    # read in WCS from source (drizzled) image
    source_wcs = stwcs.wcsutil.HSTWCS(configObj['data'])
    if source_wcs.wcs.is_unity():
        print(
            "WARNING: No valid WCS found for input drizzled image: {}!".format(
                configObj['data']))

    # define blot_wcs
    blot_wcs = None
    _refname, _refextn = fileutil.parseFilename(configObj['reference'])
    if os.path.exists(_refname):
        # read in WCS from pre-existing output image
        blot_wcs = stwcs.wcsutil.HSTWCS(configObj['reference'])
        if blot_wcs.wcs.is_unity():
            print("WARNING: No valid WCS found for output image: {} !".format(
                configObj['reference']))

    # define blot WCS based on input images or specified reference WCS values
    if user_wcs_pars['user_wcs']:
        blot_wcs = wcs_functions.build_hstwcs(user_wcs_pars['raref'],
                                              user_wcs_pars['decref'],
                                              user_wcs_pars['xrefpix'],
                                              user_wcs_pars['yrefpix'],
                                              int(user_wcs_pars['outnx']),
                                              int(user_wcs_pars['outny']),
                                              user_wcs_pars['outscale'],
                                              user_wcs_pars['orient'])
        configObj['coeffs'] = None

    # If blot_wcs is still not defined at this point, we have a problem...
    if blot_wcs is None:
        blot_wcs = stwcs.distortion.utils.output_wcs([source_wcs],
                                                     undistort=False)

    out_wcs = blot_wcs.copy()
    # perform blotting operation now
    _outsci = do_blot(_insci,
                      source_wcs,
                      out_wcs,
                      _expin,
                      coeffs=configObj['coeffs'],
                      interp=configObj['interpol'],
                      sinscl=configObj['sinscl'],
                      stepsize=configObj['stepsize'],
                      wcsmap=wcsmap)
    # create output with proper units and exptime-scaling
    if scale_pars['out_units'] == 'counts':
        if scale_pars['expout'] == 'input':
            _outscale = fileutil.getKeyword(configObj['reference'],
                                            scale_pars['expkey'])
            #_outscale = _expin
        else:
            _outscale = float(scale_pars['expout'])
        print(
            "Output blotted images scaled by exptime of {}".format(_outscale))
        np.multiply(_outsci, _outscale, _outsci)

    # Add sky back in to the blotted image, as specified by the user
    if configObj['addsky']:
        skyval = _scihdu.header['MDRIZSKY']
    else:
        skyval = configObj['skyval']
    print("Added {} counts back in to blotted image as sky.".format(skyval))
    _outsci += skyval

    del _scihdu

    # Write output Numpy objects to a PyFITS file
    # Blotting only occurs from a drizzled SCI extension
    # to a blotted SCI extension...
    outputimage.writeSingleFITS(_outsci, blot_wcs, configObj['outdata'],
                                configObj['reference'])
Esempio n. 55
0
def getSingleTemplate(fname, extlist=['SCI', 'ERR', 'DQ']):
    """
    # Obtain default headers for output file based on a single input file
    # (Copied from outputimage module.)
    #
    Returns
    -------
    headers :  tuple of `astropy.io.fits.Header` objects, not HDU objects!
        headers
    """

    if fname is None:
        raise ValueError('No data files for creating FITS output.')

    froot, fextn = fileutil.parseFilename(fname)
    if fextn is not None:
        fnum = fileutil.parseExtn(fextn)[1]
    ftemplate = fileutil.openImage(froot, mode='readonly')
    prihdr = ftemplate['PRIMARY'].header.copy()
    try:
        del prihdr['pcount']
        del prihdr['gcount']
    except KeyError:
        pass

    if fname.find('.fits') > 0 and len(ftemplate) > 1:

        # Setup which keyword we will use to select each
        # extension...
        _extkey = 'EXTNAME'

        defnum = fileutil.findKeywordExtn(ftemplate, _extkey, extlist[0])
        #
        # Now, extract the headers necessary for output (as copies)
        # 1. Find the SCI extension in the template image
        # 2. Make a COPY of the extension header for use in new output file
        if fextn is None:
            extnum = fileutil.findKeywordExtn(ftemplate, _extkey, extlist[0])
        else:
            extnum = (extlist[0], fnum)
        #scihdr = fits.Header(cards=ftemplate[extnum].header.ascard.copy())
        scihdr = fits.Header(ftemplate[extnum].header.copy())
        #scihdr.update('extver',1)
        extnum_sci = extnum

        # Extract the header for additional extensions
        if len(extlist) > 1 and extlist[1] not in [
                None, '', ' ', 'INDEF', 'None'
        ]:
            if fextn is None:
                extnum = fileutil.findKeywordExtn(ftemplate, _extkey,
                                                  extlist[1])
            else:
                # there may or may not be a second type of extension in the template
                count = 0
                for f in ftemplate:
                    if 'extname' in f.header and f.header[
                            'extname'] == extlist[1]:
                        count += 1
                if count > 0:
                    extnum = (extlist[1], fnum)
                else:
                    # Use science header for remaining headers
                    extnum = (extlist[0], fnum)
        else:
            extnum = extnum_sci

        #errhdr = fits.Header(cards=ftemplate[extnum].header.ascard.copy())
        errhdr = fits.Header(ftemplate[extnum].header.copy())
        #errhdr.update('extver',1)
        errhdr['bunit'] = 'UNITLESS'

        if len(extlist) > 2 and extlist[2] not in [
                None, '', ' ', 'INDEF', 'None'
        ]:

            if fextn is None:
                extnum = fileutil.findKeywordExtn(ftemplate, _extkey,
                                                  extlist[2])
            else:
                count = 0
                for f in ftemplate:
                    if 'extname' in f.header and f.header[
                            'extname'] == extlist[2]:
                        count += 1
                if count > 0:
                    extnum = (extlist[2], fnum)
                else:
                    # Use science header for remaining headers
                    extnum = (extlist[0], fnum)
        else:
            extnum = extnum_sci

        #dqhdr = fits.Header(cards=ftemplate[extnum].header.ascard.copy())
        dqhdr = fits.Header(ftemplate[extnum].header.copy())
        #dqhdr.update('extver',1)
        dqhdr['bunit'] = 'UNITLESS'

    else:
        # Create default headers from scratch
        scihdr = None
        errhdr = None
        dqhdr = None

    ftemplate.close()
    del ftemplate

    return prihdr, scihdr, errhdr, dqhdr