Conversation
|
Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.
|
a692354 to
6e2253d
Compare
|
Example: import numpy as np
from astropy import units as u
from astropy.coordinates import GeocentricTrueEcliptic, SkyCoord
from astropy.time import Time
from astropy.coordinates.erfa_astrom import erfa_astrom, ErfaAstromInterpolator
erfa_astrom.set(ErfaAstromInterpolator(5 * u.min))
n = 1_000_000
obstime = Time("2025-01-01") + np.linspace(0, 2, n) * u.hour
target_coord = SkyCoord(
np.linspace(0, 360, n, endpoint=False) * u.deg,
0 * u.deg,
obstime=obstime,
)
target_coord.transform_to(GeocentricTrueEcliptic(equinox=obstime))Here: on main: |
6e2253d to
349e7ca
Compare
1ff8ef2 to
b95633a
Compare
|
You can ignore the 4 failures in devdeps jobs about |
|
I found a couple of other trafos also using nut06a, would you prefer a separate PR for those or should I add the changes here? |
I have no preference as I am not a coordinates maintainer. I trust your judgement. |
|
@mhvk maybe wants to have a look? |
|
Added the rest of the transforms, little benchmark: import numpy as np
from astropy import units as u
from astropy.coordinates import GeocentricTrueEcliptic, SkyCoord, ICRS, TETE, CIRS, EarthLocation, ITRS, GCRS
from astropy.time import Time
from astropy.coordinates.erfa_astrom import erfa_astrom, ErfaAstromInterpolator
from time import perf_counter
erfa_astrom.set(ErfaAstromInterpolator(5 * u.min))
n = 100_000
t0 = Time("2025-01-01")
obstime = t0 + np.linspace(0, 2, n) * u.hour
combinations = [
(ICRS(), GeocentricTrueEcliptic(equinox=obstime)),
(GCRS(), CIRS()),
(GCRS(), TETE()),
(TETE(), ITRS()),
]
coord = SkyCoord(
np.linspace(0, 360, n, endpoint=False) * u.deg,
0 * u.deg,
obstime=obstime,
)
for from_frame, to_frame in combinations:
from_coord = coord.transform_to(from_frame)
t0 = perf_counter()
to_coord = from_coord.transform_to(to_frame)
t = perf_counter() - t0
print(f"{from_frame.__class__.__name__} -> {to_frame.__class__.__name__}: {t:5.2} s") |
mhvk
left a comment
There was a problem hiding this comment.
@maxnoe - this looks good. Mostly very minor comments, except perhaps to move _precession_nutation_matrix to utils.py so it can be used in all places (at least, if I understood correctly).
Also, a question just to be sure: might it make sense to have _precession_nutation_matrix be on ErfaAstrom? It would break the idea that it interpolates specific erfa routines, though, so I think what you have is better, but I thought I would bring it up anyway...
| jd1, jd2 = get_jd12(time, "tt") | ||
| if rbpn is None: | ||
| # erfa.gst06a calls pnm06a to calculate rbpn and then gst06. Use it in | ||
| # favour of getting rbpn with erfa.pnm06a to avoid a possibly large array. |
There was a problem hiding this comment.
So, I guess we're giving up the "possibly large array" - I think that's OK, just to confirm.
There was a problem hiding this comment.
I think we should maybe also just wrap gst06 directly? That would avoid that
I thought about something similar, basically wrapping all commonly used erfa methods and letting |
This may be used to speedup transformations involving the ``GeocentricTrueEcliptic`` frame for arrays of equinoxes.
c5ad09b to
6debeb7
Compare
| rbpn = erfa_astrom.get().pnm06a(time) | ||
| x, y = erfa.bpn2xy(rbpn) | ||
| s = erfa.s06(*get_jd12(time, "tt"), x, y) | ||
| return erfa.c2ixys(x, y, s) |
There was a problem hiding this comment.
@mhvk Isn't this also just the equivalent of get_cip? I.e. get x, y, s and then transform to the matrix?
I think I will add get_cip then to erfa_astrom directly
|
|
||
| return astrom | ||
|
|
||
| def pnm06a(self, time, return_obl=False): |
There was a problem hiding this comment.
I'm still wavering a bit about whether it makes sense to supply also functions that are not overridden. On the other hand, this one joins the others in that the input is an astropy Time rather than a TT jd1, jd2 pair, and of course in returning the obliquity.
So, overall this seems good.
However, can you just return the obliquity unconditionally? I've slowly been convinced that having the number of outputs depend on inputs is bad form (array API specifically avoids it), and there is no extra calculation involved, so one can just do rnpb, _ = erfa_astrom.get().pnm06a(...). Possibly this means one should give it a different name, though.
| @@ -0,0 +1,11 @@ | |||
| Added ``nut06a`` to ``ErfaAstrom`` and ``ErfaAstromInterpolator`` and | |||
There was a problem hiding this comment.
We need to mention pnm06a (and perhaps remove nut06a, see earlier comment).
More generally I wonder if this is not too much implementation detail. One could also note that when using the interpolator, the true-ecliptic transformations can now be sped up considerably.
This may be used to speedup transformations involving the
GeocentricTrueEclipticframe for arrays of equinoxes.Description
This pull request is to address #20415
Fixes #20415
AI Disclosure
If AI tools were used to develop this pull request, describe the tools including specific model and version, how they were used, and what content is AI generated. Otherwise enter "N/A".
OpenAI Codex using
gpt-6-astrawas used for identifying the particular functions needed to address the performance issue in the example of #20415 and then make the addition ofnut06to theerfa_astrommachinery.I refactored the model output to make it more explicit and direct.
The tests were also written by the model.
Merge method