diff options
author | Nadia Dencheva <nadia.dencheva@gmail.com> | 2016-08-10 08:24:47 -0400 |
---|---|---|
committer | Nadia Dencheva <nadia.dencheva@gmail.com> | 2016-08-10 08:24:51 -0400 |
commit | 0268dd1037bfacf06af22ff614c5d8479bd83e99 (patch) | |
tree | 8b75f2e528b24727b1c54a40b14793ceac97aafc /stwcs/distortion/utils.py | |
parent | 6ee1b08a2bc2fea4e61fb05d6c3d9250c15a1a75 (diff) | |
download | stwcs_hcf-0268dd1037bfacf06af22ff614c5d8479bd83e99.tar.gz |
first round of pep8 changes
Diffstat (limited to 'stwcs/distortion/utils.py')
-rw-r--r-- | stwcs/distortion/utils.py | 123 |
1 files changed, 64 insertions, 59 deletions
diff --git a/stwcs/distortion/utils.py b/stwcs/distortion/utils.py index 4228f62..1baad3f 100644 --- a/stwcs/distortion/utils.py +++ b/stwcs/distortion/utils.py @@ -1,4 +1,4 @@ -from __future__ import division, print_function # confidence high +from __future__ import absolute_import, division, print_function import os @@ -6,11 +6,11 @@ import numpy as np from numpy import linalg from astropy import wcs as pywcs -from stwcs import wcsutil -from stwcs import updatewcs +from .. import updatewcs from numpy import sqrt, arctan2 from stsci.tools import fileutil + def output_wcs(list_of_wcsobj, ref_wcs=None, owcs=None, undistort=True): """ Create an output WCS. @@ -33,63 +33,65 @@ def output_wcs(list_of_wcsobj, ref_wcs=None, owcs=None, undistort=True): # This new algorithm may not be strictly necessary, but it may be more # robust in handling regions near the poles or at 0h RA. - crval1,crval2 = computeFootprintCenter(fra_dec) + crval1, crval2 = computeFootprintCenter(fra_dec) - crval = np.array([crval1,crval2], dtype=np.float64) # this value is now zero-based + crval = np.array([crval1, crval2], dtype=np.float64) # this value is now zero-based if owcs is None: if ref_wcs is None: ref_wcs = list_of_wcsobj[0].deepcopy() if undistort: - #outwcs = undistortWCS(ref_wcs) + # outwcs = undistortWCS(ref_wcs) outwcs = make_orthogonal_cd(ref_wcs) else: outwcs = ref_wcs.deepcopy() outwcs.wcs.crval = crval outwcs.wcs.set() - outwcs.pscale = sqrt(outwcs.wcs.cd[0,0]**2 + outwcs.wcs.cd[1,0]**2)*3600. - outwcs.orientat = arctan2(outwcs.wcs.cd[0,1],outwcs.wcs.cd[1,1]) * 180./np.pi + outwcs.pscale = sqrt(outwcs.wcs.cd[0, 0] ** 2 + outwcs.wcs.cd[1, 0] ** 2) * 3600. + outwcs.orientat = arctan2(outwcs.wcs.cd[0, 1], outwcs.wcs.cd[1, 1]) * 180. / np.pi else: outwcs = owcs.deepcopy() - outwcs.pscale = sqrt(outwcs.wcs.cd[0,0]**2 + outwcs.wcs.cd[1,0]**2)*3600. - outwcs.orientat = arctan2(outwcs.wcs.cd[0,1],outwcs.wcs.cd[1,1]) * 180./np.pi + outwcs.pscale = sqrt(outwcs.wcs.cd[0, 0] ** 2 + outwcs.wcs.cd[1, 0] ** 2) * 3600. + outwcs.orientat = arctan2(outwcs.wcs.cd[0, 1], outwcs.wcs.cd[1, 1]) * 180. / np.pi tanpix = outwcs.wcs.s2p(fra_dec, 0)['pixcrd'] - outwcs._naxis1 = int(np.ceil(tanpix[:,0].max() - tanpix[:,0].min())) - outwcs._naxis2 = int(np.ceil(tanpix[:,1].max() - tanpix[:,1].min())) - crpix = np.array([outwcs._naxis1/2., outwcs._naxis2/2.], dtype=np.float64) + outwcs._naxis1 = int(np.ceil(tanpix[:, 0].max() - tanpix[:, 0].min())) + outwcs._naxis2 = int(np.ceil(tanpix[:, 1].max() - tanpix[:, 1].min())) + crpix = np.array([outwcs._naxis1 / 2., outwcs._naxis2 / 2.], dtype=np.float64) outwcs.wcs.crpix = crpix outwcs.wcs.set() tanpix = outwcs.wcs.s2p(fra_dec, 0)['pixcrd'] # shift crpix to take into account (floating-point value of) position of # corner pixel relative to output frame size: no rounding necessary... - newcrpix = np.array([crpix[0]+tanpix[:,0].min(), crpix[1]+ - tanpix[:,1].min()]) + newcrpix = np.array([crpix[0] + tanpix[:, 0].min(), crpix[1] + + tanpix[:, 1].min()]) newcrval = outwcs.wcs.p2s([newcrpix], 1)['world'][0] outwcs.wcs.crval = newcrval outwcs.wcs.set() - outwcs.wcs.name = wcsname # keep track of label for this solution + outwcs.wcs.name = wcsname # keep track of label for this solution return outwcs + def computeFootprintCenter(edges): """ Geographic midpoint in spherical coords for points defined by footprints. Algorithm derived from: http://www.geomidpoint.com/calculation.html This algorithm should be more robust against discontinuities at the poles. """ - alpha = np.deg2rad(edges[:,0]) - dec = np.deg2rad(edges[:,1]) + alpha = np.deg2rad(edges[:, 0]) + dec = np.deg2rad(edges[:, 1]) - xmean = np.mean(np.cos(dec)*np.cos(alpha)) - ymean = np.mean(np.cos(dec)*np.sin(alpha)) + xmean = np.mean(np.cos(dec) * np.cos(alpha)) + ymean = np.mean(np.cos(dec) * np.sin(alpha)) zmean = np.mean(np.sin(dec)) - crval1 = np.rad2deg(np.arctan2(ymean,xmean))%360.0 - crval2 = np.rad2deg(np.arctan2(zmean,np.sqrt(xmean*xmean+ymean*ymean))) + crval1 = np.rad2deg(np.arctan2(ymean, xmean)) % 360.0 + crval2 = np.rad2deg(np.arctan2(zmean, np.sqrt(xmean * xmean + ymean * ymean))) + + return crval1, crval2 - return crval1,crval2 def make_orthogonal_cd(wcs): """ Create a perfect (square, orthogonal, undistorted) CD matrix from the @@ -98,21 +100,20 @@ def make_orthogonal_cd(wcs): # get determinant of the CD matrix: cd = wcs.celestial.pixel_scale_matrix - if hasattr(wcs, 'idcv2ref') and wcs.idcv2ref is not None: # 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 - pv = updatewcs.makewcs.troll(wcs.pav3,wcs.wcs.crval[1],wcs.idcv2ref,wcs.idcv3ref) + pv = updatewcs.makewcs.troll(wcs.pav3, wcs.wcs.crval[1], wcs.idcv2ref, wcs.idcv3ref) # Add the chip rotation angle if wcs.idctheta: pv += wcs.idctheta cs = np.cos(np.deg2rad(pv)) sn = np.sin(np.deg2rad(pv)) - pvmat = np.dot(np.array([[cs,sn],[-sn,cs]]),wcs.parity) - rot = np.arctan2(pvmat[0,1],pvmat[1,1]) - scale = wcs.idcscale/3600. + pvmat = np.dot(np.array([[cs, sn], [-sn, cs]]), wcs.parity) + rot = np.arctan2(pvmat[0, 1], pvmat[1, 1]) + scale = wcs.idcscale / 3600. det = linalg.det(wcs.parity) @@ -122,36 +123,37 @@ def make_orthogonal_cd(wcs): # find pixel scale: if hasattr(wcs, 'idcscale'): - scale = (wcs.idcscale) / 3600. # HST pixel scale provided + scale = (wcs.idcscale) / 3600. # HST pixel scale provided else: - scale = np.sqrt(np.abs(det)) # find as sqrt(pixel area) + scale = np.sqrt(np.abs(det)) # find as sqrt(pixel area) # find Y-axis orientation: if hasattr(wcs, 'orientat') and not ignoreHST: - rot = np.deg2rad(wcs.orientat) # use HST ORIENTAT + rot = np.deg2rad(wcs.orientat) # use HST ORIENTAT else: - rot = np.arctan2(wcs.wcs.cd[0,1], wcs.wcs.cd[1,1]) # angle of the Y-axis + rot = np.arctan2(wcs.wcs.cd[0, 1], wcs.wcs.cd[1, 1]) # angle of the Y-axis par = -1 if det < 0.0 else 1 # create a perfectly square, orthogonal WCS sn = np.sin(rot) cs = np.cos(rot) - orthogonal_cd = scale * np.array([[par*cs, sn], [-par*sn, cs]]) + orthogonal_cd = scale * np.array([[par * cs, sn], [-par * sn, cs]]) lin_wcsobj = pywcs.WCS() lin_wcsobj.wcs.cd = orthogonal_cd lin_wcsobj.wcs.set() - lin_wcsobj.orientat = arctan2(lin_wcsobj.wcs.cd[0,1],lin_wcsobj.wcs.cd[1,1]) * 180./np.pi - lin_wcsobj.pscale = sqrt(lin_wcsobj.wcs.cd[0,0]**2 + lin_wcsobj.wcs.cd[1,0]**2)*3600. - lin_wcsobj.wcs.crval = np.array([0.,0.]) - lin_wcsobj.wcs.crpix = np.array([0.,0.]) + lin_wcsobj.orientat = arctan2(lin_wcsobj.wcs.cd[0, 1], lin_wcsobj.wcs.cd[1, 1]) * 180. / np.pi + lin_wcsobj.pscale = sqrt(lin_wcsobj.wcs.cd[0, 0] ** 2 + lin_wcsobj.wcs.cd[1, 0] ** 2) * 3600. + lin_wcsobj.wcs.crval = np.array([0., 0.]) + lin_wcsobj.wcs.crpix = np.array([0., 0.]) lin_wcsobj.wcs.ctype = ['RA---TAN', 'DEC--TAN'] lin_wcsobj.wcs.set() return lin_wcsobj -def undistortWCS(wcsobj): + +def undistortWCS(wcsobj): """ Creates an undistorted linear WCS by applying the IDCTAB distortion model to a 3-point square. The new ORIENTAT angle is calculated as well as the @@ -175,25 +177,26 @@ def undistortWCS(wcsobj): return wcsobj.copy() crpix1 = wcsobj.wcs.crpix[0] crpix2 = wcsobj.wcs.crpix[1] - xy = np.array([(crpix1,crpix2),(crpix1+1.,crpix2),(crpix1,crpix2+1.)],dtype=np.double) + xy = np.array([(crpix1, crpix2), (crpix1 + 1., crpix2), + (crpix1, crpix2 + 1.)], dtype=np.double) offsets = np.array([wcsobj.ltv1, wcsobj.ltv2]) px = xy + offsets - #order = wcsobj.sip.a_order + # order = wcsobj.sip.a_order pscale = wcsobj.idcscale - #pixref = np.array([wcsobj.sip.SIPREF1, wcsobj.sip.SIPREF2]) + # pixref = np.array([wcsobj.sip.SIPREF1, wcsobj.sip.SIPREF2]) tan_pix = apply_idc(px, cx, cy, wcsobj.wcs.crpix, pscale, order=1) - xc = tan_pix[:,0] - yc = tan_pix[:,1] + xc = tan_pix[:, 0] + yc = tan_pix[:, 1] am = xc[1] - xc[0] bm = xc[2] - xc[0] cm = yc[1] - yc[0] dm = yc[2] - yc[0] - cd_mat = np.array([[am,bm],[cm,dm]],dtype=np.double) + cd_mat = np.array([[am, bm], [cm, dm]], dtype=np.double) # Check the determinant for singularity _det = (am * dm) - (bm * cm) - if ( _det == 0.0): + if (_det == 0.0): print('Singular matrix in updateWCS, aborting ...') return @@ -202,15 +205,16 @@ def undistortWCS(wcsobj): cd = np.dot(wcsobj.wcs.cd, cd_inv).astype(np.float64) lin_wcsobj.wcs.cd = cd lin_wcsobj.wcs.set() - lin_wcsobj.orientat = arctan2(lin_wcsobj.wcs.cd[0,1],lin_wcsobj.wcs.cd[1,1]) * 180./np.pi - lin_wcsobj.pscale = sqrt(lin_wcsobj.wcs.cd[0,0]**2 + lin_wcsobj.wcs.cd[1,0]**2)*3600. - lin_wcsobj.wcs.crval = np.array([0.,0.]) - lin_wcsobj.wcs.crpix = np.array([0.,0.]) + lin_wcsobj.orientat = arctan2(lin_wcsobj.wcs.cd[0, 1], lin_wcsobj.wcs.cd[1, 1]) * 180. / np.pi + lin_wcsobj.pscale = sqrt(lin_wcsobj.wcs.cd[0, 0] ** 2 + lin_wcsobj.wcs.cd[1, 0] ** 2) * 3600. + lin_wcsobj.wcs.crval = np.array([0., 0.]) + lin_wcsobj.wcs.crpix = np.array([0., 0.]) lin_wcsobj.wcs.ctype = ['RA---TAN', 'DEC--TAN'] lin_wcsobj.wcs.set() return lin_wcsobj -def apply_idc(pixpos, cx, cy, pixref, pscale= None, order=None): + +def apply_idc(pixpos, cx, cy, pixref, pscale=None, order=None): """ Apply the IDCTAB polynomial distortion model to pixel positions. pixpos must be already corrected for ltv1/2. @@ -233,27 +237,28 @@ def apply_idc(pixpos, cx, cy, pixref, pscale= None, order=None): return pixpos # Apply in the same way that 'drizzle' would... - _cx = cx/pscale - _cy = cy/ pscale + _cx = cx / pscale + _cy = cy / pscale _p = pixpos # Do NOT include any zero-point terms in CX,CY here # as they should not be scaled by plate-scale like rest # of coeffs... This makes the computations consistent # with 'drizzle'. WJH 17-Feb-2004 - _cx[0,0] = 0. - _cy[0,0] = 0. + _cx[0, 0] = 0. + _cy[0, 0] = 0. dxy = _p - pixref # Apply coefficients from distortion model here... c = _p * 0. - for i in range(order+1): - for j in range(i+1): - c[:,0] = c[:,0] + _cx[i][j] * pow(dxy[:,0],j) * pow(dxy[:,1],(i-j)) - c[:,1] = c[:,1] + _cy[i][j] * pow(dxy[:,0],j) * pow(dxy[:,1],(i-j)) + for i in range(order + 1): + for j in range(i + 1): + c[:, 0] = c[:, 0] + _cx[i][j] * pow(dxy[:, 0], j) * pow(dxy[:, 1], (i - j)) + c[:, 1] = c[:, 1] + _cy[i][j] * pow(dxy[:, 0], j) * pow(dxy[:, 1], (i - j)) + + return c - return c def foundIDCTAB(idctab): idctab_found = True |