Skip to content

Commit 14042d0

Browse files
committed
Switch to checking calculated angular positions
This is being done in lieu of checking header values in most cases. While future versions of astrometry.net may use a different index or make some other change, the resulting WCS should yield about the same positions even if the underlying WCS representation has changed.
1 parent 92b1ae0 commit 14042d0

File tree

1 file changed

+89
-19
lines changed

1 file changed

+89
-19
lines changed

astroquery/astrometry_net/tests/test_astrometry_net_remote.py

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Licensed under a 3-clause BSD style license - see LICENSE.rst
22

3-
43
import os
54

5+
import numpy as np
66
from numpy.testing import assert_allclose
77

88
# performs similar tests as test_module.py, but performs
@@ -13,6 +13,7 @@
1313

1414
from astropy.table import Table
1515
from astropy.io import fits
16+
from astropy.wcs import WCS
1617

1718
from .. import conf, AstrometryNet
1819
from ..core import _HAVE_SOURCE_DETECTION
@@ -35,6 +36,33 @@ def data_path(filename):
3536
api_key = conf.api_key or os.environ.get('ASTROMETRY_NET_API_KEY')
3637

3738

39+
def _calculate_wcs_separation_at_points(wcses, center, extent):
40+
"""
41+
Calculate the maximum separation between the given WCS solutions at a grid of points.
42+
43+
Parameters
44+
----------
45+
wcses : list of `~astropy.wcs.WCS`
46+
The WCS solutions to compare.
47+
center : tuple of float
48+
The center of the grid of points to use for the comparison.
49+
extent : int
50+
The extent of the grid of points to use for the comparison.
51+
52+
Returns
53+
-------
54+
max_separation : float
55+
The maximum separation between the WCS solutions at the grid of points.
56+
"""
57+
grid_points = np.mgrid[center[0] - extent // 2:center[0] + extent // 2,
58+
center[1] - extent // 2:center[1] + extent // 2]
59+
60+
result_location = wcses[0].pixel_to_world(grid_points[0], grid_points[1])
61+
expected_location = wcses[1].pixel_to_world(grid_points[0], grid_points[1])
62+
63+
return result_location.separation(expected_location)
64+
65+
3866
@pytest.mark.skipif(not api_key, reason='API key not set.')
3967
@pytest.mark.remote_data
4068
def test_solve_by_source_list():
@@ -43,19 +71,25 @@ def test_solve_by_source_list():
4371
sources = Table.read(os.path.join(DATA_DIR, 'test-source-list.fit'))
4472
# The image_width, image_height and crpix_center below are set to match the
4573
# original solve on astrometry.net.
74+
image_width = 4109
75+
image_height = 4096
4676
result = a.solve_from_source_list(sources['X'], sources['Y'],
47-
4109, 4096,
77+
image_width, image_height,
4878
crpix_center=True)
4979

5080
expected_result = fits.getheader(os.path.join(DATA_DIR,
51-
'test-wcs-sol.fit'))
81+
'wcs-sol-from-source-list-index-5200.fit'))
5282

