1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 from __future__ import division
16
17 import numpy as np
18 import convolve as NC
19
20 from pytools import numcombine
21 from pytools.numcombine import numCombine
22
23 __version__ = '0.2.0'
25 """ Create a median array, rejecting the highest pixel and computing the lowest valid pixel after mask application"""
26
27 """
28 # In this case we want to calculate two things:
29 # 1) the median array, rejecting the highest pixel (thus running
30 # imcombine with nlow=0, nhigh=1, nkeep=1, using the masks)
31 # 2) the lowest valid pixel after applying the masks (thus running
32 # imcombine with nlow=0, nhigh=3, nkeep=1, using the masks)
33 #
34 # We also calculate the sum of the weight files (to produce the total
35 # effective exposure time for each pixel).
36 #
37 # The total effective background in the final image is calculated as follows:
38 # - convert background for each input image to counts/s (divide by exptime)
39 # - multiply this value by the weight image, to obtain the effective background
40 # counts (in DN) for each pixel, for each image
41 # - Add these images together, to obtain the total effective background
42 # for the combined image.
43 #
44 # Once we've made these two files, then calculate the SNR based on the
45 # median-pixel image, and compare with the minimum.
46 """
47
48 """ In this version of the mimmed algorithm we assume that the units of all input data is electons."""
49 - def __init__(self,
50 imageList,
51 weightImageList,
52 readnoiseList,
53 exposureTimeList,
54 backgroundValueList,
55 weightMaskList= None,
56 combine_grow = 1,
57 combine_nsigma1 = 4,
58 combine_nsigma2 = 3
59
60 ):
61
62
63 self.__imageList = imageList
64 self.__weightImageList = weightImageList
65 self.__weightMaskList = weightMaskList
66 self.__exposureTimeList = exposureTimeList
67 self.__readnoiseList = readnoiseList
68 self.__backgroundValueList = backgroundValueList
69 self.__numberOfImages = len( self.__imageList)
70 self.__combine_grow = combine_grow
71 self.__combine_nsigma1 = combine_nsigma1
72 self.__combine_nsigma2 = combine_nsigma2
73
74
75
76 __median_file = np.zeros(self.__imageList[0].shape,dtype=self.__imageList[0].dtype)
77 if (self.__numberOfImages == 2):
78 __tmp = numCombine(self.__imageList,numarrayMaskList=self.__weightMaskList,
79 combinationType="mean",nlow=0,nhigh=0,
80 nkeep=1,upper=None,lower=None)
81 __median_file = __tmp.combArrObj
82 else:
83
84
85
86
87
88
89 __tmp = numCombine(self.__imageList,numarrayMaskList=self.__weightMaskList,
90 combinationType="median",nlow=0,nhigh=1,
91 nkeep=1,upper=None,lower=None)
92 __median_file = __tmp.combArrObj
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 tmpList = []
117 for image in xrange(len(self.__imageList)):
118 tmp =np.where(self.__weightMaskList[image] == 1, 0, self.__imageList[image])
119 tmpList.append(tmp)
120
121
122 maskSum = self.__sumImages(self.__weightMaskList)
123
124 sciSum = self.__sumImages(tmpList)
125 del(tmpList)
126
127
128
129 __median_file = np.where(maskSum == self.__numberOfImages-1,sciSum,__median_file)
130
131
132 __maskSum = self.__sumImages(self.__weightMaskList)
133
134
135
136 _maxValue = -1e+9
137 for image in self.__imageList:
138 _newMax = image.max()
139 if (_newMax > _maxValue):
140 _maxValue = _newMax
141
142
143 for image in xrange(len(self.__imageList)):
144 self.__imageList[image] = np.where(self.__weightMaskList[image] == 1,_maxValue+1,self.__imageList[image])
145
146
147 __tmp = numCombine(self.__imageList,numarrayMaskList=None,
148 combinationType="median",nlow=0,nhigh=self.__numberOfImages-1,
149 nkeep=1,upper=None,lower=None)
150 __minimum_file = __tmp.combArrObj
151
152 __minimum_file = np.where(__maskSum == self.__numberOfImages, 0, __minimum_file)
153
154
155 __backgroundFileList = []
156 for image in xrange(len(self.__weightImageList)):
157 __tmp = self.__weightImageList[image] * (self.__backgroundValueList[image]/(self.__exposureTimeList[image]))
158 __backgroundFileList.append(__tmp)
159
160
161
162
163 __bkgd_file = self.__sumImages(__backgroundFileList)
164 del(__backgroundFileList)
165
166
167
168
169 __readnoiseFileList = []
170 for image in xrange(len(self.__weightMaskList)):
171 __tmp = np.logical_not(self.__weightMaskList[image]) * (self.__readnoiseList[image] * self.__readnoiseList[image])
172 __readnoiseFileList.append(__tmp)
173
174
175
176
177 __readnoise_file = self.__sumImages(__readnoiseFileList)
178 del(__readnoiseFileList)
179
180
181
182
183 __weight_file = self.__sumImages(self.__weightImageList)
184
185
186
187
188
189 __minimum_file_weighted = __minimum_file * __weight_file
190 __median_file_weighted = __median_file * __weight_file
191 del(__weight_file)
192
193
194
195
196
197
198 __rms_file = np.sqrt(__median_file_weighted + __bkgd_file + __readnoise_file)
199
200 del __bkgd_file, __readnoise_file
201
202
203
204 __median_rms_file = __median_file_weighted - (__rms_file * self.__combine_nsigma1)
205
206 if self.__combine_grow != 0:
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 __minimum_flag_file = np.where(np.less(__minimum_file_weighted,__median_rms_file),1,0)
226
227
228
229 __boxsize = int(2 * self.__combine_grow + 1)
230 __boxshape = (__boxsize,__boxsize)
231 __minimum_grow_file = np.zeros(self.__imageList[0].shape,dtype=self.__imageList[0].dtype)
232
233
234
235
236
237
238
239
240
241
242
243 if (__boxsize <= 0):
244 errormsg1 = "############################################################\n"
245 errormsg1 += "# The boxcar convolution in minmed has failed. The 'grow' #\n"
246 errormsg1 += "# parameter must be greater than or equal to zero. You #\n"
247 errormsg1 += "# specified an input value for the 'grow' parameter of: #\n"
248 errormsg1 += " combine_grow: " + str(self.__combine_grow)+'\n'
249 errormsg1 += "############################################################\n"
250 raise ValueError,errormsg1
251 if (__boxsize > self.__imageList[0].shape[0]):
252 errormsg2 = "############################################################\n"
253 errormsg2 += "# The boxcar convolution in minmed has failed. The 'grow' #\n"
254 errormsg2 += "# parameter specified has resulted in a boxcar kernel that #\n"
255 errormsg2 += "# has dimensions larger than the actual image. You #\n"
256 errormsg2 += "# specified an input value for the 'grow' parameter of: #\n"
257 errormsg2 += " combine_grow: " +str(self.__combine_grow)+'\n'
258 errormsg2 += "############################################################\n"
259 print self.__imageList[0].shape
260 raise ValueError,errormsg2
261
262
263 NC.boxcar(__minimum_flag_file,__boxshape,output=__minimum_grow_file,mode='constant',cval=0)
264
265 del(__minimum_flag_file)
266
267 __temp1 = (__median_file_weighted - (__rms_file * self.__combine_nsigma1))
268 __temp2 = (__median_file_weighted - (__rms_file * self.__combine_nsigma2))
269 __median_rms2_file = np.where(np.equal(__minimum_grow_file,0),__temp1,__temp2)
270 del(__temp1)
271 del(__temp2)
272 del(__rms_file)
273 del(__minimum_grow_file)
274
275
276
277
278 self.combArrObj = __tmp
279 self.combArrObj = np.where(np.less(__minimum_file_weighted,__median_rms2_file),
280 __minimum_file,
281 __median_file)
282
283 else:
284
285
286
287 self.combArrObj = __tmp
288 self.combArrObj = np.where(np.less(__minimum_file_weighted,__median_rms_file),
289 __minimum_file,
290 __median_file)
291
292
293 self.combArrObj = np.where(__maskSum == self.__numberOfImages, 0, self.combArrObj)
294
295
296
297
298
299
301 """ Sum a list of numarray objects. """
302 __sum = np.zeros(numarrayObjectList[0].shape,dtype=numarrayObjectList[0].dtype)
303 for image in numarrayObjectList:
304 __sum += image
305 return __sum
306