Example #1
0
def makecorr(fname, allowed_corr):
    """
    Purpose
    =======
    Applies corrections to the WCS of a single file

    :Parameters:
    `fname`: string
             file name
    `acorr`: list
             list of corrections to be applied
    """
    logger.info("Allowed corrections: {0}".format(allowed_corr))
    f = fits.open(fname, mode='update')
    #Determine the reference chip and create the reference HSTWCS object
    nrefchip, nrefext = getNrefchip(f)
    wcsutil.restoreWCS(f, nrefext, wcskey='O')
    rwcs = HSTWCS(fobj=f, ext=nrefext)
    rwcs.readModel(update=True, header=f[nrefext].header)

    if 'DET2IMCorr' in allowed_corr:
        kw2update = det2im.DET2IMCorr.updateWCS(f)
        for kw in kw2update:
            f[1].header[kw] = kw2update[kw]

    for i in range(len(f))[1:]:
        extn = f[i]

        if 'extname' in extn.header:
            extname = extn.header['extname'].lower()
            if extname == 'sci':
                wcsutil.restoreWCS(f, ext=i, wcskey='O')
                sciextver = extn.header['extver']
                ref_wcs = rwcs.deepcopy()
                hdr = extn.header
                ext_wcs = HSTWCS(fobj=f, ext=i)
                ### check if it exists first!!!
                # 'O ' can be safely archived again because it has been restored first.
                wcsutil.archiveWCS(f,
                                   ext=i,
                                   wcskey="O",
                                   wcsname="OPUS",
                                   reusekey=True)
                ext_wcs.readModel(update=True, header=hdr)
                for c in allowed_corr:
                    if c != 'NPOLCorr' and c != 'DET2IMCorr':
                        corr_klass = corrections.__getattribute__(c)
                        kw2update = corr_klass.updateWCS(ext_wcs, ref_wcs)
                        for kw in kw2update:
                            hdr[kw] = kw2update[kw]
                # give the primary WCS a WCSNAME value
                idcname = f[0].header.get('IDCTAB', " ")
                if idcname.strip() and 'idc.fits' in idcname:
                    wname = ''.join([
                        'IDC_',
                        utils.extract_rootname(idcname, suffix='_idc')
                    ])
                else:
                    wname = " "
                hdr['WCSNAME'] = wname

            elif extname in ['err', 'dq', 'sdq', 'samp', 'time']:
                cextver = extn.header['extver']
                if cextver == sciextver:
                    hdr = f[('SCI', sciextver)].header
                    w = pywcs.WCS(hdr, f)
                    copyWCS(w, extn.header)

            else:
                continue

    if 'NPOLCorr' in allowed_corr:
        kw2update = npol.NPOLCorr.updateWCS(f)
        for kw in kw2update:
            f[1].header[kw] = kw2update[kw]
    # Finally record the version of the software which updated the WCS
    if 'HISTORY' in f[0].header:
        f[0].header.set('UPWCSVER',
                        value=stwcs.__version__,
                        comment="Version of STWCS used to updated the WCS",
                        before='HISTORY')
        f[0].header.set('PYWCSVER',
                        value=astropy.__version__,
                        comment="Version of PYWCS used to updated the WCS",
                        before='HISTORY')
    elif 'ASN_MTYP' in f[0].header:
        f[0].header.set('UPWCSVER',
                        value=stwcs.__version__,
                        comment="Version of STWCS used to updated the WCS",
                        after='ASN_MTYP')
        f[0].header.set('PYWCSVER',
                        value=astropy.__version__,
                        comment="Version of PYWCS used to updated the WCS",
                        after='ASN_MTYP')
    else:
        # Find index of last non-blank card, and insert this new keyword after that card
        for i in range(len(f[0].header) - 1, 0, -1):
            if f[0].header[i].strip() != '':
                break
            f[0].header.set('UPWCSVER',
                            stwcs.__version__,
                            "Version of STWCS used to updated the WCS",
                            after=i)
            f[0].header.set('PYWCSVER',
                            astropy.__version__,
                            "Version of PYWCS used to updated the WCS",
                            after=i)
    # add additional keywords to be used by headerlets
    distdict = utils.construct_distname(f, rwcs)
    f[0].header['DISTNAME'] = distdict['DISTNAME']
    f[0].header['SIPNAME'] = distdict['SIPNAME']
    # Make sure NEXTEND keyword remains accurate
    f[0].header['NEXTEND'] = len(f) - 1
    f.close()
