Fix the nutation in the true-of-date <-> J2000 transform used by the astrometric kernels - #989
Open
Cybis320 wants to merge 2 commits into
Open
Fix the nutation in the true-of-date <-> J2000 transform used by the astrometric kernels#989Cybis320 wants to merge 2 commits into
Cybis320 wants to merge 2 commits into
Conversation
…astrometric kernels equatorialCoordAndRotPrecession (used by pointingCorrection, i.e. by every XY <-> RA/Dec projection) applied nutation incorrectly: the nutation in longitude was a rotation about the equatorial pole instead of the ecliptic pole, and both nutation rotations were applied after the precession to J2000 rather than removed in the frame of date. Against the IAU 2006/2000A model (erfa) the transform was off by 3-32 arcsec depending on date and direction, following the 18.6-year nutation cycle (near zero in 2024, ~15" now, ~34" in 2029). The mean precession itself (equatorialCoordPrecession) is accurate to 0.08". The nutation is now the standard rotation N = R1(-(eps+deps)) R3(-dpsi) R1(eps) built from the existing 4-term series (Meeus), removed at the start epoch and applied at the final epoch, with J2000 treated as the mean catalog frame. The position-angle change is computed from a north vector transported through the same rotation, which is the exact geometric statement that a gnomonic projection defined in one frame is the same projection in the other. The J2000 <-> alt/az converters (cyTrueRaDec2ApparentAltAz, cyApparentAltAz2TrueRADec) now use the same true-of-date transform through two new helpers, trueOfDateFromJ2000 and j2000FromTrueOfDate, so the code has one frame convention; before, they applied no nutation at all and disagreed with the kernel by up to ~30". pointingCorrection is made cpdef so it can be tested from Python. The cyjd2LST docstring is corrected: it returns mean, not apparent, sidereal time (the equation of the equinoxes, ~1", is not applied anywhere). Verified against erfa: transform within 0.2" (series-limited), round trips to 0.01", position-angle change within 0.5" of the exact geometry, and a fixed camera's kernel centre within 2" of the true direction with no drift over a night. Recalibrating a real night (USV001 2026-09-05, 217 FFs) with the old and new kernels gives identical star residuals (0.159 px both); only the fitted RA_d/dec_d/pos_angle_ref move, by a few arcsec in pointing and +14" in rotation, as expected. Because the error was a small rigid rotation of the sky that the star fit absorbed into RA_d, dec_d and pos_angle_ref, measured positions relative to the stars were never affected. The fitted parameters of existing platepars, however, compensate for the old transform: applied with the new kernel without refitting they are off by the same few arcsec to a few tens of arcsec until the next fit, which the nightly recalibration does automatically. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CzZHCZoftFjV712njkWB5v
…pixels A camera fixed in alt/az, referenced at the start of the night, is followed for 8 hours on a 9 x 7 pixel grid over an 82 x 46 deg frame, at two pointings and five dates from 2021 to 2029. The kernel's XY -> J2000 is compared with erfa (GAST rotation, IAU 2006/2000A precession-nutation), and the error field is split into the centre error, the rigid roll about the line of sight and the non-rigid remainder. Everything stays within 0.5", the roll within 0.3" and the non-rigid part within 0.1". The centre alone cannot see a rotation or scale error; the corners can. The old transform drifts by up to 11" in position and 11" in roll over a night on this test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CzZHCZoftFjV712njkWB5v
Cybis320
added a commit
that referenced
this pull request
Sep 6, 2026
…d geodetic kernels Follows the cherry-picks of the nutation fix (#989), the aberration correction (#990) and the refraction model (#991) onto this branch. The RA/Dec kernels took the scale with #991; this branch's own kernels and their iterative inverses (cyXYToAltAz, cyAltAzToXY, cyRaDecToXY_iter, cyXYHttoENU_wgs84, cyXYToGeo_wgs84, cyENUToXY_iter, cyENHtToXY_iter, cyGeoToXY_wgs84_iter) now take a refraction_scale argument as well, and every wrapper and Platepar method passes refractionScale(elev), so the alt/az and ENU paths refract consistently with the RA/Dec path. The finite-target-height fraction is provided but not yet applied in the height-aware kernels. Tests adapted to the merged kernels: the refraction fit test builds its star truth as the catalog direction (aberration removed) when the kernels model the aberration; the pointing test converts the platepar's epoch-of-date pointing to J2000 with the kernels' own transform, which now includes the nutation; the ENU -> XY round-trip tolerance reflects the solver's 0.01 px step criterion, which leaves up to ~0.1 px at low altitude with refraction. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CzZHCZoftFjV712njkWB5v
Cybis320
added a commit
that referenced
this pull request
Sep 6, 2026
…c kernels (includes PR #989 nutation fix) # Conflicts: # RMS/Astrometry/ApplyAstrometry.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
equatorialCoordAndRotPrecession, whichpointingCorrectionuses for every XY ↔ RA/Dec projection, applied nutation incorrectly: the nutation in longitude was a rotation about the equatorial pole instead of the ecliptic pole, and both nutation rotations were applied after precessing to J2000 rather than removed in the frame of date. The 4-term nutation series itself is fine, and the mean precession (equatorialCoordPrecession) is accurate to 0.08″.Against the IAU 2006/2000A model (erfa), the transform true-of-date → J2000 was off by:
It follows the 18.6-year nutation cycle: near zero in 2024, growing towards ~34″ in 2029.
Change
nutationRotate, pure C), removed at the start epoch and applied at the final epoch; J2000 is treated as the mean catalog frame.cyTrueRaDec2ApparentAltAz/cyApparentAltAz2TrueRADecuse the same true-of-date transform via two new helpers,trueOfDateFromJ2000/j2000FromTrueOfDate. Before, they applied no nutation at all, so alt/az derived from kernel output disagreed with the kernel's own frame by up to ~30″.equatorialCoordPrecession(mean precession) is unchanged.pointingCorrectioniscpdefso it can be tested from Python. Thecyjd2LSTdocstring now says what it returns (mean sidereal time; the equation of the equinoxes, ~1″, is not applied anywhere and Platepar.Ho is computed the same way, so the pair is consistent).Verification
Tests/test_precession_nutation.py(erfa-dependent tests skip if pyerfa is absent). A distortion-free synthetic camera fixed in alt/az, referenced at the start of the night and followed for 8 hours on a 9×7 pixel grid over an 82×46° frame (two pointings, five dates 2021–2029): the kernel's XY → J2000 stays within 0.5″ of erfa at every grid point, with the rigid roll of the error field within 0.3″ and the non-rigid part within 0.1″. The centre alone cannot see a rotation or scale error; the corners can. The old transform drifts by up to 11″ in position and 11″ in roll over a night on this test. Also: transform within 0.5″ of erfa at five dates, J2000→date→J2000 round trips to 0.01″, the kernel transform and the converters agree to 0.001″, the position-angle change within 0.5″ of the exact geometry, and a fixed camera's kernel centre within 2″ of the true direction with no drift over a night.Real data: USV001 2026-09-05 (217 FFs) recalibrated with the old and new kernels. Star-fit residuals identical (mean 0.1587 vs 0.1594 px). Only the fitted parameters move: the pointing by a few arcsec (the old transform's error happens to be small at that direction and date) and
pos_angle_refby +14″. Within-night pointing scatter is unchanged (0.163′ → 0.148′ in altitude).What this changes for users
Nothing in measured astrometry: the error was a small rigid rotation of the sky, and the star fit absorbed it into
RA_d,dec_dandpos_angle_ref. Those fitted values in existing platepars compensate for the old transform, so applied with the new kernel without refitting they are off by the same few arcsec to a few tens of arcsec until the next fit; the nightly recalibration does that automatically, and a SkyFit refit does it for a manually made platepar. The absolute meaning ofRA_d/dec_d(and anything derived from it, such as the stored alt/az centre) becomes correct.Found while checking the coordinate chain during the review of #986; independent of that PR and of #987.
🤖 Generated with Claude Code
https://claude.ai/code/session_01CzZHCZoftFjV712njkWB5v