コード例 #1
0
ファイル: mutil.py プロジェクト: spacetelescope/pydrizzle
def apply_wfc_tdd_coeffs(cx,cy,alpha,beta):
    ''' Apply the WFC TDD coefficients directly to the distortion
        coefficients.
    '''
    # Initialize variables to be used
    theta_v2v3 = 2.234529
    scale_idc = 0.05
    scale_jay = 0.04973324715
    idctheta = theta_v2v3
    idcrad = fileutil.DEGTORAD(idctheta)
    #idctheta = fileutil.RADTODEG(N.arctan2(cx[1,0],cy[1,0]))
    # Pre-compute the entire correction prior to applying it to the coeffs
    mrotp = fileutil.buildRotMatrix(idctheta)
    mrotn = fileutil.buildRotMatrix(-idctheta)
    abmat = np.array([[beta,alpha],[alpha,beta]])
    tdd_mat = np.array([[1+(beta/2048.), alpha/2048.],[alpha/2048.,1-(beta/2048.)]],np.float64)

    abmat1 = np.dot(tdd_mat, mrotn)
    abmat2 = np.dot(mrotp,abmat1)
    icxy = np.dot(abmat2,[cx.ravel(),cy.ravel()])
    icx = icxy[0]
    icy = icxy[1]
    icx.shape = cx.shape
    icy.shape = cy.shape

    return icx,icy
コード例 #2
0
    def zero_point_corr(cls, hwcs):
        if hwcs.idcmodel.refpix[
                'skew_coeffs'] is not None and 'TDD_CY_BETA' in hwcs.idcmodel.refpix[
                    'skew_coeffs']:
            v23_corr = np.array([[0.], [0.]])
            return v23_corr
        else:
            try:
                alpha = hwcs.idcmodel.refpix['TDDALPHA']
                beta = hwcs.idcmodel.refpix['TDDBETA']
            except KeyError:
                alpha = 0.0
                beta = 0.0
                v23_corr = np.array([[0.], [0.]])
                logger.debug("TDD Zero point correction for chip"
                             "{0} defaulted to: {1}".format(
                                 hwcs.chip, v23_corr))
                return v23_corr

        tdd = np.array([[beta, alpha], [alpha, -beta]])
        mrotp = fileutil.buildRotMatrix(2.234529) / 2048.
        xy0 = np.array([[cls.tdd_xyref[hwcs.chip][0] - 2048.],
                        [cls.tdd_xyref[hwcs.chip][1] - 2048.]])
        v23_corr = np.dot(mrotp, np.dot(tdd, xy0)) * 0.05
        logger.debug("TDD Zero point correction for chip {0}: {1}".format(
            hwcs.chip, v23_corr))
        return v23_corr
コード例 #3
0
    def wtraxy(self,pixpos,wcs,verbose=False):
        """
        Converts input pixel position 'pixpos' into an X,Y position in WCS.
        Made this function compatible with list input, as well as single
        tuple input..apply
        """

        # Insure that input wcs is centered for proper results
        # Added 1-Dec-2004.
        wcs.recenter()

        _ab,_cd = drutil.wcsfit(self,wcs)
        _orient = fileutil.RADTODEG(np.arctan2(_ab[1],_cd[0]))
        _scale = wcs.pscale/self.wcslin.pscale
        _xoff = _ab[2]
        _yoff = _cd[2]

        # changed from self.wcs.naxis[1/2]
        _naxis = (wcs.naxis1,wcs.naxis2)
        _rot_mat = fileutil.buildRotMatrix(_orient)

        if isinstance(pixpos, tuple):
            pixpos = [pixpos]

        _delta_x,_delta_y = self.apply(pixpos)
        if verbose:
            print('Raw corrected position: ',_delta_x,_delta_y)

        _delta_x += self.model.refpix['XDELTA']
        _delta_y += self.model.refpix['YDELTA']
        if verbose:
            print('Fully corrected position: ',_delta_x,_delta_y)

        _delta = np.zeros((len(pixpos),2),dtype=np.float32)
        _delta[:,0] = _delta_x
        _delta[:,1] = _delta_y

        # Need to 0.5 offset to xp,yp to compute the offset in the same way that
        # 'drizzle' computes it.
        #_xp = _naxis[0]/2. + 0.5
        #_yp = _naxis[1]/2. + 0.5
        _xp = _naxis[0]/2.
        _yp = _naxis[1]/2.
        _xt = _xoff + _xp
        _yt = _yoff + _yp

        if verbose:
            print('XSH,YSH: ',_xoff,_yoff)
            print('XDELTA,YDELTA: ',self.model.refpix['XDELTA'],self.model.refpix['YDELTA'])
            print('XREF,YREF: ',self.model.refpix['XREF'],self.model.refpix['YREF'])
            print('xt,yt: ',_xt,_yt,' based on xp,yp: ',_xp,_yp)

        _xy_corr = np.dot(_delta,_rot_mat) / _scale
        _delta[:,0] = _xy_corr[:,0] + _xt
        _delta[:,1] = _xy_corr[:,1] + _yt

        if len(pixpos) == 1:
            return _delta[0]
        else:
            return _delta
コード例 #4
0
ファイル: corrections.py プロジェクト: brechmos-stsci/stwcs
 def apply_tdd2idc(cls, hwcs, alpha, beta):
     """
     Applies TDD to the idctab coefficients of a ACS/WFC observation.
     This should be always the first correction.
     """
     theta_v2v3 = 2.234529
     mrotp = fileutil.buildRotMatrix(theta_v2v3)
     mrotn = fileutil.buildRotMatrix(-theta_v2v3)
     tdd_mat = np.array([[1+(beta/2048.), alpha/2048.],[alpha/2048.,1-(beta/2048.)]],np.float64)
     abmat1 = np.dot(tdd_mat, mrotn)
     abmat2 = np.dot(mrotp,abmat1)
     xshape, yshape = hwcs.idcmodel.cx.shape, hwcs.idcmodel.cy.shape
     icxy = np.dot(abmat2,[hwcs.idcmodel.cx.ravel(), hwcs.idcmodel.cy.ravel()])
     hwcs.idcmodel.cx = icxy[0]
     hwcs.idcmodel.cy = icxy[1]
     hwcs.idcmodel.cx.shape = xshape
     hwcs.idcmodel.cy.shape = yshape
コード例 #5
0
ファイル: corrections.py プロジェクト: stsci-hack/stwcs
 def apply_tdd2idc(cls, hwcs, alpha, beta):
     """
     Applies TDD to the idctab coefficients of a ACS/WFC observation.
     This should be always the first correction.
     """
     theta_v2v3 = 2.234529
     mrotp = fileutil.buildRotMatrix(theta_v2v3)
     mrotn = fileutil.buildRotMatrix(-theta_v2v3)
     tdd_mat = np.array([[1 + (beta / 2048.), alpha / 2048.],
                         [alpha / 2048., 1 - (beta / 2048.)]], np.float64)
     abmat1 = np.dot(tdd_mat, mrotn)
     abmat2 = np.dot(mrotp, abmat1)
     xshape, yshape = hwcs.idcmodel.cx.shape, hwcs.idcmodel.cy.shape
     icxy = np.dot(abmat2, [hwcs.idcmodel.cx.ravel(), hwcs.idcmodel.cy.ravel()])
     hwcs.idcmodel.cx = icxy[0]
     hwcs.idcmodel.cy = icxy[1]
     hwcs.idcmodel.cx.shape = xshape
     hwcs.idcmodel.cy.shape = yshape
コード例 #6
0
ファイル: util.py プロジェクト: bsugerman/drizzlepac
def getRotatedSize(corners, angle):
    """ Determine the size of a rotated (meta)image."""
    if angle:
        _rotm = fileutil.buildRotMatrix(angle)
        # Rotate about the center
        _corners = np.dot(corners, _rotm)
    else:
        # If there is no rotation, simply return original values
        _corners = corners

    return computeRange(_corners)
