Skip to content

Commit 792f2d1

Browse files
committed
Fix tests and improve pad_input handling
1 parent 009cb7f commit 792f2d1

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
lines changed

sunkit_image/coalignment/match_template.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,27 @@ def match_template_coalign(target_array, reference_array, **kwargs):
106106
The rotation angle in radians, which is fixed at 0.0 in this function.
107107
- translation : `tuple`
108108
A tuple containing the x and y translation values.
109+
110+
Notes
111+
-----
112+
This uses `skimage.feature.match_template` to perform the cross correlation.
113+
Please check the documentation of that function for details on the available keyword arguments
114+
and the details of the algorithm.
109115
"""
110116
from sunkit_image.coalignment.interface import AffineParams # NOQA: PLC0415
111117

112118
corr = match_template(np.float64(reference_array), np.float64(target_array), **kwargs)
113-
# TODO: Work out what is going on
114-
if corr.ndim != target_array.ndim:
115-
raise ValueError("The correlation output failed to work out a match.")
119+
if len(corr) < 2:
120+
raise ValueError(
121+
"match_template returned an array with fewer than two values, and cannot be used for coalignment. "
122+
"This implies the cross-correlation failed to find a match."
123+
)
116124
# Find the best match location
117125
y_shift, x_shift = _find_best_match_location(corr)
126+
if kwargs.get("pad_input"):
127+
# For pad_input=True matches correspond to the center
128+
y_shift -= target_array.shape[0] // 2
129+
x_shift -= target_array.shape[1] // 2
118130
log.debug(f"Match template shift: x: {x_shift}, y: {y_shift}")
119131
# Particularly for this method, there is no change in the rotation or scaling,
120132
# hence the hardcoded values of scale to 1.0 & rotation to identity matrix

sunkit_image/coalignment/phase_cross_correlation.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ def phase_cross_correlation_coalign(target_array, reference_array, **kwargs):
3535
The rotation angle in radians, which is fixed at 0.0 in this function.
3636
- translation : `tuple`
3737
A tuple containing the x and y translation values.
38+
39+
Notes
40+
-----
41+
This uses `skimage.registration.phase_cross_correlation` to perform the cross correlation.
42+
Please check the documentation of that function for details on the available keyword arguments
43+
and the details of the algorithm.
3844
"""
3945
from sunkit_image.coalignment.interface import AffineParams # NOQA: PLC0415
4046

sunkit_image/coalignment/tests/test_coalignment.py

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import astropy.units as u
66
from astropy.coordinates import SkyCoord
77
from astropy.io import fits
8+
from astropy.tests.helper import assert_quantity_allclose
89

910
import sunpy.map
11+
from sunpy.map.maputils import all_coordinates_from_map, coordinate_is_on_solar_disk
1012
from sunpy.util.exceptions import SunpyUserWarning
1113

1214
from sunkit_image.coalignment import coalign
@@ -70,50 +72,63 @@ def test_coalignment_eis_aia(eis_test_map, aia193_test_map):
7072
aia193_test_downsampled_map = aia193_test_map.resample(u.Quantity([nx, ny]))
7173
coaligned_eis_map = coalign(eis_test_map, aia193_test_downsampled_map, method='match_template')
7274
# Check that correction is as expected based on known pointing offset
73-
assert u.allclose(
75+
assert_quantity_allclose(
7476
eis_test_map.reference_coordinate.separation(coaligned_eis_map.reference_coordinate),
7577
5.95935177*u.arcsec,
7678
)
7779

7880

7981
def test_coalignment_match_template_full_map(incorrect_pointing_map_and_shift, aia171_test_map):
8082
incorrect_pointing_map, pointing_shift = incorrect_pointing_map_and_shift
81-
fixed_map = coalign(incorrect_pointing_map, aia171_test_map)
83+
# Crop out the array that is outside the solar disk to have something to align to
84+
hpc_coords = all_coordinates_from_map(incorrect_pointing_map)
85+
mask = coordinate_is_on_solar_disk(hpc_coords)
86+
masked_map = sunpy.map.Map(np.abs(incorrect_pointing_map.data*mask), incorrect_pointing_map.meta)
87+
# We have to pad the input map because otherwise match_template cannot find a good match
88+
fixed_map = coalign(masked_map, aia171_test_map, pad_input=True)
8289
# The actual shifts applied by coalignment should be equal to the expected shifts
83-
u.allclose(
84-
np.fabs(incorrect_pointing_map.reference_coordinate.Tx-fixed_map.reference_coordinate.Tx),
90+
assert_quantity_allclose(
91+
(incorrect_pointing_map.reference_coordinate.Tx-fixed_map.reference_coordinate.Tx),
8592
pointing_shift[0],
93+
# Not as precise for full map
94+
atol=0.6*u.arcsec,
8695
)
87-
u.allclose(
88-
np.fabs(incorrect_pointing_map.reference_coordinate.Ty-fixed_map.reference_coordinate.Ty),
96+
assert_quantity_allclose(
97+
(incorrect_pointing_map.reference_coordinate.Ty-fixed_map.reference_coordinate.Ty),
8998
pointing_shift[1],
99+
# Not as precise for full map
100+
atol=0.6*u.arcsec,
90101
)
91102

92103

93104
def test_coalignment_match_template_cutout(incorrect_pointing_cutout_map_and_shift, aia171_test_map):
94105
incorrect_pointing_cutout_map, pointing_shift = incorrect_pointing_cutout_map_and_shift
95106
fixed_cutout_map = coalign(incorrect_pointing_cutout_map, aia171_test_map)
96107
# The actual shifts applied by coalignment should be equal to the expected shifts
97-
u.allclose(
98-
np.fabs(incorrect_pointing_cutout_map.reference_coordinate.Tx-fixed_cutout_map.reference_coordinate.Tx),
108+
assert_quantity_allclose(
109+
(incorrect_pointing_cutout_map.reference_coordinate.Tx-fixed_cutout_map.reference_coordinate.Tx),
99110
pointing_shift[0],
111+
# For example, a shift is 25 arcsec but the returned shift is 24.9 arcsec
112+
atol=0.1*u.arcsec,
100113
)
101-
u.allclose(
102-
np.fabs(incorrect_pointing_cutout_map.reference_coordinate.Ty-fixed_cutout_map.reference_coordinate.Ty),
114+
assert_quantity_allclose(
115+
(incorrect_pointing_cutout_map.reference_coordinate.Ty-fixed_cutout_map.reference_coordinate.Ty),
103116
pointing_shift[1],
117+
# For example, a shift is 25 arcsec but the returned shift is 24.9 arcsec
118+
atol=0.1*u.arcsec,
104119
)
105120

106121

107122
def test_coalign_phase_cross_correlation(incorrect_pointing_map_and_shift, aia171_test_map):
108123
incorrect_pointing_map, pointing_shift = incorrect_pointing_map_and_shift
109124
fixed_map = coalign(incorrect_pointing_map, aia171_test_map, method='phase_cross_correlation')
110125
# The actual shifts applied by coalignment should be equal to the expected shifts
111-
u.allclose(
112-
np.fabs(incorrect_pointing_map.reference_coordinate.Tx-fixed_map.reference_coordinate.Tx),
126+
assert_quantity_allclose(
127+
(incorrect_pointing_map.reference_coordinate.Tx-fixed_map.reference_coordinate.Tx),
113128
pointing_shift[0],
114129
)
115-
u.allclose(
116-
np.fabs(incorrect_pointing_map.reference_coordinate.Ty-fixed_map.reference_coordinate.Ty),
130+
assert_quantity_allclose(
131+
(incorrect_pointing_map.reference_coordinate.Ty-fixed_map.reference_coordinate.Ty),
117132
pointing_shift[1],
118133
)
119134

@@ -158,10 +173,10 @@ def test_warnings_coalign(incorrect_shifted_once_map, aia171_test_map):
158173
time_shift_meta = incorrect_shifted_once_map.meta.copy()
159174
time_shift_meta['DATE-OBS'] = '2014-01-08T09:57:30.84'
160175
time_shift = sunpy.map.Map(incorrect_shifted_once_map.data, time_shift_meta)
161-
with pytest.warns(SunpyUserWarning, match=r"The time difference between the reference and target maps in time is large."):
162-
with pytest.raises(ValueError, match=r"attempt to get argmax of an empty sequence"):
176+
with pytest.warns(SunpyUserWarning, match=r"The difference in observation times of the reference and target maps is large."):
177+
with pytest.raises(ValueError, match=r"match_template returned an array with fewer than two values,"):
163178
coalign(time_shift, aia171_test_map)
164179

165180
resampled_map = incorrect_shifted_once_map.resample([100,100]*u.pix)
166-
with pytest.warns(SunpyUserWarning, match=r"There is a plate scale difference between the reference and target maps."):
181+
with pytest.warns(SunpyUserWarning, match=r"The reference and target maps have different plate scales."):
167182
coalign(resampled_map, aia171_test_map)

0 commit comments

Comments
 (0)