summaryrefslogtreecommitdiff
path: root/updatewcs/corrections.py
diff options
context:
space:
mode:
Diffstat (limited to 'updatewcs/corrections.py')
-rw-r--r--updatewcs/corrections.py164
1 files changed, 164 insertions, 0 deletions
diff --git a/updatewcs/corrections.py b/updatewcs/corrections.py
new file mode 100644
index 0000000..800c1c6
--- /dev/null
+++ b/updatewcs/corrections.py
@@ -0,0 +1,164 @@
+import datetime
+import numpy
+from numpy import linalg
+#from pytools import wcsutil
+
+from makewcs import MakeWCS
+from dgeo import 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.
+
+ Ref: Jay Anderson, ACS ISR 2007-08, Variation of the Distortion
+ Solution of the WFC
+
+ """
+ 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):
+ """
+ - Calculates alpha and beta for ACS/WFC data.
+ - Writes 2 new kw to the extension header: TDDALPHA and TDDBETA
+ """
+ if self.wcsobj.instrument == 'ACS' and self.wcsobj.detector == 'WFC':
+ newkw = ['TDDALPHA', 'TDDBETA']
+ self.set_alpha_beta()
+ self.updatehdr(newkeywords=newkw)
+
+ else:
+ pass
+
+ def set_alpha_beta(self):
+ # Compute the time dependent distortion skew terms
+ # default date of 2004.5 = 2004-7-1
+
+ datedefault = datetime.datetime(2004,7,1)
+ year,month,day = self.wcsobj.date_obs.split('-')
+ rdate = datetime.datetime(int(year),int(month),int(day))
+ self.TDDALPHA = 0.095+0.090*((rdate-datedefault).days/365.25)/2.5
+ self.TDDBETA = -0.029-0.030*((rdate-datedefault).days/365.25)/2.5
+ self.TDDALPHA = 0.0
+ self.TDDBETA = 0.0
+
+ def updatehdr(self, newkeywords=None):
+
+ for kw in newkeywords:
+ self.wcsobj.hdr.update(kw, self.__getattribute__(kw))
+
+
+class VACorr(object):
+ """
+ Purpose
+ =======
+ 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
+
+ #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)
+ else:
+ pass
+
+ def updatehdr(self, newkeywords=None):
+ for kw in newkeywords:
+ self.wcsobj.hdr.update(kw, newkeywords[kw])
+
+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):
+ kw2update = {}
+ order = self.wcsobj.idcmodel.norder
+ kw2update['A_ORDER'] = order
+ kw2update['B_ORDER'] = order
+ pscale = self.wcsobj.idcmodel.refpix['PSCALE']
+
+ cx = self.wcsobj.idcmodel.cx
+ cy = self.wcsobj.idcmodel.cy
+
+ matr = numpy.array([[cx[1,1],cx[1,0]], [cy[1,1],cy[1,0]]], dtype=numpy.float)
+ imatr = linalg.inv(matr)
+ akeys1 = numpy.zeros((order+1,order+1), dtype=numpy.float)
+ bkeys1 = numpy.zeros((order+1,order+1), dtype=numpy.float)
+ for n in range(order+1):
+ for m in range(order+1):
+ if n >= m and n>=2:
+ idcval = numpy.array([[cx[n,m]],[cy[n,m]]])
+ sipval = numpy.dot(imatr, idcval)
+ akeys1[m,n-m] = sipval[0]
+ bkeys1[m,n-m] = sipval[1]
+ Akey="A_%d_%d" % (m,n-m)
+ 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.
+ """
+
+ diff = a - b
+
+ if diff > 180.0:
+ diff -= 360.0
+
+ if diff < -180.0:
+ diff += 360.0
+
+ return diff