コード例 #7
0
ファイル: util.py プロジェクト: gbrammer/drizzlepac
def getRotatedSize(corners, angle):
    """ Determine the size of a rotated (meta)image."""
    if angle:
        _rotm = fileutil.buildRotMatrix(angle)
        # Rotate about the center
        _corners = np.dot(corners, _rotm)
    else:
        # If there is no rotation, simply return original values
        _corners = corners

    return computeRange(_corners)
コード例 #8
0
ファイル: mutil.py プロジェクト: spacetelescope/pydrizzle
def rotate_coeffs(cx,cy,rot,scale=1.0):
    ''' Rotate poly coeffs by 'rot' degrees.
    '''
    mrot = fileutil.buildRotMatrix(rot)*scale
    rcxy = np.dot(mrot,[cx.ravel(),cy.ravel()])
    rcx = rcxy[0]
    rcy = rcxy[1]
    rcx.shape = cx.shape
    rcy.shape = cy.shape

    return rcx,rcy
コード例 #9
0
ファイル: drutil.py プロジェクト: spacetelescope/pydrizzle
def rotatePos(pos, theta,offset=None,scale=None):

    if scale == None:
        scale = 1.

    if offset == None:
        offset = np.array([0.,0.],dtype=np.float64)
    mrot = buildRotMatrix(theta)
    xr = ((pos[0] * mrot[0][0]) + (pos[1]*mrot[0][1]) )/ scale + offset[0]
    yr = ((pos[0] * mrot[1][0]) + (pos[1]*mrot[1][1]) )/ scale + offset[1]

    return xr,yr
コード例 #10
0
def update_linCD(cdmat, delta_rot=0.0, delta_scale=1.0, cx=[0.0, 1.0], cy=[1.0, 0.0]):
    """ Modify an existing linear CD matrix with rotation and/or scale changes
        and return a new CD matrix.  If 'cx' and 'cy' are specified, it will
        return a distorted CD matrix.

        Only those terms which are varying need to be specified on input.
    """
    rotmat = fileutil.buildRotMatrix(delta_rot) * delta_scale
    new_lincd = np.dot(cdmat, rotmat)

    cxymat = np.array([[cx[1], cx[0]], [cy[1], cy[0]]])
    new_cd = np.dot(new_lincd, cxymat)

    return new_cd
コード例 #11
0
ファイル: wcs_functions.py プロジェクト: jhunkeler/drizzlepac
def update_linCD(cdmat, delta_rot=0.0, delta_scale=1.0, cx=[0.0,1.0], cy=[1.0,0.0]):
    """ Modify an existing linear CD matrix with rotation and/or scale changes
        and return a new CD matrix.  If 'cx' and 'cy' are specified, it will
        return a distorted CD matrix.

        Only those terms which are varying need to be specified on input.
    """
    rotmat = fileutil.buildRotMatrix(delta_rot)*delta_scale
    new_lincd = np.dot(cdmat,rotmat)

    cxymat = np.array([[cx[1],cx[0]],[cy[1],cy[0]]])
    new_cd = np.dot(new_lincd,cxymat)

    return new_cd
コード例 #12
0
ファイル: drutil.py プロジェクト: spacetelescope/pydrizzle
def getRotatedSize(corners,angle):
    """ Determine the size of a rotated (meta)image."""
    # If there is no rotation, simply return original values
    if angle == 0.:
        _corners = corners
    else:
        # Find center
        #_xr,_yr = computeRange(corners)
        #_cen = ( ((_xr[1] - _xr[0])/2.)+_xr[0],((_yr[1]-_yr[0])/2.)+_yr[0])
        _rotm = buildRotMatrix(angle)
        # Rotate about the center
        #_corners = np.dot(corners - _cen,_rotm)
        _corners = np.dot(corners,_rotm)

    return computeRange(_corners)
コード例 #13
0
ファイル: util.py プロジェクト: brechmos-stsci/drizzlepac
def getRotatedSize(corners, angle):
    """ Determine the size of a rotated (meta)image."""
    # If there is no rotation, simply return original values
    if angle == 0.:
        _corners = corners
    else:
        # Find center
        #_xr,_yr = computeRange(corners)
        #_cen = ( ((_xr[1] - _xr[0])/2.)+_xr[0],((_yr[1]-_yr[0])/2.)+_yr[0])
        _rotm = fileutil.buildRotMatrix(angle)
        # Rotate about the center
        #_corners = N.dot(corners - _cen,_rotm)
        _corners = np.dot(corners, _rotm)

    return computeRange(_corners)
コード例 #14
0
def create_CD(orient, scale, cx=None, cy=None):
    """ Create a (un?)distorted CD matrix from the basic inputs.

    The 'cx' and 'cy' parameters, if given, provide the X and Y coefficients of
    the distortion as returned by reading the IDCTAB.  Only the first 2 elements
    are used and should correspond to the 'OC[X/Y]10' and 'OC[X/Y]11' terms in that
    order as read from the expanded SIP headers.

    The units of 'scale' should be 'arcseconds/pixel' of the reference pixel.
    The value of 'orient' should be the absolute orientation on the sky of the
    reference pixel.

    """
    cxymat = np.array([[cx[1], cx[0]], [cy[1], cy[0]]])
    rotmat = fileutil.buildRotMatrix(orient) * scale/3600.
    new_cd = np.dot(rotmat, cxymat)
    return new_cd
コード例 #15
0
ファイル: wcs_functions.py プロジェクト: jhunkeler/drizzlepac
def create_CD(orient, scale, cx=None, cy=None):
    """ Create a (un?)distorted CD matrix from the basic inputs.

    The 'cx' and 'cy' parameters, if given, provide the X and Y coefficients of
    the distortion as returned by reading the IDCTAB.  Only the first 2 elements
    are used and should correspond to the 'OC[X/Y]10' and 'OC[X/Y]11' terms in that
    order as read from the expanded SIP headers.

    The units of 'scale' should be 'arcseconds/pixel' of the reference pixel.
    The value of 'orient' should be the absolute orientation on the sky of the
    reference pixel.

    """
    cxymat = np.array([[cx[1],cx[0]],[cy[1],cy[0]]])
    rotmat = fileutil.buildRotMatrix(orient)*scale/3600.
    new_cd = np.dot(rotmat,cxymat)
    return new_cd
コード例 #16
0
ファイル: buildwcs.py プロジェクト: sosey/drizzlepac
def mergewcs(outwcs, customwcs, wcspars):
    """ Merge the WCS keywords from user specified values into a full HSTWCS object
        This function will essentially follow the same algorithm as used by
        updatehdr only it will use direct calls to updatewcs.Makewcs methods
        instead of using 'updatewcs' as a whole
    """
    # start by working on a copy of the refwcs
    if outwcs.sip is not None:
        wcslin = stwcs.distortion.utils.undistortWCS(outwcs)
        outwcs.wcs.cd = wcslin.wcs.cd
        outwcs.wcs.set()
        outwcs.setOrient()
        outwcs.setPscale()
    else:
        wcslin = outwcs
    if customwcs is None:
        # update valid pars from wcspars
        if wcspars['crval1'] is not None:
            outwcs.wcs.crval = np.array([wcspars['crval1'], wcspars['crval2']])
        if wcspars['crpix1'] is not None:
            outwcs.wcs.crpix = np.array([wcspars['crpix1'], wcspars['crpix2']])
        if wcspars['naxis1'] is not None:
            outwcs._naxis1 = wcspars['naxis1']
            outwcs._naxis2 = wcspars['naxis2']
            outwcs.wcs.crpix = np.array(
                [outwcs._naxis1 / 2., outwcs._naxis2 / 2.])

        pscale = wcspars['pscale']
        orient = wcspars['orientat']
        if pscale is not None or orient is not None:
            if pscale is None: pscale = wcslin.pscale
            if orient is None: orient = wcslin.orientat
            pix_ratio = pscale / wcslin.pscale
            delta_rot = wcslin.orientat - orient
            delta_rot_mat = fileutil.buildRotMatrix(delta_rot)
            outwcs.wcs.cd = np.dot(outwcs.wcs.cd, delta_rot_mat) * pix_ratio
            # apply model to new linear CD matrix
            apply_model(outwcs)
    else:
        # A new fully described WCS was provided in customwcs
        outwcs.wcs.cd = customwcs.wcs.cd
        outwcs.wcs.crval = customwcs.wcs.crval
        outwcs.wcs.crpix = customwcs.wcs.crpix
        outwcs._naxis1 = customwcs._naxis1
        outwcs._naxis2 = customwcs._naxis2
    return outwcs
