-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
106 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,87 @@ | ||
import numpy as np | ||
|
||
|
||
def calc_pixmap(first_wcs, second_wcs): | ||
def calc_pixmap(wcs_from, wcs_to, estimate_pixel_scale_ratio=False, | ||
refpix_from=None, refpix_to=None): | ||
""" | ||
Calculate a mapping between the pixels of two images. | ||
Calculate a mapping between the pixels of two images. Pixel scale ratio, | ||
when requested, is computed near the centers of the bounding box | ||
(a property of the WCS object) or near ``refpix_*`` coordinates | ||
if supplied. | ||
Parameters | ||
---------- | ||
first_wcs : wcs | ||
wcs_from : wcs | ||
A WCS object representing the coordinate system you are | ||
converting from | ||
converting from. This object *must* have ``pixel_shape`` property | ||
defined. | ||
seond_wcs : wcs | ||
wcs_to : wcs | ||
A WCS object representing the coordinate system you are | ||
converting to | ||
converting to. | ||
estimate_pixel_scale_ratio : bool, optional | ||
Estimate the ratio of "to" to "from" WCS pixel scales. | ||
refpix_from : numpy.ndarray, tuple, list | ||
Image coordinates of the reference pixel near which pixel scale should | ||
be computed in the "from" image. In FITS WCS this could be, for example, | ||
the value of CRPIX of the ``wcs_from`` WCS. | ||
refpix_to : numpy.ndarray, tuple, list | ||
Image coordinates of the reference pixel near which pixel scale should | ||
be computed in the "to" image. In FITS WCS this could be, for example, | ||
the value of CRPIX of the ``wcs_to`` WCS. | ||
Returns | ||
------- | ||
A three dimensional array representing the transformation between | ||
the two. The last dimension is of length two and contains the x and | ||
y coordinates of a pixel center, repectively. The other two coordinates | ||
correspond to the two coordinates of the image the first WCS is from. | ||
""" | ||
pixmap : numpy.ndarray | ||
A three dimensional array representing the transformation between | ||
the two. The last dimension is of length two and contains the x and | ||
y coordinates of a pixel center, repectively. The other two coordinates | ||
correspond to the two coordinates of the image the first WCS is from. | ||
first_naxis1, first_naxis2 = first_wcs.pixel_shape | ||
pixel_scale_ratio : float | ||
Estimate the ratio of "to" to "from" WCS pixel scales. This value is | ||
returned only when ``estimate_pixel_scale_ratio`` is `True`. | ||
""" | ||
# We add one to the pixel co-ordinates before the transformation and subtract | ||
# it afterwards because wcs co-ordinates are one based, while pixel co-ordinates | ||
# are zero based, The result is the final values in pixmap give a tranformation | ||
# between the pixel co-ordinates in the first image to pixel co-ordinates in the | ||
# co-ordinate system of the second. | ||
|
||
one = np.ones(2, dtype='float64') | ||
idxmap = np.indices((first_naxis1, first_naxis2), dtype='float64') | ||
idxmap = idxmap.transpose() + one | ||
if wcs_from.pixel_shape is None: | ||
raise ValueError('The "from" WCS must have pixel_shape property set.') | ||
y, x = np.indices(wcs_from.pixel_shape, dtype=np.float64) | ||
x, y = wcs_to.invert(*wcs_from(x, y)) | ||
pixmap = np.dstack([x, y]) | ||
if estimate_pixel_scale_ratio: | ||
pscale_ratio = (_estimate_pixel_scale(wcs_to, refpix_to) / | ||
_estimate_pixel_scale(wcs_from, refpix_from)) | ||
return pixmap, pscale_ratio | ||
|
||
idxmap = idxmap.reshape(first_naxis2 * first_naxis1, 2) | ||
return pixmap | ||
|
||
worldmap = first_wcs.all_pix2world(idxmap, 1) | ||
|
||
if second_wcs.sip is None: | ||
pixmap = second_wcs.wcs_world2pix(worldmap, 1) | ||
def _estimate_pixel_scale(wcs, refpix): | ||
# estimate pixel scale (in rad) using approximate algorithm | ||
# from https://trs.jpl.nasa.gov/handle/2014/40409 | ||
if refpix is None: | ||
if wcs.bounding_box is None: | ||
refpix = np.ones(wcs.pixel_n_dim) | ||
else: | ||
refpix = np.mean(wcs.bounding_box, axis=-1) | ||
else: | ||
pixmap = second_wcs.all_world2pix(worldmap, 1) | ||
refpix = np.asarray(refpix) | ||
|
||
pixmap = pixmap.reshape(first_naxis2, first_naxis1, 2) | ||
pixmap = pixmap - one | ||
|
||
return pixmap | ||
l1, phi1 = np.deg2rad(wcs.__call__(*(refpix - 0.5))) | ||
l2, phi2 = np.deg2rad(wcs.__call__(*(refpix + [-0.5, 0.5]))) | ||
l3, phi3 = np.deg2rad(wcs.__call__(*(refpix + 0.5))) | ||
l4, phi4 = np.deg2rad(wcs.__call__(*(refpix + [0.5, -0.5]))) | ||
area = np.abs(0.5 * ((l4 - l2) * (np.sin(phi1) - np.sin(phi3)) + | ||
(l1 - l3) * (np.sin(phi2) - np.sin(phi4)))) | ||
return np.sqrt(area) | ||