You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
At the moment, one cannot compare whether frames are equivalent:
In [1]: from astropy.coordinates import FK5
In [2]: FK5(equinox='J2000') == FK5(equinox='J2010')
Out[2]: False
In [3]: FK5(equinox='J2000') == FK5(equinox='J2000')
Out[3]: False
It would be nice to have a way to check that all frame attributes are the same. Now == may be ambiguous because for frames with data this is not as well defined (are we comparing the frame attributes or the data? what if the data is a vector?).
Maybe the solution is to disable straight-off comparisons like the ones above but to instead have a method or function to check if two frames are the same (excluding data)?
At some level strict equality seems like relatively unambiguous even with data. For reference there is #2154 and #2650.
What about doing the following:
Compare all defined attributes, including the frame class and representation. All must be exactly equal.
If neither frame has data, then return a boolean with the equality of attributes.
If one frame has data and other doesn't then return False.
If both frames have data and attributes are equal, then return a np boolean array (or scalar) with the per-element equality.
As we have discussed, if you have data then in most cases what you really want is a coordinate allclose, but for the == operator perhaps this definition works as a catch-all in all cases. It is possible (likely) that if you start from a coordinate and do some round-trip transformation that the result may fail at equality, but that is just the way it goes with numerical equality of floats.
We might relax a bit and change the representation of the right side to match that of the left before comparing data. I think that would allow for equality where the only change between left and right was a representation change. Again, if small floating point diffs make for inequality that's not our problem.
As @taldcroft mentioned, I think this is a duplicate of #2154, but I think the discussion here is more relevant now, so I'm going to close the other issue. I'm working on this now. It turns out we don't have a way to compare representations, so I need to start there...
Looking at this again, maybe we also want a coordinates.allclose function with sensible defaults? Then equality is strict equality but there is a way to allow allclose matching of the data (again require strict equality of frame attributes). Also allclose might make the representation of left and right be the same while == would not.
👍 on implementing frame comparison since it is a pre-requisite for a conservative implementation of coordinate setitem. 😄 In other words, first thing you do for setting is make sure the left and right side frames are exactly the same, then setting the data from right will be fine (need to clear any caches of course, etc).
In #6888 , I implemented the code from the previous comment as a new function skycoord_equal that is used for testing. Any interest in bringing something like this into coordinates proper?
I have no idea if this works for coordinates with velocities. I do think that a strict equality comparison is a useful and well-defined thing for coordinates, basically the objects are the same at the bit level. This is different from an isclose kind of comparison.
I'm in favour of testing for equality checking - as you say, it is well-defined. I do think we need to think a bit about what to return if frames or representations do not match. Here, python and numpy seem to be diverging, sadly (though also understandably), with python never allowing == to fail. In particular, if, e.g., the shapes can be broadcast but frames and/or representation types do not match, should one return an array of False, or just False, or raise an error?
I (AGAIN) ran into this problem (or a slight variant)
In [10]: sc = SkyCoord([1,2], [3,4], unit='deg')
In [11]: sc2 = SkyCoord([1,2], [3,4], unit='deg')
In [12]: sc == sc2
Out[12]: False
This really should return a bool array of True since the objects are the same down to the bit level, not a scalar Python False.
Would there be any interest (for 4.0) in issuing a FutureWarning that SkyCoord (or Frame) __eq__ will be fixed to respect the shape of the object? This idea has been tossed about for at least 5 years now, and the problem of testing for equality at the bit level is not insurmountable (I think??).
Activity
embray commentedon Dec 8, 2014
I think it should just compare the frame attributes, not the data. But that's just me.
taldcroft commentedon Dec 9, 2014
At some level strict equality seems like relatively unambiguous even with data. For reference there is #2154 and #2650.
What about doing the following:
As we have discussed, if you have data then in most cases what you really want is a coordinate
allclose, but for the==operator perhaps this definition works as a catch-all in all cases. It is possible (likely) that if you start from a coordinate and do some round-trip transformation that the result may fail at equality, but that is just the way it goes with numerical equality of floats.We might relax a bit and change the representation of the right side to match that of the left before comparing data. I think that would allow for equality where the only change between left and right was a representation change. Again, if small floating point diffs make for inequality that's not our problem.
adrn commentedon Sep 19, 2017
As @taldcroft mentioned, I think this is a duplicate of #2154, but I think the discussion here is more relevant now, so I'm going to close the other issue. I'm working on this now. It turns out we don't have a way to compare representations, so I need to start there...
taldcroft commentedon Sep 21, 2017
Looking at this again, maybe we also want a
coordinates.allclosefunction with sensible defaults? Then equality is strict equality but there is a way to allowallclosematching of the data (again require strict equality of frame attributes). Alsoallclosemight make therepresentationof left and right be the same while==would not.👍 on implementing frame comparison since it is a pre-requisite for a conservative implementation of coordinate setitem. 😄 In other words, first thing you do for setting is make sure the left and right side frames are exactly the same, then setting the data from right will be fine (need to clear any caches of course, etc).
taldcroft commentedon Dec 21, 2017
I ran into this problem (or a slight variant) again today:
This really should return a bool array of
Truesince the objects are the same down to the bit level.What about this:
[EDIT] - I wrote this thinking SkyCoord, but I think this can be in baseframe just like this.
taldcroft commentedon Feb 7, 2018
In #6888 , I implemented the code from the previous comment as a new function
skycoord_equalthat is used for testing. Any interest in bringing something like this into coordinates proper?I have no idea if this works for coordinates with velocities. I do think that a strict equality comparison is a useful and well-defined thing for coordinates, basically the objects are the same at the bit level. This is different from an
isclosekind of comparison.@eteq @mhvk @adrn
mhvk commentedon Feb 7, 2018
I'm in favour of testing for equality checking - as you say, it is well-defined. I do think we need to think a bit about what to return if frames or representations do not match. Here, python and numpy seem to be diverging, sadly (though also understandably), with python never allowing
==to fail. In particular, if, e.g., the shapes can be broadcast but frames and/or representation types do not match, should one return an array of False, or just False, or raise an error?astrojuanlu commentedon Sep 3, 2018
Notice that
is_equivalent_frameis not always correct, see #7793.[-]Feature request: frame comparison[/-][+]Improve frame comparison[/+]astrojuanlu commentedon Feb 10, 2019
To update my previous comment, this still stands but #7793 was fixed.
taldcroft commentedon Oct 25, 2019
I (AGAIN) ran into this problem (or a slight variant)
This really should return a bool array of
Truesince the objects are the same down to the bit level, not a scalar PythonFalse.Would there be any interest (for 4.0) in issuing a FutureWarning that SkyCoord (or Frame)
__eq__will be fixed to respect theshapeof the object? This idea has been tossed about for at least 5 years now, and the problem of testing for equality at the bit level is not insurmountable (I think??).