コード例 #17
0
def build_hstwcs(crval1, crval2, crpix1, crpix2, naxis1, naxis2, pscale, orientat):
    """ Create an HSTWCS object for a default instrument without distortion
        based on user provided parameter values.
    """
    wcsout = wcsutil.HSTWCS()
    wcsout.wcs.crval = np.array([crval1, crval2])
    wcsout.wcs.crpix = np.array([crpix1, crpix2])
    wcsout.naxis1 = naxis1
    wcsout.naxis2 = naxis2
    wcsout.wcs.cd = fileutil.buildRotMatrix(orientat) * [-1, 1] * pscale / 3600.0
    # Synchronize updates with astropy.wcs/WCSLIB objects
    wcsout.wcs.set()
    wcsout.setPscale()
    wcsout.setOrient()
    wcsout.wcs.ctype = ['RA---TAN', 'DEC--TAN']

    return wcsout
コード例 #18
0
def build_hstwcs(crval, crpix, naxis1, naxis2, pscale, orientat):
    """ Create an `~stwcs.wcsutil.HSTWCS` object for a default instrument without
    distortion based on user provided parameter values.
    """
    wcsout = wcsutil.HSTWCS()
    wcsout.wcs.crval = crval.copy()
    wcsout.wcs.crpix = crpix.copy()
    wcsout.naxis1 = naxis1
    wcsout.naxis2 = naxis2
    wcsout.wcs.cd = fu.buildRotMatrix(orientat) * [-1, 1] * pscale / 3600.0
    # Synchronize updates with astropy.wcs objects
    wcsout.wcs.set()
    wcsout.setPscale()
    wcsout.setOrient()
    wcsout.wcs.ctype = ['RA---TAN', 'DEC--TAN']

    return wcsout
コード例 #19
0
ファイル: wcs_functions.py プロジェクト: jhunkeler/drizzlepac
def build_hstwcs(crval1, crval2, crpix1, crpix2, naxis1, naxis2, pscale, orientat):
    """ Create an HSTWCS object for a default instrument without distortion
        based on user provided parameter values.
    """
    wcsout = wcsutil.HSTWCS()
    wcsout.wcs.crval = np.array([crval1,crval2])
    wcsout.wcs.crpix = np.array([crpix1,crpix2])
    wcsout.naxis1 = naxis1
    wcsout.naxis2 = naxis2
    wcsout.wcs.cd = fileutil.buildRotMatrix(orientat)*[-1,1]*pscale/3600.0
    # Synchronize updates with PyWCS/WCSLIB objects
    wcsout.wcs.set()
    wcsout.setPscale()
    wcsout.setOrient()
    wcsout.wcs.ctype = ['RA---TAN','DEC--TAN']

    return wcsout
コード例 #20
0
ファイル: buildwcs.py プロジェクト: brechmos-stsci/drizzlepac
def mergewcs(outwcs, customwcs, wcspars):
    """ Merge the WCS keywords from user specified values into a full HSTWCS object
        This function will essentially follow the same algorithm as used by
        updatehdr only it will use direct calls to updatewcs.Makewcs methods
        instead of using 'updatewcs' as a whole
    """
    # start by working on a copy of the refwcs
    if outwcs.sip is not None:
        wcslin = stwcs.distortion.utils.undistortWCS(outwcs)
        outwcs.wcs.cd = wcslin.wcs.cd
        outwcs.wcs.set()
        outwcs.setOrient()
        outwcs.setPscale()
    else:
        wcslin = outwcs
    if customwcs is None:
        # update valid pars from wcspars
        if wcspars['crval1'] is not None:
            outwcs.wcs.crval = np.array([wcspars['crval1'],wcspars['crval2']])
        if wcspars['crpix1'] is not None:
            outwcs.wcs.crpix = np.array([wcspars['crpix1'],wcspars['crpix2']])
        if wcspars['naxis1'] is not None:
            outwcs._naxis1 = wcspars['naxis1']
            outwcs._naxis2 = wcspars['naxis2']
            outwcs.wcs.crpix = np.array([outwcs._naxis1/2.,outwcs._naxis2/2.])

        pscale = wcspars['pscale']
        orient = wcspars['orientat']
        if pscale is not None or orient is not None:
            if pscale is None: pscale = wcslin.pscale
            if orient is None: orient = wcslin.orientat
            pix_ratio = pscale/wcslin.pscale
            delta_rot = wcslin.orientat - orient
            delta_rot_mat = fileutil.buildRotMatrix(delta_rot)
            outwcs.wcs.cd = np.dot(outwcs.wcs.cd,delta_rot_mat)*pix_ratio
            # apply model to new linear CD matrix
            apply_model(outwcs)
    else:
        # A new fully described WCS was provided in customwcs
        outwcs.wcs.cd = customwcs.wcs.cd
        outwcs.wcs.crval = customwcs.wcs.crval
        outwcs.wcs.crpix = customwcs.wcs.crpix
        outwcs._naxis1 = customwcs._naxis1
        outwcs._naxis2 = customwcs._naxis2
    return outwcs
コード例 #21
0
def fitlin_rscale(xy, uv, verbose=False):
    """ Performs a linear, orthogonal fit between matched
        lists of positions 'xy' (input) and 'uv' (output).

        Output: (same as for fit_arrays_general)
    """
    mu = uv[:, 0].mean()
    mv = uv[:, 1].mean()
    mx = xy[:, 0].mean()
    my = xy[:, 1].mean()

    u = uv[:, 0] - mu
    v = uv[:, 1] - mv
    x = xy[:, 0] - mx
    y = xy[:, 1] - my

    Sxx = np.dot(x, x)
    Syy = np.dot(y, y)
    Sux = np.dot(u, x)
    Suy = np.dot(u, y)
    Svx = np.dot(v, x)
    Svy = np.dot(v, y)

    # implement parity check
    if (np.dot(Sux, Svy) > 0):
        p = 1
    else:
        p = -1

    XX = p * Sux + Svy
    YY = Suy - p * Svx

    # derive output values
    theta_deg = fileutil.RADTODEG(np.arctan2(YY, XX)) % 360.0
    scale = np.sqrt(XX**2 + YY**2) / (Sxx + Syy)
    shift = (mu - mx, mv - my)
    if verbose:
        print('Linear RSCALE fit: rotation = ', theta_deg, '  scale = ', scale,
              '  offset = ', shift)
    coeffs = scale * fileutil.buildRotMatrix(-theta_deg)

    P = [coeffs[0, 0], coeffs[0, 1], shift[0]]
    Q = [coeffs[1, 1], coeffs[1, 0], shift[1]]
    return P, Q
コード例 #22
0
ファイル: wcs_functions.py プロジェクト: jhunkeler/drizzlepac
def fitlin_rscale(xy,uv,verbose=False):
    """ Performs a linear, orthogonal fit between matched
        lists of positions 'xy' (input) and 'uv' (output).

        Output: (same as for fit_arrays_general)
    """
    mu = uv[:,0].mean()
    mv = uv[:,1].mean()
    mx = xy[:,0].mean()
    my = xy[:,1].mean()

    u = uv[:,0] - mu
    v = uv[:,1] - mv
    x = xy[:,0] - mx
    y = xy[:,1] - my

    Sxx = np.dot(x,x)
    Syy = np.dot(y,y)
    Sux = np.dot(u,x)
    Suy = np.dot(u,y)
    Svx = np.dot(v,x)
    Svy = np.dot(v,y)

    # implement parity check
    if (np.dot(Sux,Svy) > 0):
        p = 1
    else:
        p = -1

    XX = p*Sux + Svy
    YY = Suy - p*Svx

    # derive output values
    theta_deg = np.rad2deg(np.arctan2(YY,XX))% 360.0
    scale = np.sqrt(XX**2 + YY**2) / (Sxx+Syy)
    shift = (mu-mx,mv-my)
    if verbose:
        print('Linear RSCALE fit: rotation = ',theta_deg,'  scale = ',scale,'  offset = ',shift)
    coeffs = scale * fileutil.buildRotMatrix(-theta_deg)

    P = [coeffs[0,0],coeffs[0,1],shift[0]]
    Q = [coeffs[1,1],coeffs[1,0],shift[1]]
    return P,Q
