Skip to content

Changes to SkyCoord equality incompatible with a SkyCoord frame attribute #10287

@dstansby

Description

@dstansby

In sunpy one of the frame attributes we set on some of our frames is an observer attribute, which is itself a SkyCoord. The recent changes to coordinate equality checking in #10154 break some functionality however, because sc1 != sc2 now errors instead of returning False if sc1 is in a different frame to sc2.

In particular, a traceback where we are now seeing errors is

>       assert_quantity_allclose(implicit.separation_3d(explicit2), 0*u.AU, atol=1e-10*u.AU)

sunpy/coordinates/tests/test_transformations.py:500: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../astropy/astropy/coordinates/sky_coordinate.py:1054: in separation_3d
    if not self.is_equivalent_frame(other):
../astropy/astropy/coordinates/sky_coordinate.py:970: in is_equivalent_frame
    if np.any(getattr(self, fattrnm) != getattr(other, fattrnm)):
../astropy/astropy/coordinates/baseframe.py:1656: in __ne__
    return np.logical_not(self == value)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <HeliographicStonyhurst Coordinate (obstime=2019-06-01T00:00:00.000): (lon, lat, radius) in (deg, deg, AU)
    (0., -0.72605048, 1.01396311)>
value = <HeliographicStonyhurst Coordinate (obstime=2019-12-01T00:00:00.000): (lon, lat, radius) in (deg, deg, AU)
    (0., 0.94857499, 0.98618233)>

    def __eq__(self, value):
        """Equality operator for frame.
    
        This implements strict equality and requires that the frames are
        equivalent and that the representation data are exactly equal.
        """
        is_equiv = self.is_equivalent_frame(value)
    
        if self._data is None and value._data is None:
            # For Frame with no data, == compare is same as is_equivalent_frame()
            return is_equiv
    
        if not is_equiv:
>           raise TypeError(f'cannot compare: objects must have equivalent frames: '
                            f'{self.replicate_without_data()} vs. '
                            f'{value.replicate_without_data()}')
E           TypeError: cannot compare: objects must have equivalent frames: <HeliographicStonyhurst Frame (obstime=2019-06-01T00:00:00.000)> vs. <HeliographicStonyhurst Frame (obstime=2019-12-01T00:00:00.000)>

Because is_equivalent_frame checks all the attrs in this line:

../astropy/astropy/coordinates/sky_coordinate.py:970: in is_equivalent_frame
    if np.any(getattr(self, fattrnm) != getattr(other, fattrnm)):

it will check our observer attribute, but now the != call raises an error instead of just returning False, when self and other are not in the same frame.

I'm not entirely sure what the best way to solve this is. One the one hand, I see conceptually why an error is now raised when trying to compare coordinates in two different frames. On the other hand, I'm not sure how to practically solve this new issue, without making != return True when the two frames are different.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions