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
This issue is to report another counter-intuitive behavior of angular separations in the GCRS frame. It follows on similar reports in #5185 and #6633 (and may be of interest to @StuartLittlefair and @adrn).
The basic issue is that an object at fixed ICRS position observed at two different times will have different GCRS coordinates. However, the separation between these GCRS coordinates is calculated to be zero. Here is a MWE:
<SkyCoord (GCRS: obstime=57370.0, obsgeoloc=(0., 0., 0.) m, obsgeovel=(0., 0., 0.) m / s): (ra, dec, distance) in (deg, deg, AU)
(22.02874564, -14.46782793, 2.49351509)>
<SkyCoord (GCRS: obstime=57380.0, obsgeoloc=(0., 0., 0.) m, obsgeovel=(0., 0., 0.) m / s): (ra, dec, distance) in (deg, deg, AU)
(20.38720594, -13.68925892, 2.64894343)>
Obj(t0) RA,DEC: 22.028745635550386 -14.467827929473025
Obj(t1) RA,DEC: 20.387205935596295 -13.689258920287072
0d00m00s
0d00m00s
My understanding is that the frames of obj_t0 and obj_t1 differ (both are GCRS, but at different obstime). Thus, separation is converting the two coordinates to the same obstime, and thus the angular separation is calculated to be zero.
While I'm guessing this is the "correct" behavior, it is definitely counter-intuitive (i.e., when trying to compute parallax corrections for solar system objects).
This is the best version of this general issue yet. "All parallaxes are zero!"
This is an uninformed suggestion, but I wonder if separation should really be a method on a Representation, rather than (or in addition to) a Frame. And if there should be an option to calculate it that way when using higher-level objects like Frame or SkyCoord.
Your diagnosis is spot on in terms of what is happening, that it is correct behaviour, and that it confounds expectation. When using transform_to on a SkyCoord you are getting a pointer to the same position in spacetime but in a different reference frame. SkyCoord.separation is doing the correct thing and returning a separation of zero because all three objects do indeed reference the same point, just in different frames.
However, there are many similar issues of people finding the behaviour of SkyCoord.separation counter intuitive that we really should look at improving the documentation to make this as clear as possible. The other classic example of this is people being surprised that a.separation(b) is not the same as b.separation(a).
I think the documentation could also do with some clear examples that explain the conceptual difference between SkyCoord and Representation objects. What you want in this case is the angle between the representation of the same co-ordinate in two different frames. The code snippet below does what you want neatly, but we should improve the docs so this isn't so confusing. Any advice as to how best to do that is greatly appreciated.
repr_t0=obj_t0.cartesianrepr_t1=obj_t1.cartesian# find the separation between these two vectors using dot productsep=np.arccos(repr_t0.dot(repr_t1) /repr_t0.norm() /repr_t1.norm())
Thanks, glad to hear that this is on the radar. Improving the documentation may be a challenging solution. This operation seems intuitive, and I don't think that users are generally going to look for documentation before they try something like the example above. One idea could be to print a warning if a and b are the same, or if they are in different reference frames. However, I don't know the astropy policy on warnings (don't want to flood the user).
With regards to getting the angular separation value that I was interested in, I chose to use the lower-level angle_utilities.angular_separation with the spherical representations of each coordinate (i.e., following the source code for SkyCoord.separation, but without transforming the frames).
@StuartLittlefair your code snippet might be a useful temporary workaround, but I hope it's not intended as the permanent standard method to compute the desired quantity here. I would much prefer to use repr_t0.separation(repr_t1). Or, something likeobj_t0.separation(obj_t1, representation=True).
It may be good to separate needs & wishes a bit. In the above I see three (all useful!):
SkyCoord.separation probably needs better documentation, to point the reader the fact that SkyCoord are treated as given points in space time, and in that context separation is meaningful only at a given time.
Something like a tutorial perhaps on how to deal with multiple measurements at different times, and, say, fit a single SkyCoord to them (i.e., inferring position, proper motion, parallax).
A new method or function that calculates separation/position angle, etc. for representations.
p.s. I don't think we should change SkyCoord.separation itself, or add a keyword argument to let it do something quite different conceptually.
This has come up again on the main AstroPy mailing list. Would it be useful to issue an AstropyUserWarning whenever the frames are different? The warning could briefly indicate a potential problem and provide a link to a documentation page that explains the issue in detail with a nice example.
@eteq, @adrn and I are wondering if it wouldn't be best to just raise an exception if the frames are not identical: it can be an origin that is different at the same time or different times with the same origin. Obviously, the exception message could then clarify things. (See also #11388)
I'd be in favour of raising an exception, but we should certainly deprecate this usage first, as this will break a lot of code in the wild, and people should get some warning...
Activity
[-](Another) GCRS angular separation feature[/-][+](Another) GCRS angular separation behavior[/+]fardal commentedon Mar 19, 2019
This is the best version of this general issue yet. "All parallaxes are zero!"
This is an uninformed suggestion, but I wonder if
separationshould really be a method on a Representation, rather than (or in addition to) a Frame. And if there should be an option to calculate it that way when using higher-level objects like Frame or SkyCoord.StuartLittlefair commentedon Mar 19, 2019
Thanks @kadrlica
Your diagnosis is spot on in terms of what is happening, that it is correct behaviour, and that it confounds expectation. When using
transform_toon aSkyCoordyou are getting a pointer to the same position in spacetime but in a different reference frame.SkyCoord.separationis doing the correct thing and returning a separation of zero because all three objects do indeed reference the same point, just in different frames.However, there are many similar issues of people finding the behaviour of
SkyCoord.separationcounter intuitive that we really should look at improving the documentation to make this as clear as possible. The other classic example of this is people being surprised thata.separation(b)is not the same asb.separation(a).I think the documentation could also do with some clear examples that explain the conceptual difference between
SkyCoordandRepresentationobjects. What you want in this case is the angle between the representation of the same co-ordinate in two different frames. The code snippet below does what you want neatly, but we should improve the docs so this isn't so confusing. Any advice as to how best to do that is greatly appreciated.kadrlica commentedon Mar 19, 2019
Thanks, glad to hear that this is on the radar. Improving the documentation may be a challenging solution. This operation seems intuitive, and I don't think that users are generally going to look for documentation before they try something like the example above. One idea could be to print a warning if
aandbare the same, or if they are in different reference frames. However, I don't know the astropy policy on warnings (don't want to flood the user).With regards to getting the angular separation value that I was interested in, I chose to use the lower-level
angle_utilities.angular_separationwith the spherical representations of each coordinate (i.e., following the source code forSkyCoord.separation, but without transforming the frames).fardal commentedon Mar 20, 2019
@StuartLittlefair your code snippet might be a useful temporary workaround, but I hope it's not intended as the permanent standard method to compute the desired quantity here. I would much prefer to use
repr_t0.separation(repr_t1). Or, something likeobj_t0.separation(obj_t1, representation=True).mhvk commentedon Mar 20, 2019
It may be good to separate needs & wishes a bit. In the above I see three (all useful!):
SkyCoord.separationprobably needs better documentation, to point the reader the fact thatSkyCoordare treated as given points in space time, and in that context separation is meaningful only at a given time.SkyCoordto them (i.e., inferring position, proper motion, parallax).p.s. I don't think we should change
SkyCoord.separationitself, or add a keyword argument to let it do something quite different conceptually.taldcroft commentedon Mar 26, 2021
This has come up again on the main AstroPy mailing list. Would it be useful to issue an
AstropyUserWarningwhenever the frames are different? The warning could briefly indicate a potential problem and provide a link to a documentation page that explains the issue in detail with a nice example.mhvk commentedon Apr 5, 2021
@eteq, @adrn and I are wondering if it wouldn't be best to just raise an exception if the frames are not identical: it can be an origin that is different at the same time or different times with the same origin. Obviously, the exception message could then clarify things. (See also #11388)
StuartLittlefair commentedon Apr 6, 2021
I'd be in favour of raising an exception, but we should certainly deprecate this usage first, as this will break a lot of code in the wild, and people should get some warning...