コード例 #23
0
ファイル: makewcs.py プロジェクト: jhunkeler/stwcs
    def zero_point_corr(cls, hwcs):
        if hwcs.idcmodel.refpix['skew_coeffs'] is not None and 'TDD_CY_BETA' in hwcs.idcmodel.refpix['skew_coeffs']:
            v23_corr = np.array([[0.], [0.]])
            return v23_corr
        else:
            try:
                alpha = hwcs.idcmodel.refpix['TDDALPHA']
                beta = hwcs.idcmodel.refpix['TDDBETA']
            except KeyError:
                alpha = 0.0
                beta = 0.0
                v23_corr = np.array([[0.], [0.]])
                logger.debug("TDD Zero point correction for chip"
                             "{0} defaulted to: {1}".format(hwcs.chip, v23_corr))
                return v23_corr

        tdd = np.array([[beta, alpha], [alpha, -beta]])
        mrotp = fileutil.buildRotMatrix(2.234529) / 2048.
        xy0 = np.array([[cls.tdd_xyref[hwcs.chip][0] - 2048.],
                        [cls.tdd_xyref[hwcs.chip][1] - 2048.]])
        v23_corr = np.dot(mrotp, np.dot(tdd, xy0)) * 0.05
        logger.debug("TDD Zero point correction for chip {0}: {1}".format(hwcs.chip, v23_corr))
        return v23_corr
コード例 #24
0
    def upextwcs(cls, ext_wcs, ref_wcs, v23_corr, rv23_corr, loff, offsh):
        """
        updates an extension wcs
        """
        ltvoffx, ltvoffy = loff[0], loff[1]
        offshiftx, offshifty = offsh[0], offsh[1]
        ltv1 = ext_wcs.ltv1
        ltv2 = ext_wcs.ltv2
        if ltv1 != 0. or ltv2 != 0.:
            offsetx = ext_wcs.wcs.crpix[0] - ltv1 - ext_wcs.idcmodel.refpix[
                'XREF']
            offsety = ext_wcs.wcs.crpix[1] - ltv2 - ext_wcs.idcmodel.refpix[
                'YREF']
            ext_wcs.idcmodel.shift(offsetx, offsety)

        fx, fy = ext_wcs.idcmodel.cx, ext_wcs.idcmodel.cy

        ext_wcs.setPscale()
        tddscale = (ref_wcs.pscale / fx[1, 1])
        v2 = ext_wcs.idcmodel.refpix['V2REF'] + v23_corr[0, 0] * tddscale
        v3 = ext_wcs.idcmodel.refpix['V3REF'] - v23_corr[1, 0] * tddscale
        v2ref = ref_wcs.idcmodel.refpix['V2REF'] + rv23_corr[0, 0] * tddscale
        v3ref = ref_wcs.idcmodel.refpix['V3REF'] - rv23_corr[1, 0] * tddscale

        R_scale = ref_wcs.idcmodel.refpix['PSCALE'] / 3600.0
        off = sqrt((v2 - v2ref)**2 + (v3 - v3ref)**2) / (R_scale * 3600.0)

        if v3 == v3ref:
            theta = 0.0
        else:
            theta = atan2(ext_wcs.parity[0][0] * (v2 - v2ref),
                          ext_wcs.parity[1][1] * (v3 - v3ref))

        if ref_wcs.idcmodel.refpix['THETA']:
            theta += ref_wcs.idcmodel.refpix['THETA'] * pi / 180.0

        dX = (off * sin(theta)) + offshiftx
        dY = (off * cos(theta)) + offshifty

        px = np.array([[dX, dY]])
        newcrval = ref_wcs.wcs.p2s(px, 1)['world'][0]
        newcrpix = np.array([
            ext_wcs.idcmodel.refpix['XREF'] + ltvoffx,
            ext_wcs.idcmodel.refpix['YREF'] + ltvoffy
        ])
        ext_wcs.wcs.crval = newcrval
        ext_wcs.wcs.crpix = newcrpix
        ext_wcs.wcs.set()

        # Create a small vector, in reference image pixel scale
        delmat = np.array([[fx[1, 1], fy[1, 1]], [fx[1, 0], fy[1, 0]]
                           ]) / R_scale / 3600.

        # Account for subarray offset
        # Angle of chip relative to chip
        if ext_wcs.idcmodel.refpix['THETA']:
            dtheta = ext_wcs.idcmodel.refpix[
                'THETA'] - ref_wcs.idcmodel.refpix['THETA']
        else:
            dtheta = 0.0

        rrmat = fileutil.buildRotMatrix(dtheta)
        # Rotate the vectors
        dxy = np.dot(delmat, rrmat)
        wc = ref_wcs.wcs.p2s((px + dxy), 1)['world']

        # Calculate the new CDs and convert to degrees
        cd11 = utils.diff_angles(wc[0, 0], newcrval[0]) * cos(
            newcrval[1] * pi / 180.0)
        cd12 = utils.diff_angles(wc[1, 0], newcrval[0]) * cos(
            newcrval[1] * pi / 180.0)
        cd21 = utils.diff_angles(wc[0, 1], newcrval[1])
        cd22 = utils.diff_angles(wc[1, 1], newcrval[1])
        cd = np.array([[cd11, cd12], [cd21, cd22]])
        ext_wcs.wcs.cd = cd
        ext_wcs.wcs.set()
コード例 #25
0
ファイル: makewcs.py プロジェクト: jhunkeler/stwcs
    def upextwcs(cls, ext_wcs, ref_wcs, v23_corr, rv23_corr, loff, offsh):
        """
        updates an extension wcs
        """
        ltvoffx, ltvoffy = loff[0], loff[1]
        offshiftx, offshifty = offsh[0], offsh[1]
        ltv1 = ext_wcs.ltv1
        ltv2 = ext_wcs.ltv2
        if ltv1 != 0. or ltv2 != 0.:
            offsetx = ext_wcs.wcs.crpix[0] - ltv1 - ext_wcs.idcmodel.refpix['XREF']
            offsety = ext_wcs.wcs.crpix[1] - ltv2 - ext_wcs.idcmodel.refpix['YREF']
            ext_wcs.idcmodel.shift(offsetx, offsety)

        fx, fy = ext_wcs.idcmodel.cx, ext_wcs.idcmodel.cy

        ext_wcs.setPscale()
        tddscale = (ref_wcs.pscale / fx[1, 1])
        v2 = ext_wcs.idcmodel.refpix['V2REF'] + v23_corr[0, 0] * tddscale
        v3 = ext_wcs.idcmodel.refpix['V3REF'] - v23_corr[1, 0] * tddscale
        v2ref = ref_wcs.idcmodel.refpix['V2REF'] + rv23_corr[0, 0] * tddscale
        v3ref = ref_wcs.idcmodel.refpix['V3REF'] - rv23_corr[1, 0] * tddscale

        R_scale = ref_wcs.idcmodel.refpix['PSCALE'] / 3600.0
        off = sqrt((v2 - v2ref) ** 2 + (v3 - v3ref) ** 2) / (R_scale * 3600.0)

        if v3 == v3ref:
            theta = 0.0
        else:
            theta = atan2(ext_wcs.parity[0][0] * (v2 - v2ref),
                          ext_wcs.parity[1][1] * (v3 - v3ref))

        if ref_wcs.idcmodel.refpix['THETA']: theta += ref_wcs.idcmodel.refpix['THETA'] * pi / 180.0

        dX = (off * sin(theta)) + offshiftx
        dY = (off * cos(theta)) + offshifty

        px = np.array([[dX, dY]])
        newcrval = ref_wcs.wcs.p2s(px, 1)['world'][0]
        newcrpix = np.array([ext_wcs.idcmodel.refpix['XREF'] + ltvoffx,
                             ext_wcs.idcmodel.refpix['YREF'] + ltvoffy])
        ext_wcs.wcs.crval = newcrval
        ext_wcs.wcs.crpix = newcrpix
        ext_wcs.wcs.set()

        # Create a small vector, in reference image pixel scale
        delmat = np.array([[fx[1, 1], fy[1, 1]],
                           [fx[1, 0], fy[1, 0]]]) / R_scale / 3600.

        # Account for subarray offset
        # Angle of chip relative to chip
        if ext_wcs.idcmodel.refpix['THETA']:
            dtheta = ext_wcs.idcmodel.refpix['THETA'] - ref_wcs.idcmodel.refpix['THETA']
        else:
            dtheta = 0.0

        rrmat = fileutil.buildRotMatrix(dtheta)
        # Rotate the vectors
        dxy = np.dot(delmat, rrmat)
        wc = ref_wcs.wcs.p2s((px + dxy), 1)['world']

        # Calculate the new CDs and convert to degrees
        cd11 = utils.diff_angles(wc[0, 0], newcrval[0]) * cos(newcrval[1] * pi / 180.0)
        cd12 = utils.diff_angles(wc[1, 0], newcrval[0]) * cos(newcrval[1] * pi / 180.0)
        cd21 = utils.diff_angles(wc[0, 1], newcrval[1])
        cd22 = utils.diff_angles(wc[1, 1], newcrval[1])
        cd = np.array([[cd11, cd12], [cd21, cd22]])
        ext_wcs.wcs.cd = cd
        ext_wcs.wcs.set()
