diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f539b99..ea8ebdf 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -12,6 +12,9 @@ Release Notes - ``align_wcs`` now will raise a custom exception of type ``NotEnoughCatalogs`` when there are not enough input catalogs to perform alignment. [#203] + +- ``XYXYMatch`` now will raise a custom exception of type ``MatchSourceConfusionError`` + when multipe reference sources match a single input source. [#204] 0.8.7 (29-March-2024) diff --git a/tweakwcs/matchutils.py b/tweakwcs/matchutils.py index d846494..367fd40 100644 --- a/tweakwcs/matchutils.py +++ b/tweakwcs/matchutils.py @@ -22,12 +22,19 @@ __author__ = 'Mihai Cara' -__all__ = ['MatchCatalogs', 'XYXYMatch'] +__all__ = ['MatchCatalogs', 'XYXYMatch', 'MatchSourceConfusionError'] log = logging.getLogger(__name__) log.setLevel(logging.DEBUG) +class MatchSourceConfusionError(RuntimeError): + """ + Error indicating that multiple sources matched to a single reference + source. Try different values for ``tolerance`` and ``separation`` to fix this error. + """ + + class MatchCatalogs(ABC): """ A class that provides common interface for matching catalogs. """ @@ -180,6 +187,11 @@ def __call__(self, refcat, imcat, tp_pscale=1.0, tp_units=None, **kwargs): A tuple of two 1D `numpy.ndarray` containing indices of matched sources in the ``refcat`` and ``imcat`` catalogs accordingly. + Raises + ------ + MatchSourceConfusionError + Multiple sources matched a single reference source. Try different + values for ``tolerance`` and ``separation`` to fix this error. """ # Check catalogs: if not isinstance(refcat, astropy.table.Table): @@ -266,13 +278,19 @@ def __call__(self, refcat, imcat, tp_pscale=1.0, tp_units=None, **kwargs): else: xyoff = (self._xoffset, self._yoffset) - matches = xyxymatch( - imxy, - refxy, - origin=xyoff, - tolerance=self._tolerance, - separation=self._separation - ) + try: + matches = xyxymatch( + imxy, + refxy, + origin=xyoff, + tolerance=self._tolerance, + separation=self._separation + ) + except RuntimeError as e: + msg = e.args[0] + if msg.startswith("Number of output coordinates exceeded allocation"): + raise MatchSourceConfusionError(msg) + raise e return matches['ref_idx'], matches['input_idx'] diff --git a/tweakwcs/tests/test_matchutils.py b/tweakwcs/tests/test_matchutils.py index 2a3216d..04b4bda 100644 --- a/tweakwcs/tests/test_matchutils.py +++ b/tweakwcs/tests/test_matchutils.py @@ -17,7 +17,8 @@ import tweakwcs from tweakwcs.matchutils import (_xy_2dhist, _estimate_2dhist_shift, - _find_peak, XYXYMatch, MatchCatalogs) + _find_peak, XYXYMatch, MatchCatalogs, + MatchSourceConfusionError) from .helper_correctors import DummyWCSCorrector @@ -293,6 +294,14 @@ def test_tpmatch(tp_wcs, use2dhist): ) +def test_multi_match_error(): + tpmatch = XYXYMatch(tolerance=1.0, separation=0.01) + refcat = Table([[0.0, 0.1], [0.1, 0.0]], names=('TPx', 'TPy'), meta={'name': None}) + imcat = Table([[0.0], [0.0]], names=('TPx', 'TPy'), meta={'name': None}) + with pytest.raises(MatchSourceConfusionError): + tpmatch(refcat, imcat) + + def test_match_catalogs_abc(): class DummyMatchCatalogs(MatchCatalogs): def __call__(self, refcat, imcat):