diff options
author | embray <embray@stsci.edu> | 2011-04-05 12:11:19 -0400 |
---|---|---|
committer | embray <embray@stsci.edu> | 2011-04-05 12:11:19 -0400 |
commit | 616fc9ebf3632fb885e139f343ccf8fc1017a21b (patch) | |
tree | 7529596c70eb6316c772ad79efa0a6e9c7b2fae5 /wcsutil/hstwcs.py | |
parent | 462577895390869011e5aeb22e6afdd55b95c008 (diff) | |
download | stwcs_hcf-616fc9ebf3632fb885e139f343ccf8fc1017a21b.tar.gz |
Various cleanup and small bug fixes. In particular, init_wcscorr() now works what I believe to be 'correctly'--it applies all existing WCSs from the SCI extension headers to the new WCSCORR table in the correct order (wcs_key w/ 'O' first; extver).
git-svn-id: http://svn.stsci.edu/svn/ssb/stsci_python/stsci_python/trunk/stwcs@12393 fe389314-cf27-0410-b35b-8c050e845b92
Diffstat (limited to 'wcsutil/hstwcs.py')
-rw-r--r-- | wcsutil/hstwcs.py | 126 |
1 files changed, 63 insertions, 63 deletions
diff --git a/wcsutil/hstwcs.py b/wcsutil/hstwcs.py index b4e9123..d16e174 100644 --- a/wcsutil/hstwcs.py +++ b/wcsutil/hstwcs.py @@ -17,22 +17,22 @@ from mappings import basic_wcs __docformat__ = 'restructuredtext' - + class HSTWCS(WCS): def __init__(self, fobj=None, ext=None, minerr=0.0, wcskey=" "): """ Create a WCS object based on the instrument. - + In addition to basic WCS keywords this class provides instrument specific information needed in distortion computation. - + Parameters ---------- fobj: string or PyFITS HDUList object or None a file name, e.g j9irw4b1q_flt.fits a fully qualified filename[EXTNAME,EXTNUM], e.g. j9irw4b1q_flt.fits[sci,1] - a pyfits file object, e.g pyfits.open('j9irw4b1q_flt.fits'), in which case the + a pyfits file object, e.g pyfits.open('j9irw4b1q_flt.fits'), in which case the user is responsible for closing the file object. ext: int or None extension number @@ -42,14 +42,14 @@ class HSTWCS(WCS): If CPERRja, CQERRja are smaller than minerr, the corersponding distortion is not applied. wcskey: str - A one character A-Z or " " used to retrieve and define an + A one character A-Z or " " used to retrieve and define an alternate WCS description. """ self.inst_kw = ins_spec_kw self.minerr = minerr self.wcskey = wcskey - + if fobj != None: filename, hdr0, ehdr, phdu = getinput.parseSingleInput(f=fobj, ext=ext) self.filename = filename @@ -62,14 +62,14 @@ class HSTWCS(WCS): # If input was a pyfits HDUList object, it's the user's # responsibility to close it, otherwise, it's closed here. if not isinstance(fobj, pyfits.HDUList): - phdu.close() + phdu.close() self.setInstrSpecKw(hdr0, ehdr) self.readIDCCoeffs(ehdr) extname = ehdr.get('EXTNAME', "") extnum = ehdr.get('EXTVER', None) self.extname = (extname, extnum) else: - # create a default HSTWCS object + # create a default HSTWCS object self.instrument = 'DEFAULT' WCS.__init__(self, minerr=self.minerr, key=self.wcskey) self.pc2cd() @@ -89,22 +89,22 @@ class HSTWCS(WCS): """ Populate the instrument specific attributes: - These can be in different headers but each instrument class has knowledge + These can be in different headers but each instrument class has knowledge of where to look for them. - + Parameters ---------- prim_hdr: pyfits.Header primary header ext_hdr: pyfits.Header extension header - - """ + + """ if self.instrument in inst_mappings.keys(): inst_kl = inst_mappings[self.instrument] inst_kl = instruments.__dict__[inst_kl] insobj = inst_kl(prim_hdr, ext_hdr) - + for key in self.inst_kw: try: self.__setattr__(key, insobj.__getattribute__(key)) @@ -115,7 +115,7 @@ class HSTWCS(WCS): raise else: pass - + else: raise KeyError, "Unsupported instrument - %s" %self.instrument @@ -132,7 +132,7 @@ class HSTWCS(WCS): to a CD matrix, if reasonable, by running pc2.cd() method.\n \ The plate scale can be set then by calling setPscale() method.\n" self.pscale = None - + def setOrient(self): """ Computes ORIENTAT from the CD matrix @@ -146,30 +146,30 @@ class HSTWCS(WCS): to a CD matrix, if reasonable, by running pc2.cd() method.\n \ The orientation can be set then by calling setOrient() method.\n" self.pscale = None - + def updatePscale(self, scale): """ Updates the CD matrix with a new plate scale """ self.wcs.cd = self.wcs.cd/self.pscale*scale self.setPscale() - + def readModel(self, update=False, header=None): """ Reads distortion model from IDCTAB. - + If IDCTAB is not found ('N/A', "", or not found on disk), then if SIP coefficients and first order IDCTAB coefficients are present in the header, restore the idcmodel from the header. If not - assign None to self.idcmodel. - + Parameters ---------- header: pyfits.Header fits extension header update: boolean (False) if True - record the following IDCTAB quantities as header keywords: - CX10, CX11, CY10, CY11, IDCSCALE, IDCTHETA, IDCXREF, IDCYREF, + CX10, CX11, CY10, CY11, IDCSCALE, IDCTHETA, IDCXREF, IDCYREF, IDCV2REF, IDCV3REF """ if self.idctab in [None, '', ' ','N/A']: @@ -187,7 +187,7 @@ class HSTWCS(WCS): self.idcmodel = None else: self.readModelFromIDCTAB(header=header, update=update) - + def _readModelFromHeader(self, header): # Recreate idc model from SIP coefficients and header kw print 'Restoring IDC model from SIP coefficients\n' @@ -197,7 +197,7 @@ class HSTWCS(WCS): model.cy = cy model.name = "sip" model.norder = header['A_ORDER'] - + refpix = {} refpix['XREF'] = header['IDCXREF'] refpix['YREF'] = header['IDCYREF'] @@ -206,23 +206,23 @@ class HSTWCS(WCS): refpix['V3REF'] = header['IDCV3REF'] refpix['THETA'] = header['IDCTHETA'] model.refpix = refpix - + self.idcmodel = model - - + + def readModelFromIDCTAB(self, header=None, update=False): """ Read distortion model from idc table. - + Parameters ---------- header: pyfits.Header fits extension header update: boolean (False) if True - save teh following as header keywords: - CX10, CX11, CY10, CY11, IDCSCALE, IDCTHETA, IDCXREF, IDCYREF, + CX10, CX11, CY10, CY11, IDCSCALE, IDCTHETA, IDCXREF, IDCYREF, IDCV2REF, IDCV3REF - + """ if self.date_obs == None: print 'date_obs not available\n' @@ -247,10 +247,10 @@ class HSTWCS(WCS): def wcs2header(self, sip2hdr=False, idc2hdr=True): """ Create a pyfits.Header object from WCS keywords. - + If the original header had a CD matrix, return a CD matrix, otherwise return a PC matrix. - + Parameters ---------- sip2hdr: boolean @@ -259,7 +259,7 @@ class HSTWCS(WCS): h = self.to_header() if self.wcs.has_cd(): h = altwcs.pc2cd(h, key=self.wcskey) - + if idc2hdr: for card in self._idc2hdr(): h.update(card.key,value=card.value,comment=card.comment) @@ -267,7 +267,7 @@ class HSTWCS(WCS): del h.ascard['RESTFRQ'] del h.ascard['RESTWAV'] except KeyError: pass - + if sip2hdr and self.sip: for card in self._sip2hdr('a'): h.update(card.key,value=card.value,comment=card.comment) @@ -282,7 +282,7 @@ class HSTWCS(WCS): bp = self.sip.bp except AssertionError: bp = None - + if ap: for card in self._sip2hdr('ap'): h.update(card.key,value=card.value,comment=card.comment) @@ -290,26 +290,26 @@ class HSTWCS(WCS): for card in self._sip2hdr('bp'): h.update(card.key,value=card.value,comment=card.comment) return h - - + + def _sip2hdr(self, k): """ - Get a set of SIP coefficients in the form of an array - and turn them into a pyfits.Cardlist. + Get a set of SIP coefficients in the form of an array + and turn them into a pyfits.Cardlist. k - one of 'a', 'b', 'ap', 'bp' """ - + cards = pyfits.CardList() korder = self.sip.__getattribute__(k+'_order') cards.append(pyfits.Card(key=k.upper()+'_ORDER', value=korder)) coeffs = self.sip.__getattribute__(k) ind = coeffs.nonzero() for i in range(len(ind[0])): - card = pyfits.Card(key=k.upper()+'_'+str(ind[0][i])+'_'+str(ind[1][i]), + card = pyfits.Card(key=k.upper()+'_'+str(ind[0][i])+'_'+str(ind[1][i]), value=coeffs[ind[0][i], ind[1][i]]) cards.append(card) return cards - + def _idc2hdr(self): # save some of the idc coefficients coeffs = ['ocx10', 'ocx11', 'ocy10', 'ocy11', 'idcscale'] @@ -321,51 +321,51 @@ class HSTWCS(WCS): continue cards.append(pyfits.Card(key=c, value=val)) return cards - + def pc2cd(self): self.wcs.cd = self.wcs.pc.copy() - + def all_sky2pix(self,ra,dec,origin): - """ - Performs full inverse transformation using iterative solution + """ + Performs full inverse transformation using iterative solution on full forward transformation with complete distortion model. - + NOTES ----- We now need to find the position we want by iterative improvement of an initial guess - the centre of the chip - + The method is to derive an "effective CD matrix" and use that to apply a correction until we are close enough (as defined by the ERR variable) - + Code from the drizzle task TRANBACK (dither$drizzle/tranback.f) defined the algorithm for this implementation - + """ from stwcs.distortion import utils - + # Define some output arrays xout = np.zeros(len(ra),dtype=np.float64) yout = np.zeros(len(ra),dtype=np.float64) # ... and internal arrays x = np.zeros(3,dtype=np.float64) y = np.zeros(3,dtype=np.float64) - + # define delta for comparison err = 0.0001 - + # Use linear WCS as frame in which to perform fit # rather than on the sky undistort = True if self.sip is None: # Only apply distortion if distortion coeffs are present. - undistort = False + undistort = False wcslin = utils.output_wcs([self],undistort=undistort) - + # We can only transform 1 position at a time for r,d,n in zip(ra,dec,xrange(len(ra))): - # First guess for output + # First guess for output x[0],y[0] = self.wcs_sky2pix(r,d,origin) # also convert RA,Dec into undistorted linear pixel positions lx,ly = wcslin.wcs_sky2pix(r,d,origin) @@ -374,7 +374,7 @@ class HSTWCS(WCS): ev_old = None for i in xrange(20): x[1] = x[0] + 1.0 - y[1] = y[0] + y[1] = y[0] x[2] = x[0] y[2] = y[0] + 1.0 # Perform full transformation on pixel position @@ -382,11 +382,11 @@ class HSTWCS(WCS): # convert RA,Dec into linear pixel positions for fitting xo,yo = wcslin.wcs_sky2pix(rao,deco,origin) - # Compute deltas between output and initial guess as + # Compute deltas between output and initial guess as # an affine transform then invert that transformation dxymat = np.array([[xo[1]-xo[0],yo[1]-yo[0]], [xo[2]-xo[0],yo[2]-yo[0]]],dtype=np.float64) - + invmat = np.linalg.inv(dxymat) # compute error in output position dx = lx - xo[0] @@ -402,14 +402,14 @@ class HSTWCS(WCS): # Work out the error vector length ev = np.sqrt((x[0] - xold)**2 + (y[0] - yold)**2) - + # initialize record of previous error measurement during 1st iteration if ev_old is None: ev_old = ev - - # Check to see whether we have reached the limit or + + # Check to see whether we have reached the limit or # the new error is greater than error from previous iteration - if ev < err or (np.abs(ev) > np.abs(ev_old)): + if ev < err or (np.abs(ev) > np.abs(ev_old)): break # remember error measurement from previous iteration ev_old = ev @@ -418,7 +418,7 @@ class HSTWCS(WCS): yout[n] = y[0] return xout,yout - + def _updatehdr(self, ext_hdr): #kw2add : OCX10, OCX11, OCY10, OCY11 # record the model in the header for use by pydrizzle @@ -432,7 +432,7 @@ class HSTWCS(WCS): ext_hdr.update('IDCYREF', self.idcmodel.refpix['YREF']) ext_hdr.update('IDCV2REF', self.idcmodel.refpix['V2REF']) ext_hdr.update('IDCV3REF', self.idcmodel.refpix['V3REF']) - + def printwcs(self): """ Print the basic WCS keywords. |