コード例 #26
0
ファイル: makewcs.py プロジェクト: spacetelescope/pydrizzle
def _update(image,idctab,nimsets,apply_tdd=False,
            quiet=None,instrument=None,prepend=None,nrchip=None, nrext=None):

    tdd_xyref = {1: [2048, 3072], 2:[2048, 1024]}
    _prepend = prepend
    _dqname = None
    # Make a copy of the header for keyword access
    # This copy includes both Primary header and
    # extension header
    hdr = fileutil.getHeader(image)

    # Try to get the instrument if we don't have it already
    instrument = readKeyword(hdr,'INSTRUME')

    binned = 1
    # Read in any specified OFFTAB, if present (WFPC2)
    offtab = readKeyword(hdr,'OFFTAB')
    dateobs = readKeyword(hdr,'DATE-OBS')
    if not quiet:
        print("OFFTAB, DATE-OBS: ",offtab,dateobs)

    print("-Updating image ",image)

    if not quiet:
        print("-Reading IDCTAB file ",idctab)

    # Get telescope orientation from image header
    # If PA_V# is not present of header, try to get it from the spt file
    pvt = readKeyword(hdr,'PA_V3')
    if pvt == None:
        sptfile = fileutil.buildNewRootname(image, extn='_spt.fits')
        if os.path.exists(sptfile):
            spthdr = fileutil.getHeader(sptfile)
            pvt = readKeyword(spthdr,'PA_V3')
    if pvt != None:
        pvt = float(pvt)
    else:
        print('PA_V3 keyword not found, WCS cannot be updated. Quitting ...')
        raise ValueError

    # Find out about instrument, detector & filters
    detector = readKeyword(hdr,'DETECTOR')

    Nrefchip=1
    if instrument == 'WFPC2':
        filter1 = readKeyword(hdr,'FILTNAM1')
        filter2 = readKeyword(hdr,'FILTNAM2')
        mode = readKeyword(hdr,'MODE')
        if os.path.exists(fileutil.buildNewRootname(image, extn='_c1h.fits')):
            _dqname = fileutil.buildNewRootname(image, extn='_c1h.fits')
            dqhdr = pyfits.getheader(_dqname,1)
            dqext = readKeyword(dqhdr, 'EXTNAME')
        if mode == 'AREA':
            binned = 2
        Nrefchip=nrchip
    elif instrument == 'NICMOS':
        filter1 = readKeyword(hdr,'FILTER')
        filter2 = None
    elif instrument == 'WFC3':
        filter1 = readKeyword(hdr,'FILTER')
        filter2 = None
        # use value of 'BINAXIS' keyword to set binning value for WFC3 data
        binned = readKeyword(hdr,'BINAXIS1')
    else:
        filter1 = readKeyword(hdr,'FILTER1')
        filter2 = readKeyword(hdr,'FILTER2')

    if filter1 == None or filter1.strip() == '': filter1 = 'CLEAR'
    else: filter1 = filter1.strip()
    if filter2 == None or filter2.strip() == '': filter2 = 'CLEAR'
    else: filter2 = filter2.strip()

    if filter1.find('CLEAR') == 0: filter1 = 'CLEAR'
    if filter2.find('CLEAR') == 0: filter2 = 'CLEAR'

    # Set up parity matrix for chip
    if instrument == 'WFPC2' or instrument =='STIS' or instrument == 'NICMOS':
        parity = PARITY[instrument]
    elif detector in PARITY:
        parity = PARITY[detector]
    else:
        raise ValueError('Detector ',detector,
                         ' Not supported at this time. Exiting...')

    # Get the VAFACTOR keyword if it exists, otherwise set to 1.0
    # we also need the reference pointing position of the target
    # as this is where
    _va_key = readKeyword(hdr,'VAFACTOR')
    if _va_key != None:
        VA_fac = float(_va_key)
    else:
        VA_fac=1.0

    if not quiet:
        print('VA factor: ',VA_fac)

    #ra_targ = float(readKeyword(hdr,'RA_TARG'))
    #dec_targ = float(readKeyword(hdr,'DEC_TARG'))

    # Get the chip number
    _c = readKeyword(hdr,'CAMERA')
    _s = readKeyword(hdr,'CCDCHIP')
    _d = readKeyword(hdr,'DETECTOR')
    if _c != None and str(_c).isdigit():
        chip = int(_c)
    elif _s == None and _d == None:
        chip = 1
    else:
        if _s:
            chip = int(_s)
        elif str(_d).isdigit():
            chip = int(_d)
        else:
            chip = 1
    # For the ACS/WFC case the chip number doesn't match the image
    # extension
    nr = 1
    if (instrument == 'ACS' and detector == 'WFC') or (instrument == 'WFC3' and detector == 'UVIS'):
        if nimsets > 1:
            Nrefchip = 2
        else:
            Nrefchip = chip
    elif instrument == 'NICMOS':
        Nrefchip = readKeyword(hdr,'CAMERA')
    elif instrument == 'WFPC2':
        nr = nrext
    else:
        if nimsets > 1:
            nr = Nrefchip

    if not quiet:
        print("-PA_V3 : ",pvt," CHIP #",chip)


    # Extract the appropriate information from the IDCTAB
    #fx,fy,refpix,order=fileutil.readIDCtab(idctab,chip=chip,direction='forward',
    #            filter1=filter1,filter2=filter2,offtab=offtab,date=dateobs)
    idcmodel = models.IDCModel(idctab,
                               chip=chip, direction='forward', date=dateobs,
                               filter1=filter1, filter2=filter2, offtab=offtab, binned=binned,
                               tddcorr=apply_tdd)
    fx = idcmodel.cx
    fy = idcmodel.cy
    refpix = idcmodel.refpix
    order = idcmodel.norder

    # Determine whether to perform time-dependent correction
    # Construct matrices neded to correct the zero points for TDD
    if apply_tdd:
        #alpha,beta = mutil.compute_wfc_tdd_coeffs(dateobs,skew_coeffs)
        alpha = refpix['TDDALPHA']
        beta = refpix['TDDBETA']
        tdd = N.array([[beta, alpha], [alpha, -beta]])
        mrotp = fileutil.buildRotMatrix(2.234529)/2048.

    else:
        alpha = 0.0
        beta = 0.0

    # Get the original image WCS
    Old=wcsutil.WCSObject(image,prefix=_prepend)

    # Reset the WCS keywords to original archived values.
    Old.restore()

    #
    # Look for any subarray offset
    #
    ltv1,ltv2 = drutil.getLTVOffsets(image)
    #
    # If reference point is not centered on distortion model
    # shift coefficients to be applied relative to observation
    # reference position
    #
    offsetx = Old.crpix1 - ltv1 - refpix['XREF']
    offsety = Old.crpix2 - ltv2 - refpix['YREF']
    shiftx = refpix['XREF'] + ltv1
    shifty = refpix['YREF'] + ltv2
    if ltv1 != 0. or ltv2 != 0.:
        ltvoffx = ltv1 + offsetx
        ltvoffy = ltv2 + offsety
        offshiftx = offsetx + shiftx
        offshifty = offsety + shifty
    else:
        ltvoffx = 0.
        ltvoffy = 0.
        offshiftx = 0.
        offshifty = 0.

    if ltv1 != 0. or ltv2 != 0.:
        fx,fy = idcmodel.shift(idcmodel.cx,idcmodel.cy,offsetx,offsety)

    # Extract the appropriate information for reference chip

    ridcmodel = models.IDCModel(idctab,
                                chip=Nrefchip, direction='forward', date=dateobs,
                                filter1=filter1, filter2=filter2, offtab=offtab, binned=binned,
                                tddcorr=apply_tdd)
    rfx = ridcmodel.cx
    rfy = ridcmodel.cy
    rrefpix = ridcmodel.refpix
    rorder = ridcmodel.norder
    """
    rfx,rfy,rrefpix,rorder=mutil.readIDCtab(idctab,chip=Nrefchip,
        direction='forward', filter1=filter1,filter2=filter2,offtab=offtab,
        date=dateobs,tddcorr=apply_tdd)
    """
    # Create the reference image name
    rimage = image.split('[')[0]+"[sci,%d]" % nr
    if not quiet:
        print("Reference image: ",rimage)

    # Create the tangent plane WCS on which the images are defined
    # This is close to that of the reference chip
    R=wcsutil.WCSObject(rimage)
    R.write_archive(rimage)
    R.restore()

    # Reacd in declination of target (for computing orientation at aperture)
    # Note that this is from the reference image
    #dec = float(fileutil.getKeyword(rimage,'CRVAL2'))
    #crval1 = float(fileutil.getKeyword(rimage,'CRVAL1'))
    #crval1 = float(R.crval1)
    #crval2 = dec
    dec = float(R.crval2)

    # Get an approximate reference position on the sky
    rref = (rrefpix['XREF']+ltvoffx, rrefpix['YREF']+ltvoffy)

    crval1,crval2=R.xy2rd(rref)

    if apply_tdd:
        # Correct zero points for TDD
        tddscale = (R.pscale/fx[1][1])
        rxy0 = N.array([[tdd_xyref[Nrefchip][0]-2048.],[ tdd_xyref[Nrefchip][1]-2048.]])
        xy0 = N.array([[tdd_xyref[chip][0]-2048.], [tdd_xyref[chip][1]-2048.]])
        rv23_corr = N.dot(mrotp,N.dot(tdd,rxy0))*tddscale
        v23_corr = N.dot(mrotp,N.dot(tdd,xy0))*tddscale
    else:
        rv23_corr = N.array([[0],[0]])
        v23_corr = N.array([[0],[0]])

    # Convert the PA_V3 orientation to the orientation at the aperture
    # This is for the reference chip only - we use this for the
    # reference tangent plane definition
    # It has the same orientation as the reference chip
    v2ref = rrefpix['V2REF'] +  rv23_corr[0][0]*0.05
    v3ref = rrefpix['V3REF'] - rv23_corr[1][0]*0.05
    v2 = refpix['V2REF'] + v23_corr[0][0]*0.05
    v3 = refpix['V3REF'] - v23_corr[1][0] *0.05

    pv = wcsutil.troll(pvt,dec,v2ref,v3ref)

    # Add the chip rotation angle
    if rrefpix['THETA']:
        pv += rrefpix['THETA']


    # Set values for the rest of the reference WCS
    R.crval1=crval1
    R.crval2=crval2
    R.crpix1=0.0 + offshiftx
    R.crpix2=0.0 + offshifty

    R_scale=rrefpix['PSCALE']/3600.0
    R.cd11=parity[0][0] *  cos(pv*pi/180.0)*R_scale
    R.cd12=parity[0][0] * -sin(pv*pi/180.0)*R_scale
    R.cd21=parity[1][1] *  sin(pv*pi/180.0)*R_scale
    R.cd22=parity[1][1] *  cos(pv*pi/180.0)*R_scale

    ##print R
    R_cdmat = N.array([[R.cd11,R.cd12],[R.cd21,R.cd22]])

    if not quiet:
        print("  Reference Chip Scale (arcsec/pix): ",rrefpix['PSCALE'])

    # Offset and angle in V2/V3 from reference chip to
    # new chip(s) - converted to reference image pixels

    off = sqrt((v2-v2ref)**2 + (v3-v3ref)**2)/(R_scale*3600.0)

    # Here we must include the PARITY
    if v3 == v3ref:
        theta=0.0
    else:
        theta = atan2(parity[0][0]*(v2-v2ref),parity[1][1]*(v3-v3ref))

    if rrefpix['THETA']: theta += rrefpix['THETA']*pi/180.0

    dX=(off*sin(theta)) + offshiftx
    dY=(off*cos(theta)) + offshifty

    # Check to see whether we are working with GEIS or FITS input
    _fname,_iextn = fileutil.parseFilename(image)

    if _fname.find('.fits') < 0:
        # Input image is NOT a FITS file, so
        #     build a FITS name for it's copy.
        _fitsname = fileutil.buildFITSName(_fname)
    else:
        _fitsname = None
    # Create a new instance of a WCS
    if _fitsname == None:
        _new_name = image
    else:
        _new_name = _fitsname+'['+str(_iextn)+']'

    #New=wcsutil.WCSObject(_new_name,new=yes)
    New = Old.copy()

    # Calculate new CRVALs and CRPIXs
    New.crval1,New.crval2=R.xy2rd((dX,dY))
    New.crpix1=refpix['XREF'] + ltvoffx
    New.crpix2=refpix['YREF'] + ltvoffy

    # Account for subarray offset
    # Angle of chip relative to chip
    if refpix['THETA']:
        dtheta = refpix['THETA'] - rrefpix['THETA']
    else:
        dtheta = 0.0

    # Create a small vector, in reference image pixel scale
    # There is no parity effect here ???
    delXX=fx[1,1]/R_scale/3600.
    delYX=fy[1,1]/R_scale/3600.
    delXY=fx[1,0]/R_scale/3600.
    delYY=fy[1,0]/R_scale/3600.

    # Convert to radians
    rr=dtheta*pi/180.0

    # Rotate the vectors
    dXX= cos(rr)*delXX - sin(rr)*delYX
    dYX= sin(rr)*delXX + cos(rr)*delYX

    dXY= cos(rr)*delXY - sin(rr)*delYY
    dYY= sin(rr)*delXY + cos(rr)*delYY

    # Transform to sky coordinates
    a,b=R.xy2rd((dX+dXX,dY+dYX))
    c,d=R.xy2rd((dX+dXY,dY+dYY))

    # Calculate the new CDs and convert to degrees
    New.cd11=diff_angles(a,New.crval1)*cos(New.crval2*pi/180.0)
    New.cd12=diff_angles(c,New.crval1)*cos(New.crval2*pi/180.0)
    New.cd21=diff_angles(b,New.crval2)
    New.cd22=diff_angles(d,New.crval2)

    # Apply the velocity aberration effect if applicable
    if VA_fac != 1.0:

        # First shift the CRVALs apart
