drizzle 1.15.2__cp312-cp312-win_amd64.whl → 2.0.0__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of drizzle might be problematic. Click here for more details.
- drizzle/__init__.py +2 -1
- drizzle/cdrizzle.cp312-win_amd64.pyd +0 -0
- drizzle/resample.py +702 -0
- drizzle/tests/test_cdrizzle.py +14 -9
- drizzle/tests/test_overlap_calc.py +2 -2
- drizzle/tests/test_resample.py +1437 -0
- drizzle/tests/test_utils.py +193 -0
- drizzle/util.py +17 -239
- drizzle/utils.py +239 -0
- {drizzle-1.15.2.dist-info → drizzle-2.0.0.dist-info}/METADATA +13 -175
- drizzle-2.0.0.dist-info/RECORD +15 -0
- {drizzle-1.15.2.dist-info → drizzle-2.0.0.dist-info}/WHEEL +1 -1
- drizzle/calc_pixmap.py +0 -52
- drizzle/doblot.py +0 -80
- drizzle/dodrizzle.py +0 -189
- drizzle/drizzle.py +0 -569
- drizzle/tests/test_drizzle.py +0 -798
- drizzle/tests/test_file_io.py +0 -173
- drizzle/tests/test_pixmap.py +0 -76
- drizzle-1.15.2.dist-info/RECORD +0 -18
- {drizzle-1.15.2.dist-info → drizzle-2.0.0.dist-info}/LICENSE.rst +0 -0
- {drizzle-1.15.2.dist-info → drizzle-2.0.0.dist-info}/top_level.txt +0 -0
drizzle/drizzle.py
DELETED
|
@@ -1,569 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
The `drizzle` module defines the `Drizzle` class, for combining input
|
|
3
|
-
images into a single output image using the drizzle algorithm.
|
|
4
|
-
"""
|
|
5
|
-
import os
|
|
6
|
-
import os.path
|
|
7
|
-
|
|
8
|
-
import numpy as np
|
|
9
|
-
from astropy import wcs
|
|
10
|
-
from astropy.io import fits
|
|
11
|
-
|
|
12
|
-
from . import util
|
|
13
|
-
from . import doblot
|
|
14
|
-
from . import dodrizzle
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Drizzle(object):
|
|
18
|
-
"""
|
|
19
|
-
Combine images using the drizzle algorithm
|
|
20
|
-
"""
|
|
21
|
-
def __init__(self, infile="", outwcs=None,
|
|
22
|
-
wt_scl="exptime", pixfrac=1.0, kernel="square",
|
|
23
|
-
fillval="INDEF"):
|
|
24
|
-
"""
|
|
25
|
-
Create a new Drizzle output object and set the drizzle parameters.
|
|
26
|
-
|
|
27
|
-
All parameters are optional, but either infile or outwcs must be supplied.
|
|
28
|
-
If infile initializes the object from a file written after a
|
|
29
|
-
previous run of drizzle. Results from the previous run will be combined
|
|
30
|
-
with new results. The value passed in outwcs will be ignored. If infile is
|
|
31
|
-
not set, outwcs will be used to initilize a new run of drizzle.
|
|
32
|
-
|
|
33
|
-
Parameters
|
|
34
|
-
----------
|
|
35
|
-
|
|
36
|
-
infile : str, optional
|
|
37
|
-
A fits file containing results from a previous run. The three
|
|
38
|
-
extensions SCI, WHT, and CTX contain the combined image, total counts
|
|
39
|
-
and image id bitmap, repectively. The WCS of the combined image is
|
|
40
|
-
also read from the SCI extension.
|
|
41
|
-
|
|
42
|
-
outwcs : wcs, optional
|
|
43
|
-
The world coordinate system (WCS) of the combined image. This
|
|
44
|
-
parameter must be present if no input file is given and is ignored if
|
|
45
|
-
one is.
|
|
46
|
-
|
|
47
|
-
wt_scl : str, optional
|
|
48
|
-
How each input image should be scaled. The choices are `exptime`
|
|
49
|
-
which scales each image by its exposure time, `expsq` which scales
|
|
50
|
-
each image by the exposure time squared, or an empty string, which
|
|
51
|
-
allows each input image to be scaled individually.
|
|
52
|
-
|
|
53
|
-
pixfrac : float, optional
|
|
54
|
-
The fraction of a pixel that the pixel flux is confined to. The
|
|
55
|
-
default value of 1 has the pixel flux evenly spread across the image.
|
|
56
|
-
A value of 0.5 confines it to half a pixel in the linear dimension,
|
|
57
|
-
so the flux is confined to a quarter of the pixel area when the square
|
|
58
|
-
kernel is used.
|
|
59
|
-
|
|
60
|
-
kernel : str, optional
|
|
61
|
-
The name of the kernel used to combine the inputs. The choice of
|
|
62
|
-
kernel controls the distribution of flux over the kernel. The kernel
|
|
63
|
-
names are: "square", "turbo", "point", "gaussian", "lanczos2",
|
|
64
|
-
and "lanczos3".
|
|
65
|
-
|
|
66
|
-
.. warning::
|
|
67
|
-
The "gaussian" and "lanczos2/3" kernels **DO NOT** conserve flux.
|
|
68
|
-
|
|
69
|
-
fillval : str, otional
|
|
70
|
-
The value a pixel is set to in the output if the input image does
|
|
71
|
-
not overlap it. The default value of INDEF does not set a value.
|
|
72
|
-
"""
|
|
73
|
-
|
|
74
|
-
# Initialize the object fields
|
|
75
|
-
|
|
76
|
-
self.outsci = None
|
|
77
|
-
self.outwht = None
|
|
78
|
-
self.outcon = None
|
|
79
|
-
|
|
80
|
-
self.outexptime = 0.0
|
|
81
|
-
self.uniqid = 0
|
|
82
|
-
|
|
83
|
-
self.outwcs = outwcs
|
|
84
|
-
self.wt_scl = wt_scl
|
|
85
|
-
self.kernel = kernel
|
|
86
|
-
self.fillval = fillval
|
|
87
|
-
self.pixfrac = float(pixfrac)
|
|
88
|
-
|
|
89
|
-
self.sciext = "SCI"
|
|
90
|
-
self.whtext = "WHT"
|
|
91
|
-
self.ctxext = "CTX"
|
|
92
|
-
|
|
93
|
-
out_units = "cps"
|
|
94
|
-
|
|
95
|
-
if not util.is_blank(infile):
|
|
96
|
-
if os.path.exists(infile):
|
|
97
|
-
handle = fits.open(infile)
|
|
98
|
-
|
|
99
|
-
# Read parameters from image header
|
|
100
|
-
self.outexptime = util.get_keyword(handle, "DRIZEXPT", default=0.0)
|
|
101
|
-
self.uniqid = util.get_keyword(handle, "NDRIZIM", default=0)
|
|
102
|
-
|
|
103
|
-
self.sciext = util.get_keyword(handle, "DRIZOUDA", default="SCI")
|
|
104
|
-
self.whtext = util.get_keyword(handle, "DRIZOUWE", default="WHT")
|
|
105
|
-
self.ctxext = util.get_keyword(handle, "DRIZOUCO", default="CTX")
|
|
106
|
-
|
|
107
|
-
self.wt_scl = util.get_keyword(handle, "DRIZWTSC", default=wt_scl)
|
|
108
|
-
self.kernel = util.get_keyword(handle, "DRIZKERN", default=kernel)
|
|
109
|
-
self.fillval = util.get_keyword(handle, "DRIZFVAL", default=fillval)
|
|
110
|
-
self.pixfrac = float(util.get_keyword(handle,
|
|
111
|
-
"DRIZPIXF", default=pixfrac))
|
|
112
|
-
|
|
113
|
-
out_units = util.get_keyword(handle, "DRIZOUUN", default="cps")
|
|
114
|
-
|
|
115
|
-
try:
|
|
116
|
-
hdu = handle[self.sciext]
|
|
117
|
-
self.outsci = hdu.data.copy().astype(np.float32)
|
|
118
|
-
self.outwcs = wcs.WCS(hdu.header, fobj=handle)
|
|
119
|
-
except KeyError:
|
|
120
|
-
pass
|
|
121
|
-
|
|
122
|
-
try:
|
|
123
|
-
hdu = handle[self.whtext]
|
|
124
|
-
self.outwht = hdu.data.copy().astype(np.float32)
|
|
125
|
-
except KeyError:
|
|
126
|
-
pass
|
|
127
|
-
|
|
128
|
-
try:
|
|
129
|
-
hdu = handle[self.ctxext]
|
|
130
|
-
self.outcon = hdu.data.copy().astype(np.int32)
|
|
131
|
-
if self.outcon.ndim == 2:
|
|
132
|
-
self.outcon = np.reshape(self.outcon, (1,
|
|
133
|
-
self.outcon.shape[0],
|
|
134
|
-
self.outcon.shape[1]))
|
|
135
|
-
|
|
136
|
-
elif self.outcon.ndim == 3:
|
|
137
|
-
pass
|
|
138
|
-
|
|
139
|
-
else:
|
|
140
|
-
msg = ("Drizzle context image has wrong dimensions: " +
|
|
141
|
-
infile)
|
|
142
|
-
raise ValueError(msg)
|
|
143
|
-
|
|
144
|
-
except KeyError:
|
|
145
|
-
pass
|
|
146
|
-
|
|
147
|
-
handle.close()
|
|
148
|
-
|
|
149
|
-
# Check field values
|
|
150
|
-
|
|
151
|
-
if self.outwcs:
|
|
152
|
-
util.set_pscale(self.outwcs)
|
|
153
|
-
else:
|
|
154
|
-
raise ValueError("Either an existing file or wcs must be supplied to Drizzle")
|
|
155
|
-
|
|
156
|
-
if util.is_blank(self.wt_scl):
|
|
157
|
-
self.wt_scl = ''
|
|
158
|
-
elif self.wt_scl != "exptime" and self.wt_scl != "expsq":
|
|
159
|
-
raise ValueError("Illegal value for wt_scl: %s" % out_units)
|
|
160
|
-
|
|
161
|
-
if out_units == "counts":
|
|
162
|
-
np.divide(self.outsci, self.outexptime, self.outsci)
|
|
163
|
-
elif out_units != "cps":
|
|
164
|
-
raise ValueError("Illegal value for wt_scl: %s" % out_units)
|
|
165
|
-
|
|
166
|
-
# Initialize images if not read from a file
|
|
167
|
-
outwcs_naxis1, outwcs_naxis2 = self.outwcs.pixel_shape
|
|
168
|
-
if self.outsci is None:
|
|
169
|
-
self.outsci = np.zeros(self.outwcs.pixel_shape[::-1],
|
|
170
|
-
dtype=np.float32)
|
|
171
|
-
|
|
172
|
-
if self.outwht is None:
|
|
173
|
-
self.outwht = np.zeros(self.outwcs.pixel_shape[::-1],
|
|
174
|
-
dtype=np.float32)
|
|
175
|
-
if self.outcon is None:
|
|
176
|
-
self.outcon = np.zeros((1, outwcs_naxis2, outwcs_naxis1),
|
|
177
|
-
dtype=np.int32)
|
|
178
|
-
|
|
179
|
-
def add_fits_file(self, infile, inweight="",
|
|
180
|
-
xmin=0, xmax=0, ymin=0, ymax=0,
|
|
181
|
-
unitkey="", expkey="", wt_scl=1.0):
|
|
182
|
-
"""
|
|
183
|
-
Combine a fits file with the output drizzled image.
|
|
184
|
-
|
|
185
|
-
Parameters
|
|
186
|
-
----------
|
|
187
|
-
|
|
188
|
-
infile : str
|
|
189
|
-
The name of the fits file, possibly including an extension.
|
|
190
|
-
|
|
191
|
-
inweight : str, otional
|
|
192
|
-
The name of a file containing a pixel by pixel weighting
|
|
193
|
-
of the input data. If it is not set, an array will be generated
|
|
194
|
-
where all values are set to one.
|
|
195
|
-
|
|
196
|
-
xmin : float, otional
|
|
197
|
-
This and the following three parameters set a bounding rectangle
|
|
198
|
-
on the output image. Only pixels on the output image inside this
|
|
199
|
-
rectangle will have their flux updated. Xmin sets the minimum value
|
|
200
|
-
of the x dimension. The x dimension is the dimension that varies
|
|
201
|
-
quickest on the image. If the value is zero or less, no minimum will
|
|
202
|
-
be set in the x dimension. All four parameters are zero based,
|
|
203
|
-
counting starts at zero.
|
|
204
|
-
|
|
205
|
-
xmax : float, otional
|
|
206
|
-
Sets the maximum value of the x dimension on the bounding box
|
|
207
|
-
of the ouput image. If the value is zero or less, no maximum will
|
|
208
|
-
be set in the x dimension.
|
|
209
|
-
|
|
210
|
-
ymin : float, optional
|
|
211
|
-
Sets the minimum value in the y dimension on the bounding box. The
|
|
212
|
-
y dimension varies less rapidly than the x and represents the line
|
|
213
|
-
index on the output image. If the value is zero or less, no minimum
|
|
214
|
-
will be set in the y dimension.
|
|
215
|
-
|
|
216
|
-
ymax : float, optional
|
|
217
|
-
Sets the maximum value in the y dimension. If the value is zero or
|
|
218
|
-
less, no maximum will be set in the y dimension.
|
|
219
|
-
|
|
220
|
-
unitkey : string, optional
|
|
221
|
-
The name of the header keyword containing the image units. The
|
|
222
|
-
units can either be "counts" or "cps" (counts per second.) If it is
|
|
223
|
-
left blank, the value is assumed to be "cps." If the value is counts,
|
|
224
|
-
before using the input image it is scaled by dividing it by the
|
|
225
|
-
exposure time.
|
|
226
|
-
|
|
227
|
-
expkey : string, optional
|
|
228
|
-
The name of the header keyword containing the exposure time. The
|
|
229
|
-
exposure time is used to scale the image if the units are counts and
|
|
230
|
-
to scale the image weighting if the drizzle was initialized with
|
|
231
|
-
wt_scl equal to "exptime" or "expsq." If the value of this parameter
|
|
232
|
-
is blank, the exposure time is set to one, implying no scaling.
|
|
233
|
-
|
|
234
|
-
wt_scl : float, optional
|
|
235
|
-
If drizzle was initialized with wt_scl left blank, this value will
|
|
236
|
-
set a scaling factor for the pixel weighting. If drizzle was
|
|
237
|
-
initialized with wt_scl set to "exptime" or "expsq", the exposure time
|
|
238
|
-
will be used to set the weight scaling and the value of this parameter
|
|
239
|
-
will be ignored.
|
|
240
|
-
"""
|
|
241
|
-
|
|
242
|
-
insci = None
|
|
243
|
-
inwht = None
|
|
244
|
-
|
|
245
|
-
if not util.is_blank(infile):
|
|
246
|
-
fileroot, extn = util.parse_filename(infile)
|
|
247
|
-
|
|
248
|
-
if os.path.exists(fileroot):
|
|
249
|
-
handle = fits.open(fileroot)
|
|
250
|
-
hdu = util.get_extn(handle, extn=extn)
|
|
251
|
-
|
|
252
|
-
if hdu is not None:
|
|
253
|
-
insci = hdu.data
|
|
254
|
-
inwcs = wcs.WCS(header=hdu.header)
|
|
255
|
-
insci = hdu.data.copy()
|
|
256
|
-
handle.close()
|
|
257
|
-
|
|
258
|
-
if insci is None:
|
|
259
|
-
raise ValueError("Drizzle cannot find input file: %s" % infile)
|
|
260
|
-
|
|
261
|
-
if not util.is_blank(inweight):
|
|
262
|
-
fileroot, extn = util.parse_filename(inweight)
|
|
263
|
-
|
|
264
|
-
if os.path.exists(fileroot):
|
|
265
|
-
handle = fits.open(fileroot)
|
|
266
|
-
hdu = util.get_extn(handle, extn=extn)
|
|
267
|
-
|
|
268
|
-
if hdu is not None:
|
|
269
|
-
inwht = hdu.data.copy()
|
|
270
|
-
handle.close()
|
|
271
|
-
|
|
272
|
-
in_units = util.get_keyword(fileroot, unitkey, "cps")
|
|
273
|
-
expin = util.get_keyword(fileroot, expkey, 1.0)
|
|
274
|
-
|
|
275
|
-
self.add_image(insci, inwcs, inwht=inwht,
|
|
276
|
-
xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
|
|
277
|
-
expin=expin, in_units=in_units, wt_scl=wt_scl)
|
|
278
|
-
|
|
279
|
-
def add_image(self, insci, inwcs, inwht=None,
|
|
280
|
-
xmin=0, xmax=0, ymin=0, ymax=0,
|
|
281
|
-
expin=1.0, in_units="cps", wt_scl=1.0):
|
|
282
|
-
"""
|
|
283
|
-
Combine an input image with the output drizzled image.
|
|
284
|
-
|
|
285
|
-
Instead of reading the parameters from a fits file, you can set
|
|
286
|
-
them by calling this lower level method. `Add_fits_file` calls
|
|
287
|
-
this method after doing its setup.
|
|
288
|
-
|
|
289
|
-
Parameters
|
|
290
|
-
----------
|
|
291
|
-
|
|
292
|
-
insci : array
|
|
293
|
-
A 2d numpy array containing the input image to be drizzled.
|
|
294
|
-
it is an error to not supply an image.
|
|
295
|
-
|
|
296
|
-
inwcs : wcs
|
|
297
|
-
The world coordinate system of the input image. This is
|
|
298
|
-
used to convert the pixels to the output coordinate system.
|
|
299
|
-
|
|
300
|
-
inwht : array, optional
|
|
301
|
-
A 2d numpy array containing the pixel by pixel weighting.
|
|
302
|
-
Must have the same dimenstions as insci. If none is supplied,
|
|
303
|
-
the weghting is set to one.
|
|
304
|
-
|
|
305
|
-
xmin : float, optional
|
|
306
|
-
This and the following three parameters set a bounding rectangle
|
|
307
|
-
on the output image. Only pixels on the output image inside this
|
|
308
|
-
rectangle will have their flux updated. Xmin sets the minimum value
|
|
309
|
-
of the x dimension. The x dimension is the dimension that varies
|
|
310
|
-
quickest on the image. If the value is zero or less, no minimum will
|
|
311
|
-
be set in the x dimension. All four parameters are zero based,
|
|
312
|
-
counting starts at zero.
|
|
313
|
-
|
|
314
|
-
xmax : float, optional
|
|
315
|
-
Sets the maximum value of the x dimension on the bounding box
|
|
316
|
-
of the ouput image. If the value is zero or less, no maximum will
|
|
317
|
-
be set in the x dimension.
|
|
318
|
-
|
|
319
|
-
ymin : float, optional
|
|
320
|
-
Sets the minimum value in the y dimension on the bounding box. The
|
|
321
|
-
y dimension varies less rapidly than the x and represents the line
|
|
322
|
-
index on the output image. If the value is zero or less, no minimum
|
|
323
|
-
will be set in the y dimension.
|
|
324
|
-
|
|
325
|
-
ymax : float, optional
|
|
326
|
-
Sets the maximum value in the y dimension. If the value is zero or
|
|
327
|
-
less, no maximum will be set in the y dimension.
|
|
328
|
-
|
|
329
|
-
expin : float, optional
|
|
330
|
-
The exposure time of the input image, a positive number. The
|
|
331
|
-
exposure time is used to scale the image if the units are counts and
|
|
332
|
-
to scale the image weighting if the drizzle was initialized with
|
|
333
|
-
wt_scl equal to "exptime" or "expsq."
|
|
334
|
-
|
|
335
|
-
in_units : str, optional
|
|
336
|
-
The units of the input image. The units can either be "counts"
|
|
337
|
-
or "cps" (counts per second.) If the value is counts, before using
|
|
338
|
-
the input image it is scaled by dividing it by the exposure time.
|
|
339
|
-
|
|
340
|
-
wt_scl : float, optional
|
|
341
|
-
If drizzle was initialized with wt_scl left blank, this value will
|
|
342
|
-
set a scaling factor for the pixel weighting. If drizzle was
|
|
343
|
-
initialized with wt_scl set to "exptime" or "expsq", the exposure time
|
|
344
|
-
will be used to set the weight scaling and the value of this parameter
|
|
345
|
-
will be ignored.
|
|
346
|
-
"""
|
|
347
|
-
|
|
348
|
-
insci = insci.astype(np.float32)
|
|
349
|
-
util.set_pscale(inwcs)
|
|
350
|
-
|
|
351
|
-
if inwht is None:
|
|
352
|
-
inwht = np.ones(insci.shape, dtype=insci.dtype)
|
|
353
|
-
else:
|
|
354
|
-
inwht = inwht.astype(np.float32)
|
|
355
|
-
|
|
356
|
-
if self.wt_scl == "exptime":
|
|
357
|
-
wt_scl = expin
|
|
358
|
-
elif self.wt_scl == "expsq":
|
|
359
|
-
wt_scl = expin * expin
|
|
360
|
-
|
|
361
|
-
self.increment_id()
|
|
362
|
-
self.outexptime += expin
|
|
363
|
-
|
|
364
|
-
dodrizzle.dodrizzle(insci, inwcs, inwht, self.outwcs,
|
|
365
|
-
self.outsci, self.outwht, self.outcon,
|
|
366
|
-
expin, in_units, wt_scl,
|
|
367
|
-
wcslin_pscale=inwcs.pscale, uniqid=self.uniqid,
|
|
368
|
-
xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax,
|
|
369
|
-
pixfrac=self.pixfrac, kernel=self.kernel,
|
|
370
|
-
fillval=self.fillval)
|
|
371
|
-
|
|
372
|
-
def blot_fits_file(self, infile, interp='poly5', sinscl=1.0):
|
|
373
|
-
"""
|
|
374
|
-
Resample the output using another image's world coordinate system.
|
|
375
|
-
|
|
376
|
-
Parameters
|
|
377
|
-
----------
|
|
378
|
-
|
|
379
|
-
infile : str
|
|
380
|
-
The name of the fits file containing the world coordinate
|
|
381
|
-
system that the output file will be resampled to. The name may
|
|
382
|
-
possibly include an extension.
|
|
383
|
-
|
|
384
|
-
interp : str, optional
|
|
385
|
-
The type of interpolation used in the resampling. The
|
|
386
|
-
possible values are "nearest" (nearest neighbor interpolation),
|
|
387
|
-
"linear" (bilinear interpolation), "poly3" (cubic polynomial
|
|
388
|
-
interpolation), "poly5" (quintic polynomial interpolation),
|
|
389
|
-
"sinc" (sinc interpolation), "lan3" (3rd order Lanczos
|
|
390
|
-
interpolation), and "lan5" (5th order Lanczos interpolation).
|
|
391
|
-
|
|
392
|
-
sincscl : float, optional
|
|
393
|
-
The scaling factor for sinc interpolation.
|
|
394
|
-
"""
|
|
395
|
-
blotwcs = None
|
|
396
|
-
|
|
397
|
-
fileroot, extn = util.parse_filename(infile)
|
|
398
|
-
|
|
399
|
-
if os.path.exists(fileroot):
|
|
400
|
-
handle = fits.open(fileroot)
|
|
401
|
-
hdu = util.get_extn(handle, extn=extn)
|
|
402
|
-
|
|
403
|
-
if hdu is not None:
|
|
404
|
-
blotwcs = wcs.WCS(header=hdu.header)
|
|
405
|
-
handle.close()
|
|
406
|
-
|
|
407
|
-
if not blotwcs:
|
|
408
|
-
raise ValueError("Drizzle did not get a blot reference image")
|
|
409
|
-
|
|
410
|
-
self.blot_image(blotwcs, interp=interp, sinscl=sinscl)
|
|
411
|
-
|
|
412
|
-
def blot_image(self, blotwcs, interp='poly5', sinscl=1.0):
|
|
413
|
-
"""
|
|
414
|
-
Resample the output image using an input world coordinate system.
|
|
415
|
-
|
|
416
|
-
Parameters
|
|
417
|
-
----------
|
|
418
|
-
|
|
419
|
-
blotwcs : wcs
|
|
420
|
-
The world coordinate system to resample on.
|
|
421
|
-
|
|
422
|
-
interp : str, optional
|
|
423
|
-
The type of interpolation used in the resampling. The
|
|
424
|
-
possible values are "nearest" (nearest neighbor interpolation),
|
|
425
|
-
"linear" (bilinear interpolation), "poly3" (cubic polynomial
|
|
426
|
-
interpolation), "poly5" (quintic polynomial interpolation),
|
|
427
|
-
"sinc" (sinc interpolation), "lan3" (3rd order Lanczos
|
|
428
|
-
interpolation), and "lan5" (5th order Lanczos interpolation).
|
|
429
|
-
|
|
430
|
-
sincscl : float, optional
|
|
431
|
-
The scaling factor for sinc interpolation.
|
|
432
|
-
"""
|
|
433
|
-
|
|
434
|
-
util.set_pscale(blotwcs)
|
|
435
|
-
self.outsci = doblot.doblot(self.outsci, self.outwcs, blotwcs,
|
|
436
|
-
1.0, interp=interp, sinscl=sinscl)
|
|
437
|
-
|
|
438
|
-
self.outwcs = blotwcs
|
|
439
|
-
|
|
440
|
-
def increment_id(self):
|
|
441
|
-
"""
|
|
442
|
-
Increment the id count and add a plane to the context image if needed
|
|
443
|
-
|
|
444
|
-
Drizzle tracks which input images contribute to the output image
|
|
445
|
-
by setting a bit in the corresponding pixel in the context image.
|
|
446
|
-
The uniqid indicates which bit. So it must be incremented each time
|
|
447
|
-
a new image is added. Each plane in the context image can hold 32 bits,
|
|
448
|
-
so after each 32 images, a new plane is added to the context.
|
|
449
|
-
"""
|
|
450
|
-
|
|
451
|
-
# Compute what plane of the context image this input would
|
|
452
|
-
# correspond to:
|
|
453
|
-
planeid = int(self.uniqid / 32)
|
|
454
|
-
|
|
455
|
-
# Add a new plane to the context image if planeid overflows
|
|
456
|
-
|
|
457
|
-
if self.outcon.shape[0] == planeid:
|
|
458
|
-
plane = np.zeros_like(self.outcon[0])
|
|
459
|
-
self.outcon = np.append(self.outcon, [plane], axis=0)
|
|
460
|
-
|
|
461
|
-
# Increment the id
|
|
462
|
-
self.uniqid += 1
|
|
463
|
-
|
|
464
|
-
def write(self, outfile, out_units="cps", outheader=None):
|
|
465
|
-
"""
|
|
466
|
-
Write the output from a set of drizzled images to a file.
|
|
467
|
-
|
|
468
|
-
The output file will contain three extensions. The "SCI" extension
|
|
469
|
-
contains the resulting image. The "WHT" extension contains the
|
|
470
|
-
combined weights. The "CTX" extension is a bit map. The nth bit
|
|
471
|
-
is set to one if the nth input image contributed non-zero flux
|
|
472
|
-
to the output image. The "CTX" image is three dimensionsional
|
|
473
|
-
to account for the possibility that there are more than 32 input
|
|
474
|
-
images.
|
|
475
|
-
|
|
476
|
-
Parameters
|
|
477
|
-
----------
|
|
478
|
-
|
|
479
|
-
outfile : str
|
|
480
|
-
The name of the output file. If the file already exists,
|
|
481
|
-
the old file is deleted after writing the new file.
|
|
482
|
-
|
|
483
|
-
out_units : str, optional
|
|
484
|
-
The units of the output image, either `counts` or `cps`
|
|
485
|
-
(counts per second.) If the units are counts, the resulting
|
|
486
|
-
image will be multiplied by the computed exposure time.
|
|
487
|
-
|
|
488
|
-
outheader : header, optional
|
|
489
|
-
A fits header containing cards to be added to the primary
|
|
490
|
-
header of the output image.
|
|
491
|
-
"""
|
|
492
|
-
|
|
493
|
-
if out_units != "counts" and out_units != "cps":
|
|
494
|
-
raise ValueError("Illegal value for out_units: %s" % str(out_units))
|
|
495
|
-
|
|
496
|
-
# Write the WCS to the output image
|
|
497
|
-
|
|
498
|
-
handle = self.outwcs.to_fits()
|
|
499
|
-
phdu = handle[0]
|
|
500
|
-
|
|
501
|
-
# Write the class fields to the primary header
|
|
502
|
-
phdu.header['DRIZOUDA'] = \
|
|
503
|
-
(self.sciext, 'Drizzle, output data image')
|
|
504
|
-
phdu.header['DRIZOUWE'] = \
|
|
505
|
-
(self.whtext, 'Drizzle, output weighting image')
|
|
506
|
-
phdu.header['DRIZOUCO'] = \
|
|
507
|
-
(self.ctxext, 'Drizzle, output context image')
|
|
508
|
-
phdu.header['DRIZWTSC'] = \
|
|
509
|
-
(self.wt_scl, 'Drizzle, weighting factor for input image')
|
|
510
|
-
phdu.header['DRIZKERN'] = \
|
|
511
|
-
(self.kernel, 'Drizzle, form of weight distribution kernel')
|
|
512
|
-
phdu.header['DRIZPIXF'] = \
|
|
513
|
-
(self.pixfrac, 'Drizzle, linear size of drop')
|
|
514
|
-
phdu.header['DRIZFVAL'] = \
|
|
515
|
-
(self.fillval, 'Drizzle, fill value for zero weight output pix')
|
|
516
|
-
phdu.header['DRIZOUUN'] = \
|
|
517
|
-
(out_units, 'Drizzle, units of output image - counts or cps')
|
|
518
|
-
|
|
519
|
-
# Update header keyword NDRIZIM to keep track of how many images have
|
|
520
|
-
# been combined in this product so far
|
|
521
|
-
phdu.header['NDRIZIM'] = (self.uniqid, 'Drizzle, number of images')
|
|
522
|
-
|
|
523
|
-
# Update header of output image with exptime used to scale the output data
|
|
524
|
-
# if out_units is not counts, this will simply be a value of 1.0
|
|
525
|
-
# the keyword 'exptime' will always contain the total exposure time
|
|
526
|
-
# of all input image regardless of the output units
|
|
527
|
-
|
|
528
|
-
phdu.header['EXPTIME'] = \
|
|
529
|
-
(self.outexptime, 'Drizzle, total exposure time')
|
|
530
|
-
|
|
531
|
-
outexptime = 1.0
|
|
532
|
-
if out_units == 'counts':
|
|
533
|
-
np.multiply(self.outsci, self.outexptime, self.outsci)
|
|
534
|
-
outexptime = self.outexptime
|
|
535
|
-
phdu.header['DRIZEXPT'] = (outexptime, 'Drizzle, exposure time scaling factor')
|
|
536
|
-
|
|
537
|
-
# Copy the optional header to the primary header
|
|
538
|
-
|
|
539
|
-
if outheader:
|
|
540
|
-
phdu.header.extend(outheader, unique=True)
|
|
541
|
-
|
|
542
|
-
# Add three extensions containing, the drizzled output image,
|
|
543
|
-
# the total counts, and the context bitmap, in that order
|
|
544
|
-
|
|
545
|
-
extheader = self.outwcs.to_header()
|
|
546
|
-
|
|
547
|
-
ehdu = fits.ImageHDU()
|
|
548
|
-
ehdu.data = self.outsci
|
|
549
|
-
ehdu.header['EXTNAME'] = (self.sciext, 'Extension name')
|
|
550
|
-
ehdu.header['EXTVER'] = (1, 'Extension version')
|
|
551
|
-
ehdu.header.extend(extheader, unique=True)
|
|
552
|
-
handle.append(ehdu)
|
|
553
|
-
|
|
554
|
-
whdu = fits.ImageHDU()
|
|
555
|
-
whdu.data = self.outwht
|
|
556
|
-
whdu.header['EXTNAME'] = (self.whtext, 'Extension name')
|
|
557
|
-
whdu.header['EXTVER'] = (1, 'Extension version')
|
|
558
|
-
whdu.header.extend(extheader, unique=True)
|
|
559
|
-
handle.append(whdu)
|
|
560
|
-
|
|
561
|
-
xhdu = fits.ImageHDU()
|
|
562
|
-
xhdu.data = self.outcon
|
|
563
|
-
xhdu.header['EXTNAME'] = (self.ctxext, 'Extension name')
|
|
564
|
-
xhdu.header['EXTVER'] = (1, 'Extension version')
|
|
565
|
-
xhdu.header.extend(extheader, unique=True)
|
|
566
|
-
handle.append(xhdu)
|
|
567
|
-
|
|
568
|
-
handle.writeto(outfile, overwrite=True)
|
|
569
|
-
handle.close()
|