Example #1
0
def irafglob(inlist, atfile=None):
    """ Returns a list of filenames based on the type of IRAF input.

    Handles lists, wild-card characters, and at-files.  For special
    at-files, use the atfile keyword to process them.

    This function is recursive, so IRAF lists can also contain at-files
    and wild-card characters, e.g. `a.fits`, `@file.lst`, `*flt.fits`.
    """

    # Sanity check
    if inlist == None or len(inlist) == 0:
        return []

    # Determine which form of input was provided:
    if isinstance(inlist, list):
        #  python list
        flist = []
        for f in inlist:
            flist += irafglob(f)
    elif ',' in inlist:
        #  comma-separated string list
        flist = []
        for f in inlist.split(','):
            f = f.strip()
            flist += irafglob(f)
    elif inlist[0] == '@':
        #  file list
        flist = []
        for f in open(inlist[1:], 'r').readlines():
            f = f.rstrip()
            # hook for application specific atfiles.
            if atfile:
                f = atfile(f)
            flist += irafglob(f)
    else:
        #  shell globbing
        if osfn:
            inlist = osfn(inlist)
        flist = glob.glob(inlist)

    return flist
Example #2
0
def readASNTable(fname, output=None, prodonly=False):
    """
    Given a fits filename repesenting an association table reads in the table as a
    dictionary which can be used by pydrizzle and multidrizzle.

    :Algorithm: An association table is a FITS binary table with 2 required columns: 'MEMNAME',
                'MEMTYPE'. It checks 'MEMPRSNT' column and removes all files for which its value is 'no'.

    Examples
    ========
    An association table can be read from a file using the following commands::

        >>> from stsci.tools import asnutil
        >>> asntab = asnutil.readASNTable('j8bt06010_shifts_asn.fits', prodonly=False)

    The `asntab` object can now be passed to other code to provide relationships
    between input and output images defined by the association table.


    Parameters
    ==========
    `fname`: string
             name of association table
    `output`: string
              name of output product - if not specified by the user,
              the first PROD-DTH name is used if present,
              if not, the first PROD-RPT name is used if present,
              if not, the rootname of the input association table is used.
    `prodonly`: bool
                what files should be considered as input
                if True - select only MEMTYPE=PROD* as input
                if False - select only MEMTYPE=EXP as input

    Returns
    =======
    `asndict`: dict-object
               A dictionary-like object with all the association information

    """

    try:
        f = fits.open(fu.osfn(fname))
    except:
        raise IOError, "Can't open file %s\n" % fname

    colnames = f[1].data.names
    try:
        colunits = f[1].data.units
    except AttributeError: pass

    hdr = f[0].header

    if 'MEMNAME' not in colnames or 'MEMTYPE' not in colnames:
        msg = 'Association table incomplete: required column(s) MEMNAME/MEMTYPE NOT found!'
        raise ValueError, msg

    d = {}
    for n in colnames:
        d[n]=f[1].data.field(n)
    f.close()

    valid_input = d['MEMPRSNT'].copy()
    memtype = d['MEMTYPE'].copy()
    prod_dth = (memtype.find('PROD-DTH')==0).nonzero()[0]
    prod_rpt = (memtype.find('PROD-RPT')==0).nonzero()[0]
    prod_crj = (memtype.find('PROD-CRJ')==0).nonzero()[0]

    # set output name
    if output == None:
        if prod_dth:
            output = d['MEMNAME'][prod_dth[0]]
        elif prod_rpt:
            output = d['MEMNAME'][prod_rpt[0]]
        elif prod_crj:
            output = d['MEMNAME'][prod_crj[0]]
        else:
            output = fname.split('_')[0]

    if prodonly:
        input = d['MEMTYPE'].find('PROD')==0
        if prod_dth:
            input[prod_dth] = False
    else:
        input = (d['MEMTYPE'].find('EXP')==0)
    valid_input *= input

    for k in d.keys():
        d[k] = d[k][valid_input]

    infiles = list(d['MEMNAME'].lower())
    if not infiles:
        print "No valid input specified"
        return None

    if ('XOFFSET' in colnames and d['XOFFSET'].any()) or ('YOFFSET' in colnames and d['YOFFSET'].any()):
        abshift = True
        dshift = False
        try:
            units=colunits[colnames.index('XOFFSET')]
        except: units='pixels'
        xshifts = list(d['XOFFSET'])
        yshifts = list(d['YOFFSET'])
    elif ('XDELTA' in colnames and d['XDELTA'].any()) or  ('YDELTA' in colnames and d['YDELTA'].any()):
        abshift = False
        dshift = True
        try:
            units=colunits[colnames.index('XDELTA')]
        except: units='pixels'
        xshifts = list(d['XDELTA'])
        yshifts = list(d['YDELTA'])
    else:
        abshift = False
        dshift = False
    members = {}

    if not abshift and not dshift:
        asndict = ASNTable(infiles,output=output)
        asndict.create()
        return asndict
    else:
        try:
            refimage = hdr['refimage']
        except KeyError: refimage = None
        try:
            frame = hdr['shframe']
        except KeyError: frame = 'input'
        if 'ROTATION' in colnames:
            rots = list(d['ROTATION'])
        if 'SCALE' in colnames:
            scales = list(d['SCALE'])

        for r in range(len(infiles)):
            row = r
            xshift = xshifts[r]
            yshift = yshifts[r]
            if rots: rot = rots[r]
            if scales: scale = scales[r]
            members[infiles[r]] = ASNMember(row=row, dshift=dshift, abshift=abshift, rot=rot, xshift=xshift,
                                      yshift=yshift, scale=scale, refimage=refimage, shift_frame=frame,
                                      shift_units=units)


        asndict= ASNTable(infiles, output=output)
        asndict.create()
        asndict['members'].update(members)
        return asndict
Example #3
0
    def __init__(self, rootname,header=None,shape=None,pa_key='PA_V3',new=no,prefix=None):
        # Initialize wcs dictionaries:
        #   wcsdef - default values for new images
        #   wcstrans - translation table from header keyword to attribute
        #   wcskeys  - keywords in the order they should appear in the header
        self.wcsdef = {'crpix1':0.0,'crpix2':0.0,'crval1':0.0,'crval2':0.0,'cd11':1.0,
                'cd12':1.0,'cd21':1.0,'cd22':1.0,'orient':1.0,'naxis1':0,'naxis2':0,'pscale':1.0,
                'postarg1':0.0,'postarg2':0.0,'pa_obs':0.0,
                'ctype1':'RA---TAN','ctype2':'DEC--TAN'}
        self.wcstrans = {'CRPIX1':'crpix1','CRPIX2':'crpix2','CRVAL1':'crval1','CRVAL2':'crval2',
            'CD1_1':'cd11','CD1_2':'cd12','CD2_1':'cd21','CD2_2':'cd22',
            'ORIENTAT':'orient', 'NAXIS1':'naxis1','NAXIS2':'naxis2',
            'pixel scale':'pscale','CTYPE1':'ctype1','CTYPE2':'ctype2'}
        self.wcskeys = ['NAXIS1','NAXIS2','CRPIX1','CRPIX2',
                        'CRVAL1','CRVAL2','CTYPE1','CTYPE2',
                        'CD1_1','CD1_2','CD2_1','CD2_2',
                        'ORIENTAT']
        # Now, read in the CRPIX1/2, CRVAL1/2, CD1/2_1/2 keywords.
        # Simplistic, but easy to understand what you are asking for.

        _exists = yes
        if rootname != None:
            self.rootname = rootname
        else:
            self.rootname = 'New'
            new = yes
            _exists = no

        # Initialize attribute for GEIS image name, just in case...
        self.geisname = None

        # Look for extension specification in rootname
        _indx = _section = string.find(self.rootname,'[')
        # If none are found, use entire rootname
        if _indx < 0:
            _indx = len(self.rootname)

        # Determine whether we are working with a new image or not.
        _dir,_rootname = os.path.split(fileutil.osfn(self.rootname[:_indx]))
        if _dir:
            _filename = _dir+os.sep+_rootname
        else:
            _filename = _rootname
        self.filename = _filename

        if not new:
            _exists = fileutil.checkFileExists(_rootname,directory=_dir)

        else:
            _exists = no

        # If no header has been provided, get the PRIMARY and the
        # specified extension header... This call uses the fully
        # expanded version of the filename, plus any sections listed by
        # by the user in the original rootname.
        if not header and _exists:
            _hdr_file = _filename+self.rootname[_indx:]
            _header = fileutil.getHeader(_hdr_file)
        else:
            # Otherwise, simply use the header already read into memory
            # for this exposure/chip.
            _header = header

        if _exists or header:
            # Initialize WCS object with keyword values...
            try:
                _dkey = 'orientat'
                if 'orientat' in _header:
                    self.orient = _header['orientat']
                else:
                    self.orient = None

                if _header['naxis'] == 0 and 'pixvalue' in _header:

                # Check for existence of NPIX/PIXVALUE keywords
                # which represent a constant array extension
                    _dkey = 'npix1'
                    self.naxis1 = _header['npix1']
                    _dkey = 'npix2'
                    self.naxis2 = _header['npix2']
                    _dkey = 'pixvalue'
                    self.pixvalue = _header['pixvalue']
                else:
                    _dkey = 'naxis1'
                    self.naxis1 = _header['naxis1']
                    _dkey = 'naxis2'
                    self.naxis2 = _header['naxis2']
                    self.pixvalue = None

                self.npix1 = self.naxis1
                self.npix2 = self.naxis2

                for key in self.wcstrans.keys():
                    _dkey = self.wcstrans[key]
                    if _dkey not in ['pscale','orient','naxis1','naxis2']:
                        self.__dict__[_dkey] = _header[key]

                self.new = no
            except:
                print 'Could not find WCS keyword: ',_dkey
                raise IOError,'Image %s does not contain all required WCS keywords!' % self.rootname

            # Now, try to read in POSTARG keyword values, if they exist...
            try:
                self.postarg1 = _header['postarg1']
                self.postarg2 = _header['postarg2']
            except:
                # If these keywords, don't exist set defaults...
                self.postarg1 = 0.0
                self.postarg2 = 0.0
            try:
                self.pa_obs = _header[pa_key]
            except:
                # If no such keyword exists, use orientat value later
                self.pa_obs = None

        else:
            # or set default values...
            self.new = yes
            for key in self.wcsdef.keys():
                self.__dict__[key] = self.wcsdef[key]

            if shape != None:
                # ... and update with user values.
                self.naxis1 = int(shape[0])
                self.naxis2 = int(shape[1])
                self.pscale = float(shape[2])

        # Make sure reported 'orient' is consistent with CD matrix
        # while preserving the original 'ORIENTAT' keyword value
        self.orientat = self.orient

        self.orient = RADTODEG(N.arctan2(self.cd12,self.cd22))

        # If no keyword provided pa_obs value (PA_V3), then default to
        # image orientation from CD matrix.
        if self.pa_obs == None:
            self.pa_obs = self.orient

        if shape == None:
            self.set_pscale()
            #self.pscale = N.sqrt(N.power(self.cd11,2)+N.power(self.cd21,2)) * 3600.
            # Use Jacobian determination of pixel scale instead of X or Y separately...
            #self.pscale = N.sqrt(abs(self.cd11*self.cd22 - self.cd12*self.cd21))*3600.

        # Establish an attribute for the linearized orient
        # defined as the orientation of the CD after applying the default
        # distortion correction.
        self._orient_lin = 0.

        # attribute to define format for printing WCS
        self.__format__=yes

        # Keep track of the keyword names used as the backup keywords
        # for the original WCS values
        #    backup - dict relating active keywords with backup keywords
        #    prepend - string prepended to active keywords to create backup keywords
        #    orig_wcs - dict containing orig keywords and values
        self.backup = {}
        self.revert = {}
        self.prepend = None
        self.orig_wcs = {}
        # Read in any archived WCS keyword values, if they exist
        self.read_archive(_header,prepend=prefix)