#       New.crval1 = ra_targ + VA_fac*(New.crval1 - ra_targ)
#       New.crval2 = dec_targ + VA_fac*(New.crval2 - dec_targ)
        # First shift the CRVALs apart
        # This is now relative to the reference chip, not the
        # target position.
        New.crval1 = R.crval1 + VA_fac*diff_angles(New.crval1, R.crval1)
        New.crval2 = R.crval2 + VA_fac*diff_angles(New.crval2, R.crval2)

        # and scale the CDs
        New.cd11 = New.cd11*VA_fac
        New.cd12 = New.cd12*VA_fac
        New.cd21 = New.cd21*VA_fac
        New.cd22 = New.cd22*VA_fac

    New_cdmat = N.array([[New.cd11,New.cd12],[New.cd21,New.cd22]])

    # Store new one
    # archive=yes specifies to also write out archived WCS keywords
    # overwrite=no specifies do not overwrite any pre-existing archived keywords

    New.write(fitsname=_new_name,overwrite=no,quiet=quiet,archive=yes)
    if _dqname:
        _dq_iextn = _iextn.replace('sci', dqext.lower())
        _new_dqname = _dqname +'['+_dq_iextn+']'
        dqwcs = wcsutil.WCSObject(_new_dqname)
        dqwcs.write(fitsname=_new_dqname, wcs=New,overwrite=no,quiet=quiet, archive=yes)

    """ Convert distortion coefficients into SIP style
        values and write out to image (assumed to be FITS).
    """
    #First the CD matrix:
    f = refpix['PSCALE']/3600.0
    a = fx[1,1]/3600.0
    b = fx[1,0]/3600.0
    c = fy[1,1]/3600.0
    d = fy[1,0]/3600.0
    det = (a*d - b*c)*refpix['PSCALE']

    # Write to header
    fimg = fileutil.openImage(_new_name,mode='update')
    _new_root,_nextn = fileutil.parseFilename(_new_name)
    _new_extn = fileutil.getExtn(fimg,_nextn)


    # Transform the higher-order coefficients
    for n in range(order+1):
        for m in range(order+1):
            if n >= m and n>=2:

                # Form SIP-style keyword names
                Akey="A_%d_%d" % (m,n-m)
                Bkey="B_%d_%d" % (m,n-m)

                # Assign them values
                Aval= f*(d*fx[n,m]-b*fy[n,m])/det
                Bval= f*(a*fy[n,m]-c*fx[n,m])/det

                _new_extn.header.update(Akey,Aval)
                _new_extn.header.update(Bkey,Bval)

    # Update the SIP flag keywords as well
    #iraf.hedit(image,"CTYPE1","RA---TAN-SIP",verify=no,show=no)
    #iraf.hedit(image,"CTYPE2","DEC--TAN-SIP",verify=no,show=no)
    _new_extn.header.update("CTYPE1","RA---TAN-SIP")
    _new_extn.header.update("CTYPE2","DEC--TAN-SIP")

    # Finally we also need the order
    #iraf.hedit(image,"A_ORDER","%d" % order,add=yes,verify=no,show=no)
    #iraf.hedit(image,"B_ORDER","%d" % order,add=yes,verify=no,show=no)
    _new_extn.header.update("A_ORDER",order)
    _new_extn.header.update("B_ORDER",order)

    # Update header with additional keywords required for proper
    # interpretation of SIP coefficients by PyDrizzle.

    _new_extn.header.update("IDCSCALE",refpix['PSCALE'])
    _new_extn.header.update("IDCV2REF",refpix['V2REF'])
    _new_extn.header.update("IDCV3REF",refpix['V3REF'])
    _new_extn.header.update("IDCTHETA",refpix['THETA'])
    _new_extn.header.update("OCX10",fx[1][0])
    _new_extn.header.update("OCX11",fx[1][1])
    _new_extn.header.update("OCY10",fy[1][0])
    _new_extn.header.update("OCY11",fy[1][1])
    #_new_extn.header.update("TDDXOFF",rv23_corr[0][0] - v23_corr[0][0])
    #_new_extn.header.update("TDDYOFF",-(rv23_corr[1][0] - v23_corr[1][0]))

    # Report time-dependent coeffs, if computed
    if instrument == 'ACS' and detector == 'WFC':
        _new_extn.header.update("TDDALPHA",alpha)
        _new_extn.header.update("TDDBETA",beta)


    # Close image now
    fimg.close()
    del fimg
コード例 #27
0
ファイル: pattern.py プロジェクト: spacetelescope/pydrizzle
    def computeOffsets(self,parity=None,refchip=None):
        """
        This version of 'computeOffsets' calculates the zero-point
        shifts to be included in the distortion coefficients table
        used by 'drizzle'.
        It REQUIRES a parity matrix to convert from
        V2/V3 coordinates into detector image X/Y coordinates. This
        matrix will be specific to each detector.
        """
        vref = []

        # Check to see if any chip-to-chip offsets need to be computed at all
        if len(self.members) == 1:
            refp = self.members[0].geometry.model.refpix
            refp['XDELTA'] = 0.
            refp['YDELTA'] = 0.
            #refp['centered'] = yes
            return

        # Set up the parity matrix here for a SINGLE chip
        if parity == None:
            # Use class defined dictionary as default
            parity = self.PARITY
        # Get reference chip information
        ref_model=None
        for member in self.members:
            if not refchip or refchip == int(member.chip):
                ref_model = member.geometry.model
                ref_scale = ref_model.refpix['PSCALE']
                ref_v2v3 = np.array([ref_model.refpix['V2REF'],ref_model.refpix['V3REF']])
                ref_theta = ref_model.refpix['THETA']
                if ref_theta == None: ref_theta = 0.0
                ref_pmat = np.dot(fileutil.buildRotMatrix(ref_theta), member.parity)
                ref_xy = (ref_model.refpix['XREF'],ref_model.refpix['YREF'])
                break

        if not ref_model:
            ref_scale = 1.0
            ref_theta = 0.0
            ref_v2v3 = [0.,0.]
            ref_xy = [0.,0.]
            ref_pmat = np.array([[1.,0.],[0.,1.0]])

        # Now compute the offset for each chip
        # Compute position of each chip's common point relative
        # to the output chip's reference position.
        for member in self.members:
            in_model = member.geometry.model
            refp = in_model.refpix
            pscale = in_model.pscale
            memwcs = member.geometry.wcs

            v2v3 = np.array([in_model.refpix['V2REF'],in_model.refpix['V3REF']])
            scale = refp['PSCALE']
            theta = refp['THETA']
            if theta == None: theta = 0.0

            chipcen = ( (memwcs.naxis1/2.) + memwcs.offset_x,
                        (memwcs.naxis2/2.) + memwcs.offset_y)
            """
            Changed two lines below starting with '##'.
            The reasoning is that this function computes the offsets between the
            chips in an observation in model space based on a reference chip.
            That's why xypos shoulf be coomputed in reference chip space and offset_xy
            (X/YDELTA) should be chip specific.
            """
            ##xypos = np.dot(ref_pmat,v2v3-ref_v2v3) / scale + ref_xy
            xypos = np.dot(ref_pmat,v2v3-ref_v2v3) / ref_scale #+ ref_xy

            chiprot = fileutil.buildRotMatrix(theta - ref_theta)
            offcen = ((refp['XREF'] - chipcen[0]), (refp['YREF'] - chipcen[1]))

            # Update member's geometry model with computed
            # reference position...
            #refp['XDELTA'] = vref[i][0] - v2com + chip.geometry.delta_x
            #refp['YDELTA'] = vref[i][1] - v3com + chip.geometry.delta_y

            ##offset_xy = np.dot(chiprot,xypos-offcen)*scale/ref_scale
            offset_xy = np.dot(chiprot,xypos)*ref_scale/scale - offcen
            if 'empty_model' in refp and refp['empty_model'] == True:
                offset_xy[0]  += ref_xy[0] * scale/ref_scale
                offset_xy[1]  += ref_xy[1] * scale/ref_scale

            refp['XDELTA'] = offset_xy[0]
            refp['YDELTA'] = offset_xy[1]


            # Only set centered to yes for full exposures...
            if member.geometry.wcs.subarray != yes:
                refp['centered'] = no
            else:
                refp['centered'] = yes
