Пример #1
0
def checkNGOODPIX(filelist):
    """
    Only for ACS, WFC3 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 = []
    supported_instruments = ['ACS', 'STIS', 'WFC3']
    for inputfile in filelist:
        if fileutil.getKeyword(inputfile, 'instrume') in supported_instruments:
            file = fits.open(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)

    if removed_files != []:
        print(
            "Warning:  Files without valid pixels detected: keyword NGOODPIX = 0.0"
        )
        print("Warning:  Removing the following files from input list")
        for f in removed_files:
            print('\t', f)

    return removed_files
Пример #2
0
def checkNGOODPIX(filelist):
    """
    Only for ACS, WFC3 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 = []
    supported_instruments = ['ACS','STIS','WFC3']
    for inputfile in filelist:
        if fileutil.getKeyword(inputfile,'instrume') in supported_instruments:
            file = fits.open(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)

    if removed_files != []:
        print("Warning:  Files without valid pixels detected: keyword NGOODPIX = 0.0")
        print("Warning:  Removing the following files from input list")
        for f in removed_files:
            print('\t',f)

    return removed_files
Пример #3
0
def getLTVOffsets(rootname,header=None):

    _ltv1 = None
    _ltv2 = None
    if header:
        if 'LTV1' in header:
            _ltv1 = header['LTV1']
        if 'LTV2' in header:
            _ltv2 = header['LTV2']
    else:
        _ltv1 = fileutil.getKeyword(rootname,'LTV1')
        _ltv2 = fileutil.getKeyword(rootname,'LTV2')

    if _ltv1 == None: _ltv1 = 0.
    if _ltv2 == None: _ltv2 = 0.

    return _ltv1,_ltv2
Пример #4
0
def findNumExt(filename):
    # Open the file given by 'rootname' and return the
    # number of extensions written out for the observation.
    # It will be up to the Exposure classes to determine how
    # many IMSETS they have to work with.
    #
    # Only look in the primary extension or first group.
    #_s = iraf.hselect(filename,'NEXTEND',expr='yes',Stdout=1)
    _s = fileutil.getKeyword(filename,keyword='NEXTEND')
    if not _s:
        _s = fileutil.getKeyword(filename,keyword='GCOUNT')
    # This may need to be changed to support simple image without
    # extensions (such as simple FITS images).
    if _s == '':
        raise ValueError("There are NO extensions to be read in this image!")

    return _s
Пример #5
0
    def addMembers(self,filename):

        # The PC chip defines the orientation of the metachip, so use
        # it for the PARITY as well.
        self.detector = 'WFPC'

        _chip1_rot = None
        # Build rootname here for each SCI extension...
        if self.pars['section'] == None:
            self.pars['section'] = [None] * self.nmembers
            group_indx = list(range(1,self.nmembers+1))
        else:
            group_indx = self.pars['section']

        for i in range(self.nmembers):
            _extname = self.imtype.makeSciName(i+1,section=self.pars['section'][i])

            _detnum = fileutil.getKeyword(_extname,self.DETECTOR_NAME)

            # Start by looking for the corresponding WFPC2 'c1h' files
            _dqfile, _dqextn = self._findDQFile()

            # Reset dqfile name in ImType class to point to new file
            self.imtype.dqfile = _dqfile
            self.imtype.dq_extn = _dqextn

            # Build mask file for this member chip
            _dqname = self.imtype.makeDQName(extver=group_indx[i])
            _masklist = []
            _masknames = []

            if _dqname != None:
                _maskname = buildmask.buildMaskName(fileutil.buildNewRootname(_dqname),_detnum)
            else:
                _maskname = None
            _masknames.append(_maskname)

            outmask = buildmask.buildShadowMaskImage(_dqname,_detnum,group_indx[i],_maskname, bitvalue=self.bitvalue[0], binned=self.binned)
            _masklist.append(outmask)

            _maskname = _maskname.replace('final_mask','single_mask')
            _masknames.append(_maskname)
            outmask = buildmask.buildShadowMaskImage(_dqname,_detnum,group_indx[i],_maskname, bitvalue=self.bitvalue[1], binned=self.binned)
            _masklist.append(outmask)
            _masklist.append(_masknames)


            self.members.append(Exposure(_extname, idckey=self.idckey, dqname=_dqname,
                mask=_masklist, parity=self.PARITY[str(i+1)],
                idcdir=self.pars['idcdir'], group_indx = i+1,
                rot=_chip1_rot, handle=self.image_handle, extver=_detnum,
                exptime=self.exptime[0], ref_pscale=self.REFDATA['1']['psize'], binned=self.binned))

            if self.idckey != 'idctab':
                _chip1_rot = self.members[0].geometry.def_rot
Пример #6
0
def _getExposure(img, output, frame, idckey):

    # setup Exposure object with distortion model and WCS info
    if frame == 'input':
        if img.find('[') < 0:
            img += '[sci]'
            _val = fileutil.getKeyword(img, 'CD1_1')
            if _val == None:
                img[:-7] += '[0]'

        if fileutil.getKeyword(img, 'CD1_1') == None:
            print("Input %s not valid!" % img)
            raise Exception

        _exp = pydrizzle.Exposure(img, idckey)
        _wcs = _exp.geometry.wcslin

    else:
        # Use output frame for converting pixel shifts
        # to units of arcseconds...
        # Make sure we have a recognized file:
        if not fileutil.findFile(output):
            if fileutil.findFile(output + '.fits'):
                output += '.fits'
            else:
                print("Can NOT find output file %s!" % output)
                raise Exception

        if output.find('[') < 0:
            output += '[0]'
            _val = fileutil.getKeyword(output, 'CD1_1')
            if _val == None:
                output[:-3] += '[sci,1]'

        if fileutil.getKeyword(output, 'CD1_1') == None:
            print("Output %s not valid!" % output)
            raise Exception

        _exp = pydrizzle.Exposure(output, idckey)
        _wcs = _exp.geometry.wcs

    return _wcs
Пример #7
0
def check_exptime(filelist):
    """
    Removes files with EXPTIME==0 from filelist.
    """
    removed_files = []

    for f in filelist:
        if fileutil.getKeyword(f, 'EXPTIME') <= 0:
            removed_files.append(f)

    return removed_files
