drizzle 1.15.0__cp310-cp310-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 +11 -0
- drizzle/calc_pixmap.py +52 -0
- drizzle/cdrizzle.cp310-win_amd64.pyd +0 -0
- drizzle/doblot.py +80 -0
- drizzle/dodrizzle.py +189 -0
- drizzle/drizzle.py +569 -0
- drizzle/tests/__init__.py +0 -0
- drizzle/tests/test_cdrizzle.py +24 -0
- drizzle/tests/test_drizzle.py +644 -0
- drizzle/tests/test_file_io.py +173 -0
- drizzle/tests/test_overlap_calc.py +262 -0
- drizzle/tests/test_pixmap.py +76 -0
- drizzle/util.py +256 -0
- drizzle-1.15.0.dist-info/LICENSE.rst +31 -0
- drizzle-1.15.0.dist-info/METADATA +364 -0
- drizzle-1.15.0.dist-info/RECORD +18 -0
- drizzle-1.15.0.dist-info/WHEEL +5 -0
- drizzle-1.15.0.dist-info/top_level.txt +1 -0
drizzle/util.py
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def find_keyword_extn(fimg, keyword, value=None):
|
|
5
|
+
"""
|
|
6
|
+
This function will return the index of the extension in a multi-extension
|
|
7
|
+
FITS file which contains the desired keyword with the given value.
|
|
8
|
+
|
|
9
|
+
Parameters
|
|
10
|
+
----------
|
|
11
|
+
|
|
12
|
+
fimg : hdulist
|
|
13
|
+
A list of header data units
|
|
14
|
+
|
|
15
|
+
keyword : str
|
|
16
|
+
The keyword to search for
|
|
17
|
+
|
|
18
|
+
value : str or number, optional
|
|
19
|
+
If set, the value the keyword must have to match
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
|
|
24
|
+
The index of the extension
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
i = 0
|
|
28
|
+
extnum = -1
|
|
29
|
+
# Search through all the extensions in the FITS object
|
|
30
|
+
for chip in fimg:
|
|
31
|
+
hdr = chip.header
|
|
32
|
+
# Check to make sure the extension has the given keyword
|
|
33
|
+
if keyword in hdr:
|
|
34
|
+
if value is not None:
|
|
35
|
+
# If it does, then does the value match the desired value
|
|
36
|
+
# MUST use 'str.strip' to match against any input string!
|
|
37
|
+
if hdr[keyword].strip() == value:
|
|
38
|
+
extnum = i
|
|
39
|
+
break
|
|
40
|
+
else:
|
|
41
|
+
extnum = i
|
|
42
|
+
break
|
|
43
|
+
i += 1
|
|
44
|
+
# Return the index of the extension which contained the
|
|
45
|
+
# desired EXTNAME value.
|
|
46
|
+
return extnum
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def get_extn(fimg, extn=''):
|
|
50
|
+
"""
|
|
51
|
+
Returns the FITS extension corresponding to extension specified in
|
|
52
|
+
filename. Defaults to returning the first extension with data or the
|
|
53
|
+
primary extension, if none have data.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
|
|
58
|
+
fimg : hdulist
|
|
59
|
+
A list of header data units
|
|
60
|
+
|
|
61
|
+
extn : str
|
|
62
|
+
The extension name and version to match
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
|
|
67
|
+
The matching header data unit
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
if extn:
|
|
71
|
+
try:
|
|
72
|
+
_extn = parse_extn(extn)
|
|
73
|
+
if _extn[0]:
|
|
74
|
+
_e = fimg.index_of(_extn)
|
|
75
|
+
else:
|
|
76
|
+
_e = _extn[1]
|
|
77
|
+
|
|
78
|
+
except KeyError:
|
|
79
|
+
_e = None
|
|
80
|
+
|
|
81
|
+
if _e is None:
|
|
82
|
+
_extn = None
|
|
83
|
+
else:
|
|
84
|
+
_extn = fimg[_e]
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
# If no extension is provided, search for first extension
|
|
88
|
+
# in FITS file with data associated with it.
|
|
89
|
+
|
|
90
|
+
# Set up default to point to PRIMARY extension.
|
|
91
|
+
_extn = fimg[0]
|
|
92
|
+
# then look for first extension with data.
|
|
93
|
+
for _e in fimg:
|
|
94
|
+
if _e.data is not None:
|
|
95
|
+
_extn = _e
|
|
96
|
+
break
|
|
97
|
+
|
|
98
|
+
return _extn
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def get_keyword(fimg, keyword, default=None):
|
|
102
|
+
"""
|
|
103
|
+
Return a keyword value from the header of an image,
|
|
104
|
+
or the default if the keyword is not found.
|
|
105
|
+
|
|
106
|
+
Parameters
|
|
107
|
+
----------
|
|
108
|
+
|
|
109
|
+
fimg : hdulist
|
|
110
|
+
A list of header data units
|
|
111
|
+
|
|
112
|
+
keyword : hdulist
|
|
113
|
+
The keyword value to search for
|
|
114
|
+
|
|
115
|
+
default : str or number, optional
|
|
116
|
+
The default value if not found
|
|
117
|
+
|
|
118
|
+
Returns
|
|
119
|
+
-------
|
|
120
|
+
|
|
121
|
+
The value if found or default if not
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
value = None
|
|
125
|
+
if keyword:
|
|
126
|
+
_nextn = find_keyword_extn(fimg, keyword)
|
|
127
|
+
try:
|
|
128
|
+
value = fimg[_nextn].header[keyword]
|
|
129
|
+
except KeyError:
|
|
130
|
+
value = None
|
|
131
|
+
|
|
132
|
+
if value is None and default is not None:
|
|
133
|
+
value = default
|
|
134
|
+
|
|
135
|
+
return value
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def is_blank(value):
|
|
139
|
+
"""
|
|
140
|
+
Determines whether or not a value is considered 'blank'.
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
|
|
145
|
+
value : str
|
|
146
|
+
The value to check
|
|
147
|
+
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
|
|
151
|
+
True or False
|
|
152
|
+
"""
|
|
153
|
+
return value.strip() == ""
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def parse_extn(extn=''):
|
|
157
|
+
"""
|
|
158
|
+
Parse a string representing a qualified fits extension name as in the
|
|
159
|
+
output of parse_filename and return a tuple (str(extname), int(extver)),
|
|
160
|
+
which can be passed to pyfits functions using the 'ext' kw.
|
|
161
|
+
Default return is the first extension in a fits file.
|
|
162
|
+
|
|
163
|
+
Examples
|
|
164
|
+
--------
|
|
165
|
+
>>> parse_extn('sci,2')
|
|
166
|
+
('sci', 2)
|
|
167
|
+
>>> parse_extn('2')
|
|
168
|
+
('', 2)
|
|
169
|
+
>>> parse_extn('sci')
|
|
170
|
+
('sci', 1)
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
extn : str
|
|
175
|
+
The extension name
|
|
176
|
+
|
|
177
|
+
Returns
|
|
178
|
+
-------
|
|
179
|
+
A tuple of the extension name and value
|
|
180
|
+
"""
|
|
181
|
+
if not extn:
|
|
182
|
+
return ('', 0)
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
lext = extn.split(',')
|
|
186
|
+
except Exception:
|
|
187
|
+
return ('', 1)
|
|
188
|
+
|
|
189
|
+
if len(lext) == 1 and lext[0].isdigit():
|
|
190
|
+
return ("", int(lext[0]))
|
|
191
|
+
elif len(lext) == 2:
|
|
192
|
+
return (lext[0], int(lext[1]))
|
|
193
|
+
else:
|
|
194
|
+
return (lext[0], 1)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def parse_filename(filename):
|
|
198
|
+
"""
|
|
199
|
+
Parse out filename from any specified extensions.
|
|
200
|
+
Returns rootname and string version of extension name.
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
|
|
205
|
+
filename : str
|
|
206
|
+
The filename to be parsed
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
|
|
211
|
+
A tuple with the filename root and extension
|
|
212
|
+
"""
|
|
213
|
+
# Parse out any extension specified in filename
|
|
214
|
+
_indx = filename.find('[')
|
|
215
|
+
if _indx > 0:
|
|
216
|
+
# Read extension name provided
|
|
217
|
+
_fname = filename[:_indx]
|
|
218
|
+
_extn = filename[_indx + 1:-1]
|
|
219
|
+
else:
|
|
220
|
+
_fname = filename
|
|
221
|
+
_extn = ''
|
|
222
|
+
|
|
223
|
+
return _fname, _extn
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def set_pscale(the_wcs):
|
|
227
|
+
"""
|
|
228
|
+
Calculates the plate scale from cdelt and the pc matrix and adds
|
|
229
|
+
it to the WCS. Plate scale is not part of the WCS standard, but is
|
|
230
|
+
required by the drizzle code
|
|
231
|
+
|
|
232
|
+
Parameters
|
|
233
|
+
----------
|
|
234
|
+
|
|
235
|
+
the_wcs : wcs
|
|
236
|
+
A WCS object
|
|
237
|
+
"""
|
|
238
|
+
try:
|
|
239
|
+
cdelt = the_wcs.wcs.get_cdelt()
|
|
240
|
+
pc = the_wcs.wcs.get_pc()
|
|
241
|
+
|
|
242
|
+
except Exception:
|
|
243
|
+
try:
|
|
244
|
+
# for non-celestial axes, get_cdelt doesnt work
|
|
245
|
+
cdelt = the_wcs.wcs.cd * the_wcs.wcs.cdelt
|
|
246
|
+
except AttributeError:
|
|
247
|
+
cdelt = the_wcs.wcs.cdelt
|
|
248
|
+
|
|
249
|
+
try:
|
|
250
|
+
pc = the_wcs.wcs.pc
|
|
251
|
+
except AttributeError:
|
|
252
|
+
pc = 1
|
|
253
|
+
|
|
254
|
+
pccd = np.array(cdelt * pc)
|
|
255
|
+
scales = np.sqrt((pccd ** 2).sum(axis=0, dtype=float))
|
|
256
|
+
the_wcs.pscale = scales[0]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Copyright (C) 2011,2014 Association of Universities for Research in
|
|
2
|
+
Astronomy (AURA)
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
|
5
|
+
modification, are permitted provided that the following conditions
|
|
6
|
+
are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above
|
|
9
|
+
copyright notice, this list of conditions and the following
|
|
10
|
+
disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above
|
|
13
|
+
copyright notice, this list of conditions and the following
|
|
14
|
+
disclaimer in the documentation and/or other materials
|
|
15
|
+
provided with the distribution.
|
|
16
|
+
|
|
17
|
+
3. The name of AURA and its representatives may not be used to
|
|
18
|
+
endorse or promote products derived from this software without
|
|
19
|
+
specific prior written permission.
|
|
20
|
+
|
|
21
|
+
THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR
|
|
22
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
23
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
24
|
+
ARE DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT,
|
|
25
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
26
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
27
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
28
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
29
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
30
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
31
|
+
OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: drizzle
|
|
3
|
+
Version: 1.15.0
|
|
4
|
+
Summary: A package for combining dithered images into a single image
|
|
5
|
+
Author-email: STScI <help@stsci.edu>
|
|
6
|
+
License: Copyright (C) 2011,2014 Association of Universities for Research in
|
|
7
|
+
Astronomy (AURA)
|
|
8
|
+
|
|
9
|
+
Redistribution and use in source and binary forms, with or without
|
|
10
|
+
modification, are permitted provided that the following conditions
|
|
11
|
+
are met:
|
|
12
|
+
|
|
13
|
+
1. Redistributions of source code must retain the above
|
|
14
|
+
copyright notice, this list of conditions and the following
|
|
15
|
+
disclaimer.
|
|
16
|
+
|
|
17
|
+
2. Redistributions in binary form must reproduce the above
|
|
18
|
+
copyright notice, this list of conditions and the following
|
|
19
|
+
disclaimer in the documentation and/or other materials
|
|
20
|
+
provided with the distribution.
|
|
21
|
+
|
|
22
|
+
3. The name of AURA and its representatives may not be used to
|
|
23
|
+
endorse or promote products derived from this software without
|
|
24
|
+
specific prior written permission.
|
|
25
|
+
|
|
26
|
+
THIS SOFTWARE IS PROVIDED BY AURA ``AS IS'' AND ANY EXPRESS OR
|
|
27
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
28
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
29
|
+
ARE DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT,
|
|
30
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
31
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
32
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
33
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
34
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
35
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
36
|
+
OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
37
|
+
|
|
38
|
+
Project-URL: Homepage, https://github.com/spacetelescope/drizzle
|
|
39
|
+
Project-URL: Bug Tracker, https://github.com/spacetelescope/drizzle/issues
|
|
40
|
+
Project-URL: Documentation, http://spacetelescope.github.io/drizzle/
|
|
41
|
+
Project-URL: Source Code, https://github.com/spacetelescope/drizzle
|
|
42
|
+
Requires-Python: >=3.9
|
|
43
|
+
Description-Content-Type: text/x-rst
|
|
44
|
+
License-File: LICENSE.rst
|
|
45
|
+
Requires-Dist: numpy
|
|
46
|
+
Requires-Dist: astropy
|
|
47
|
+
Provides-Extra: docs
|
|
48
|
+
Requires-Dist: sphinx ; extra == 'docs'
|
|
49
|
+
Requires-Dist: sphinx-automodapi ; extra == 'docs'
|
|
50
|
+
Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
|
|
51
|
+
Requires-Dist: matplotlib ; extra == 'docs'
|
|
52
|
+
Requires-Dist: tomli ; (python_version < "3.11") and extra == 'docs'
|
|
53
|
+
Provides-Extra: test
|
|
54
|
+
Requires-Dist: pytest ; extra == 'test'
|
|
55
|
+
|
|
56
|
+
drizzle Documentation
|
|
57
|
+
=====================
|
|
58
|
+
|
|
59
|
+
.. image:: http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat
|
|
60
|
+
:target: http://www.astropy.org
|
|
61
|
+
:alt: Powered by Astropy Badge
|
|
62
|
+
|
|
63
|
+
.. image:: https://codecov.io/github/spacetelescope/drizzle/branch/main/graphs/badge.svg
|
|
64
|
+
:target: https://codecov.io/gh/spacetelescope/drizzle
|
|
65
|
+
:alt: Drizzle's Coverage Status
|
|
66
|
+
|
|
67
|
+
.. image:: https://github.com/spacetelescope/drizzle/workflows/CI/badge.svg
|
|
68
|
+
:target: https://github.com/spacetelescope/drizzle/actions
|
|
69
|
+
:alt: CI Status
|
|
70
|
+
|
|
71
|
+
.. image:: https://readthedocs.org/projects/spacetelescope-drizzle/badge/?version=latest
|
|
72
|
+
:target: https://spacetelescope-drizzle.readthedocs.io/en/latest/?badge=latest
|
|
73
|
+
:alt: Documentation Status
|
|
74
|
+
|
|
75
|
+
.. image:: https://img.shields.io/pypi/v/drizzle.svg
|
|
76
|
+
:target: https://pypi.org/project/drizzle
|
|
77
|
+
:alt: PyPI Status
|
|
78
|
+
|
|
79
|
+
The ``drizzle`` library is a Python package for combining dithered images into a
|
|
80
|
+
single image. This library is derived from code used in DrizzlePac. Like
|
|
81
|
+
DrizzlePac, most of the code is implemented in the C language. The biggest
|
|
82
|
+
change from DrizzlePac is that this code passes an array that maps the input to
|
|
83
|
+
output image into the C code, while the DrizzlePac code computes the mapping by
|
|
84
|
+
using a Python callback. Switching to using an array allowed the code to be
|
|
85
|
+
greatly simplified.
|
|
86
|
+
|
|
87
|
+
The DrizzlePac code is currently used in the Space Telescope processing
|
|
88
|
+
pipelines. This library is forward looking in that it can be used with
|
|
89
|
+
the new GWCS code.
|
|
90
|
+
|
|
91
|
+
Requirements
|
|
92
|
+
------------
|
|
93
|
+
|
|
94
|
+
- Python 3.9 or later
|
|
95
|
+
|
|
96
|
+
- Numpy
|
|
97
|
+
|
|
98
|
+
- Astropy
|
|
99
|
+
|
|
100
|
+
The Drizzle Algorithm
|
|
101
|
+
---------------------
|
|
102
|
+
|
|
103
|
+
This section has been extracted from Chapter 2 of
|
|
104
|
+
`The DrizzlePac Handbook <http://www.stsci.edu/hst/HST_overview/drizzlepac/documents/handbooks/drizzlepac.pdf>`_ [Driz2012]_
|
|
105
|
+
|
|
106
|
+
There are a family of linear reconstruction techniques that, at two opposite
|
|
107
|
+
extremes, are represented by the interlacing and shift-and-add techniques, with
|
|
108
|
+
the Drizzle algorithm representing a continuum between these two extremes.
|
|
109
|
+
|
|
110
|
+
If the dithers are particularly well-placed, one can simply interlace the pixels
|
|
111
|
+
from the images onto a finer grid. In the interlacing method, pixels from the
|
|
112
|
+
independent input images are placed in alternate pixels on the output image
|
|
113
|
+
according to the alignment of the pixel centers in the original images. However,
|
|
114
|
+
due to occasional small positioning errors by the telescope, and non-uniform
|
|
115
|
+
shifts in pixel space across the detector caused by geometric distortion of the
|
|
116
|
+
optics, true interlacing of images is generally not feasible.
|
|
117
|
+
|
|
118
|
+
Another standard simple linear technique for combining shifted images,
|
|
119
|
+
descriptively named “shift-and-add”, has been used for many years to combine
|
|
120
|
+
dithered infrared data onto finer grids. Each input pixel is block-replicated
|
|
121
|
+
onto a finer subsampled grid, shifted into place, and added to the output image.
|
|
122
|
+
Shift-and-add has the advantage of being able to easily handle arbitrary dither
|
|
123
|
+
positions. However, it convolves the image yet again with the original pixel,
|
|
124
|
+
thus adding to the blurring of the image and to the correlation of noise in the
|
|
125
|
+
image. Furthermore, it is difficult to use shift-and-add in the presence of
|
|
126
|
+
missing data (e.g., from cosmic rays) and geometric distortion.
|
|
127
|
+
|
|
128
|
+
In response to the limitations of the two techniques described above, an
|
|
129
|
+
improved method known formally as variable-pixel linear reconstruction, and more
|
|
130
|
+
commonly referred to as Drizzle, was developed by Andy Fruchter and Richard
|
|
131
|
+
Hook, initially for the purposes of combining dithered images of the Hubble Deep
|
|
132
|
+
Field North (HDF-N). This algorithm can be thought of as a continuous set of
|
|
133
|
+
linear functions that vary smoothly between the optimum linear combination
|
|
134
|
+
technique (interlacing) and shift-and-add. This often allows an improvement in
|
|
135
|
+
resolution and a reduction in correlated noise, compared with images produced by
|
|
136
|
+
only using shift-and-add.
|
|
137
|
+
|
|
138
|
+
The degree to which the algorithm departs from interlacing and moves towards
|
|
139
|
+
shift-and-add depends upon how well the PSF is subsampled by the shifts in the
|
|
140
|
+
input images. In practice, the behavior of the Drizzle algorithm is controlled
|
|
141
|
+
through the use of a parameter called pixfrac, which can be set to values
|
|
142
|
+
ranging from 0 to 1, that represents the amount by which input pixels are shrunk
|
|
143
|
+
before being mapped onto the output image plane.
|
|
144
|
+
|
|
145
|
+
A key to understanding the use of pixfrac is to realize that a CCD image can be
|
|
146
|
+
thought of as the true image convolved first by the optics, then by the pixel
|
|
147
|
+
response function (ideally a square the size of a pixel), and then sampled by a
|
|
148
|
+
delta-function at the center of each pixel. A CCD image is thus a set of point
|
|
149
|
+
samples of a continuous two-dimensional function. Hence the natural value of
|
|
150
|
+
pixfrac is 0, which corresponds to pure interlacing. Setting pixfrac to values
|
|
151
|
+
greater than 0 causes additional broadening of the output PSF by convolving the
|
|
152
|
+
original PSF with pixels of non-zero size. Thus, setting pixfrac to its maximum
|
|
153
|
+
value of 1 is equivalent to shift-and-add, the other extreme of linear
|
|
154
|
+
combination, in which the output image PSF has been smeared by a convolution
|
|
155
|
+
with the full size of the original input pixels.
|
|
156
|
+
|
|
157
|
+
The Drizzle algorithm is conceptually straightforward. Pixels in the original
|
|
158
|
+
input images are mapped into pixels in the subsampled output image, taking into
|
|
159
|
+
account shifts and rotations between images and the optical distortion of the
|
|
160
|
+
camera. However, in order to avoid convolving the image with the large pixel
|
|
161
|
+
“footprint” of the camera, Drizzle allows the user to shrink the pixel before it
|
|
162
|
+
is averaged into the output image through the pixfrac parameter.
|
|
163
|
+
|
|
164
|
+
The flux value of each input pixel is divided up into the output pixels with
|
|
165
|
+
weights proportional to the area of overlap between the “drop” and each output
|
|
166
|
+
pixel. If the drop size is too small, not all output pixels have data added to
|
|
167
|
+
them from each of the input images. One should therefore choose a drop size that
|
|
168
|
+
is small enough to avoid convolving the image with too large an input pixel
|
|
169
|
+
footprint, yet sufficiently large to ensure that there is not too much variation
|
|
170
|
+
in the number of input pixels contributing to each output pixel.
|
|
171
|
+
|
|
172
|
+
When images are combined using Drizzle, a weight map can be specified for each
|
|
173
|
+
input image. The weight image contains information about bad pixels in the image
|
|
174
|
+
(in that bad pixels result in lower weight values). When the final output
|
|
175
|
+
science image is generated, an output weight map which combines information from
|
|
176
|
+
all the input weight images, is also saved.
|
|
177
|
+
|
|
178
|
+
Drizzle has a number of advantages over standard linear reconstruction methods.
|
|
179
|
+
Since the pixel area can be scaled by the Jacobian of the geometric distortion,
|
|
180
|
+
it is preserved for surface and absolute photometry. Therefore, the flux in the
|
|
181
|
+
drizzled image, that was corrected for geometric distortion, can be measured
|
|
182
|
+
with an aperture size that's not dependent of its position on the image. Since
|
|
183
|
+
the Drizzle code anticipates that a given output pixel might not receive any
|
|
184
|
+
information from an input pixel, missing data does not cause a substantial
|
|
185
|
+
problem as long as the observer has taken enough dither samples to fill in the
|
|
186
|
+
missing information.
|
|
187
|
+
|
|
188
|
+
The blot methods perform the inverse operation of drizzle. That is, blotting
|
|
189
|
+
performs the inverse mapping to transform the dithered median image back into
|
|
190
|
+
the coordinate system of the original input image. Blotting is primarily used
|
|
191
|
+
for identifying cosmic rays in the original image. Like the original drizzle
|
|
192
|
+
task, blot requires the user to provide the world coordinate system (WCS)
|
|
193
|
+
transformations as inputs.
|
|
194
|
+
|
|
195
|
+
.. [Driz2012] Gonzaga, S., Hack, W., Fruchter, A., Mack, J., eds. 2012, The DrizzlePac Handbook. (Baltimore, STScI)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
The Drizzle Library
|
|
199
|
+
-------------------
|
|
200
|
+
|
|
201
|
+
The Drizzle library is object-oriented and you use it by first creating an object of
|
|
202
|
+
the ``Drizzle`` class. To create a new Drizzle output image, supply an Astropy
|
|
203
|
+
WCS object representing the coordinate system of the output image.
|
|
204
|
+
The other parameters are the linear pixel dimension described in the previous
|
|
205
|
+
section, the drizzle kernel used, how each input image is scaled (by exposure
|
|
206
|
+
time or time squared), and the pixel value set in the output image where the
|
|
207
|
+
input images do not overlap.
|
|
208
|
+
|
|
209
|
+
After creating a Drizzle object, you add one or more images by calling the
|
|
210
|
+
``add_fits_file`` method. The arguments are the name of the FITS file containing
|
|
211
|
+
the input image and optionally the name of a FITS file containing the pixel
|
|
212
|
+
weighting. Both file names can be followed by an extension name or number in
|
|
213
|
+
square brackets. Optionally you can pass the name of the header keywords
|
|
214
|
+
containing the exposure time and units. Two units are understood: counts and
|
|
215
|
+
cps (counts per second).
|
|
216
|
+
|
|
217
|
+
The following function is a demonstration of how you can create a new output
|
|
218
|
+
image::
|
|
219
|
+
|
|
220
|
+
def drizzle_demo_one(reference, outfile, infiles):
|
|
221
|
+
"""
|
|
222
|
+
First demonstration of drizzle
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
==========
|
|
226
|
+
reference
|
|
227
|
+
A file containing the wcs of the output image
|
|
228
|
+
|
|
229
|
+
outfile
|
|
230
|
+
The name of the output image
|
|
231
|
+
|
|
232
|
+
infiles
|
|
233
|
+
The names of the input images to be combined
|
|
234
|
+
"""
|
|
235
|
+
# Get the WCS for the output image
|
|
236
|
+
hdulist = fits.open(reference)
|
|
237
|
+
reference_wcs = wcs.WCS(hdulist[1].header)
|
|
238
|
+
|
|
239
|
+
# Initialize the output with the WCS
|
|
240
|
+
driz = drizzle.drizzle.Drizzle(outwcs=reference_wcs)
|
|
241
|
+
|
|
242
|
+
# Combine the input images into on drizzle image
|
|
243
|
+
for infile in infiles:
|
|
244
|
+
driz.add_fits_file(infile)
|
|
245
|
+
|
|
246
|
+
# Write the drizzled image out
|
|
247
|
+
driz.write(outfile)
|
|
248
|
+
|
|
249
|
+
Optionally you can supply the input and weight images as Numpy arrays by using
|
|
250
|
+
the ``add_image`` method. If you use this method, you must supply the extra
|
|
251
|
+
information that would otherwise be read from the FITS image: The WCS
|
|
252
|
+
of the input image, the exposure time, and image units.
|
|
253
|
+
|
|
254
|
+
Here is an example of how you would call ``add_image``::
|
|
255
|
+
|
|
256
|
+
def drizzle_demo_two(reference, outfile, infiles):
|
|
257
|
+
"""
|
|
258
|
+
Demonstration of drizzle with add image.
|
|
259
|
+
|
|
260
|
+
Parameters
|
|
261
|
+
==========
|
|
262
|
+
reference
|
|
263
|
+
A file containing the wcs of the output image.
|
|
264
|
+
|
|
265
|
+
outfile
|
|
266
|
+
The name of the output image.
|
|
267
|
+
|
|
268
|
+
infiles
|
|
269
|
+
The names of the input images to be combined.
|
|
270
|
+
"""
|
|
271
|
+
# Get the WCS for the output image
|
|
272
|
+
reflist = fits.open(reference)
|
|
273
|
+
reference_wcs = wcs.WCS(reflist[1].header)
|
|
274
|
+
|
|
275
|
+
# Initialize the output with the WCS
|
|
276
|
+
driz = drizzle.drizzle.Drizzle(outwcs=reference_wcs)
|
|
277
|
+
|
|
278
|
+
# Combine the input images into on drizzle image
|
|
279
|
+
for infile in infiles:
|
|
280
|
+
# Open the file and read the image and wcs
|
|
281
|
+
# This is a contrived example, we would not do this
|
|
282
|
+
# unless the data came from another source
|
|
283
|
+
# than a FITS file
|
|
284
|
+
imlist = fits.open(reference)
|
|
285
|
+
image = imlist[1].data
|
|
286
|
+
image_wcs = wcs.WCS(imlist[1].header)
|
|
287
|
+
driz.add_image(image, image_wcs)
|
|
288
|
+
|
|
289
|
+
# Write the drizzled image out
|
|
290
|
+
driz.write(outfile)
|
|
291
|
+
|
|
292
|
+
After combining all the input images, you write the output image into a FITS
|
|
293
|
+
file with the ``write`` method. You must pass the name of the output image and
|
|
294
|
+
optionally the units. You can also supply a set of header cards to be added
|
|
295
|
+
to the primary header of the output FITS file.
|
|
296
|
+
|
|
297
|
+
You can also add more images to an existing Drizzle output file by creating
|
|
298
|
+
a new Drizzle object and passing the existing output file name as the new
|
|
299
|
+
object is created. In that case the output WCS and all
|
|
300
|
+
other parameters are read from the file.
|
|
301
|
+
|
|
302
|
+
Here is a demonstration of adding additional input images to a drizzled image::
|
|
303
|
+
|
|
304
|
+
def drizzle_demo_three(outfile, infiles):
|
|
305
|
+
"""
|
|
306
|
+
Demonstration of drizzle and adding to an existing output.
|
|
307
|
+
|
|
308
|
+
Parameters
|
|
309
|
+
==========
|
|
310
|
+
outfile
|
|
311
|
+
Name of output image that new files will be appended to.
|
|
312
|
+
|
|
313
|
+
infiles
|
|
314
|
+
The names of the input images to be added.
|
|
315
|
+
"""
|
|
316
|
+
# Re-open the output file
|
|
317
|
+
driz = drizzle.drizzle.Drizzle(infile=outfile)
|
|
318
|
+
|
|
319
|
+
# Add the input images to the existing output image
|
|
320
|
+
for infile in infiles:
|
|
321
|
+
driz.add_fits_file(infile)
|
|
322
|
+
|
|
323
|
+
# Write the modified drizzled image out
|
|
324
|
+
driz.write(outfile)
|
|
325
|
+
|
|
326
|
+
You can use the methods ``blot_fits_file`` and ``blot_image`` to transform the drizzled
|
|
327
|
+
output image into another WCS. Most usually this is the
|
|
328
|
+
coordinates of one of the input images and is used to identify cosmic rays or
|
|
329
|
+
other defects. The two methods ``blot_fits_file`` and ``blot_image`` allow you to
|
|
330
|
+
retrieve the WCS from the FITS file header or input it directly.
|
|
331
|
+
The optional parameter ``interp`` allows you to selct the method used to resample
|
|
332
|
+
the pixels on the new grid, and ``sincscl`` is used to scale the sinc function if one
|
|
333
|
+
of the sinc interpolation methods is used. This function demonstrates how both
|
|
334
|
+
methods are called::
|
|
335
|
+
|
|
336
|
+
def drizzle_demo_four(outfile, blotfile):
|
|
337
|
+
"""
|
|
338
|
+
Demonstration of blot methods.
|
|
339
|
+
|
|
340
|
+
Parameters
|
|
341
|
+
==========
|
|
342
|
+
outfile
|
|
343
|
+
Name of output image that will be converted.
|
|
344
|
+
|
|
345
|
+
blotfile
|
|
346
|
+
Name of image containing wcs to be transformed to.
|
|
347
|
+
"""
|
|
348
|
+
# Open drizzle using the output file
|
|
349
|
+
# Transform it to another coordinate system
|
|
350
|
+
driz = drizzle.drizzle.Drizzle(infile=outfile)
|
|
351
|
+
driz.blot_fits_file(blotfile)
|
|
352
|
+
driz.write(outfile)
|
|
353
|
+
|
|
354
|
+
# Read the WCS and transform using it instead
|
|
355
|
+
# This is a contrived example
|
|
356
|
+
blotlist = fits.open(blotfile)
|
|
357
|
+
blot_wcs = wcs.WCS(blotlist[1].header)
|
|
358
|
+
driz = drizzle.drizzle.Drizzle(infile=outfile)
|
|
359
|
+
driz.blot_image(blot_wcs)
|
|
360
|
+
driz.write(outfile)
|
|
361
|
+
|
|
362
|
+
The lower level function ``dodrizzle`` is present for backwards compatibility with
|
|
363
|
+
the existing STScI DrizzlePac code and should not be used unless you are also
|
|
364
|
+
concerned with this compatibility.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
drizzle/__init__.py,sha256=7M-hCW6QcKqJl0bdkCixW08PBJzLdMz6UTTzz2CKbgc,271
|
|
2
|
+
drizzle/calc_pixmap.py,sha256=pM4Wvsjzc_gzb7NR23kLoxQy426ZXZF07tq59qqfEyA,1702
|
|
3
|
+
drizzle/cdrizzle.cp310-win_amd64.pyd,sha256=ShcSVecvN9Y0p3HI_bAFemSJcdTVeqSPFZG9qZ-LcfE,100352
|
|
4
|
+
drizzle/doblot.py,sha256=Qr5FdfV9-GY93Do5Jb9VAX-Y7M4EusIzAwwneV76Ai4,2576
|
|
5
|
+
drizzle/dodrizzle.py,sha256=3h8FE46FoHUdt9T4FjXlSOQvGU_OQZm3FRXX33I2XDM,6979
|
|
6
|
+
drizzle/drizzle.py,sha256=jnsv5GUX-NZHJN3GQhkWmmxDp1QK9iSFeYDpgNpeVVY,23441
|
|
7
|
+
drizzle/util.py,sha256=8qPA7C8nqRL7vAjJ3Ip6yLeaIauJXLtV9JBAzIDUNiY,5999
|
|
8
|
+
drizzle/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
drizzle/tests/test_cdrizzle.py,sha256=JHwVwOQ-evOD1XMPyKStxODy3AGwzXa6PMDGJldmFik,714
|
|
10
|
+
drizzle/tests/test_drizzle.py,sha256=pAEDodtD3DkeqdHaX_MUZjiPmTsDzBQk03idymgWPQY,21010
|
|
11
|
+
drizzle/tests/test_file_io.py,sha256=z6deDDdwGog03wC96poDDWoqafB2cfyR9q0PJzAaJ_g,5094
|
|
12
|
+
drizzle/tests/test_overlap_calc.py,sha256=0vtswuOXa2bP4GLm2c5q1tuIWdXePfZ_6Xd0-odKia0,7062
|
|
13
|
+
drizzle/tests/test_pixmap.py,sha256=B8Xj0MjpeP6Tc2vIL7gV7kBDmyDdo5SEafxGHrTnESM,2131
|
|
14
|
+
drizzle-1.15.0.dist-info/LICENSE.rst,sha256=sUXj5W73D9TcOw5ZXaDdcthYdY2b2dTJPsxBuZTOYWQ,1505
|
|
15
|
+
drizzle-1.15.0.dist-info/METADATA,sha256=sRkBxOA3jsNoEtTX9RWCW0ug4jbHBdIIJ81G50_PxHA,17024
|
|
16
|
+
drizzle-1.15.0.dist-info/WHEEL,sha256=5JPYeYl5ZdvdSkrGS4u21mmpPzpFx42qrXOSIgWf4pg,102
|
|
17
|
+
drizzle-1.15.0.dist-info/top_level.txt,sha256=MA5uqwTj1sJBi-hCeQj9v3-sZ9nVUTe6bd_zGWTKy5A,8
|
|
18
|
+
drizzle-1.15.0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
drizzle
|