コード例 #28
0
ファイル: drutil.py プロジェクト: spacetelescope/pydrizzle
def getRange(members,ref_wcs,verbose=None):
    xma,yma = [],[]
    xmi,ymi = [],[]
    #nref_x, nref_y = [], []
    # Compute corrected positions of each chip's common point
    crpix = (ref_wcs.crpix1,ref_wcs.crpix2)
    ref_rot = ref_wcs.orient
    _rot = ref_wcs.orient - members[0].geometry.wcslin.orient

    for member in members:
        # Need to make sure this is populated with proper defaults
        # for ALL exposures!
        _model = member.geometry.model
        _wcs = member.geometry.wcs
        _wcslin = member.geometry.wcslin
        _theta = _wcslin.orient - ref_rot

        # Need to scale corner positions to final output scale
        _scale =_wcslin.pscale/ ref_wcs.pscale

        # Compute the corrected,scaled corner positions for each chip
        #xyedge = member.calcNewEdges(pscale=ref_wcs.pscale)
        xypos = member.geometry.calcNewCorners() * _scale

        if _theta != 0.0:
            #rotate coordinates to match output orientation
            # Now, rotate new coord
            _mrot = buildRotMatrix(_theta)
            xypos = np.dot(xypos,_mrot)

        _oxmax = np.maximum.reduce(xypos[:,0])
        _oymax = np.maximum.reduce(xypos[:,1])
        _oxmin = np.minimum.reduce(xypos[:,0])
        _oymin = np.minimum.reduce(xypos[:,1])

        # Update the corners attribute of the member with the
        # positions of the computed, distortion-corrected corners
        #member.corners['corrected'] = np.array([(_oxmin,_oymin),(_oxmin,_oymax),(_oxmax,_oymin),(_oxmax,_oymax)],dtype=np.float64)
        member.corners['corrected'] = xypos

        xma.append(_oxmax)
        yma.append(_oymax)
        xmi.append(_oxmin)
        ymi.append(_oymin)
        #nrefx = (_oxmin+_oxmax) * ref_wcs.pscale/ _wcslin.pscale
        #nrefy = (_oymin+_oymax) * ref_wcs.pscale/ _wcslin.pscale
        #nref_x.append(nrefx)
        #nref_y.append(nrefy)
        #if _rot != 0.:
        #    mrot = buildRotMatrix(_rot)
        #    nref = np.dot(np.array([nrefx,nrefy]),_mrot)
    # Determine the full size of the metachip
    xmax = np.maximum.reduce(xma)
    ymax = np.maximum.reduce(yma)
    ymin = np.minimum.reduce(ymi)
    xmin = np.minimum.reduce(xmi)

    # Compute offset from center that distortion correction shifts the image.
    # This accounts for the fact that the output is no longer symmetric around
    # the reference position...
    # Scale by ratio of plate-scales so that DELTAs are always in input frame
    #

    """
    Keep the computation of nref in reference chip space.
    Using the ratio below is almost correct for ACS and wrong for WFPC2 subarrays

    """
    ##_ratio = ref_wcs.pscale / _wcslin.pscale
    ##nref = ( (xmin + xmax)*_ratio, (ymin + ymax)*_ratio )

    nref = ( (xmin + xmax), (ymin + ymax))
    #print 'nref_x, nref_y', nref_x, nref_y
    #nref = (np.maximum.reduce(nref_x), np.maximum.reduce(nref_y))



    if _rot != 0.:
        _mrot = buildRotMatrix(_rot)
        nref = np.dot(nref,_mrot)

    # Now, compute overall size based on range of pixels and offset from center.
    #xsize = int(xmax - xmin + nref[0])
    #ysize = int(ymax - ymin + nref[1])
    # Add '2' to each dimension to allow for fractional pixels at the
    # edge of the image. Also, 'drizzle' centers the output, so
    # adding 2 only expands image by 1 row on each edge.
    # An additional two is added to accomodate floating point errors in drizzle.
    xsize = int(ceil(xmax)) - int(floor(xmin))
    ysize = int(ceil(ymax)) - int(floor(ymin))

    meta_range = {}
    meta_range = {'xmin':xmin,'xmax':xmax,'ymin':ymin,'ymax':ymax,'nref':nref}
    meta_range['xsize'] = xsize
    meta_range['ysize'] = ysize

    if verbose:
        print('Meta_WCS:')
        print('    NREF         :',nref)
        print('    X range      :',xmin,xmax)
        print('    Y range      :',ymin,ymax)
        print('    Computed Size: ',xsize,ysize)

    return meta_range
コード例 #29
0
def mergeWCS(default_wcs,user_pars):
    """ Merges the user specified WCS values given as dictionary derived from
        the input configObj object with the output PyWCS object computed
        using distortion.output_wcs().

        The user_pars dictionary needs to have the following set of keys::

            user_pars = {'ra':None,'dec':None,'scale':None,'rot':None,
                         'outnx':None,'outny':None,'crpix1':None,'crpix2':None}
    """
    #
    # Start by making a copy of the input WCS...
    #
    outwcs = default_wcs.deepcopy()

    # If there are no user set parameters, just return a copy of the original WCS
    merge = False
    for upar in user_pars.values():
        if upar is not None:
            merge = True
            break

    if not merge:
        return outwcs

    if ('ra' not in user_pars) or user_pars['ra'] == None:
        _crval = None
    else:
        _crval = (user_pars['ra'],user_pars['dec'])

    if ('scale' not in user_pars) or user_pars['scale'] == None:
        _ratio = 1.0
        _psize = None
        # Need to resize the WCS for any changes in pscale
    else:
        _ratio = outwcs.pscale / user_pars['scale']
        _psize = user_pars['scale']

    if ('rot' not in user_pars) or user_pars['rot'] == None:
        _orient = None
        _delta_rot = 0.
    else:
        _orient = user_pars['rot']
        _delta_rot = outwcs.orientat - user_pars['rot']

    _mrot = fileutil.buildRotMatrix(_delta_rot)

    if ('outnx' not in user_pars) or user_pars['outnx'] == None:
        _corners = np.array([[0.,0.],[outwcs._naxis1,0.],[0.,outwcs._naxis2],[outwcs._naxis1,outwcs._naxis2]])
        _corners -= (outwcs._naxis1/2.,outwcs._naxis2/2.)
        _range = util.getRotatedSize(_corners,_delta_rot)
        shape = ((_range[0][1] - _range[0][0])*_ratio,(_range[1][1]-_range[1][0])*_ratio)
        old_shape = (outwcs._naxis1*_ratio,outwcs._naxis2*_ratio)

        _crpix = (shape[0]/2., shape[1]/2.)

    else:
        shape = [user_pars['outnx'],user_pars['outny']]
        if user_pars['crpix1'] == None:
            _crpix = (shape[0]/2.,shape[1]/2.)
        else:
            _crpix = [user_pars['crpix1'],user_pars['crpix2']]

    # Set up the new WCS based on values from old one.
    # Update plate scale
    outwcs.wcs.cd = outwcs.wcs.cd / _ratio
    outwcs.pscale /= _ratio
    #Update orientation
    outwcs.rotateCD(_delta_rot)
    outwcs.orientat += -_delta_rot
    # Update size
    outwcs._naxis1 =  int(shape[0])
    outwcs._naxis2 =  int(shape[1])
    # Update reference position
    outwcs.wcs.crpix = np.array(_crpix,dtype=np.float64)
    if _crval is not None:
        outwcs.wcs.crval = np.array(_crval,dtype=np.float64)

    return outwcs