Skip to content

Broadcast SkyCoord.spherical_offsets_by #14383

Closed

Description

@evertrol

What is the problem this feature will solve?

I found that offsetting a set of coordinates by the same value, conveniently stored in a single SkyCoord, requires the longitude and latitude values to spherical_offsets_by to be each of the same length. I had hoped that I could give a single offset, and that that would be broadcasted to the entire coordinate array, i.e.

coord = SkyCoord(ra=np.array([123, 134, 145]), dec=np.array([45, 56, 67]), unit=units.degree)
coord.spherical_offsets_by(2*units.degree, 2*units.degree)

would offset each of (123, 45), (134, 56), (145, 67) by 2 degrees east(?) and north.

Instead, this results in a lenghty traceback, somewhat summarised below:

...
ValueError: cannot broadcast a non-scalar to a scalar array
During handling of the above exception, another exception occurred:
...
ValueError: attribute origin should be scalar or have shape (), but it has shape (3,) and could not be broadcast.

I ended up doing

offsets = 2 * np.ones(3) * units.degree
coord.spherical_offsets_by(offsets, offsets)

but I wondere if it's worth implementing some broadcasting mechanism.

Describe the desired outcome

The results would be that

coord1 = SkyCoord(ra=np.array([123, 134, 145]), dec=np.array([45, 56, 67]), unit=units.degree)
coord.spherical_offsets_by(2*units.degree, 2*units.degree)

yields

<SkyCoord (ICRS): (ra, dec) in deg
    [(125.92947215, 46.96384624), (137.76807718, 57.94547037),
     (150.56248577, 68.91058429)]>

Of course, it may be possible I've overlooked something, and doing this wrong.

Alternatively, this may be too niche of a case to add this. Although to me, this fits with standard NumPy broadcasting behaviour for cases like np.arange(5) + 20.

There may be other similar functions / methods that have this non-broadcasting behaviour where it could be relevant. Interestingly, SkyCoord.spherical_offsets_to does appear to show the (expected) broadcasting behaviour.

If deemed useful, I'd be happy to give this a go, although it may be quicker for someone else to implement it.

Additional context

No response

Activity

  1. mhvk commented on Feb 14, 2023

    @mhvk
    Contributor

    I agree this should work but it is not trivial, as internally what is done is:

    return self.__class__(
    SkyOffsetFrame(d_lon, d_lat, origin=self.frame).transform_to(self)
    )

    So, a SkyOffsetFrame is created, with the single coordinate at the origin. That class is not designed to take array-valued origins. That could (and probably should) be changed, but will need some real thought.

  2. added 6 commits that reference this issue on Aug 3, 2023
    3797b5b
    990bdec
    ba38c2e
    aa1989c
    1d45f88
    37cfed6
  3. added 5 commits that reference this issue on Aug 18, 2023
    99035b2
    9081d6a
    2f04b20
    7b82928
    5d84c35
  4. added 3 commits that reference this issue on Sep 30, 2023
    b19fb2a
    1f3a2b6
    33cca6f
  5. added a commit that references this issue on Oct 3, 2023
    00e64a9
  6. tjgalvin commented on Aug 23, 2024

    @tjgalvin

    Hi all -- sorry to be a pain, but is this pulled into a stable main? I see that the current set of docs for spherical_offsets_by suggest it is not. I'm currently using the approach listed in the original post, so not the biggest deal.

  7. pllim commented on Aug 23, 2024

    @pllim
    Member

    Hello, @tjgalvin . This issue was closed by #15121 that was milestoned to v6.0 so it would have been in the stable docs. Can you please clarify what you mean by "current set of docs"? What are the exact URL(s) you are referring to and what do you expect to see? Thanks.

  8. tjgalvin commented on Aug 27, 2024

    @tjgalvin

    This was a user error by yours truly. Sorry for the confusion :S

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