Пример #8
0
    def __init__(self, filename, output, pars=None):

        # Now initialize Pattern with all member exposures...
        Pattern.__init__(self, filename, output=output, pars=pars)

        self.instrument = 'WFPC2'
        self.REFDATA ={'1':{'psize':0.04554,'xoff':354.356,'yoff':343.646,'v2':2.374,'v3':-30.268,'theta':224.8480},
        '2':{'psize':0.0996,'xoff':345.7481,'yoff':375.28818,'v2':-51.368,'v3':-5.698,'theta':314.3520},
        '3':{'psize':0.0996,'xoff':366.56876,'yoff':354.79435,'v2':0.064,'v3':48.692,'theta':44.67},
        '4':{'psize':0.0996,'xoff':355.85016,'yoff':351.29183,'v2':55.044,'v3':-6.098,'theta':135.2210}}

        self.REFPIX = {'x':400.,'y':400.}
        gcount = None

        # build output rootnames here...
        self.setNames(filename,output)

        # Set EXPTIME for exposure
        self.exptime = self.getExptime()

        _mode = fileutil.getKeyword(filename, 'MODE')
        if _mode == 'AREA':
            self.binned = 2
            if self.idckey == 'cubic':
                for l in self.REFPIX.keys(): self.REFPIX[l]= self.REFPIX[l] / self.binned
                for l in self.REFDATA.keys():
                    self.REFDATA[l]['psize'] = self.REFDATA[l]['psize'] * self.binned
                    self.REFDATA[l]['xoff'] = self.REFDATA[l]['xoff'] / self.binned
                    self.REFDATA[l]['yoff'] = self.REFDATA[l]['yoff'] / self.binned

        # Now, build list of members and initialize them
        self.addMembers(filename)
        self.setBunit('COUNTS')

        chips = [int(member.chip) for member in self.members]
        try:
            chip_ind = chips.index(self.__refchip)
        except ValueError:
            chip_ind = 0
        self.refchip = chips[chip_ind]

        if self.members[0].geometry.ikey != 'idctab':
            # Correct distortion coefficients to match output pixel scale
            self.computeCubicCoeffs()
        else:
            #self.computeOffsets(refchip=self.__refchip)
            self.computeOffsets(refchip=self.refchip)
        # Determine desired orientation of product
        self.setOrient()

        # Set up the input members and create the product meta-chip
        self.buildProduct(filename, output)
