diff options
Diffstat (limited to 'updatewcs')
-rw-r--r-- | updatewcs/__init__.py | 45 | ||||
-rw-r--r-- | updatewcs/corrections.py | 167 | ||||
-rw-r--r-- | updatewcs/makewcs.py | 189 |
3 files changed, 171 insertions, 230 deletions
diff --git a/updatewcs/__init__.py b/updatewcs/__init__.py index db89d13..107a9f5 100644 --- a/updatewcs/__init__.py +++ b/updatewcs/__init__.py @@ -4,12 +4,13 @@ import pyfits from hstwcs.wcsutil import HSTWCS from hstwcs.mappings import allowed_corrections #from .. mappings import allowed_corrections +from hstwcs import utils import corrections, makewcs import dgeo import time from pytools import parseinput, fileutil -#NB! the order of corrections matters +#Note: The order of corrections is important __docformat__ = 'restructuredtext' @@ -52,19 +53,30 @@ def updatewcs(input, vacorr=True, tddcorr=True, checkfiles=True): print 'No valid input, quitting ...\n' return for f in files: - instr = pyfits.getval(f, 'INSTRUME') + instrument = pyfits.getval(f, 'INSTRUME') + if instrument == 'ACS' and pyfits.getval(f, 'DETECTOR')== 'WFC': + try: + tdc = pyfits.getval(f, 'TDDCORR') + if tdc == 'PERFORM': + tddcorr = True + else: + tddcorr = False + except KeyError: + tddcorr = True try: - acorr = setCorrections(instr,vacorr=vacorr, tddcorr=tddcorr) + #define which corrections will be performed + acorr = setCorrections(instrument,vacorr=vacorr, tddcorr=tddcorr) except KeyError: print 'Unsupported instrument %s ' %instr print 'Removing %s from list of processed files\n' % f files.remove(f) continue - + #restore the original WCS keywords + utils.restoreWCS(f) makecorr(f, acorr) return files -def makecorr(fname, acorr): +def makecorr(fname, allowed_corr): """ Purpose ======= @@ -78,23 +90,26 @@ def makecorr(fname, acorr): """ f = pyfits.open(fname, mode='update') + #Determine the reference chip and make a copy of its restored header. nrefchip, nrefext = getNrefchip(f) primhdr = f[0].header - + ref_hdr = f[nrefext].header.copy() + utils.write_archive(ref_hdr) for extn in f: - refwcs = HSTWCS(primhdr, f[nrefext].header) - refwcs.archive_kw() - refwcs.readModel() + # Perhaps all ext headers should be corrected (to be consistent) if extn.header.has_key('extname') and extn.header['extname'].lower() == 'sci': + refwcs = HSTWCS(primhdr, ref_hdr, fobj=f) + refwcs.readModel(ref_hdr) hdr = extn.header - owcs = HSTWCS(primhdr, hdr) - owcs.archive_kw() - owcs.readModel() - for c in acorr: - owcs.__setattr__('DO'+c, 'PERFORM') + owcs = HSTWCS(primhdr, hdr, fobj=f) + utils.write_archive(hdr) + owcs.readModel(hdr) + for c in allowed_corr: corr_klass = corrections.__getattribute__(c) - corr_klass(owcs, refwcs) + kw2update = corr_klass.updateWCS(owcs, refwcs) + for kw in kw2update: + hdr.update(kw, kw2update[kw]) diff --git a/updatewcs/corrections.py b/updatewcs/corrections.py index e94be64..ac49833 100644 --- a/updatewcs/corrections.py +++ b/updatewcs/corrections.py @@ -2,51 +2,44 @@ import datetime import numpy from numpy import linalg from pytools import fileutil +from hstwcs.utils import diff_angles +import makewcs, dgeo -from makewcs import MakeWCS -from dgeo import DGEO +MakeWCS = makewcs.MakeWCS +DGEO = dgeo.DGEO class TDDCorr(object): """ Purpose ======= Apply time dependent distortion correction to SIP coefficients and basic - WCS keywords. Atthi stime it is applicable only to ACS/WFC data. + WCS keywords. It is applicable only to ACS/WFC data. Ref: Jay Anderson, ACS ISR 2007-08, Variation of the Distortion Solution of the WFC + :Parameters: + `owcs`: HSTWCS object + An extension HSTWCS object to be modified + `refwcs`: HSTWCS object + A reference HSTWCS object """ - def __init__(self, owcs=None, refwcs=None): - """ - :Parameters: - `owcs`: HSTWCS object - An extension HSTWCS object to be modified - `refwcs`: HSTWCS object - A reference HSTWCS object - """ - self.wcsobj = owcs - if self.wcsobj.DOTDDCorr == 'PERFORM': - self.updateWCS() - self.wcsobj.DOTDDCorr = 'COMPLETE' - else: - pass - - def updateWCS(self): + + def updateWCS(cls, wcs, refwcs): """ - Calculates alpha and beta for ACS/WFC data. - Writes 2 new kw to the extension header: TDDALPHA and TDDBETA + - sets TDDCORR to COMPLETE """ - if self.wcsobj.instrument == 'ACS' and self.wcsobj.detector == 'WFC': - newkw = ['TDDALPHA', 'TDDBETA'] - self.set_alpha_beta() - self.applyTDD() - self.updatehdr(newkeywords=newkw) - - else: - pass + + alpha, beta = cls.set_alpha_beta(wcs) + cls.apply_tdd2idc(wcs, alpha, beta) + newkw = {'TDDALPHA': alpha, 'TDDBETA':beta, 'TDDCORR': 'COMPLETE'} + + return newkw + updateWCS = classmethod(updateWCS) - def applyTDD(self): + def apply_tdd2idc(cls,wcs, alpha, beta): """ Applies TDD to the idctab coefficients of a ACS/WFC observation. This should be always the first correction. @@ -56,36 +49,36 @@ class TDDCorr(object): idcrad = fileutil.DEGTORAD(idctheta) mrotp = fileutil.buildRotMatrix(idctheta) mrotn = fileutil.buildRotMatrix(-idctheta) - abmat = numpy.array([[self.TDDBETA,self.TDDALPHA],[self.TDDALPHA,self.TDDBETA]]) - tdd_mat = numpy.array([[1+(self.TDDBETA/2048.), self.TDDALPHA/2048.],[self.TDDALPHA/2048.,1-(self.TDDBETA/2048.)]],numpy.float64) + abmat = numpy.array([[beta,alpha],[alpha,beta]]) + tdd_mat = numpy.array([[1+(beta/2048.), alpha/2048.],[alpha/2048.,1-(beta/2048.)]],numpy.float64) abmat1 = numpy.dot(tdd_mat, mrotn) abmat2 = numpy.dot(mrotp,abmat1) - xshape, yshape = self.wcsobj.idcmodel.cx.shape, self.wcsobj.idcmodel.cy.shape - icxy = numpy.dot(abmat2,[self.wcsobj.idcmodel.cx.ravel(),self.wcsobj.idcmodel.cy.ravel()]) - self.wcsobj.idcmodel.cx = icxy[0] - self.wcsobj.idcmodel.cy = icxy[1] - self.wcsobj.idcmodel.cx.shape = xshape - self.wcsobj.idcmodel.cy.shape = yshape + xshape, yshape = wcs.idcmodel.cx.shape, wcs.idcmodel.cy.shape + icxy = numpy.dot(abmat2,[wcs.idcmodel.cx.ravel(),wcs.idcmodel.cy.ravel()]) + wcs.idcmodel.cx = icxy[0] + wcs.idcmodel.cy = icxy[1] + wcs.idcmodel.cx.shape = xshape + wcs.idcmodel.cy.shape = yshape + wcs.set() + + apply_tdd2idc = classmethod(apply_tdd2idc) - def set_alpha_beta(self): + def set_alpha_beta(cls, wcs): """ Compute the time dependent distortion skew terms default date of 2004.5 = 2004-7-1 """ dday = 2004.5 - year,month,day = self.wcsobj.date_obs.split('-') + year,month,day = wcs.date_obs.split('-') rdate = datetime.datetime(int(year),int(month),int(day)) rday = float(rdate.strftime("%j"))/365.25 + rdate.year alpha = 0.095 + 0.090*(rday-dday)/2.5 beta = -0.029 - 0.030*(rday-dday)/2.5 - self.TDDALPHA = alpha - self.TDDBETA = beta - - def updatehdr(self, newkeywords=None): - - for kw in newkeywords: - self.wcsobj.hdr.update(kw, self.__getattribute__(kw)) + return alpha, beta + + set_alpha_beta = classmethod(set_alpha_beta) + class VACorr(object): """ @@ -93,60 +86,44 @@ class VACorr(object): ======= Apply velocity aberation correction to WCS keywords. Modifies the CD matrix and CRVAL1/2 + """ - def __init__(self, owcs=None, refwcs=None): - self.wcsobj = owcs - self.refwcs = refwcs - if self.wcsobj.DOVACorr == 'PERFORM': - self.updateWCS() - self.wcsobj.DOVACorr == 'COMPLETE' - else: - pass - - def updateWCS(self): - if self.wcsobj.vafactor != 1: - self.wcsobj.cd = self.wcsobj.cd * self.wcsobj.vafactor + + def updateWCS(cls, wcs, refwcs): + if wcs.vafactor != 1: + wcs.cd = wcs.cd * wcs.vafactor + crval1 = wcs.crval[0] + crval2 = wcs.crval[1] + wcs.crval[0] = wcs.crval[0] + wcs.vafactor*diff_angles(wcs.crval[0], crval1) + wcs.crval[1] = wcs.crval[1] + wcs.vafactor*diff_angles(wcs.crval[1], crval2) - #self.wcsobj.crval[0] = self.wcsobj.ra_targ + self.wcsobj.vafactor*(self.wcsobj.crval[0] - self.wcsobj.ra_targ) - #self.wcsobj.crval[1] = self.wcsobj.dec_targ + self.wcsobj.vafactor*(self.wcsobj.crval[1] - self.wcsobj.dec_targ) - ref_backup = self.refwcs.restore() - crval1 = ref_backup['CRVAL1'] - crval2 = ref_backup['CRVAL2'] - self.wcsobj.crval[0] = crval1 + self.wcsobj.vafactor*diff_angles(self.wcsobj.crval[0], crval1) - self.wcsobj.crval[1] = crval2 + self.wcsobj.vafactor*diff_angles(self.wcsobj.crval[1], crval2) - - kw2update={'CD1_1': self.wcsobj.cd[0,0], 'CD1_2':self.wcsobj.cd[0,1], - 'CD2_1':self.wcsobj.cd[1,0], 'CD2_2':self.wcsobj.cd[1,1], - 'CRVAL1':self.wcsobj.crval[0], 'CRVAL2':self.wcsobj.crval[1]} - self.updatehdr(newkeywords=kw2update) + kw2update={'CD1_1': wcs.cd[0,0], 'CD1_2':wcs.cd[0,1], + 'CD2_1':wcs.cd[1,0], 'CD2_2':wcs.cd[1,1], + 'CRVAL1':wcs.crval[0], 'CRVAL2':wcs.crval[1]} + wcs.set() else: pass - - def updatehdr(self, newkeywords=None): - for kw in newkeywords: - self.wcsobj.hdr.update(kw, newkeywords[kw]) + return kw2update + + updateWCS = classmethod(updateWCS) + class CompSIP(object): """ Purpose ======= Compute SIP coefficients from idc table coefficients. - """ - def __init__(self, owcs, refwcs): - self.wcsobj = owcs - self.updateWCS() - self.DOCOMPSIP = 'COMPLETE' - - def updateWCS(self): + + def updateWCS(cls, wcs, refwcs): kw2update = {} - order = self.wcsobj.idcmodel.norder + order = wcs.idcmodel.norder kw2update['A_ORDER'] = order kw2update['B_ORDER'] = order - pscale = self.wcsobj.idcmodel.refpix['PSCALE'] + pscale = wcs.idcmodel.refpix['PSCALE'] - cx = self.wcsobj.idcmodel.cx - cy = self.wcsobj.idcmodel.cy + cx = wcs.idcmodel.cx + cy = wcs.idcmodel.cy matr = numpy.array([[cx[1,1],cx[1,0]], [cy[1,1],cy[1,0]]], dtype=numpy.float) imatr = linalg.inv(matr) @@ -163,26 +140,8 @@ class CompSIP(object): Bkey="B_%d_%d" % (m,n-m) kw2update[Akey] = sipval[0,0] kw2update[Bkey] = sipval[1,0] - self.updatehdr(newkw=kw2update) - - def updatehdr(self, newkw=None): - if not newkw: return - for kw in newkw.keys(): - self.wcsobj.hdr.update(kw, newkw[kw]) - - -def diff_angles(a,b): - """ - Perform angle subtraction a-b taking into account - small-angle differences across 360degree line. - """ + return kw2update - diff = a - b + updateWCS = classmethod(updateWCS) - if diff > 180.0: - diff -= 360.0 - if diff < -180.0: - diff += 360.0 - - return diff diff --git a/updatewcs/makewcs.py b/updatewcs/makewcs.py index 451da13..ddb4d06 100644 --- a/updatewcs/makewcs.py +++ b/updatewcs/makewcs.py @@ -3,6 +3,7 @@ from hstwcs.mappings import DEGTORAD, RADTODEG import numpy from numpy import math from math import sin, sqrt, pow, cos, asin, atan2,pi +from hstwcs import utils class MakeWCS(object): """ @@ -17,74 +18,73 @@ class MakeWCS(object): - update extension header """ - - def __init__(self, owcs, refwcs): - self.wcsobj = owcs - self.refwcs = refwcs - self.updateWCS() - self.DOMakeWCS = 'COMPLETE' - - def updateWCS(self): + + def updateWCS(cls, wcs, refwcs): """ recomputes the basic WCS kw """ - backup_wcs = self.wcsobj.restore() - ltvoff, offshift = self.getOffsets(backup_wcs) + ltvoff, offshift = cls.getOffsets(wcs) - self.uprefwcs(ltvoff, offshift) - self.upextwcs(ltvoff, offshift) - self.updatehdr() - - def upextwcs(self, loff, offsh): + cls.uprefwcs(wcs, refwcs, ltvoff, offshift) + cls.upextwcs(wcs, refwcs, ltvoff, offshift) + + kw2update = {'CD1_1': wcs.cd[0,0], + 'CD1_2': wcs.cd[0,1], + 'CD2_1': wcs.cd[1,0], + 'CD2_2': wcs.cd[1,1], + 'CRVAL1': wcs.crval[0], + 'CRVAL2': wcs.crval[1], + 'CRPIX1': wcs.crpix[0], + 'CRPIX2': wcs.crpix[1], + } + return kw2update + + updateWCS = classmethod(updateWCS) + + def upextwcs(self, wcs, refwcs, loff, offsh): """ updates an extension wcs """ ltvoffx, ltvoffy = loff[0], loff[1] offshiftx, offshifty = offsh[0], offsh[1] - backup_wcs = self.wcsobj.restore() - ltv1 = self.wcsobj.ltv1 - ltv2 = self.wcsobj.ltv2 - - + ltv1 = wcs.ltv1 + ltv2 = wcs.ltv2 if ltv1 != 0. or ltv2 != 0.: - offsetx = backup_wcs['CRPIX1'] - ltv1 - self.wcsobj.idcmodel.refpix['XREF'] - offsety = backup_wcs['CRPIX2'] - ltv2 - self.wcsobj.idcmodel.refpix['YREF'] - fx,fy = self.wcsobj.idcmodel.shift(self.wcsobj.idcmodel.cx,self.wcsobj.idcmodel.cy,offsetx,offsety) + offsetx = backup_wcs['CRPIX1'] - ltv1 - wcs.idcmodel.refpix['XREF'] + offsety = backup_wcs['CRPIX2'] - ltv2 - wcs.idcmodel.refpix['YREF'] + fx,fy = wcs.idcmodel.shift(wcs.idcmodel.cx,wcs.idcmodel.cy,offsetx,offsety) else: - fx, fy = self.wcsobj.idcmodel.cx, self.wcsobj.idcmodel.cy + fx, fy = wcs.idcmodel.cx, wcs.idcmodel.cy - ridcmodel = self.refwcs.idcmodel - v2 = self.wcsobj.idcmodel.refpix['V2REF'] - v3 = self.wcsobj.idcmodel.refpix['V3REF'] - v2ref = self.refwcs.idcmodel.refpix['V2REF'] + ridcmodel = refwcs.idcmodel + v2 = wcs.idcmodel.refpix['V2REF'] + v3 = wcs.idcmodel.refpix['V3REF'] + v2ref = refwcs.idcmodel.refpix['V2REF'] - v3ref = self.refwcs.idcmodel.refpix['V3REF'] - R_scale = self.refwcs.idcmodel.refpix['PSCALE']/3600.0 + v3ref = refwcs.idcmodel.refpix['V3REF'] + R_scale = refwcs.idcmodel.refpix['PSCALE']/3600.0 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(self.wcsobj.parity[0][0]*(v2-v2ref),self.wcsobj.parity[1][1]*(v3-v3ref)) + theta = atan2(wcs.parity[0][0]*(v2-v2ref), wcs.parity[1][1]*(v3-v3ref)) - if self.refwcs.idcmodel.refpix['THETA']: theta += self.refwcs.idcmodel.refpix['THETA']*pi/180.0 + if refwcs.idcmodel.refpix['THETA']: theta += refwcs.idcmodel.refpix['THETA']*pi/180.0 dX=(off*sin(theta)) + offshiftx dY=(off*cos(theta)) + offshifty px = numpy.array([[dX,dY]]) - newcrval = self.refwcs.pixel2world_fits(px)[0] - newcrpix = numpy.array([self.wcsobj.idcmodel.refpix['XREF'] + ltvoffx, - self.wcsobj.idcmodel.refpix['YREF'] + ltvoffy]) - - self.wcsobj.crval = newcrval - self.wcsobj.crpix = newcrpix + newcrval = refwcs.pixel2world_fits(px)[0] + newcrpix = numpy.array([wcs.idcmodel.refpix['XREF'] + ltvoffx, + wcs.idcmodel.refpix['YREF'] + ltvoffy]) + wcs.crval = newcrval + wcs.crpix = newcrpix # Account for subarray offset # Angle of chip relative to chip - if self.wcsobj.idcmodel.refpix['THETA']: - dtheta = self.wcsobj.idcmodel.refpix['THETA'] - self.refwcs.idcmodel.refpix['THETA'] + if wcs.idcmodel.refpix['THETA']: + dtheta = wcs.idcmodel.refpix['THETA'] - refwcs.idcmodel.refpix['THETA'] else: dtheta = 0.0 @@ -96,8 +96,7 @@ class MakeWCS(object): 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 @@ -110,93 +109,74 @@ class MakeWCS(object): px = numpy.array([[dX+dXX,dY+dYX]]) # Transform to sky coordinates - - wc = self.refwcs.pixel2world_fits(px) + wc = refwcs.pixel2world_fits(px) a = wc[0,0] b = wc[0,1] px = numpy.array([[dX+dXY,dY+dYY]]) - wc = self.refwcs.pixel2world_fits(px) + wc = refwcs.pixel2world_fits(px) c = wc[0,0] d = wc[0,1] - + # Calculate the new CDs and convert to degrees - cd11 = diff_angles(a,newcrval[0])*cos(newcrval[1]*pi/180.0) - cd12 = diff_angles(c,newcrval[0])*cos(newcrval[1]*pi/180.0) - cd21 = diff_angles(b,newcrval[1]) - cd22 = diff_angles(d,newcrval[1]) - + cd11 = utils.diff_angles(a,newcrval[0])*cos(newcrval[1]*pi/180.0) + cd12 = utils.diff_angles(c,newcrval[0])*cos(newcrval[1]*pi/180.0) + cd21 = utils.diff_angles(b,newcrval[1]) + cd22 = utils.diff_angles(d,newcrval[1]) cd = numpy.array([[cd11, cd12], [cd21, cd22]]) - self.wcsobj.cd = cd + wcs.cd = cd + + upextwcs = classmethod(upextwcs) - def uprefwcs(self, loff, offsh): + def uprefwcs(self, wcs, refwcs, loff, offsh): """ Updates the reference chip """ ltvoffx, ltvoffy = loff[0], loff[1] offshift = offsh - backup_refwcs = self.refwcs.restore() - dec = backup_refwcs['CRVAL2'] - + dec = refwcs.crval[1] # Get an approximate reference position on the sky - rref = numpy.array([[self.refwcs.idcmodel.refpix['XREF']+ltvoffx, - self.refwcs.idcmodel.refpix['YREF']+ltvoffy]]) - - - crval = self.refwcs.pixel2world_fits(rref) + rref = numpy.array([[refwcs.idcmodel.refpix['XREF']+ltvoffx, + refwcs.idcmodel.refpix['YREF']+ltvoffy]]) + crval = refwcs.pixel2world_fits(rref) # 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 = troll(self.wcsobj.pav3,dec,self.refwcs.idcmodel.refpix['V2REF'], - self.refwcs.idcmodel.refpix['V3REF']) + pv = troll(wcs.pav3,dec,refwcs.idcmodel.refpix['V2REF'], + refwcs.idcmodel.refpix['V3REF']) # Add the chip rotation angle - if self.refwcs.idcmodel.refpix['THETA']: - pv += self.refwcs.idcmodel.refpix['THETA'] + if refwcs.idcmodel.refpix['THETA']: + pv += refwcs.idcmodel.refpix['THETA'] # Set values for the rest of the reference WCS - self.refwcs.crval = crval[0] - self.refwcs.crpix = numpy.array([0.0,0.0])+offsh - parity = self.refwcs.parity - R_scale = self.refwcs.idcmodel.refpix['PSCALE']/3600.0 + refwcs.crval = crval[0] + refwcs.crpix = numpy.array([0.0,0.0])+offsh + parity = refwcs.parity + R_scale = refwcs.idcmodel.refpix['PSCALE']/3600.0 cd11 = parity[0][0] * cos(pv*pi/180.0)*R_scale cd12 = parity[0][0] * -sin(pv*pi/180.0)*R_scale cd21 = parity[1][1] * sin(pv*pi/180.0)*R_scale cd22 = parity[1][1] * cos(pv*pi/180.0)*R_scale rcd = numpy.array([[cd11, cd12], [cd21, cd22]]) - self.refwcs.cd = rcd - self.refwcs.set() - - + refwcs.cd = rcd + refwcs.set() - def updatehdr(self): - """ - Keywords to update: - CD1_1, CD1_2, CD2_1, CD2_2, CRPIX1, CRPIX2, CRVAL1, CRVAL2 - """ - - self.wcsobj.hdr.update('CD1_1', self.wcsobj.cd[0,0]) - self.wcsobj.hdr.update('CD1_2', self.wcsobj.cd[0,1]) - self.wcsobj.hdr.update('CD2_1', self.wcsobj.cd[1,0]) - self.wcsobj.hdr.update('CD2_2', self.wcsobj.cd[1,1]) - self.wcsobj.hdr.update('CRVAL1', self.wcsobj.crval[0]) - self.wcsobj.hdr.update('CRVAL2', self.wcsobj.crval[1]) - self.wcsobj.hdr.update('CRPIX1', self.wcsobj.crpix[0]) - self.wcsobj.hdr.update('CRPIX2', self.wcsobj.crpix[1]) - self.wcsobj.hdr.update('ORIENTAT', self.wcsobj.orientat) + uprefwcs = classmethod(uprefwcs) - def getOffsets(self, backup_wcs): - ltv1 = self.wcsobj.ltv1 - ltv2 = self.wcsobj.ltv2 + + def getOffsets(cls, wcs): + ltv1 = wcs.ltv1 + ltv2 = wcs.ltv2 - offsetx = backup_wcs['CRPIX1'] - ltv1 - self.wcsobj.idcmodel.refpix['XREF'] - offsety = backup_wcs['CRPIX2'] - ltv2 - self.wcsobj.idcmodel.refpix['YREF'] + offsetx = wcs.crpix[0] - ltv1 - wcs.idcmodel.refpix['XREF'] + offsety = wcs.crpix[1] - ltv2 - wcs.idcmodel.refpix['YREF'] - shiftx = self.wcsobj.idcmodel.refpix['XREF'] + ltv1 - shifty = self.wcsobj.idcmodel.refpix['YREF'] + ltv2 + shiftx = wcs.idcmodel.refpix['XREF'] + ltv1 + shifty = wcs.idcmodel.refpix['YREF'] + ltv2 if ltv1 != 0. or ltv2 != 0.: ltvoffx = ltv1 + offsetx ltvoffy = ltv2 + offsety @@ -212,21 +192,8 @@ class MakeWCS(object): offshift = numpy.array([offshiftx, offshifty]) return ltvoff, offshift -def diff_angles(a,b): - """ - Perform angle subtraction a-b taking into account - small-angle differences across 360degree line. - """ - - diff = a - b - - if diff > 180.0: - diff -= 360.0 - - if diff < -180.0: - diff += 360.0 + getOffsets = classmethod(getOffsets) - return diff def troll(roll, dec, v2, v3): """ Computes the roll angle at the target position based on: |