Repository navigation
Conversation
|
(Now posting in the right thread... Sorry) @ayshih - this looks very promising indeed! I'll try to bring in @eteq and @adrn again, as I realize now we did in fact have a discussion about some of this when the proper motions were first implemented, and how to handle transformations to a different obstime was explicitly left as a to-do item - see #6280. Not dealing with it has left us in a fine mess... Your approach of having a context manager may well be the most sensible, and I certainly like in this PR that it seems to properly identify the cause by making explicit the previously implicit ICRS->BCRS transformation. |
| return transform_propagator.get().propagate(icrs_coo, bcrs_frame.obstime) | ||
| else: | ||
| data = icrs_coo.data | ||
| if data.isscalar and not bcrs_frame.obstime.isscalar: |
There was a problem hiding this comment.
Yikes! This probably is the best argument yet for allowing attributes that have a bigger shape than the data, and then just broadcasting the data - but almost certainly best not in this PR! See #8819 for an earlier issue about this. I think we should fix this in the initializer...
mhvk
left a comment
There was a problem hiding this comment.
With a bit more of a closer look, it seems obvious we need BCRS, but I am wondering whether we are not sticking too much in the context manager. Shouldn't the SkyCoord itself carry information on whether it is "solar system" or not? It seems to me boils down mostly on what one really means by obstime (this partially reflects perhaps that even horizons turned out to have multiple options, and one question would be whether we can solve this with coordinate attributes (perhaps with my suggestion of obsgeoloc gaining the ability to mean "body itself", or a new attribute; it does feel some of this we've just been dealing with for the new SpectralCoord as well...)
Also, a perhaps stupid question, but is ICRS even useful for solar system, or is it really just BCRS that is needed in the first place? It would seem that a position without a time would be nearly meaningless for solar system objects.
| if 's' in icrs_coord.data.differentials: | ||
| dt = (to_time - self.ref_epoch).to(u.yr) | ||
| log.debug(f"Propagating forward by {dt} after {self.ref_epoch}") | ||
| result = SkyCoord(icrs_coord).apply_space_motion(dt=dt).frame |
There was a problem hiding this comment.
For now, an implementation detail, but clearly apply_space_motion needs to become a standalone function that can be used here, so we do not have to initialize a SkyCoord.
There was a problem hiding this comment.
Agreed. I've added some TODO comments so that it doesn't get forgotten.
| cartrep = _get_apparent_body_position(body, time, ephemeris, obsgeoloc) | ||
| icrs = ICRS(cartrep) | ||
| gcrs = icrs.transform_to(GCRS(obstime=time, | ||
| bcrs = BCRS(cartrep, obstime=time) |
There was a problem hiding this comment.
This in itself would seem to prove the use of adding BCRS!
|
You are definitely on the right track here. I would suggest that you iterate on the light time delay in The time scale here should properly be Again, you may achieve greater accuracy by expressing this as:
I agree that it might be easier for the user to figure out how to do this if the relevant information could be specified when instantiating an ICRS |
I shouldn't need to. The If it doesn't exactly reverse, then I've messed up the math. |
|
Thanks @ayshih this does look very promising and necessary! I'll ping @eteq on Slack to see if he can dig in to the details here, as he is more of an expert on this (I understand the general concepts but never have to deal with these things in practice in my own work). One minor comment: The context manager approach is clever, but feels a little awkward to me. However, I haven't thought of another idea that would work with the current transformation framework, so fine to ignore this comment for now! |
|
Nice work @ayshih ! I very much like the inclusion of an explicit BCRS frame and hope to find time to look at the detailed code. In the meantime though, there's one minor suggestion, and an awkward point raised by your inclusion. First - minor issue - the docstring for the The awkward point is that, according to the sofa docs the transform from |
|
@StuartLittlefair - our transformations do go through BCRS for any code that relies on SOFA. The problem is that when we included proper motions, a decision was made to not propagate those by default, i.e., they are explicitly left out in the transformation chain (which you pointed out already then was a mistake, but at the time the result was that we raised an issue - #6280 - that we ended up just forgetting about...). My feeling is still that somehow we have to be able to let the |
|
@mhvk I don't think they do, and they won't under this PR either. If I define a SkyCoord (frame is ICRS) with proper motion, parallax etc, then the transform to (e.g.) GCRS should be ICRS->BCRS->GCRS. However, this PR leaves the direct ICRS->GCRS transform in the transform graph (using the function icrs_to_gcrs. That will be the shortest route from ICRS to GCRS and so the following code would bypass BCRS entirely. # coo is an ICRS SkyCoord with proper motion, parallax etc
coo.transform_to(GCRS(obstime=Time("J2015.5")))At the moment, and still under this PR as it stands, if you want true GCRS you'd have to do |
|
@StuartLittlefair - sorry, I was unclear - I didn't mean we could just use our current transformation, but that since they rely on sofa anyway, we can change them such that they take proper motion into account as needed. In the example function you pointed to, it would mean changing the call to Though obviously how to give a choice is the crux of the problem... Do we need an |
|
@mhvk I see what you mean. We could keep the direct ICRS->GCRS step in place, but update all transforms out of ICRS to include space motion. It seems simpler to have one transform that implements the space motion correction (ICRS->BCRS) and make BCRS the only route in and out of ICRS. This might be slower though. As for how to give a choice about how this is handled to the user; this is really hard. Remember that frames can also use these transforms, so an implementation should work for frames and skycoords. I also think it is desirable to allow SkyCoords to have a mixture of solar system objects and stellar objects, and transform them to a single BCRS object correctly. The use case I have in mind is my own robotic telescope scheduler; we have a vectorised SkyCoord object containing all the targets for a night, and we mix and match SS objects with stars! |
|
@StuartLittlefair - nice telescope, it sounds like! For that, though, I think you'd want any proper motions on stars properly propagated (just in case Barnard's star is on the list...). I.e., would it be a problem if all entries were propagated? |
|
No, it would be perfect. |
|
I'm not sure why anyone would not want to apply space motion as the result would be the incorrect position of the star on the date of observation. |
|
I've been thinking a fair bit about this challenge of how to choose which propagation method to apply to I keep coming back to @mhvk 's comment that the I believe the solution to this is to add attributes to The presence of stellar motion attributes (proper motion, rvs) would indicate a ICRS <--> BCRS transform using Support for currently non-supported solar system bodies could be added to |
|
(aside:) a consistent implementation of
|
|
Since in a way we're discussing different classes of objects which behave slightly differently, another option would be to introduce a different class to represent them, i.e., define a |
|
I'm keener on retaining SkyCoord for both - Although it's never been clearly defined I've always felt that SkyCoord represents a thing at a particular point and time. It might be a lot of work to introduce a new class, and they would behave identically apart from the method used to progopate coords between obstimes I guess? For stars I think we should always apply space motion for transforms out of ICRS. Arguably it is a bug that we do not. If we allow this as an option, the default should definitely be true... |
|
Yes, agreed it is a bug not to apply motion... On the solar-system vs star case, I think the main thing I would like to avoid is to have a decision be made just on distance (though fine if that informs the default!). I slightly prefer the subclass since it is for different objects, and while for stars only one type of behaviour seems to make sense, for solar system objects it seems less clear whether there is only one type (but I realize in part I still do not fully understand what is needed!). Anyway, at some level these are just implementation details. One more concrete suggestion, though, would be to break up the work in smaller pieces. E.g., first correct the star case (which I think is relatively easy) and only then add the solar-system pieces. |
|
Coming back to this (sorry for the sporadic involvement). I think we need to resolve the sub-class/attribute question as a first step. An attribute would (in principle) allow a vector SkyCoord to contain a mix of object types, so it would be my preference. Once that is decided, we could split the work into the following steps?
|
|
The list sounds good. I'm still slightly in favour of a subclass as I think it cleaner and I suspect there may be other behaviour for which some special methods would make a lot of sense for solar-system objects and not so much for sky coordinates. But it is only a mild preference (i.e., as far as I'm concerned, whoever does the work gets to decide!). For an attribute, it does seem to be asking for trouble if we were to allow a mix in a single |
|
I was thinking of someone trying to do - for example - a lot of Alt/Az calculations with a mix of targets (stellar and planetary). Even for that use case though you could always split your targets into two batches. As you say, allowing that mix sounds problematic. Thinking of the issues you've seen with |
|
@mkbrewer - Isn't this PR trying to solve the problem that we don't have a frame to represent solar system objects at an absolute time? As I mentioned, I think "ICRS" for solar system bodies effectively becomes that given the transformation at https://github.com/astropy/astropy/pull/10404/files#diff-86311e5590ca8c380eae0e346fdc47e0736e57601f5e4decc5ab6f5fbd2e7d83R125-R147. More generally, wouldn't it be useful to have this option as part of the transformation network instead of having the custom |
|
@mhvk There are several aspects to this. First we need to settle on exactly what we mean by a BCRS frame. I would suggest that this represents the ICRS aligned position of the object referred to the SSB, adjusted for space motion (not parallax as that is within the purview of the astrometric frame) and light time to the observer. Second, we need to settle on how to realize this frame. In that regard, it seems to me that there are three classes of objects:
For the third class of objects, I say that the reference epoch must be within a few days of Now the problem becomes simply how to properly identify each class of object in order to realize its position in the BCRS frame at
For the first class of objects, the realization would be
I would tend to call |
|
@mkbrewer - thanks! Agreed with needing some way to distinguish at least between objects with ephemerides and those with only velocities, and, between the latter, between close and distant ones (perhaps simply based on how much the velocity over a given amount of time changes the fractional position). I'm tending towards subclasses, but an attribute may end up being better - actually, the distinguishing attribute itself could be On |
|
Some targeted comments:
When I also suggested "transient phenomena", I had specifically in mind coronal mass ejections (CMEs). The "object" could be the 3D position/velocity of the peak of the erupting magnetic flux rope. A Keplerian propagator wouldn't be physically accurate in this case, although in truth it may not be appreciably worse than a linear propagator.
I disagree with the notion that Astropy's I don't know of any place where the current transformation framework has a notion of J2000 with
Why do you want an Astropy BCRS to account for light time to the observer? And you want the observer to not necessarily be the SSB, so the frame would have an observer frame attribute? Why not defer it to a more observer-aware astrometric frame (e.g., what I tried to do in #10372)?
No, you're correct:
I support having some sort of meeting to hash this all out, as I think there are still a lot of details to achieve consensus on. |
|
@ayshih Thanks for chiming in on this. I was beginning to think that only @mhvk was interested.
Because, that is how it is currently handled. In this PR, you have modified I agree that this means that both BCRS and astrometric need to be aware of the observer's position. The alternative is to skip BCRS and go straight to astrometric.
Is this really true? If one defines a
I'm not really understanding this. If the frame's origin and axes are defined by
Well, we are talking about using SOFA's distinction here to distinguish between ICRS and BCRS. For solar system bodies, one could imagine backing out the light time delay and calling that the ICRS position, but this would only be valid at |
|
Actually, backing out the light time delay for a solar system object and calling that the ICRS position is a perfectly reasonable thing to do. This would imply adding a reference epoch to the ICRS frame as I stated here:
|
|
Basically, |
|
@ayshih, @mkbrewer - We may all be fairly aligned. But perhaps it still is helpful to be even clearer about what is needed. In terms of implementation, I think there are actually two items: 1. how positions are defined, and 2. how they are transformed.
|
|
@mhvk I'm not sure where you came up with |
|
@mkbrewer - The transformations I'm not as clear about, though it seemed to me that for a given But really it was mostly about implementation, for which it seems important to recognize that the planetary ephemerides are given in terms of locations at some absolute time, while the stellar ones are given in terms of positions as observed at the SSB. But when you mentioned p.s. Just a heads up: feature freeze for astropy 4.2 is close, so expect (even) slower responses than usual! |
|
Since this PR has been been mentioned elsewhere twice today, I thought I should affirm that I haven't abandoned this effort, and I'm continuing to mull over ways to proceed. My minor epiphany recently has been that we shouldn't be trying to treat stars and solar-system bodies differently, but rather we should be treating them the same (cf. @mhvk's mention of Barnard's star). The API should instead distinguish between apparent locations and true locations. I've been tinkering on possible API approaches, which may include some breaking changes to |
|
Well, they are somewhat different as, in the case of stars, proper motion and radial velocity are applied, while for planets, a new ephemeris lookup is required. |
|
@ayshih - sounds good! I think it will also (continue to) be good to try to break things up in small pieces - e.g., first just doing proper motion and velocity, and worrying about full ephemerides later. E.g., just having |
|
Well, you can't do a BCRS[t1]->BCRS[t2] transform without looking up the position of a planet at the new time. This gets back to the idea of having a new attribute on the |
|
@mkbrewer - absolutely! And it is not that I wouldn't want to deal with planets, but rather that I'd like to break things up in pieces, and deal with the simple ones first! |
|
Here is yet another reason to implement an astrometric frame: #11701 (comment) |
|
And another: #11755 (comment) |
|
Hi humans 👋 - this pull request hasn't had any new commits for approximately 1 year, 3 months. I plan to close this in 30 days if the pull request doesn't have any new commits by then. In lieu of a stalled pull request, please consider closing this and open an issue instead if a reminder is needed to revisit in the future. Maintainers may also choose to add keep-open label to keep this PR open but it is discouraged unless absolutely necessary. If this PR still needs to be reviewed, as an author, you can rebase it to reset the clock. If you believe I commented on this pull request incorrectly, please report this here. |
|
Hi humans 👋 - this pull request hasn't had any new commits for approximately 1 year, 3 months. I plan to close this in 30 days if the pull request doesn't have any new commits by then. In lieu of a stalled pull request, please consider closing this and open an issue instead if a reminder is needed to revisit in the future. Maintainers may also choose to add keep-open label to keep this PR open but it is discouraged unless absolutely necessary. If this PR still needs to be reviewed, as an author, you can rebase it to reset the clock. If you believe I commented on this pull request incorrectly, please report this here. |
|
Ops, sorry for the double bot post. Hopefully I fixed the bug upstream. |
|
I'm going to close this pull request as per my previous message. If you think what is being added/fixed here is still important, please remember to open an issue to keep track of it. Thanks! If this is the first time I am commenting on this issue, or if you believe I closed this issue incorrectly, please report this here. |

This PR is a wholly different approach to achieve similar aims as #10372 (see also #10230). Ping @mhvk @mkbrewer
Currently, the transformations between ICRS and {CIRS, GCRS, HCRS} do not account for space motion. This PR introduces a BCRS coordinate frame, which is simply the ICRS coordinate frame with an
obstime. The existing transformations between ICRS and {CIRS, GCRS, HCRS} have been switched to be between BCRS and those frames. To apply space motion as part of the transformation framework, the ICRS<->BCRS transformations can be modified using a "propagator", which is specified via aScienceState(so can be set globally or can be used as a context manager). This PR provides two propagators:LinearPropagator: all objects are propagated assuming linear motion for the difference in time between the observation time and the specified reference epoch (basically a wrapper toSkyCoord.apply_space_motion())SolarSystemLinearPropagator: works likeLinearPropagatorfor objects farther than 1 light-year of the solar-system barycenter; closer objects are treated as solar-system bodies and propagated backwards in time to account for light travel time (i.e., "planetary aberration")The intent is to allow for adding more propagators in the future that, for example, include ephemeris look-ups.
There's currently no documentation/tests in the PR, but here are some examples for discussion/feedback:
A star
Venus
Thoughts?