Skip to content

(Another) GCRS angular separation behavior #8505

Closed

Description

@kadrlica

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:

from astropy.coordinates import SkyCoord, GCRS, ICRS
from astropy.time import Time

obj = SkyCoord(ra=37.0*u.degree,dec=-4.5*u.degree, distance=3*u.au)
obj_t0 = obj.transform_to(GCRS(obstime=Time(57370.0, format='mjd')))
obj_t1 = obj.transform_to(GCRS(obstime=Time(57380.0, format='mjd')))

print(obj_t0)
print(obj_t1)
print("Obj(t0) RA,DEC: ", obj_t0.ra.deg,obj_t0.dec.deg)
print("Obj(t1) RA,DEC: ",obj_t1.ra.deg,obj_t1.dec.deg)

print(obj_t0.separation(obj_t1))
print(obj_t1.separation(obj_t0))

and the output:

<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.

print("Equivalent frame?",obj_t0.is_equivalent_frame(obj_t1))

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).

Activity

  1. changed the title [-](Another) GCRS angular separation feature[/-] [+](Another) GCRS angular separation behavior[/+] on Mar 16, 2019
  2. fardal commented on Mar 19, 2019

    @fardal
    Contributor

    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.

  3. StuartLittlefair commented on Mar 19, 2019

    @StuartLittlefair
    Contributor

    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_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.cartesian
    repr_t1 = obj_t1.cartesian
    # find the separation between these two vectors using dot product
    sep = np.arccos(repr_t0.dot(repr_t1) / repr_t0.norm() / repr_t1.norm())
  4. kadrlica commented on Mar 19, 2019

    @kadrlica
    ContributorAuthor

    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).

  5. fardal commented on Mar 20, 2019

    @fardal
    Contributor

    @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).

  6. mhvk commented on Mar 20, 2019

    @mhvk
    Contributor

    It may be good to separate needs & wishes a bit. In the above I see three (all useful!):

    1. 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.
    2. 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).
    3. 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.

  7. taldcroft commented on Mar 26, 2021

    @taldcroft
    Member

    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.

  8. mhvk commented on Apr 5, 2021

    @mhvk
    Contributor

    @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)

  9. StuartLittlefair commented on Apr 6, 2021

    @StuartLittlefair
    Contributor

    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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions