Beispiel #1
0
def restoreWCS(f, ext, wcskey=" ", wcsname=" "):
    """
    Copy a WCS with key "WCSKEY" to the primary WCS

    Reads in a WCS defined with wcskey and saves it as the primary WCS.
    Goes sequentially through the list of extensions in ext.
    Alternatively uses 'fromext' and 'toext'.


    Parameters
    ----------
    f : str or `astropy.io.fits.HDUList`
        file name or a file object
    ext : int, tuple, str, or list of integers or tuples (e.g.('sci',1))
        fits extensions to work with
        If a string is provided, it should specify the EXTNAME of extensions
        with WCSs to be archived
    wcskey : str
        "A"-"Z" - Used for one of 26 alternate WCS definitions.
        or " " - find a key from WCSNAMe value
    wcsname : str
        (optional) if given and wcskey is " ", will try to restore by WCSNAME value

    See Also
    --------
    archiveWCS - copy the primary WCS as an alternate WCS
    restore_from_to

    """
    if isinstance(f, str):
        fobj = fits.open(f, mode='update')
    else:
        fobj = f

    if not _parpasscheck(fobj, ext=ext, wcskey=wcskey):
        closefobj(f, fobj)
        raise ValueError("Input parameters problem")

    # Interpret input 'ext' value to get list of extensions to process
    ext = _buildExtlist(fobj, ext)

    # the case of an HDUList object in memory without an associated file

    wcskeyext = 0 if fu.isFits(fobj)[1] == 'simple' else 1

    if wcskey == " ":
        if wcsname.strip():
            wcskey = getKeyFromName(fobj[wcskeyext].header, wcsname)
            if not wcskey:
                closefobj(f, fobj)
                raise KeyError(
                    f"Could not get a key from wcsname '{wcsname}'.")

    for e in ext:
        if wcskey in wcskeys(fobj, ext=e):
            _restore(fobj, wcskey, fromextnum=e, verbose=False)

    if fobj.filename() is not None:
        closefobj(f, fobj)
Beispiel #2
0
def checkFiles(input):
    """
    Checks that input files are in the correct format.
    Converts geis and waiver fits files to multiextension fits.
    """
    from stsci.tools.check_files import geis2mef, waiver2mef, checkFiles
    logger.info("\n\tChecking files %s" % input)
    removed_files = []
    newfiles = []
    if not isinstance(input, list):
        input = [input]

    for file in input:
        try:
            imgfits, imgtype = fileutil.isFits(file)
        except IOError:
            logger.warning(
                "\n\tFile %s could not be found, removing it from the input list.\n"
                % file)
            removed_files.append(file)
            continue
        # Check for existence of waiver FITS input, and quit if found.
        # Or should we print a warning and continue but not use that file
        if imgfits:
            if imgtype == 'waiver':
                newfilename = waiver2mef(file, convert_dq=True)
                if newfilename == None:
                    logger.warning(
                        "\n\tRemoving file %s from input list - could not convert waiver to mef"
                        % file)
                    removed_files.append(file)
                else:
                    newfiles.append(newfilename)
            else:
                newfiles.append(file)

        # If a GEIS image is provided as input, create a new MEF file with
        # a name generated using 'buildFITSName()'
        # Convert the corresponding data quality file if present
        if not imgfits:
            newfilename = geis2mef(file, convert_dq=True)
            if newfilename == None:
                logger.warning(
                    "\n\tRemoving file %s from input list - could not convert geis to mef"
                    % file)
                removed_files.append(file)
            else:
                newfiles.append(newfilename)
    if removed_files:
        logger.warning(
            '\n\tThe following files will be removed from the list of files to be processed %s'
            % removed_files)

    newfiles = checkFiles(newfiles)[0]
    logger.info(
        "\n\tThese files passed the input check and will be processed: %s" %
        newfiles)
    return newfiles
Beispiel #3
0
def countInput(input):
    files = parseinput.parseinput(input)
    count = len(files[0])
    for f in files[0]:
        if fileutil.isFits(f)[0]:
            try:
                ins = fits.getval(f, 'INSTRUME')
            except: # allow odd fits files; do not stop the count
                ins = None
            if ins == 'STIS':
                count += (stisObsCount(f)-1)
    return count
Beispiel #4
0
def countInput(input):
    files = parseinput.parseinput(input)
    count = len(files[0])
    for f in files[0]:
        if fileutil.isFits(f)[0]:
            try:
                ins = fits.getval(f, 'INSTRUME')
            except:  # allow odd fits files; do not stop the count
                ins = None
            if ins == 'STIS':
                count += (stisObsCount(f) - 1)
    return count
Beispiel #5
0
def checkFiles(input):
    """
    Checks that input files are in the correct format.
    Converts geis and waiver fits files to multiextension fits.
    """
    from stsci.tools.check_files import geis2mef, waiver2mef, checkFiles
    logger.info("\n\tChecking files %s" % input)
    removed_files = []
    newfiles = []
    if not isinstance(input, list):
        input = [input]

    for file in input:
        try:
                imgfits, imgtype = fileutil.isFits(file)
        except IOError:
            logger.warning("File {0} could not be found, removing it from the"
                           "input list.".format(file))
            removed_files.append(file)
            continue
        # Check for existence of waiver FITS input, and quit if found.
        # Or should we print a warning and continue but not use that file
        if imgfits:
            if imgtype == 'waiver':
                newfilename = waiver2mef(file, convert_dq=True)
                if newfilename is None:
                    logger.warning("Could not convert waiver to mef."
                                   "Removing file {0} from input list".format(file))
                    removed_files.append(file)
                else:
                    newfiles.append(newfilename)
            else:
                newfiles.append(file)

        # If a GEIS image is provided as input, create a new MEF file with
        # a name generated using 'buildFITSName()'
        # Convert the corresponding data quality file if present
        if not imgfits:
            newfilename = geis2mef(file, convert_dq=True)
            if newfilename is None:
                logger.warning("Could not convert file {0} from geis to mef, removing it from input list".format(file))
                removed_files.append(file)
            else:
                newfiles.append(newfilename)
    if removed_files:
        logger.warning('\n\tThe following files will be removed from the list of files',
                       'to be processed %s' % removed_files)

    newfiles = checkFiles(newfiles)[0]
    logger.info("\n\tThese files passed the input check and will be processed: %s" % newfiles)
    return newfiles
Beispiel #6
0
def convert2fits(sci_ivm):
    """
    Checks if a file is in WAIVER of GEIS format and converts it to MEF
    """
    removed_files = []
    translated_names = []
    newivmlist = []

    for file in sci_ivm:
        #find out what the input is
        # if science file is not found on disk, add it to removed_files for removal
        try:
            imgfits, imgtype = fileutil.isFits(file[0])
        except IOError:
            print("Warning:  File %s could not be found" % file[0])
            print("Warning:  Removing file %s from input list" % file[0])
            removed_files.append(file[0])
            continue

        # Check for existence of waiver FITS input, and quit if found.
        # Or should we print a warning and continue but not use that file
        if imgfits and imgtype == 'waiver':
            newfilename = waiver2mef(file[0], convert_dq=True)
            if newfilename == None:
                print(
                    "Removing file %s from input list - could not convert WAIVER format to MEF\n"
                    % file[0])
                removed_files.append(file[0])
            else:
                removed_files.append(file[0])
                translated_names.append(newfilename)
                newivmlist.append(file[1])

        # If a GEIS image is provided as input, create a new MEF file with
        # a name generated using 'buildFITSName()'
        # Convert the corresponding data quality file if present
        if not imgfits:
            newfilename = geis2mef(file[0], convert_dq=True)
            if newfilename == None:
                print(
                    "Removing file %s from input list - could not convert GEIS format to MEF\n"
                    % file[0])
                removed_files.append(file[0])
            else:
                removed_files.append(file[0])
                translated_names.append(newfilename)
                newivmlist.append(file[1])

    return removed_files, translated_names, newivmlist
Beispiel #7
0
def convert2fits(sci_ivm):
    """
    Checks if a file is in WAIVER of GEIS format and converts it to MEF
    """
    removed_files = []
    translated_names = []
    newivmlist = []

    for file in sci_ivm:
        #find out what the input is
        # if science file is not found on disk, add it to removed_files for removal
        try:
            imgfits,imgtype = fileutil.isFits(file[0])
        except IOError:
            print("Warning:  File %s could not be found" %file[0])
            print("Warning:  Removing file %s from input list" %file[0])
            removed_files.append(file[0])
            continue

        # Check for existence of waiver FITS input, and quit if found.
        # Or should we print a warning and continue but not use that file
        if imgfits and imgtype == 'waiver':
            newfilename = waiver2mef(file[0], convert_dq=True)
            if newfilename is None:
                print("Removing file %s from input list - could not convert WAIVER format to MEF\n" %file[0])
                removed_files.append(file[0])
            else:
                removed_files.append(file[0])
                translated_names.append(newfilename)
                newivmlist.append(file[1])

        # If a GEIS image is provided as input, create a new MEF file with
        # a name generated using 'buildFITSName()'
        # Convert the corresponding data quality file if present
        if not imgfits:
            newfilename = geis2mef(file[0], convert_dq=True)
            if newfilename is None:
                print("Removing file %s from input list - could not convert GEIS format to MEF\n" %file[0])
                removed_files.append(file[0])
            else:
                removed_files.append(file[0])
                translated_names.append(newfilename)
                newivmlist.append(file[1])

    return removed_files, translated_names, newivmlist
    def _make_odd_signs(self):
        """
        Determine odd number of pixels
        """
        import math
        from astropy.io import fits as pyfits

        # get the x-and y-dimension
        ftype = fileutil.isFits(self.mdrizzle_image)
        if ftype[1] == "mef":
            ext = 1
        else:
            ext = 0
        fits_im = pyfits.open(self.mdrizzle_image, 'readonly')
        x_dim = fits_im[ext].data.shape[1]
        y_dim = fits_im[ext].data.shape[0]
        fits_im.close()

        # return a tuple with odd-signs for x and y
        return (math.fmod(float(x_dim), 2.0) > 0.0,
                (math.fmod(float(y_dim), 2.0) > 0.0))
Beispiel #9
0
def parse_colnames(colnames, coords=None):
    """ Convert colnames input into list of column numbers.
    """
    cols = []
    if not isinstance(colnames, list):
        colnames = colnames.split(',')
    # parse column names from coords file and match to input values
    if coords is not None and fileutil.isFits(coords)[0]:
        # Open FITS file with table
        ftab = fits.open(coords, memmap=False)
        # determine which extension has the table
        for extn in ftab:
            if isinstance(extn, fits.BinTableHDU):
                # parse column names from table and match to inputs
                cnames = extn.columns.names
                if colnames is not None:
                    for c in colnames:
                        for name, i in zip(cnames, list(range(len(cnames)))):
                            if c == name.lower(): cols.append(i)
                    if len(cols) < len(colnames):
                        errmsg = "Not all input columns found in table..."
                        ftab.close()
                        raise ValueError(errmsg)
                else:
                    cols = cnames[:2]
                break
        ftab.close()
    else:
        for c in colnames:
            if isinstance(c, str):
                if c[0].lower() == 'c': cols.append(int(c[1:]) - 1)
                else:
                    cols.append(int(c))
            else:
                if isinstance(c, int):
                    cols.append(c)
                else:
                    errmsg = "Unsupported column names..."
                    raise ValueError(errmsg)
    return cols
Beispiel #10
0
def parse_colnames(colnames,coords=None):
    """ Convert colnames input into list of column numbers.
    """
    cols = []
    if not isinstance(colnames,list):
        colnames = colnames.split(',')
    # parse column names from coords file and match to input values
    if coords is not None and fileutil.isFits(coords)[0]:
        # Open FITS file with table
        ftab = fits.open(coords, memmap=False)
        # determine which extension has the table
        for extn in ftab:
            if isinstance(extn, fits.BinTableHDU):
                # parse column names from table and match to inputs
                cnames = extn.columns.names
                if colnames is not None:
                    for c in colnames:
                        for name,i in zip(cnames,list(range(len(cnames)))):
                            if c == name.lower(): cols.append(i)
                    if len(cols) < len(colnames):
                        errmsg = "Not all input columns found in table..."
                        ftab.close()
                        raise ValueError(errmsg)
                else:
                    cols = cnames[:2]
                break
        ftab.close()
    else:
        for c in colnames:
            if isinstance(c, str):
                if c[0].lower() == 'c': cols.append(int(c[1:])-1)
                else:
                    cols.append(int(c))
            else:
                if isinstance(c, int):
                    cols.append(c)
                else:
                    errmsg = "Unsupported column names..."
                    raise ValueError(errmsg)
    return cols
Beispiel #11
0
def rd2xy(input,ra=None,dec=None,coordfile=None,colnames=None,
            precision=6,output=None,verbose=True):
    """ Primary interface to perform coordinate transformations from
        pixel to sky coordinates using STWCS and full distortion models
        read from the input image header.
    """
    single_coord = False
    if coordfile is not None:
        if colnames in blank_list:
            colnames = ['c1','c2']
        elif isinstance(colnames,type('a')):
            colnames = colnames.split(',')
        # convert input file coordinates to lists of decimal degrees values
        xlist,ylist = tweakutils.readcols(coordfile,cols=colnames)
    else:
        if isinstance(ra,np.ndarray):
            ralist = ra.tolist()
            declist = dec.tolist()
        elif not isinstance(ra, list):
            ralist = [ra]
            declist = [dec]
        else:
            ralist = ra
            declist = dec
        xlist  = [0]*len(ralist)
        ylist = [0]*len(ralist)
        if len(xlist) == 1:
            single_coord = True
        for i,(r,d) in enumerate(zip(ralist,declist)):
            # convert input value into decimal degrees value
            xval,yval = tweakutils.parse_skypos(r,d)
            xlist[i] = xval
            ylist[i] = yval

    # start by reading in WCS+distortion info for input image
    inwcs = wcsutil.HSTWCS(input)
    if inwcs.wcs.is_unity():
        print("####\nNo valid WCS found in {}.\n  Results may be invalid.\n####\n".format(input))

    # Now, convert pixel coordinates into sky coordinates
    try:
        outx,outy = inwcs.all_world2pix(xlist,ylist,1)
    except RuntimeError:
        outx,outy = inwcs.wcs_world2pix(xlist,ylist,1)

    # add formatting based on precision here...
    xstr = []
    ystr = []
    fmt = "%."+repr(precision)+"f"
    for x,y in zip(outx,outy):
        xstr.append(fmt%x)
        ystr.append(fmt%y)

    if verbose or (not verbose and util.is_blank(output)):
        print ('# Coordinate transformations for ',input)
        print('# X      Y         RA             Dec\n')
        for x,y,r,d in zip(xstr,ystr,xlist,ylist):
            print("%s  %s    %s  %s"%(x,y,r,d))

    # Create output file, if specified
    if output:
        f = open(output,mode='w')
        f.write("# Coordinates converted from %s\n"%input)
        for x,y in zip(xstr,ystr):
            f.write('%s    %s\n'%(x,y))
        f.close()
        print('Wrote out results to: ',output)

    if single_coord:
        outx = outx[0]
        outy = outy[0]
    return outx,outy

    """ Convert colnames input into list of column numbers
    """
    cols = []
    if not isinstance(colnames,list):
        colnames = colnames.split(',')

    # parse column names from coords file and match to input values
    if coordfile is not None and fileutil.isFits(coordfile)[0]:
        # Open FITS file with table
        ftab = fits.open(coordfile)
        # determine which extension has the table
        for extn in ftab:
            if isinstance(extn, fits.BinTableHDU):
                # parse column names from table and match to inputs
                cnames = extn.columns.names
                if colnames is not None:
                    for c in colnames:
                        for name,i in zip(cnames,list(range(len(cnames)))):
                            if c == name.lower(): cols.append(i)
                    if len(cols) < len(colnames):
                        errmsg = "Not all input columns found in table..."
                        ftab.close()
                        raise ValueError(errmsg)
                else:
                    cols = cnames[:2]
                break
        ftab.close()
    else:
        for c in colnames:
            if isinstance(c, str):
                if c[0].lower() == 'c':
                    cols.append(int(c[1:])-1)
                else:
                    cols.append(int(c))
            else:
                if isinstance(c, int):
                    cols.append(c)
                else:
                    errmsg = "Unsupported column names..."
                    raise ValueError(errmsg)
    return cols
def checkFiles(filelist, ivmlist = None):
    """
    1. Converts waiver fits sciece and data quality files to MEF format
    2. Converts all GEIS science and data quality files to MEF format
    3. Checks for stis association tables
    4. Checks if kw idctab exists, if not tries to populate it
        based on the spt file
    5. Removes files with EXPTIME=0 and the corresponding ivm files
    6. Removes files with NGOODPIX == 0 (to exclude saturated images)
    """
    #newfilelist = []
    removed_files = []
    translated_names = []
    newivmlist = []

    if ivmlist == None:
        ivmlist = [None for l in filelist]

    sci_ivm = zip(filelist, ivmlist)

    for file in sci_ivm:
        #find out what the input is
        # if science file is not found on disk, add it to removed_files for removal
        try:
            imgfits,imgtype = fileutil.isFits(file[0])
        except IOError:
            print("Warning:  File %s could not be found\n" %file[0])
            print("Removing file %s from input list" %file[0])
            removed_files.append(file)
            continue
        if file[1] != None:
            #If an ivm file is not found on disk
            # Remove the corresponding science file
            try:
                ivmfits,ivmtype = fileutil.isFits(file[1])
            except IOError:
                print("Warning:  File %s could not be found\n" %file[1])
                print("Removing file %s from input list" %file[0])
                removed_files.append(file)
        # Check for existence of waiver FITS input, and quit if found.
        # Or should we print a warning and continue but not use that file
        if imgfits and imgtype == 'waiver':
            newfilename = waiver2mef(file[0], convert_dq=True)
            if newfilename == None:
                print("Removing file %s from input list - could not convert waiver to mef" %file[0])
                removed_files.append(file[0])
            else:
                translated_names.append(newfilename)

        # If a GEIS image is provided as input, create a new MEF file with
        # a name generated using 'buildFITSName()'
        # Convert the corresponding data quality file if present
        if not imgfits:
            newfilename = geis2mef(file[0], convert_dq=True)
            if newfilename == None:
                print("Removing file %s from input list - could not convert geis to mef" %file[0])
                removed_files.append(file[0])
            else:
                translated_names.append(newfilename)
        if file[1] != None:
            if ivmfits and ivmtype == 'waiver':
                print("Warning: PyDrizzle does not support waiver fits format.\n")
                print("Convert the input files to GEIS or multiextension FITS.\n")
                print("File %s appears to be in waiver fits format \n" %file[1])
                print("Removing file %s from input list" %file[0])
                removed_files.append(file[0])

            if not ivmfits:
                newfilename = geis2mef(file[1], convert_dq=False)
                if newfilename == None:
                    print("Removing file %s from input list" %file[0])
                    removed_files.append(file[0])
                else:
                    newivmlist.append(newfilename)

    newfilelist, ivmlist = update_input(filelist, ivmlist, removed_files)

    if newfilelist == []:
        return [], []
    """
    errormsg = "\n No valid input was found. Quitting ...\n"
    raise IOError, errormsg
    """
    if translated_names != []:
        # Since we don't allow input from different instruments
        # we can abandon the original input list and provide as
        # input only the translated names
        removed_expt_files = check_exptime(translated_names)
        newfilelist, ivmlist = update_input(translated_names, newivmlist, removed_expt_files)
    else:
        # check for STIS association files. This must be done before
        # the check for EXPTIME in order to handle correctly stis
        # assoc files
        if pyfits.getval(newfilelist[0], 'INSTRUME') == 'STIS':
            newfilelist, ivmlist = checkStisFiles(newfilelist, ivmlist)
            #removed_files = check_exptime(newflist)

        removed_expt_files = check_exptime(newfilelist)
        newfilelist, ivmlist = update_input(newfilelist, ivmlist, removed_expt_files)
    if removed_expt_files:
        errorstr =  "#############################################\n"
        errorstr += "#                                           #\n"
        errorstr += "# ERROR:                                    #\n"
        errorstr += "#                                           #\n"
        errorstr += "#  The following files were excluded from   #\n"
        errorstr += "#  Multidrizzle processing because their    #\n"
        errorstr += "#  header keyword EXPTIME values were 0.0:  #\n"
        for name in removed_expt_files:
            errorstr += "         "+ str(name) + "\n"
        errorstr += "#                                           #\n"
        errorstr += "#############################################\n\n"
        print(errorstr)

    removed_ngood_files = checkNGOODPIX(newfilelist)
    newfilelist, ivmlist = update_input(newfilelist, ivmlist, removed_ngood_files)
    if removed_ngood_files:
        msgstr =  "####################################\n"
        msgstr += "#                                  #\n"
        msgstr += "# WARNING:                         #\n"
        msgstr += "#  NGOODPIX keyword value of 0 in  #\n"
        for name in removed_ngood_files:
            msgstr += "         "+ str(name) + "\n"
        msgstr += "#  has been detected.  Images with #\n"
        msgstr += "#  no valid pixels will not be     #\n"
        msgstr += "#  used during processing.  If you #\n"
        msgstr += "#  wish this file to be used in    #\n"
        msgstr += "#  processing, please check its DQ #\n"
        msgstr += "#  array and reset driz_sep_bits   #\n"
        msgstr += "#  and final_bits parameters       #\n"
        msgstr += "#  to accept flagged pixels.       #\n"
        msgstr += "#                                  #\n"
        msgstr += "####################################\n"
        print(msgstr)

    return newfilelist, ivmlist