53-
for key in result:
54-
try:
55-
difference = expected_result[key] - result[key]
56-
except TypeError:
57-
pass
58-
assert difference == 0
83+
wcs_r = WCS(result)
84+
wcs_e = WCS(header=expected_result)
85+
# Check that, at a a grid of points roughly in the center of the image, the WCS
86+
# solutions are the same to within 0.1 arcsec.
87+
# The grid created below covers about 1/4 of the pixels in the image.
88+
center = np.array([image_width // 2, image_height // 2])
89+
extent = image_width // 2
90+
91+
separations = _calculate_wcs_separation_at_points([wcs_r, wcs_e], center, extent)
92+
assert (separations.arcsec).max() < 0.1
5993

6094

6195
@pytest.mark.skipif(not api_key, reason='API key not set.')
@@ -65,20 +99,28 @@ def test_solve_image_upload():
6599
a = AstrometryNet()
66100
a.api_key = api_key
67101
image = os.path.join(DATA_DIR, 'thumbnail-image.fit.gz')
102+
103+
image_width = 256
104+
image_height = 256
68105
# The test image only solves if it is not downsampled
106+
69107
result = a.solve_from_image(image,
70108
force_image_upload=True,
71-
downsample_factor=1)
72109
downsample_factor=1,
73110
crpix_center=True)
74111
expected_result = fits.getheader(os.path.join(DATA_DIR,
75-
'thumbnail-wcs-sol.fit'))
76-
for key in result:
77-
try:
78-
difference = expected_result[key] - result[key]
79-
except TypeError:
80-
pass
81-
assert difference == 0
112+
'wcs-sol-from-thumbnail-image-index-5200.fit'))
113+
114+
wcs_r = WCS(result)
115+
wcs_e = WCS(header=expected_result)
116+
# Check that, at a a grid of points roughly in the center of the image, the WCS
117+
# solutions are the same to within 0.1 arcsec.
118+
# The grid created below covers all of this small image.
119+
center = np.array([image_width // 2, image_height // 2])
120+
extent = image_width
121+
122+
separations = _calculate_wcs_separation_at_points([wcs_r, wcs_e], center, extent)
123+
assert (separations.arcsec).max() < 0.1
82124

83125

84126
@pytest.mark.skipif(not api_key, reason='API key not set.')
@@ -107,6 +149,9 @@ def test_solve_image_detect_source_local():
107149
a = AstrometryNet()
108150
a.api_key = api_key
109151
image = os.path.join(DATA_DIR, 'thumbnail-image.fit.gz')
152+
153+
image_width = 256
154+
image_height = 256
110155
# The source detection parameters below (fwhm, detect_threshold)
111156
# are specific to this test image. They should not be construed
112157
# as a general recommendation.
@@ -116,8 +161,33 @@ def test_solve_image_detect_source_local():
116161
fwhm=1.5, detect_threshold=5,
117162
center_ra=135.618, center_dec=49.786,
118163
radius=0.5, crpix_center=True)
164+
165+
# Use the result from the image solve for this test. The two WCS solutions really should be
166+
# nearly identical in thesee two cases. Note that the closeness of the match is affected by the
167+
# very low resolution of these images (256 x 256 pixels). That low resolution was
168+
# chosen to keep the test data small.
119169
expected_result = fits.getheader(os.path.join(DATA_DIR,
120-
'thumbnail-wcs-sol-from-photutils.fit'))
170+
'wcs-sol-from-thumbnail-image-index-5200.fit'))
171+
172+
wcs_r = WCS(result)
173+
wcs_e = WCS(header=expected_result)
174+
175+
# Check that, at a a grid of points roughly in the center of the image, the WCS
176+
# solutions are the same to within 0.1 arcsec.
177+
# The grid created below covers all of this small image.
178+
center = np.array([image_width // 2, image_height // 2])
179+
extent = image_width
180+
181+
separations = _calculate_wcs_separation_at_points([wcs_r, wcs_e], center, extent)
182+
183+
# The tolerance is higher here than in the other tests because of the
184+
# low resolution of the test image. It leads to a difference in calculated
185+
# coordinates of up to 2 arcsec across the whole image. The likely reason
186+
# is that the source detection method is different locally than on
187+
# astrometry.net.
188+
assert (separations.arcsec).max() < 2.2
189+
190+
# The headers should also be about the same in this case.
121191
for key in result:
122192
if key == 'COMMENT' or key == 'HISTORY':
123193
continue
@@ -151,7 +221,7 @@ def test_solve_timeout_behavior():
151221
result = a.monitor_submission(submission_id, solve_timeout=120)
152222

153223
expected_result = fits.getheader(os.path.join(DATA_DIR,
154-
'test-wcs-sol.fit'))
224+
'wcs-sol-from-source-list-index-5200.fit'))
155225

156226
for key in result:
157227
if key == 'COMMENT' or key == 'HISTORY':

0 commit comments

Comments
 (0)