Пример #9
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
Пример #10
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'])
Пример #11
0
def run(configObj, wcsmap=None):
    """ Interface for running `wdrizzle` from TEAL or Python command-line.

    This code performs all file ``I/O`` to set up the use of the drizzle code for
    a single exposure to replicate the functionality of the original `wdrizzle`.
    """

    # Insure all output filenames specified have .fits extensions
    if configObj['outdata'][-5:] != '.fits': configObj['outdata'] += '.fits'
    if not util.is_blank(
            configObj['outweight']) and configObj['outweight'][-5:] != '.fits':
        configObj['outweight'] += '.fits'
    if not util.is_blank(configObj['outcontext']
                         ) and configObj['outcontext'][-5:] != '.fits':
        configObj['outcontext'] += '.fits'

    # Keep track of any files we need to open
    in_sci_handle = None
    in_wht_handle = None
    out_sci_handle = None
    out_wht_handle = None
    out_con_handle = None

    _wcskey = configObj['wcskey']
    if util.is_blank(_wcskey):
        _wcskey = ' '

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

    # Open the SCI (and WHT?) image
    # read file to get science array
    insci = get_data(configObj['input'])
    expin = fileutil.getKeyword(configObj['input'], scale_pars['expkey'])
    in_sci_phdr = fits.getheader(fileutil.parseFilename(configObj['input'])[0],
                                 memmap=False)

    # we need to read in the input WCS
    input_wcs = stwcs.wcsutil.HSTWCS(configObj['input'], wcskey=_wcskey)

    if not util.is_blank(configObj['inweight']):
        inwht = get_data(configObj['inweight']).astype(np.float32)
    else:
        # Generate a default weight map of all good pixels
        inwht = np.ones(insci.shape, dtype=insci.dtype)

    output_exists = False
    outname = fileutil.osfn(fileutil.parseFilename(configObj['outdata'])[0])
    if os.path.exists(outname):
        output_exists = True
    # Output was specified as a filename, so open it in 'update' mode
    outsci = get_data(configObj['outdata'])

    if output_exists:
        # we also need to read in the output WCS from pre-existing output
        output_wcs = stwcs.wcsutil.HSTWCS(configObj['outdata'])

        out_sci_hdr = fits.getheader(outname, memmap=False)
        outexptime = out_sci_hdr['DRIZEXPT']
        if 'ndrizim' in out_sci_hdr:
            uniqid = out_sci_hdr['ndrizim'] + 1
        else:
            uniqid = 1

    else:  # otherwise, define the output WCS either from user pars or refimage
        if util.is_blank(configObj['User WCS Parameters']['refimage']):
            # Define a WCS based on user provided WCS values
            # NOTE:
            #   All parameters must be specified, not just one or a few
            if not util.is_blank(user_wcs_pars['outscale']):
                output_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'])
            else:
                # Define default WCS based on input image
                applydist = True
                if input_wcs.sip is None or input_wcs.instrument == 'DEFAULT':
                    applydist = False
                output_wcs = stwcs.distortion.utils.output_wcs(
                    [input_wcs], undistort=applydist)
        else:
            refimage = configObj['User WCS Parameters']['refimage']
            refroot, extroot = fileutil.parseFilename(refimage)
            if extroot is None:
                fimg = fits.open(refroot, memmap=False)
                for i, extn in enumerate(fimg):
                    if 'CRVAL1' in extn.header:  # Key on CRVAL1 for valid WCS
                        refwcs = stwcs.wcsutil.HSTWCS('{}[{}]'.format(
                            refroot, i))
                        if refwcs.wcs.has_cd():
                            extroot = i
                            break
                fimg.close()
                # try to find extension with valid WCS
                refimage = "{}[{}]".format(refroot, extroot)
            # Define the output WCS based on a user specified reference image WCS
            output_wcs = stwcs.wcsutil.HSTWCS(refimage)
        # Initialize values used for combining results
        outexptime = 0.0
        uniqid = 1

    # Set up the output data array and insure that the units for that array is 'cps'
    if outsci is None:
        # Define a default blank array based on definition of output_wcs
        outsci = np.empty(output_wcs.array_shape, dtype=np.float32)
        outsci.fill(np.nan)
    else:
        # Convert array to units of 'cps', if needed
        if outexptime != 0.0:
            np.divide(outsci, outexptime, outsci)
        outsci = outsci.astype(np.float32)

    # Now update output exposure time for additional input file
    outexptime += expin

    outwht = None
    if not util.is_blank(configObj['outweight']):
        outwht = get_data(configObj['outweight'])

    if outwht is None:
        outwht = np.zeros(output_wcs.array_shape, dtype=np.float32)
    else:
        outwht = outwht.astype(np.float32)

    outcon = None
    keep_con = False

    if not util.is_blank(configObj['outcontext']):
        outcon = get_data(configObj['outcontext'])
        keep_con = True
        if outcon is None:
            outcon = np.zeros((1, ) + output_wcs.array_shape, dtype=np.int32)
        else:
            outcon = outcon.astype(np.int32)
            planeid = int((uniqid - 1) / 32)

            # Add a new plane to the context image if planeid overflows
            while outcon.shape[0] <= planeid:
                plane = np.zeros_like(outcon[0])
                outcon = np.append(outcon, plane, axis=0)

    # Interpret wt_scl parameter
    if configObj['wt_scl'] == 'exptime':
        wt_scl = expin
    elif configObj['wt_scl'] == 'expsq':
        wt_scl = expin * expin
    else:
        wt_scl = float(configObj['wt_scl'])

    # Interpret coeffs parameter to determine whether to apply coeffs or not
    undistort = True
    if not configObj[
            'coeffs'] or input_wcs.sip is None or input_wcs.instrument == 'DEFAULT':
        undistort = False
    # turn off use of coefficients if undistort is False (coeffs == False)
    if not undistort:
        input_wcs.sip = None
        input_wcs.cpdis1 = None
        input_wcs.cpdis2 = None
        input_wcs.det2im = None

    wcslin = distortion.utils.output_wcs([input_wcs], undistort=undistort)

    # Perform actual drizzling now...
    _vers = do_driz(insci,
                    input_wcs,
                    inwht,
                    output_wcs,
                    outsci,
                    outwht,
                    outcon,
                    expin,
                    scale_pars['in_units'],
                    wt_scl,
                    wcslin_pscale=wcslin.pscale,
                    uniqid=uniqid,
                    pixfrac=configObj['pixfrac'],
                    kernel=configObj['kernel'],
                    fillval=scale_pars['fillval'],
                    stepsize=configObj['stepsize'],
                    wcsmap=None)

    out_sci_handle, outextn = create_output(configObj['outdata'])
    if not output_exists:
        # Also, define default header based on input image Primary header
        out_sci_handle[outextn].header = in_sci_phdr.copy()

    # Update header of output image with exptime used to scale the output data
    # if out_units is not counts, this will simply be a value of 1.0
    # the keyword 'exptime' will always contain the total exposure time
    # of all input image regardless of the output units
    out_sci_handle[outextn].header['EXPTIME'] = outexptime

    # create CTYPE strings
    ctype1 = input_wcs.wcs.ctype[0]
    ctype2 = input_wcs.wcs.ctype[1]
    if ctype1.find('-SIP'): ctype1 = ctype1.replace('-SIP', '')
    if ctype2.find('-SIP'): ctype2 = ctype2.replace('-SIP', '')

    # Update header with WCS keywords
    out_sci_handle[outextn].header['ORIENTAT'] = output_wcs.orientat
    out_sci_handle[outextn].header['CD1_1'] = output_wcs.wcs.cd[0][0]
    out_sci_handle[outextn].header['CD1_2'] = output_wcs.wcs.cd[0][1]
    out_sci_handle[outextn].header['CD2_1'] = output_wcs.wcs.cd[1][0]
    out_sci_handle[outextn].header['CD2_2'] = output_wcs.wcs.cd[1][1]
    out_sci_handle[outextn].header['CRVAL1'] = output_wcs.wcs.crval[0]
    out_sci_handle[outextn].header['CRVAL2'] = output_wcs.wcs.crval[1]
    out_sci_handle[outextn].header['CRPIX1'] = output_wcs.wcs.crpix[0]
    out_sci_handle[outextn].header['CRPIX2'] = output_wcs.wcs.crpix[1]
    out_sci_handle[outextn].header['CTYPE1'] = ctype1
    out_sci_handle[outextn].header['CTYPE2'] = ctype2
    out_sci_handle[outextn].header['VAFACTOR'] = 1.0

    if scale_pars['out_units'] == 'counts':
        np.multiply(outsci, outexptime, outsci)
        out_sci_handle[outextn].header['DRIZEXPT'] = outexptime

    else:
        out_sci_handle[outextn].header['DRIZEXPT'] = 1.0

    # Update header keyword NDRIZIM to keep track of how many images have
    # been combined in this product so far
    out_sci_handle[outextn].header['NDRIZIM'] = uniqid

    # define keywords to be written out to product header
    drizdict = outputimage.DRIZ_KEYWORDS.copy()

    # Update drizdict with current values
    drizdict['VER']['value'] = _vers[:44]
    drizdict['DATA']['value'] = configObj['input'][:64]
    drizdict['DEXP']['value'] = expin
    drizdict['OUDA']['value'] = configObj['outdata'][:64]
    drizdict['OUWE']['value'] = configObj['outweight'][:64]
    drizdict['OUCO']['value'] = configObj['outcontext'][:64]
    drizdict['MASK']['value'] = configObj['inweight'][:64]
    drizdict['WTSC']['value'] = wt_scl
    drizdict['KERN']['value'] = configObj['kernel']
    drizdict['PIXF']['value'] = configObj['pixfrac']
    drizdict['OUUN']['value'] = scale_pars['out_units']
    drizdict['FVAL']['value'] = scale_pars['fillval']
    drizdict['WKEY']['value'] = configObj['wcskey']
    outputimage.writeDrizKeywords(out_sci_handle[outextn].header, uniqid,
                                  drizdict)

    # add output array to output file
    out_sci_handle[outextn].data = outsci
    out_sci_handle.close()

    if not util.is_blank(configObj['outweight']):
        out_wht_handle, outwhtext = create_output(configObj['outweight'])
        out_wht_handle[outwhtext].header = out_sci_handle[outextn].header.copy(
        )
        out_wht_handle[outwhtext].data = outwht
        out_wht_handle.close()

    if keep_con:
        out_con_handle, outconext = create_output(configObj['outcontext'])
        out_con_handle[outconext].data = outcon
        out_con_handle.close()