Beispiel #13
0
    def transform_toflux(self, segm_image):
        """Transform an image from cps to flux

        The method creates a flux image for a direct multidrizzled
        image. The direct image comes directly from multidrizzle,
        its unit is [cts/s], however the fluxcubes need the information
        in ergs/cm^2/s/AA.

        Parameters
        ----------
        segm_image: str
            the segmentation for the data set

        Notes
        -----
        Formulas:
        STmag = -2.5*log10(image) + self.st_zero
        STmag = -2.5*log10(F_lam) -21.10
        F_lam = 10**(-0.4*(st_zero+21.10)) * image
        """
        # get the name of the flux image
        self.flux_name = self._get_fluxname(self.image_name)

        # delete the flux image if it already exists
        if os.path.isfile(self.flux_name):
            os.unlink(self.flux_name)

        # the expression to apply to the image data
        expon = 10.0**(-0.4 * (21.10 + self.st_zero))

        _log.info(f" image_name: {self.image_name.split('[')[0]}")
        _log.info(f" segm_image: {segm_image}")
        _log.info(f" flux_name: {self.flux_name}")

        # open the input files and apply the conversion
        file_a = fits.open(self.image_name.split('[')[0], 'readonly')
        file_b = fits.open(segm_image, 'readonly')
        ftype = fileutil.isFits(file_b.filename())[1]
        if (ftype == 'mef'):
            bgt1 = file_b[1].data >= 1  # assume in first
            blt1 = file_b[1].data < 1  # assume in first
        else:
            bgt1 = file_b[0].data >= 1
            blt1 = file_b[0].data < 1

        ftype = fileutil.isFits(file_a.filename())[1]

        if (ftype == 'mef'):
            file_a['SCI'].data[bgt1] *= expon
            file_a['SCI'].data[blt1] = 0.0
        else:
            file_a[0].data[bgt1] *= expon
            file_a[0].data[blt1] = 0.0

        # concatenate the primary and extension headers for output
        # to a simple FITS file
        prihdr = file_a[0].header

        del prihdr['nextend']

        if (ftype == 'mef'):
            scihdr = file_a['SCI'].header
            scihdr._strip()
            newhdr = fits.Header(prihdr + scihdr)
            data = file_a['SCI'].data
        else:
            newhdr = fits.Header(prihdr)
            data = file_a[0].data

        # write the new flux image in simple fits format
        # regardless of input format
        fits.writeto(self.flux_name, data, newhdr)
        file_a.close()
        file_b.close()

        _log.info(f"\n{self.image_name} --> {self.flux_name}")