Example #2
0
def _align_1image(resample,
                  image,
                  image_ext,
                  primary_cutouts,
                  seg,
                  image_sky=None,
                  wcslin=None,
                  fitgeom='general',
                  nclip=3,
                  sigma=3.0,
                  use_weights=True,
                  cc_type='NCC',
                  combine_seg_mask=True):
    img_info = {
        'file_name': image,
        'wcs_info': [],  # a list of: [extension, original WCS, corrected WCS]
        'fits_ext': [],  # image ext. from which an image cutout was extracted
        'image_cutouts': [],
        'driz_cutouts': [],
        'blotted_cutouts': [],  # non-shifted blot images of drizzled cutouts
        'ICC': []  # interlaced (oversampled) cross-correlation images
    }

    drz_sci_fname, drz_sci_ext = parse_file_name(resample.output_sci)
    with fits.open(drz_sci_fname) as hdulist:
        drz_sci = hdulist[drz_sci_ext].data
        drz_wcs = HSTWCS(hdulist, ext=drz_sci_ext)
        if 'EXPTIME' in hdulist[drz_sci_ext].header:
            drz_exptime = hdulist[drz_sci_ext].header['EXPTIME']
        else:
            drz_exptime = hdulist[0].header['EXPTIME']
        drz_units = hdulist[drz_sci_ext].header['BUNIT']
        drz_units = 'rate' if '/' in drz_units else 'counts'

    # get image data, info and create cutouts:
    with fits.open(image) as hdulist:
        for ext in image_ext:
            img_sci = hdulist[ext].data
            img_wcs = HSTWCS(hdulist, ext=ext)
            orig_img_wcs = img_wcs.deepcopy()
            img_exptime = hdulist[0].header['EXPTIME']
            img_units = hdulist[ext].header['BUNIT']
            img_units = 'rate' if '/' in img_units else 'counts'

            if image_sky is not None and image_sky[ext] is not None:
                img_sci -= image_sky[ext]

            imgct_ext, drzct_ext = cutout.create_cutouts(
                primary_cutouts,
                seg,
                drz_sci,
                drz_wcs,
                img_sci,
                img_wcs,
                drz_data_units=drz_units,
                drz_exptime=drz_exptime,
                flt_data_units=img_units,
                flt_exptime=img_exptime,
                combine_seg_mask=combine_seg_mask)

            img_info['wcs_info'].append([ext, orig_img_wcs, img_wcs])
            img_info['fits_ext'].extend(len(imgct_ext) * [ext])
            img_info['image_cutouts'].extend(imgct_ext)
            img_info['driz_cutouts'].extend(drzct_ext)

    # find linear fit:
    fit, interlaced_cc, nonshifted_blts = find_linear_fit(
        img_cutouts=imgct_ext,
        drz_cutouts=drzct_ext,
        wcslin=wcslin,
        fitgeom=fitgeom,
        nclip=nclip,
        sigma=sigma,
        use_weights=use_weights,
        cc_type=cc_type)

    img_info['blotted_cutouts'].extend(nonshifted_blts)
    img_info['ICC'].extend(interlaced_cc)

    print("\nComputed '{:s}' fit for image {:s}:".format(fitgeom, image))

    if fitgeom == 'shift':
        print("XSH: {:.4f}  YSH: {:.4f}".format(fit['offset'][0],
                                                fit['offset'][1]))

    elif fitgeom == 'rscale' and fit['proper']:
        print(
            "XSH: {:.4f}  YSH: {:.4f}    ROT: {:.10g}    SCALE: {:.6f}".format(
                fit['offset'][0], fit['offset'][1], fit['rot'],
                fit['scale'][0]))

    elif (fitgeom == 'general' or (fitgeom == 'rscale' and not fit['proper'])):
        print("XSH: {:.4f}  YSH: {:.4f}    PROPER ROT: {:.10g}    ".format(
            fit['offset'][0], fit['offset'][1], fit['rot']))

        print("<ROT>: {:.10g}  SKEW: {:.10g}    ROT_X: {:.10g}  "
              "ROT_Y: {:.10g}".format(fit['rotxy'][2], fit['skew'],
                                      fit['rotxy'][0], fit['rotxy'][1]))

        print("<SCALE>: {:.10g}  SCALE_X: {:.10g}  SCALE_Y: {:.10g}".format(
            fit['scale'][0], fit['scale'][1], fit['scale'][2]))

    print('FIT RMSE: {:.3g}    FIT MAE: {:.3g}    IMAGE FIT RMSE: {:.3g}\n'.
          format(fit['rmse'], fit['mae'], fit['irmse']))
    nmatch = fit['resids'].shape[0]
    print('Final solution based on {:d} objects.'.format(nmatch))

    # correct WCS:
    for ext, owcs, wcs in img_info['wcs_info']:
        correct_wcs(imwcs=wcs,
                    wcslin=drz_wcs,
                    rotmat=fit['matrix'],
                    shifts=fit['offset'],
                    fitgeom=fitgeom)

        print("\n------- ORIGINAL WCS for '{:s}[{}]': ------".format(
            image, ext))
        print(owcs)

        print("\n------- CORRECTED WCS for '{:s}[{}]': ------".format(
            image, ext))
        print(wcs)

    return fit, img_info