astropy: Frame representation is not respected when instanced using a representation

Yes, the title of this issue is awful… Please feel free to edit for clarity.

When I instance a frame using a subclass of BaseRepresentation as the container of the data (instead of passing the data directly to the initializer of the frame), I would expect the representation of the frame to be the one I used, but it’s not:

In [3]: GCRS(CartesianRepresentation(*iss.r))
Out[3]: 
<GCRS Coordinate (obstime=J2000.000, obsgeoloc=( 0.,  0.,  0.) m, obsgeovel=( 0.,  0.,  0.) m / s): (ra, dec, distance) in (deg, deg, km)
    ( 281.73052421,  51.41284322,  6774.76995296)>

In [4]: _.representation
Out[4]: astropy.coordinates.representation.SphericalRepresentation

Is there a reason for this? I’m aware that there are other ways to instance a frame though, which behave differently:

In [5]: GCRS(x=iss.r[0], y=iss.r[1], z=iss.r[2], representation="cartesian")
Out[5]: 
<GCRS Coordinate (obstime=J2000.000, obsgeoloc=( 0.,  0.,  0.) m, obsgeovel=( 0.,  0.,  0.) m / s): (x, y, z) in km
    ( 859.07256, -4137.20368,  5295.56871)>

In [6]: GCRS(x=iss.r[0], y=iss.r[1], z=iss.r[2], representation=CartesianRepresentation)
Out[6]: 
<GCRS Coordinate (obstime=J2000.000, obsgeoloc=( 0.,  0.,  0.) m, obsgeovel=( 0.,  0.,  0.) m / s): (x, y, z) in km
    ( 859.07256, -4137.20368,  5295.56871)>

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 17 (17 by maintainers)

Commits related to this issue

Most upvoted comments

Yup, in principle. In practice, it’s a bit more tricky: the transformed frames are currently instantiated via .realize_frame(), which has no way to pass in the representation_type. Unless that is changed, I’ll need to either switch to the private ._replicate() or change the representation_type after instantiation.

I was using ._replicate() in poliastro for this exact reason, which I reported in #7784. Seems like we’re converging 🙂 Let us tackle that one first, so we can pave the way to the changes we propose here, if we all agree.

These examples do worry me a bit - there is a bit of a mix between telling how to display and how to interpret input in the current scheme.

I agree, and in fact after going over #4903 and #6184 again to try to gather some context, I think there are three aspects to consider:

  1. How to interpret input in the frame initializer (i.e. what **kwargs to accept, using representation_type and the corresponding keys of .representation_component_names)
  2. How to store frame ._data (i.e. how the frame attributes are transformed to representation attributes using the .representation_component_names mapping)
  3. How to display frame ._data (i.e. how the representation attributes are again transformed to frame attributes using the .representation_component_names inverse mapping in ._data_repr())

I’ll scratch my head a little bit more and see if I can find a solution to this long standing annoyance that is not too disruptive with current code.

Actually, checking further, representation_type seems to be used just for repr - setting it changes what is shown and what attributes the frame has, but it does not affect .data. That said, a simple fix for the repr issue would be that, if a representation is passed in, the code sets the self._representation private attribute.

EDIT: ah, now see the link the #10253 - seems like the fix should not be difficult.