Beispiel #14
0
    def _a_blot_segment_image(self, image_to_blot, tempname, x_excess,
                              y_excess, interp):
        """Blot the segmentation or other nondrizzled image as if it were
        assume self.grism_image is always used as the source wcs reference
        Thats just a simple wrapper around the task blot in astrodrizzle

        Parameters
        ----------
        image_to_blot: str
            the input image name, either the grism or direct drizzled image
        tempname: str
            the name of the output blotted image

        Notes
        -----
        exposure time is hard coded to 1 since it was made from the
        drizzled image and we dont want the id numbers rescaled by the
        exposure time that was used for blotting

        """
        excess_x = 0
        excess_y = 0

        # the drizzle coeff information for adriz is taken
        # from the self.data image
        # use the current data as reference image
        input_image = (self.data).split("[")[0]
        flt_header = fits.getheader(input_image)
        flt_wcs = HSTWCS(self.data)

        # check to see if this is a simple fits or MEF and grab
        # the science information.
        ftype = fileutil.isFits(self.grism_image_name)[1]

        if (ftype is 'mef'):
            grism_wcs = HSTWCS(self.grism_image_name,
                               ext=(str(self.fcube_info["ext_nam"]),
                                    self.fcube_info["ext_ver"]))
        elif (ftype is 'simple'):
            grism_wcs = HSTWCS(self.grism_image_name)
        else:
            return IOError("File type of fits image is not "
                           "supported {0:s}".format(image_to_blot))

        ftype = fileutil.isFits(image_to_blot)[1]
        if (ftype is 'mef'):
            image_data = fits.getdata(image_to_blot,
                                      ext=(str(self.fcube_info["ext_nam"]),
                                           self.fcube_info["ext_ver"]))
        elif (ftype is 'simple'):
            image_data = fits.getdata(image_to_blot)
        else:
            return IOError("Input image is not a supported FITS "
                           "type: {0:s}".format(image_to_blot))

        # edit the wcs header information to add any dim_info shifts that we
        # need the segment image needs to be the same sky area cut without
        # the added pixels
        type(x_excess)
        if x_excess > 0:
            excess_x = int(flt_wcs.naxis1 + x_excess * 2.)
            flt_wcs.naxis1 = excess_x
            crpix = flt_wcs.wcs.crpix
            newx = int(crpix[0]) + x_excess
            flt_wcs.wcs.crpix = np.array([newx, crpix[1]])
            flt_wcs.sip.crpix[0] = newx

        if y_excess > 0:
            excess_y = int(flt_wcs.naxis2 + y_excess * 2.)
            flt_wcs.naxis2 = excess_y
            crpix = flt_wcs.wcs.crpix
            newy = int(crpix[1]) + y_excess
            flt_wcs.wcs.crpix = np.array([int(crpix[0]), newy])
            flt_wcs.sip.crpix[1] = newy

        # returns a numpy.ndarray which is just the data
        outimage = astrodrizzle.ablot.do_blot(image_data.astype(np.float32),
                                              grism_wcs,
                                              flt_wcs,
                                              1.,
                                              interp=interp,
                                              sinscl=1.,
                                              coeffs=True,
                                              wcsmap=None,
                                              stepsize=10)

        # update the flt_header with the flt_wcs information I created
        flt_header['CRPIX1'] = flt_wcs.wcs.crpix[0]
        flt_header['CRPIX2'] = flt_wcs.wcs.crpix[1]

        # if the input flt was an MEF we need to write an MEF out
        try:
            newimage = fits.PrimaryHDU()
            newimage.data = outimage
            newimage.header = flt_header
            newimage.header.update(flt_wcs.to_header())
            newimage.verify('silentfix')
            newimage.writeto(tempname)
        except:
            raise IOError("Problem writing fits image {0:s}".format(tempname))
Beispiel #15
0
    def _a_blot_image(self, image_to_blot, tempname, x_excess, y_excess,
                      interp):
        """
        Blot one image.

        Thats just a simple wrapper around the task blot in astrodrizzle

        Parameters
        ----------
        image_to_blot: str
            the input image name, either the grism or direct drizzled image

        tempname: str
            the name of the output blotted image

        """
        # the drizzle coeff information for adriz is taken
        # from the self.data image,
        excess_x = 0
        excess_y = 0

        # use the current data as reference image for output
        # self.data comes from the header of the input grism or flux image
        # and is one of the input images used to make the drizzled
        # image_to_blot
        input_image = (self.data).split("[")[0]
        bunit = fits.getval(image_to_blot, 'BUNIT')

        flt_header = fits.getheader(input_image)
        flt_wcs = HSTWCS(self.data)

        # now look at the image to blot, this is a drizzled image
        ftype = fileutil.isFits(image_to_blot)[1]

        if (ftype == 'mef'):
            blot_wcs = HSTWCS(image_to_blot,
                              ext=(str(self.fcube_info["ext_nam"]),
                                   str(self.fcube_info["ext_ver"])))
            image_data = fits.getdata(image_to_blot,
                                      extname=str(self.fcube_info["ext_nam"]),
                                      extver=int(self.fcube_info["ext_nam"]))

        elif (ftype is 'simple'):
            blot_wcs = HSTWCS(image_to_blot)  # assume simple
            image_data = fits.getdata(image_to_blot)

        else:
            return IOError("File type of fits image is not "
                           "supported {0:s}".format(image_to_blot))

        # edit the wcs header information to add any dim_info shifts that
        # we need, expanding the size of the output image
        # make sure this gets saved to the output extension header.
        # The lambda image will be bigger than the segment image
        if x_excess > 0:
            excess_x = int(flt_wcs.naxis1 + x_excess * 2.)
            flt_wcs.naxis1 = excess_x
            crpix = flt_wcs.wcs.crpix
            newx = int(crpix[0]) + x_excess
            flt_wcs.wcs.crpix = np.array([newx, int(crpix[1])])
            flt_wcs.sip.crpix[0] = newx

        if y_excess > 0:
            excess_y = int(flt_wcs.naxis2 + y_excess * 2.)
            flt_wcs.naxis2 = excess_y
            crpix = flt_wcs.wcs.crpix
            newy = int(crpix[1]) + y_excess
            flt_wcs.wcs.crpix = np.array([int(crpix[0]), newy])
            flt_wcs.sip.crpix[1] = newy

        # outimage is just the data array
        outimage = astrodrizzle.ablot.do_blot(image_data.astype(np.float32),
                                              blot_wcs,
                                              flt_wcs,
                                              1.,
                                              interp=interp,
                                              sinscl=1.,
                                              coeffs=True,
                                              wcsmap=None,
                                              stepsize=10)

        # update the flt_header with the flt_wcs information I created
        flt_header['CRPIX1'] = flt_wcs.wcs.crpix[0]
        flt_header['CRPIX2'] = flt_wcs.wcs.crpix[1]

        try:
            newimage = fits.PrimaryHDU()
            newimage.data = outimage
            newimage.header = flt_header
            newimage.header['BUNIT'] = bunit
            newimage.header.update(flt_wcs.to_header())
            newimage.verify('silentfix')
            newimage.writeto(tempname)
        except:
            raise IOError("Problem writing fits image {0:s}".format(tempname))