Пример #12
0
def updateAsnTable(tabname,
                   rootname,
                   xsh=None,
                   ysh=None,
                   form="absolute",
                   rot=None,
                   scale=None,
                   frame="input",
                   units="pixels",
                   output=None,
                   mode="replace"):
    """ Updates an existing ASN table with shifts in arcseconds of RA and Dec.
        Parameters:
            tabname     - name of ASN table to be updated
            rootname    - name of image whose pointing needs to be updated
            xsh         - X shift from nominal to be applied
            ysh         - Y shift from nominal to be applied
            rot         - additional rotation to be applied
            scale       - scale factor to be applied
            form        - specifies how shifts are computed:
                            absolute (default) or delta
            frame       - specifies whether xsh/ysh are given in terms of
                            input (default) or output frame
            units       - specifies units of xsh/ysh:
                            pixels (default) or arcseconds
            output      - filename (with or without path) of output image
                          from which output pixels shifts were computed.
            mode        - replace or add shifts to existing values
                            'replace' (default) or 'sum'
        The task will:
            - open the ASN file (tabname)
            - search for the row matching the rootname provided by
                the user (img),
            - convert any pixel shifts to arcseconds
            - update the XOFFSET, YOFFSET, ROTATION columns
                (or create them if they don't already exist)

        This task assumes that the shifts given as 'input' pixels are
        already distortion-corrected, but not scaled/rotated to output frame.

        The conversion of shifts given in terms of output pixel coordinates
        requires the use of the WCS from the output frame in order to correctly
        take into account the output frame's pixel scale and orientation.

        Both input and output image specifications assume '.fits' and that
        the WCS information appropriate for this are in either [0] or [sci,1].
        If necessary a different extension can be specified in the filename.
        Also, the output filename can include a path which will be used.

    EXAMPLE:
            1. Update ASN table 'j8cw03020_asn.fits' for 'j8cw03021_crj.fits'
                which has pixel shifts of (10.3,4.72) in (undistorted) input
                frame.
            >>> updateasn.updateAsnTable('j8cw03020_asn.fits','j8cw03021',
                xsh=10.3,ysh=4.72,rot=0.14)
    NOTE:
        This task still does not correctly work with 'NaN' entries in
        the table.  For those values, it will not change the values at all.

    """
    if frame == 'output' and output == None:
        print('Please specify output image needed to compute deltas...')
        return

    print('updateAsnTable Version ', __version__)

    _tmpname = 'buildasn_' + tabname
    # Start by opening the ASN table
    _asntab = pyfits.open(tabname, 'update')

    if form == 'absolute' or form == 'relative':
        # absolute/relative shifts
        _colx = 'XOFFSET'
        _coly = 'YOFFSET'

    else:
        # delta shifts
        _colx = 'XDELTA'
        _coly = 'YDELTA'
    #
    # Work out what needs to be done to update ASN table
    # Do the XOFFSET/YOFFSET/ROTATION columns already exist or not?
    #
    _update = no
    _add_rot = yes
    _add_scale = yes
    _colnum = 0
    for name in _asntab[1].columns.names:
        if name == _colx:
            # Make the assumption that XOFFSET/YOFFSET and ROTATION
            # are all present if one is present...
            _update = yes
            break
        _colnum += 1

    if _update:
        _tab_units = _asntab[1].columns.units[_colnum]
        if _tab_units == '' or _tab_units == None: _tab_units = 'pixels'
    else:
        _tab_units = units

    for name in _asntab[1].columns.names:
        if name == 'ROTATION':
            _add_rot = no
            break
    for name in _asntab[1].columns.names:
        if name == 'SCALE':
            _add_scale = no
            break

    # Get the shift frame and refimage if present
    # If keywords don't exist, assume default of 'input' shifts
    # with no need for refimage.
    try:
        _tab_frame = _asntab[0].header['shframe']
    except KeyError:
        _tab_frame = 'input'

    try:
        _tab_refimg = _asntab[0].header['refimage']
    except KeyError:
        _tab_refimg = None

    # Find row which corresponds to input image
    _rownum = 0
    for row in _asntab[1].data:
        if rootname.find(row.field('MEMNAME')) > -1:
            _row = row
            break
        _rownum += 1
    print('Updating table row ', _rownum, ' for image: ', rootname)

    #
    # Determine where to get the distortion coefficients
    # create complete filename from given rootname
    img = fileutil.buildRootname(rootname)
    if img == None:
        print('No valid input image for filename ', rootname)
        raise ValueError

    _instrument = fileutil.getKeyword(img, 'instrume')
    if _instrument not in IDCKEYS: _instrument = 'detector'
    _key = IDCKEYS[_instrument]
    if xsh == None: xsh = 0.
    if ysh == None: ysh = 0.

    # If we have any trouble computing offsets, abort and
    # do NOT update table.
    try:
        # Start by determining values to be used to update the table.
        #
        # Need to compute: _delta_ra, _delta_dec (undistorted arcsec)
        if units == _tab_units or (xsh == 0. and ysh == 0.):
            _delta_xoff = xsh
            _delta_yoff = ysh
            if rot == None:
                rot = 0.
            if scale == None:
                scale = 1.0

        elif units.find('pixels') > -1 and _tab_units.find('arcsec') > -1:
            #
            # We need to convert the pixel values to arcseconds
            #
            _wcs = _getExposure(img, output, frame, _key)

            # If there is any additional rotation, account for it first
            if rot != None:
                if scale != None:
                    pscale = scale * _wcs.pscale
                else:
                    pscale = None
                _wcs.updateWCS(orient=_wcs.orient + rot, pixel_scale=pscale)

            # determine delta CRVALs from CRPIX+(xsh,ysh)
            _rd_delta = _wcs.xy2rd((_wcs.crpix1 + xsh, _wcs.crpix2 + ysh))

            # Now, convert from degrees to arcseconds
            #### Do we need to multiply by cos(dec) for delta(RA)???
            _delta_xoff = (_rd_delta[0] - _wcs.crval1) * 3600.
            _delta_yoff = (_rd_delta[1] - _wcs.crval2) * 3600.

        elif units.find('arcsec') > -1 and _tab_units.find('pixels') > -1:
            _wcs = _getExposure(img, _tab_refimg, _tab_frame, _key)
            # If there is any additional rotation, account for it first
            if rot != None:
                if scale != None:
                    pscale = scale * _wcs.pscale
                else:
                    pscale = None
                _wcs.updateWCS(orient=_wcs.orient + rot, pixel_scale=pscale)

            _xy_delta = _wcs.rd2xy((_wcs.crval1 + xsh, _wcs.crval2 + ysh))
            _delta_xoff = (_xy_delta[0] - _wcs.crpix1)
            _delta_yoff = (_xy_delta[1] - _wcs.crpix2)

    except:
        print('ERROR: Error in updating table ', tabname)
        print('Closing existing table without updating it...')
        _asntab.close()
        return

    if _update:
        # Offset columns exist, just update the values in the table
        if mode == 'sum':
            _shift_xoff = _asntab[1].data.field(_colx)[_rownum]
            _shift_yoff = _asntab[1].data.field(_coly)[_rownum]
            _shift_rot = _asntab[1].data.field('ROTATION')[_rownum]
            _shift_scale = _asntab[1].data.field('SCALE')[_rownum]

            # Account for INDEF values in table
            # Logic: If set to INDEF, adding 1.0 will not change its value
            if _shift_xoff + 1.0 == _shift_xoff: _shift_xoff = 0.
            if _shift_yoff + 1.0 == _shift_yoff: _shift_yoff = 0.
            if _shift_rot + 1.0 == _shift_rot: _shift_rot = 0.
            if _shift_scale + 1.0 == _shift_scale: _shift_scale = 1.0
        else:
            _shift_xoff = 0.
            _shift_yoff = 0.
            _shift_rot = 0.
            _shift_scale = 1.
        _asntab[1].data.field(_colx)[_rownum] = _shift_xoff + _delta_xoff
        _asntab[1].data.field(_coly)[_rownum] = _shift_yoff + _delta_yoff
        if rot != None:
            _asntab[1].data.field('ROTATION')[_rownum] = _shift_rot + rot
        if scale != None:
            _asntab[1].data.field('SCALE')[_rownum] = _shift_scale * scale
    else:
        # We need to add the extra columns to the table
        # Build arrays for each additional column
        _numrows = len(_asntab[1].data)
        _xsh = N.zeros(_numrows, dtype=N.float32)
        _ysh = N.zeros(_numrows, dtype=N.float32)

        # Now update entry associated with this particular image
        _xsh[_rownum] = _delta_xoff
        _ysh[_rownum] = _delta_yoff

        # Build the column objects for the table
        #_xc,_yc,_rc = buildasn._makeOffsetColumns(_xsh,_ysh,_rot)
        _xc = pyfits.Column(name=_colx,
                            format='E',
                            unit=_tab_units,
                            array=_xsh)
        _yc = pyfits.Column(name=_coly,
                            format='E',
                            unit=_tab_units,
                            array=_ysh)
        _newcols = _asntab[1].columns + _xc
        _newcols += _yc
        #_asndefs = _asntab[1].get_coldefs()
        #_asndefs.add_col(_xc)
        #_asndefs.add_col(_yc)

        # If rotation column does NOT exist,
        if _add_rot:
            _rot = N.zeros(_numrows, dtype=N.float32)
            if rot != None:
                _rot[_rownum] = rot
            _rc = pyfits.Column(name='ROTATION',
                                format='E',
                                unit='degrees',
                                array=_rot)
            #  add newly created column
            #_asndefs.add_col(_rc)
            _newcols += _rc
        else:
            # else, update column directly.
            _asntab[1].data.field('ROTATION')[_rownum] = rot

        # If scaling column does NOT exist,
        if _add_scale:
            _scale = N.zeros(_numrows, dtype=N.float32)
            if scale != None:
                _scale[_rownum] = scale
            _sc = pyfits.Column(name='SCALE',
                                format='E',
                                unit='',
                                array=_scale)
            _newcols += _sc
        else:
            # else, update column directly.
            _asntab[1].data.field('SCALE')[_rownum] = scale

        _asnhdu = pyfits.new_table(_newcols)
        _asnhdu.writeto(_tmpname)
        # remove old data
        #del _asntab[1]
        # add table extension with old data and new columns
        #_asntab.append(_asnhdu)

    # Close and clean-up
    _asntab.close()
    del _asntab
    if os.path.exists(_tmpname):
        os.remove(tabname)
        os.rename(_tmpname, tabname)
