-
Notifications
You must be signed in to change notification settings - Fork 3
/
header.py
executable file
·181 lines (146 loc) · 6.21 KB
/
header.py
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
"""
"""
import astropy.io.fits as fits
import sys
import repipy.utilities as utils
import numpy as np
import os
class NotFoundKeyword(KeyError):
mssg = ("ERROR! None of the known keywords for {} is found in the header of image {}."
" Add your own keyword to the file keywords_aliases.json or include in the header a valid keyword: {}")
def __init__(self, keyword, image, valid):
self.keyword = keyword
self.im_name = image
self.valid = valid
def __str__(self):
return self.mssg.format(self.keyword, self.im_name, ", ".join(self.valid))
class Header(object):
""" Object with the information we can gather from the header of the image about observatory, telescope, instrument,
and the keywords for the most important parameters: airmass, object, exposure time, ...
"""
_KEYWORDS_ALIASES = dict(
FILTER = ('INSFLNAM', 'FILTER', 'JAGFBAND', 'ALFLTNM', 'WFFBAND', 'ESO INS FILT1 NAME'),
EXPTIME = ('EXPTIME',),
OBJECT = ('OBJECT',),
DATE = ('DATE-OBS',),
TIME = ('TIME-OBS',"UTSTART"),
GAIN = ('CCDSENS', 'GAIN','ESO DET OUT1 GAIN'),
RON = ('CCDRON', 'READNOIS', 'READNOISE', 'ESO DET OUT1 RON'),
AIRMASS = ('AIRMASS','ESO TEL AIRM END'),
FILTER_WAVELENGTH = ('INSFLWL',),
FILTER_WIDTH = ('INSFLDWL',),
FILTER_ID = ('ALFLTID', 'FAFTLID', 'JAGFID', 'INSFLID', 'WFFID', 'ESO INS FILT1 ID'),
FILTER_SYS = ('JAGFSYS', 'WFFPSYS'),
TELESCOPE = ('TELESCOP', 'INSTRUME', 'ORIGIN', 'INSTRID'),
SEEING = ('SEEING', 'FWHM', 'LEMON FWHM','ESO TEL AMBI FWHM END'),
SKY = ("SKY",),
SIGMA = ("SKY_STD", "SIGMA"),
RA = ("RA",),
DEC = ("DEC",)
)
_TELESCOPES_ALIASES = { 'NOT' : ['ALFOSC', 'NOT'],
'CAHA' : ['DSAZ', 'CAFOS', 'CA-2.2', 'CAHA'],
'OSN' : ['OSN', 'OSN 1.5m'],
'JKT' : ['JKT'],
'INT' : ['INT'],
'VST' : ['ESO-VST ', 'ESO-VST']
}
def __init__(self, header, im_name=None):
if im_name:
self.im_name = im_name
self.hdr = header
def get(self, *keywords):
""" Return the value of a keyword in the header.
:param keywords: keywords whose value we want to return
:return: value of the keyword given by user
"""
try:
result = []
for ii in keywords:
result.append(self.hdr[ii])
if len(result) == 1:
return result[0]
else:
return result
except:
return None
@property
def telescope(self):
return self._get_telescope()[1]
@property
def filterk(self):
""" Determine the keyword that keeps the name of the filter in the header."""
return self._get_filterk()
@property
def airmass(self):
return self.hdr[self.airmassk]
@utils.memoize
def _get_telescope(self):
""" Try to find the telescope name from which the image comes.
Since every observatory, telescope and/or instrument has different keywords, we need to go into some effort
to do this search. The information of the telescope could be hidden in any/all/none of the keywords under the
TELESCOPE key of the dictionary _KEYWORDS_ALIASES above. And the value could be any of a long list of aliases
such as putting the instrument instead of the telescope in the keyword 'TELESCOP' (sigh). Thus the selection
of aliases used.
"""
key, value = self.find_in_header(self._KEYWORDS_ALIASES['TELESCOPE'], self._TELESCOPES_ALIASES)
return key, value
@utils.memoize
def _get_filterID(self):
""" Try to find the ID of the filter used for the image.
I know, right? Crazy to uniquely identify a filter in the header of the image...
"""
value = self._get_value(self._KEYWORDS_ALIASES['FILTER_ID'])
return value
@utils.memoize
def _get_keyword(self, keywords):
""" Try keywords from the dictionary until you find one that exists. Return the keyword. """
return self._key_and_value(keywords)[0]
@utils.memoize
def _get_value(self, keywords):
""" Try keywords from the dictionary until you find one that exists. Return the value. """
return self._key_and_value(keywords)[1]
def find_in_header(self, list_keywords, dict_patterns):
""" Find the keyword in which elements from both lists coincide.
"""
k, p = None, None
dict_targets = {key: self.hdr.get(key) for key in list_keywords}
for pattern_key, pattern_value in dict_patterns.iteritems():
for target_key, target_value in dict_targets.iteritems():
if target_value in pattern_value:
k, p = target_key, pattern_key
return k, p
def _key_and_value(self, keywords):
""" Find if any of the unique keywords is in the header. Return its value
Look fot all the keywords in the header, if any is present and is not empty, return its value
"""
k, v = None, None
for key in keywords:
if self.hdr.get(key) is not None:
k,v = key, self.hdr.get(key)
break
return k, v
def _add_property(name, keyword):
""" Dynamically add a property to the 'header' class.
Add to the 'header' class the property 'name', whose getter function is
header._get_keyword(), called with header._KEYWORDS_ALIASES[keyword] as
its sole argument.
"""
def getter(self):
return self._get_keyword(self._KEYWORDS_ALIASES[keyword])
setattr(Header, name, property(getter))
_add_property('filterk', 'FILTER')
_add_property('filtersysk', 'FILTER_SYS')
_add_property('airmassk', 'AIRMASS')
_add_property('exptimek', 'EXPTIME')
_add_property('objectk', 'OBJECT')
_add_property('datek', 'DATE')
_add_property('timek', 'TIME')
_add_property('seeingk', 'SEEING')
_add_property('gaink', 'GAIN')
_add_property('skyk', 'SKY')
_add_property('sigmak', 'SIGMA')
_add_property('ccdronk', 'RON')
_add_property('RAk', 'RA')
_add_property('DECk', 'DEC')
_add_property('timek', 'TIME')