Beispiel #16
0
def rd2xy(input,
          ra=None,
          dec=None,
          coordfile=None,
          colnames=None,
          precision=6,
          output=None,
          verbose=True):
    """ Primary interface to perform coordinate transformations from
        pixel to sky coordinates using STWCS and full distortion models
        read from the input image header.
    """
    single_coord = False
    if coordfile is not None:
        if colnames in blank_list:
            colnames = ['c1', 'c2']
        elif isinstance(colnames, type('a')):
            colnames = colnames.split(',')
        # convert input file coordinates to lists of decimal degrees values
        xlist, ylist = tweakutils.readcols(coordfile, cols=colnames)
    else:
        if isinstance(ra, np.ndarray):
            ralist = ra.tolist()
            declist = dec.tolist()
        elif not isinstance(ra, list):
            ralist = [ra]
            declist = [dec]
        else:
            ralist = ra
            declist = dec
        xlist = [0] * len(ralist)
        ylist = [0] * len(ralist)
        if len(xlist) == 1:
            single_coord = True
        for i, (r, d) in enumerate(zip(ralist, declist)):
            # convert input value into decimal degrees value
            xval, yval = tweakutils.parse_skypos(r, d)
            xlist[i] = xval
            ylist[i] = yval

    # start by reading in WCS+distortion info for input image
    inwcs = wcsutil.HSTWCS(input)
    if inwcs.wcs.is_unity():
        print(
            "####\nNo valid WCS found in {}.\n  Results may be invalid.\n####\n"
            .format(input))

    # Now, convert pixel coordinates into sky coordinates
    try:
        outx, outy = inwcs.all_world2pix(xlist, ylist, 1)
    except RuntimeError:
        outx, outy = inwcs.wcs_world2pix(xlist, ylist, 1)

    # add formatting based on precision here...
    xstr = []
    ystr = []
    fmt = "%." + repr(precision) + "f"
    for x, y in zip(outx, outy):
        xstr.append(fmt % x)
        ystr.append(fmt % y)

    if verbose or (not verbose and util.is_blank(output)):
        print('# Coordinate transformations for ', input)
        print('# X      Y         RA             Dec\n')
        for x, y, r, d in zip(xstr, ystr, xlist, ylist):
            print("%s  %s    %s  %s" % (x, y, r, d))

    # Create output file, if specified
    if output:
        f = open(output, mode='w')
        f.write("# Coordinates converted from %s\n" % input)
        for x, y in zip(xstr, ystr):
            f.write('%s    %s\n' % (x, y))
        f.close()
        print('Wrote out results to: ', output)

    if single_coord:
        outx = outx[0]
        outy = outy[0]
    return outx, outy
    """ Convert colnames input into list of column numbers
    """
    cols = []
    if not isinstance(colnames, list):
        colnames = colnames.split(',')

    # parse column names from coords file and match to input values
    if coordfile is not None and fileutil.isFits(coordfile)[0]:
        # Open FITS file with table
        ftab = fits.open(coordfile)
        # determine which extension has the table
        for extn in ftab:
            if isinstance(extn, fits.BinTableHDU):
                # parse column names from table and match to inputs
                cnames = extn.columns.names
                if colnames is not None:
                    for c in colnames:
                        for name, i in zip(cnames, list(range(len(cnames)))):
                            if c == name.lower(): cols.append(i)
                    if len(cols) < len(colnames):
                        errmsg = "Not all input columns found in table..."
                        ftab.close()
                        raise ValueError(errmsg)
                else:
                    cols = cnames[:2]
                break
        ftab.close()
    else:
        for c in colnames:
            if isinstance(c, str):
                if c[0].lower() == 'c':
                    cols.append(int(c[1:]) - 1)
                else:
                    cols.append(int(c))
            else:
                if isinstance(c, int):
                    cols.append(c)
                else:
                    errmsg = "Unsupported column names..."
                    raise ValueError(errmsg)
    return cols
