Skip to content

SkyCoord.replicate returns underlying BaseFrame type, not SkyCoord #15643

Open

Description

@maxnoe

Description

The SkyCoord.replicate method returns an instance of the underlying frame type, forgetting any stored attributes not part of that frame.

Expected behavior

Returns SkyCoord instace with changed frame attributes, keeping original attributes not overwritten.

How to Reproduce

from astropy.coordinates import SkyCoord, AltAz
from astropy.time import Time

coord = SkyCoord(alt=5, az=10, frame=AltAz())
replica = cord.replicate(obstime=Time.now())
print(type(coord))
print(type(replica))
<class 'astropy.coordinates.sky_coordinate.SkyCoord'>
<class 'astropy.coordinates.builtin_frames.altaz.AltAz'>

Versions

Linux-5.14.0-1051-oem-x86_64-with-glibc2.35
Python 3.11.6 | packaged by conda-forge | (main, Oct 3 2023, 10:40:35) [GCC 12.3.0]
astropy 5.3.4
Numpy 1.26.0
pyerfa 2.0.1.1
Scipy 1.11.3
Matplotlib 3.8.2

Activity

  1. eerovaher commented on Nov 23, 2023

    @eerovaher
    Member

    SkyCoord class has no replicate() method. SkyCoord instances expose the replicate() method of their underlying frame, just like how they expose many other methods and attributes.

  2. mhvk commented on Nov 24, 2023

    @mhvk
    Contributor

    Hmm, that's pretty bad, SkyCoord should not have exposed that, or, arguably better, implement its own replicate.

    I guess generally one might expose all attributes, but probably should be more selective with methods.

    Aside: it is slightly unfortunate that astropy has replicate and copy instead of copy and deepcopy, resp., but I fear that ship has sailed.

  3. nstarman commented on Nov 24, 2023

    @nstarman
    Member

    Aside: it is slightly unfortunate that astropy has replicate and copy instead of copy and deepcopy

    We also have clone!

    but I fear that ship has sailed.

    When Cosmology becomes a dataclass I'm planning to deprecate the .clone method in favor of replace, which is the dataclasses library standard and suggestion. The .clone method will just be a deprecated alias of replace that'll stick around for a good long while.

    We can do the same for all the other miscellaneous implementations!

  4. ayshih commented on Nov 24, 2023

    @ayshih
    Contributor

    Hmm, that's pretty bad, SkyCoord should not have exposed that, or, arguably better, implement its own replicate.

    SkyCoord having its own replicate() makes a lot of sense, since otherwise there's no way to perserve attributes that are not used for the particular frame. I'll note that it creates a bit of non-parallelism if replicate_without_data() is still exposed, because the output of that method cannot be a SkyCoord. (That is, it's unfortunate the name of that method didn't happen to be something like replicate_only_frame().)

    I guess generally one might expose all attributes, but probably should be more selective with methods.

    I'll point out that sunpy has multiple frame-specific methods and properties (beyond the frame attributes) that are defined on frame subclasses, and it's convenient that they are automatically exposed as methods and properties of corresponding SkyCoord instances. It wouldn't be a huge deal to educate users to call coord.frame.whatever() instead of coord.whatever(), but some internals might need to do more SkyCoord/not-SkyCoord checking. It may also have users thinking more about the implementation than they need to be.

    Aside: it is slightly unfortunate that astropy has replicate and copy instead of copy and deepcopy, resp., but I fear that ship has sailed.

    I imagine that the vast majority of calls to replicate() are to change the value of at least one frame attribute. As such, copy()/deepcopy() are not great analogies, but as mentioned by @nstarman, the dataclasses replace() would be.

  5. nstarman commented on Dec 4, 2024

    @nstarman
    Member

    Aside: it is slightly unfortunate that astropy has replicate and copy instead of copy and deepcopy, resp., but I fear that ship has sailed.

    #16887!

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