Пример #13
0
def run(configObj, wcsmap=None):
    """ Interface for running `wdrizzle` from TEAL or Python command-line.

    This code performs all file ``I/O`` to set up the use of the drizzle code for
    a single exposure to replicate the functionality of the original `wdrizzle`.
    """

    # Insure all output filenames specified have .fits extensions
    if configObj['outdata'][-5:] != '.fits': configObj['outdata'] += '.fits'
    if not util.is_blank(configObj['outweight']) and configObj['outweight'][-5:] != '.fits': configObj['outweight'] += '.fits'
    if not util.is_blank(configObj['outcontext']) and configObj['outcontext'][-5:] != '.fits': configObj['outcontext'] += '.fits'

    # Keep track of any files we need to open
    in_sci_handle = None
    in_wht_handle = None
    out_sci_handle = None
    out_wht_handle = None
    out_con_handle = None

    _wcskey = configObj['wcskey']
    if util.is_blank(_wcskey):
        _wcskey = ' '

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

    # Open the SCI (and WHT?) image
    # read file to get science array
    insci = get_data(configObj['input'])
    expin = fileutil.getKeyword(configObj['input'],scale_pars['expkey'])
    in_sci_phdr = fits.getheader(fileutil.parseFilename(configObj['input'])[0])

    # we need to read in the input WCS
    input_wcs = stwcs.wcsutil.HSTWCS(configObj['input'],wcskey=_wcskey)

    if not util.is_blank(configObj['inweight']):
        inwht = get_data(configObj['inweight']).astype(np.float32)
    else:
        # Generate a default weight map of all good pixels
        inwht = np.ones(insci.shape,dtype=insci.dtype)

    output_exists = False
    outname = fileutil.osfn(fileutil.parseFilename(configObj['outdata'])[0])
    if os.path.exists(outname):
        output_exists = True
    # Output was specified as a filename, so open it in 'update' mode
    outsci = get_data(configObj['outdata'])

    if output_exists:
        # we also need to read in the output WCS from pre-existing output
        output_wcs = stwcs.wcsutil.HSTWCS(configObj['outdata'])

        out_sci_hdr = fits.getheader(outname)
        outexptime = out_sci_hdr['DRIZEXPT']
        if 'ndrizim' in out_sci_hdr:
            uniqid = out_sci_hdr['ndrizim']+1
        else:
            uniqid = 1

    else:  # otherwise, define the output WCS either from user pars or refimage
        if util.is_blank(configObj['User WCS Parameters']['refimage']):
            # Define a WCS based on user provided WCS values
            # NOTE:
            #   All parameters must be specified, not just one or a few
            if not util.is_blank(user_wcs_pars['outscale']):
                output_wcs = wcs_functions.build_hstwcs(
                    user_wcs_pars['raref'], user_wcs_pars['decref'],
                    user_wcs_pars['xrefpix'], user_wcs_pars['yrefpix'],
                    user_wcs_pars['outnx'], user_wcs_pars['outny'],
                    user_wcs_pars['outscale'], user_wcs_pars['orient'] )
            else:
                # Define default WCS based on input image
                applydist = True
                if input_wcs.sip is None or input_wcs.instrument=='DEFAULT':
                    applydist = False
                output_wcs = stwcs.distortion.utils.output_wcs([input_wcs],undistort=applydist)
        else:
            refimage = configObj['User WCS Parameters']['refimage']
            refroot,extroot = fileutil.parseFilename(refimage)
            if extroot is None:
                fimg = fits.open(refroot)
                for i,extn in enumerate(fimg):
                    if 'CRVAL1' in extn.header: # Key on CRVAL1 for valid WCS
                        refwcs = wcsutil.HSTWCS('{}[{}]'.format(refroot,i))
                        if refwcs.wcs.has_cd():
                            extroot = i
                            break
                fimg.close()
                # try to find extension with valid WCS
                refimage = "{}[{}]".format(refroot,extroot)
            # Define the output WCS based on a user specified reference image WCS
            output_wcs = stwcs.wcsutil.HSTWCS(refimage)
        # Initialize values used for combining results
        outexptime = 0.0
        uniqid = 1

    # Set up the output data array and insure that the units for that array is 'cps'
    if outsci is None:
        # Define a default blank array based on definition of output_wcs
        #outsci = np.zeros((output_wcs._naxis2,output_wcs._naxis1),dtype=np.float32)
        outsci = np.empty((output_wcs._naxis2,output_wcs._naxis1),dtype=np.float32)
        outsci.fill(np.nan)
    else:
        # Convert array to units of 'cps', if needed
        if outexptime != 0.0:
            np.divide(outsci, outexptime, outsci)
        outsci = outsci.astype(np.float32)

    # Now update output exposure time for additional input file
    outexptime += expin

    outwht = None
    if not util.is_blank(configObj['outweight']):
        outwht = get_data(configObj['outweight'])

    if outwht is None:
        outwht = np.zeros((output_wcs._naxis2,output_wcs._naxis1),dtype=np.float32)
    else:
        outwht = outwht.astype(np.float32)

    outcon = None
    keep_con = False

    if not util.is_blank(configObj['outcontext']):
        outcon = get_data(configObj['outcontext'])
        keep_con = True
        if outcon is None:
            outcon = np.zeros((1,output_wcs._naxis2,output_wcs._naxis1),dtype=np.int32)
        else:
            outcon = outcon.astype(np.int32)
            planeid = int((uniqid - 1)/ 32)

            # Add a new plane to the context image if planeid overflows
            while outcon.shape[0] <= planeid:
                plane = np.zeros_like(outcon[0])
                outcon = np.append(outcon, plane, axis=0)

    # Interpret wt_scl parameter
    if configObj['wt_scl'] == 'exptime':
        wt_scl = expin
    elif configObj['wt_scl'] == 'expsq':
        wt_scl = expin*expin
    else:
        wt_scl = float(configObj['wt_scl'])

    # Interpret coeffs parameter to determine whether to apply coeffs or not
    undistort = True
    if not configObj['coeffs'] or input_wcs.sip is None or input_wcs.instrument == 'DEFAULT':
        undistort = False
    # turn off use of coefficients if undistort is False (coeffs == False)
    if not undistort:
        input_wcs.sip = None
        input_wcs.cpdis1 = None
        input_wcs.cpdis2 = None
        input_wcs.det2im = None

    wcslin = distortion.utils.output_wcs([input_wcs],undistort=undistort)

    # Perform actual drizzling now...
    _vers = do_driz(insci, input_wcs, inwht,
            output_wcs, outsci, outwht, outcon,
            expin, scale_pars['in_units'],
            wt_scl, wcslin_pscale=wcslin.pscale ,uniqid=uniqid,
            pixfrac=configObj['pixfrac'], kernel=configObj['kernel'],
            fillval=scale_pars['fillval'], stepsize=configObj['stepsize'],
            wcsmap=None)

    out_sci_handle,outextn = create_output(configObj['outdata'])
    if not output_exists:
        # Also, define default header based on input image Primary header
        out_sci_handle[outextn].header = in_sci_phdr.copy()

    # Update header of output image with exptime used to scale the output data
    # if out_units is not counts, this will simply be a value of 1.0
    # the keyword 'exptime' will always contain the total exposure time
    # of all input image regardless of the output units
    out_sci_handle[outextn].header['EXPTIME'] = outexptime

    # create CTYPE strings
    ctype1 = input_wcs.wcs.ctype[0]
    ctype2 = input_wcs.wcs.ctype[1]
    if ctype1.find('-SIP'): ctype1 = ctype1.replace('-SIP','')
    if ctype2.find('-SIP'): ctype2 = ctype2.replace('-SIP','')

    # Update header with WCS keywords
    out_sci_handle[outextn].header['ORIENTAT'] = output_wcs.orientat
    out_sci_handle[outextn].header['CD1_1'] = output_wcs.wcs.cd[0][0]
    out_sci_handle[outextn].header['CD1_2'] = output_wcs.wcs.cd[0][1]
    out_sci_handle[outextn].header['CD2_1'] = output_wcs.wcs.cd[1][0]
    out_sci_handle[outextn].header['CD2_2'] = output_wcs.wcs.cd[1][1]
    out_sci_handle[outextn].header['CRVAL1'] = output_wcs.wcs.crval[0]
    out_sci_handle[outextn].header['CRVAL2'] = output_wcs.wcs.crval[1]
    out_sci_handle[outextn].header['CRPIX1'] = output_wcs.wcs.crpix[0]
    out_sci_handle[outextn].header['CRPIX2'] = output_wcs.wcs.crpix[1]
    out_sci_handle[outextn].header['CTYPE1'] = ctype1
    out_sci_handle[outextn].header['CTYPE2'] = ctype2
    out_sci_handle[outextn].header['VAFACTOR'] = 1.0


    if scale_pars['out_units'] == 'counts':
        np.multiply(outsci, outexptime, outsci)
        out_sci_handle[outextn].header['DRIZEXPT'] = outexptime

    else:
        out_sci_handle[outextn].header['DRIZEXPT'] = 1.0

    # Update header keyword NDRIZIM to keep track of how many images have
    # been combined in this product so far
    out_sci_handle[outextn].header['NDRIZIM'] = uniqid

    #define keywords to be written out to product header
    drizdict = outputimage.DRIZ_KEYWORDS.copy()

    # Update drizdict with current values
    drizdict['VER']['value'] = _vers[:44]
    drizdict['DATA']['value'] = configObj['input'][:64]
    drizdict['DEXP']['value'] = expin
    drizdict['OUDA']['value'] = configObj['outdata'][:64]
    drizdict['OUWE']['value'] = configObj['outweight'][:64]
    drizdict['OUCO']['value'] = configObj['outcontext'][:64]
    drizdict['MASK']['value'] = configObj['inweight'][:64]
    drizdict['WTSC']['value'] = wt_scl
    drizdict['KERN']['value'] = configObj['kernel']
    drizdict['PIXF']['value'] = configObj['pixfrac']
    drizdict['OUUN']['value'] = scale_pars['out_units']
    drizdict['FVAL']['value'] = scale_pars['fillval']
    drizdict['WKEY']['value'] = configObj['wcskey']
    outputimage.writeDrizKeywords(out_sci_handle[outextn].header,uniqid,drizdict)

    # add output array to output file
    out_sci_handle[outextn].data = outsci
    out_sci_handle.close()

    if not util.is_blank(configObj['outweight']):
        out_wht_handle,outwhtext = create_output(configObj['outweight'])
        out_wht_handle[outwhtext].header = out_sci_handle[outextn].header.copy()
        out_wht_handle[outwhtext].data = outwht
        out_wht_handle.close()

    if keep_con:
        out_con_handle,outconext = create_output(configObj['outcontext'])
        out_con_handle[outconext].data = outcon
        out_con_handle.close()
Пример #14
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)
    _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'],
            user_wcs_pars['outnx'], 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'])
Пример #15
0
    def __init__(self,expname, handle=None, dqname=None, idckey=None,
                    new=no,wcs=None,mask=None,pa_key=None, parity=None,
                    idcdir=None, rot=None, extver=1, exptime=None,
                    ref_pscale=1.0, binned=1, mt_wcs=None, group_indx = None):

        # This name should be formatted for use in image I/O
        self.name = fileutil.osfn(expname)

        # osfn() will expand '.' unnecessarily, potentially
        # creating a string-length problem for 'drizzle', which
        # is limited to strings of 80 chars.
        _path,_name = os.path.split(self.name)
        # if path for this filename is the same as the current dir,
        # then there is no need to pass along the path.
        if _path == os.getcwd(): self.name = _name


        # Keep track of any associated mask file created for
        # this exposure from its DQ file, or other mask file.
        _fname,_extn = fileutil.parseFilename(expname)
        _open = False

        # Make sure we have an open file handle to use for getting the
        # header and data arrays.
        if not handle and not new:
            handle = fileutil.openImage(expname)
            _open = True

        # If no extension was specified, try to interrogate the file
        # to find whether the SCI array is in the Primary
        # (as in Simple FITS) or first extension (as in MEF).
        if handle and _extn == None:
            if handle[0].data == None:
                # Primary extension specified and no data present.
                # Try looking for data in next extension.
                if len(handle) > 1 and handle[1].data != None:
                    _extn = 1
                    expname += '[1]'
                else:
                    raise IOError("No valid image data in %s.\n"%expname)
            else:
                _extn = 0

        self.dgeoname = None
        self.xgeoim = ""
        self.ygeoim = ""
        self.exptime = exptime
        self.group_indx = group_indx
        if not new:
            # Read in a copy of the header for this exposure/group/extension
            _header = fileutil.getHeader(expname,handle=handle)
            _chip = drutil.getChipId(_header)
            self.chip = str(_chip)
            # Keep track of any distortion correction images provided
            # for this chip
            self.dgeoname = fileutil.getKeyword(expname,'DGEOFILE',handle=handle)
            self.xgeoim,self.ygeoim = self.getDGEOExtn()
            if self.exptime == None:
                self.exptime = float(_header['EXPTIME'])
                if self.exptime == 0.: self.exptime = 1.0
            #
            # Extract photometric transformation keywords
            #    If they do not exist, use default values of 0 and 1
            #
            self.plam = float(fileutil.getKeyword(expname,'PHOTPLAM',handle=handle)) / 10.
            if self.plam == None:
                # Setup a default value in case this keyword does not exist
                self.plam = 555.
            self.photzpt = float(fileutil.getKeyword(expname,'PHOTZPT',handle=handle))
            if self.photzpt == None: self.photzpt = 0.0
            self.photflam = float(fileutil.getKeyword(expname,'PHOTFLAM',handle=handle))
            if self.photflam == None: self.photflam = 1.0

            # Read in date-obs from primary header
            if _header:
                if 'date-obs' in _header:
                    self.dateobs = _header['date-obs']
                elif 'date_obs' in _header:
                    self.dateobs = _header['date_obs']
                else:
                    self.dateobs = None
            else:
                self.dateobs = None

            # Initialize the value of BUNIT based on the header information, if
            # the header has the keyword
            if 'BUNIT' in _header and _header['BUNIT'].find('ergs') < 0:
                self.bunit = _header['BUNIT']
            else:
                self.bunit = 'ELECTRONS'

        else:
            _chip = 1
            _header = None
            self.chip = str(_chip)
            # Set a default value for pivot wavelength
            self.plam = 555.
            self.photzpt = 0.0
            self.photflam = 1.0
            self.dateobs = None
            if self.exptime == None:
                self.exptime = 1.

        self.parity = parity
        self.header = _header
        self.extver = extver

        # Create a pointer to the mask file's data array
        # and the name of the original input DQ file
        self.maskname = None
        self.singlemaskname = None
        self.masklist = None
        if mask != None:
            # Specifies filenames to be used if created.
            self.maskname = mask[0]
            self.singlemaskname = mask[1]
            self.masklist = mask[2]

        self.dqname = dqname

        # Remember the name of the coeffs file generated for this chip
        self.coeffs = self.buildCoeffsName()

        # Read the name of idcfile from image header if not explicitly
        # provided by user.
        if idckey != None and idckey.lower() != 'wcs':
            _indx = expname.find('[')
            if  _indx > -1:
                _idc_fname = expname[:_indx]+'[0]'
            else: _idc_fname = expname+'[0]'

            idcfile, idctype = drutil.getIDCFile(self.header,keyword=idckey,
                                        directory=idcdir)
        else:
            idcfile = None
            idctype = None

        if (idckey != None)  and (idckey.lower() == 'header'):
            idckey = idctype

        # Get distortion model and WCS info.
        self.geometry = ObsGeometry(expname, idcfile, idckey=idckey,
                chip=_chip, new=new, header=self.header,
                pa_key=pa_key, rot=rot, date=self.dateobs,
                ref_pscale=ref_pscale, binned=binned, mt_wcs=mt_wcs)

        # Remember the name and type of the IDC file used...
        self.idcfile = idcfile
        self.idctype = idctype

        # Remember the names of the filters used for the exposure
        self.filters = self.geometry.filter1+','+self.geometry.filter2

        # Define shape here...
        # nx,ny,pixel scale
        #
        if wcs != None:
            # We have been passed a WCS to use
            self.geometry.wcs = wcs
            self.geometry.model.pscale = wcs.pscale
            if expname != None:
                self.geometry.wcs.rootname = expname

        self.naxis1 = self.geometry.wcs.naxis1
        self.naxis2 = self.geometry.wcs.naxis2
        self.pscale = self.geometry.wcs.pscale
        self.shape = (self.naxis1,self.naxis2,self.pscale)

        # Keep track of the positions of the corners of the exposure
        # both for the RAW image and the
        # distortion-corrected, unscaled, unrotated image
        self.corners = {'raw':np.zeros((4,2),dtype=np.float64),'corrected':np.zeros((4,2),dtype=np.float64)}
        self.setCorners()

        # Generate BLOT output name specific to this Exposure
        _blot_extn = '_sci'+repr(extver)+'_blt.fits'
        self.outblot = fileutil.buildNewRootname(self.name,extn=_blot_extn)

        # Keep track of undistorted frame's position relative to metachip
        # Zero-point offset for chip relative to meta-chip product
        # These values get computed using 'setSingleOffsets' from 'writeCoeffs'
        # to insure that the final XDELTA/YDELTA values have been computed.
        self.product_wcs = self.geometry.wcslin
        self.xzero = 0.
        self.yzero = 0.
        self.chip_shape = (0.,0.)
        self.xsh2 = 0.
        self.ysh2 = 0.

        if _open:
            handle.close()
            del handle
Пример #16
0
def run(input,quiet=yes,restore=no,prepend='O', tddcorr=True):

    print("+ MAKEWCS Version %s" % __version__)

    _prepend = prepend

    files = parseinput.parseinput(input)[0]
    newfiles = []
    if files == []:
        print("No valid input files found.\n")
        raise IOError

    for image in files:
        #find out what the input is
        imgfits,imgtype = fileutil.isFits(image)

        # Check for existence of waiver FITS input, and quit if found.
        if imgfits and imgtype == 'waiver':
            """
            errormsg = '\n\nPyDrizzle does not support waiver fits format.\n'
            errormsg += 'Convert the input files to GEIS or multiextension FITS.\n\n'
            raise ValueError, errormsg
            """
            newfilename = fileutil.buildNewRootname(image, extn='_c0h.fits')
            # Convert GEIS image to MEF file
            newimage = fileutil.openImage(image,writefits=True,fitsname=newfilename,clobber=True)
            del newimage
            # Work with new file
            image = newfilename
            newfiles.append(image)
        # If a GEIS image is provided as input, create a new MEF file with
        # a name generated using 'buildFITSName()' and update that new MEF file.
        if not imgfits:
            # Create standardized name for MEF file
            newfilename = fileutil.buildFITSName(image)
            # Convert GEIS image to MEF file
            newimage = fileutil.openImage(image,writefits=True,fitsname=newfilename,clobber=True)
            del newimage
            # Work with new file
            image = newfilename
            newfiles.append(image)

        if not quiet:
            print("Input files: ",files)

        # First get the name of the IDC table
        #idctab = drutil.getIDCFile(_files[0][0],keyword='idctab')[0]
        idctab = drutil.getIDCFile(image,keyword='idctab')[0]
        _found = fileutil.findFile(idctab)
        if idctab == None or idctab == '':
            print('#\n No IDCTAB specified.  No correction can be done for file %s.Quitting makewcs\n' %image)
            #raise ValueError
            continue
        elif not _found:
            print('#\n IDCTAB: ',idctab,' could not be found. \n')
            print('WCS keywords for file %s will not be updated.\n' %image)
            #raise IOError
            continue

        _phdu = image + '[0]'
        _instrument = fileutil.getKeyword(_phdu,keyword='INSTRUME')
        if _instrument == 'WFPC2':
            Nrefchip, Nrefext = getNrefchip(image)
        else:
            Nrefchip = None
            Nrefext = None
        if _instrument not in NUM_PER_EXTN:

            raise ValueError("Instrument %s not supported yet. Exiting..." \
                             %_instrument)

        _detector = fileutil.getKeyword(_phdu, keyword='DETECTOR')
        _nimsets = get_numsci(image)

        for i in range(_nimsets):
            if image.find('.fits') > 0:
                _img = image+'[sci,'+repr(i+1)+']'
            else:
                _img = image+'['+repr(i+1)+']'
            if not restore:
                if not quiet:
                    print('Updating image: ', _img)

                _update(_img,idctab, _nimsets, apply_tdd=False,
                        quiet=quiet,instrument=_instrument,prepend=_prepend,
                        nrchip=Nrefchip, nrext = Nrefext)
                if _instrument == 'ACS' and _detector == 'WFC':
                    tddswitch = fileutil.getKeyword(_phdu,keyword='TDDCORR')
                    # This logic requires that TDDCORR be in the primary header
                    # and set to PERFORM in order to turn this on at all. It can
                    # be turned off by setting either tddcorr=False or setting
                    # the keyword to anything but PERFORM or by deleting the
                    # keyword altogether. PyDrizzle will rely simply on the
                    # values of alpha and beta as computed here to apply the
                    # correction to the coefficients.
                    if (tddcorr and tddswitch != 'OMIT'):
                        print('Applying time-dependent distortion corrections...')
                        _update(_img,idctab, _nimsets, apply_tdd=True, \
                                quiet=quiet,instrument=_instrument,prepend=_prepend, nrchip=Nrefchip, nrext = Nrefext)
            else:
                if not quiet:
                    print('Restoring original WCS values for',_img)
                restoreCD(_img,_prepend)

        #fimg = fileutil.openImage(image,mode='update')
        #if 'TDDCORR' in fimg[0].header and fimg[0].header['TDDCORR'] == 'PERFORM':
        #    fimg[0].header['TDDCORR'] = 'COMPLETE'
        #fimg.close()

    if newfiles == []:
        return files
    else:
        return newfiles