Beispiel #17
0
def restore_from_to(f, fromext=None, toext=None, wcskey=" ", wcsname=" "):
    """
    Copy an alternate WCS from one extension as a primary WCS of another extension

    Reads in a WCS defined with wcskey and saves it as the primary WCS.
    Goes sequentially through the list of extensions in ext.
    Alternatively uses 'fromext' and 'toext'.


    Parameters
    ----------
    f:       string or `astropy.io.fits.HDUList`
             a file name or a file object
    fromext: string
             extname from which to read in the alternate WCS, for example 'SCI'
    toext:   string or python list
             extname or a list of extnames to which the WCS will be copied as
             primary, for example ['SCI', 'ERR', 'DQ']
    wcskey:  a charater
             "A"-"Z" - Used for one of 26 alternate WCS definitions.
             or " " - find a key from WCSNAMe value
    wcsname: string (optional)
             if given and wcskey is " ", will try to restore by WCSNAME value

    See Also
    --------
    archiveWCS - copy the primary WCS as an alternate WCS
    restoreWCS - Copy a WCS with key "WCSKEY" to the primary WCS

    """
    if isinstance(f, str):
        fobj = fits.open(f, mode='update')
    else:
        fobj = f

    if not _parpasscheck(fobj, ext=None, wcskey=wcskey, fromext=fromext, toext=toext):
        closefobj(f, fobj)
        raise ValueError("Input parameters problem")

    # Interpret input 'ext' value to get list of extensions to process
    # ext = _buildExtlist(fobj, ext)

    if isinstance(toext, str):
        toext = [toext]

    # the case of an HDUList object in memory without an associated file

    # if fobj.filename() is not None:
    #        name = fobj.filename()

    simplefits = fu.isFits(fobj)[1] is 'simple'
    if simplefits:
        wcskeyext = 0
    else:
        wcskeyext = 1

    if wcskey == " ":
        if wcsname.strip():
            wkey = getKeyFromName(fobj[wcskeyext].header, wcsname)
            if not wkey:
                closefobj(f, fobj)
                raise KeyError("Could not get a key from wcsname %s ." % wcsname)
    else:
        if wcskey not in wcskeys(fobj, ext=wcskeyext):
            print("Could not find alternate WCS with key %s in this file" % wcskey)
            closefobj(f, fobj)
            return
        wkey = wcskey

    countext = fu.countExtn(fobj, fromext)
    if not countext:
        raise KeyError("File does not have extension with extname %s", fromext)
    else:
        for i in range(1, countext + 1):
            for toe in toext:
                _restore(fobj, fromextnum=i, fromextnam=fromext, toextnum=i, toextnam=toe, ukey=wkey)

    if fobj.filename() is not None:
        # fobj.writeto(name)
        closefobj(f, fobj)
Beispiel #18
0
def restoreWCS(f, ext, wcskey=" ", wcsname=" "):
    """
    Copy a WCS with key "WCSKEY" to the primary WCS

    Reads in a WCS defined with wcskey and saves it as the primary WCS.
    Goes sequentially through the list of extensions in ext.
    Alternatively uses 'fromext' and 'toext'.


    Parameters
    ----------
    f : str or `astropy.io.fits.HDUList`
        file name or a file object
    ext : int, tuple, str, or list of integers or tuples (e.g.('sci',1))
        fits extensions to work with
        If a string is provided, it should specify the EXTNAME of extensions
        with WCSs to be archived
    wcskey : str
        "A"-"Z" - Used for one of 26 alternate WCS definitions.
        or " " - find a key from WCSNAMe value
    wcsname : str
        (optional) if given and wcskey is " ", will try to restore by WCSNAME value

    See Also
    --------
    archiveWCS - copy the primary WCS as an alternate WCS
    restore_from_to

    """
    if isinstance(f, str):
        fobj = fits.open(f, mode='update')
    else:
        fobj = f

    if not _parpasscheck(fobj, ext=ext, wcskey=wcskey):
        closefobj(f, fobj)
        raise ValueError("Input parameters problem")

    # Interpret input 'ext' value to get list of extensions to process
    ext = _buildExtlist(fobj, ext)

    # the case of an HDUList object in memory without an associated file

    simplefits = fu.isFits(fobj)[1] is 'simple'
    if simplefits:
        wcskeyext = 0
    else:
        wcskeyext = 1

    if wcskey == " ":
        if wcsname.strip():
            wcskey = getKeyFromName(fobj[wcskeyext].header, wcsname)
            if not wcskey:
                closefobj(f, fobj)
                raise KeyError("Could not get a key from wcsname %s ." % wcsname)

    for e in ext:
        if wcskey not in wcskeys(fobj, ext=e):
            continue
        else:
            _restore(fobj, wcskey, fromextnum=e, verbose=False)

    if fobj.filename() is not None:
        closefobj(f, fobj)
Beispiel #19
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