summaryrefslogtreecommitdiff
path: root/wcsutil/__init__.py
blob: 46ad42e33e20a1e04b2313021b6663c0866d0a81 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#from .. pywcs.sip import SIP
from pywcs.sip import SIP
import pyfits
import instruments
#from .. distortion import models
from hstwcs.distortion import models
import numpy as N

#from .. mappings import inst_mappings, ins_spec_kw, DEGTORAD, RADTODEG, basic_wcs
from hstwcs.mappings import inst_mappings, ins_spec_kw, DEGTORAD, RADTODEG
from hstwcs.mappings import basic_wcs, prim_hdr_kw

__docformat__ = 'restructuredtext'

class HSTWCS(SIP):
    """
    Purpose
    =======
    Create a wcs object based on the instrument.
    It has all basic WCS kw as attribbutes (set by pywcs).
    It also uses the primary and extension header to define 
    instrument specific attributes needed by the correction classes.
    """
    
    def __init__(self, hdr0, hdr):
        """
        :Parameters:
        `hdr0`: Pyfits Header
                primary header
        `hdr`: Pyfits Header
               extension header
        """
        self.hdr = hdr
        self.hdr0 = hdr0
        SIP.__init__(self, self.hdr)
        self.setHDR0kw(hdr0)
        self.detector = self.setDetector()
        self.inst_kw = ins_spec_kw
        self.setInstrSpecKw()
        self.pscale = self.setPscale()
        self.orientat = self.setOrient()
        
        
       
    def setHDR0kw(self, primhdr):
        #sets attributes from kw defined in the primary header
        self.instrument = primhdr.get('INSTRUME', None)
        self.offtab = primhdr.get('OFFTAB', None) 
        self.idctab = primhdr.get('IDCTAB', None)
        self.date_obs = primhdr.get('DATE-OBS', None)
        self.pav3 = primhdr.get('PA_V3', None)
        self.ra_targ = primhdr.get('RA_TARG', None)
        self.dec_targ = primhdr.get('DEC_TARG', None)
    
    
    def setDetector(self):
        #sets detector attribute for instuments which have more than one detector
        if self.instrument in ['ACS', 'WFC3']:
            return self.hdr0.get('DETECTOR', None)
    
    
    def setInstrSpecKw(self):
        #Based on the instrument kw creates an instalnce of an instrument WCS class
        #and sets attributes from instrument specific kw 
        if self.instrument in inst_mappings.keys():
            inst_kl = inst_mappings[self.instrument]
            inst_kl = instruments.__dict__[inst_kl]
            insobj = inst_kl(self.hdr0, self.hdr)
            for key in self.inst_kw:
                self.__setattr__(key, insobj.__getattribute__(key))
        else:
            raise KeyError, "Unsupported instrument - %s" %self.instrument
    
    def setPscale(self):
        #Calculates the plate scale from the cd matrix
        #this may not be needed now and shoufl probably be done after all 
        # corrections
        cd11 = self.cd[0][0]
        cd21 = self.cd[1][0]
        return N.sqrt(N.power(cd11,2)+N.power(cd21,2)) * 3600.
    
    def setOrient(self):
        #same as setPscale
        cd12 = self.cd[0][1]
        cd22 = self.cd[1][1]
        return RADTODEG(N.arctan2(cd12,cd22))
    
    def verifyPa_V3(self):
        """make sure PA_V3 is populated"""    
        
    def verifyKw(self):
        """verify that all required kw have meaningful values"""
            
    def readModel(self):
        """
        Purpose
        =======
        Read distortion model from idc table.
        Save some of the information as kw needed later by pydrizzle
        
        list of kw - to be revised later
        """
        self.idcmodel = models.IDCModel(self.idctab,
                    chip=self.chip, direction='forward', date=self.date_obs,
                    filter1=self.filter1, filter2=self.filter2, 
                    offtab=self.offtab, binned=self.binned)
        
        
        self.updatehdr()
                   
    
    def updatehdr(self, newkeywords=None):
        #kw2add : OCX10, OCX11, OCY10, OCY11 
        # record the model in the header for use by pydrizzle
        self.hdr.update('OCX10', self.idcmodel.cx[1,0])
        self.hdr.update('OCX11', self.idcmodel.cx[1,1])
        self.hdr.update('OCY10', self.idcmodel.cy[1,0])
        self.hdr.update('OCY11', self.idcmodel.cy[1,1])
        self.hdr.update('IDCSCALE', self.idcmodel.refpix['PSCALE'])
        self.hdr.update('IDCTHETA', self.idcmodel.refpix['THETA'])
        self.hdr.update('IDCXREF', self.idcmodel.refpix['XREF'])
        self.hdr.update('IDCYREF', self.idcmodel.refpix['YREF'])
        self.hdr.update('IDCV2REF', self.idcmodel.refpix['V2REF'])
        self.hdr.update('IDCV3REF', self.idcmodel.refpix['V3REF'])
        self.hdr.update('IDCXSIZE', self.idcmodel.refpix['XSIZE'])
        self.hdr.update('IDCYSIZE', self.idcmodel.refpix['YSIZE'])
        self.hdr.update('IDCXDELT', self.idcmodel.refpix['XDELTA'])
        self.hdr.update('IDCYDELT', self.idcmodel.refpix['YDELTA'])
        self.hdr.update('CENTERED', self.idcmodel.refpix['centered'])
        
    
    def restore(self):
        """
        restores basic wcs keywords from archive
        this should be modified to always return a populated 
        dictionary, although the values may be None.
        """    

        backup = {}
        for k in basic_wcs:
            try:
                nkw = ('O'+k)[:7]
                #backup[k] = self.hdr.__getitem__('O'+k)
                backup[k] = self.hdr[nkw]
                #self.__setattr__(k, self.hdr.__getitem__('O'+k))
                self.__setattr__(k, self.hdr[nkw])
            except KeyError:
                print 'Keyword %s not found' % k
                
        return backup
    
    def archive_kw(self):
        """
        archive original WCS kw before recalculating them.
        """
        backup_kw = self.restore()
        if backup_kw != {}:
            return
        else:
            # keep the archived kw 8 characters long
            cmt = 'archived value'
            for kw in basic_wcs:
                nkw = 'O'+kw
                self.hdr.update(nkw[:7], self.hdr[kw], comment=cmt)