Skip to content

Fix hardcoded degree units in fitswcs APE 14 world to pixel#19506

Open
nabobalis wants to merge 6 commits intoastropy:mainfrom
nabobalis:main
Open

Fix hardcoded degree units in fitswcs APE 14 world to pixel#19506
nabobalis wants to merge 6 commits intoastropy:mainfrom
nabobalis:main

Conversation

@nabobalis
Copy link
Copy Markdown
Member

@nabobalis nabobalis commented Mar 31, 2026

Description

I started using preserve_units with astropy 7.2 for my WCS and I have a roundtrip issues for my solar raster data.

  • Changelog if this patch is ok
  • By checking this box, the PR author has requested that maintainers do NOT use the "Squash and Merge" button. Maintainers should respect this when possible; however, the final decision is at the discretion of the maintainer that merges the PR.

@github-actions
Copy link
Copy Markdown
Contributor

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.

  • Do the proposed changes actually accomplish desired goals?
  • Do the proposed changes follow the Astropy coding guidelines?
  • Are tests added/updated as required? If so, do they follow the Astropy testing guidelines?
  • Are docs added/updated as required? If so, do they follow the Astropy documentation guidelines?
  • Is rebase and/or squash necessary? If so, please provide the author with appropriate instructions. Also see instructions for rebase and squash.
  • Did the CI pass? If no, are the failures related? If you need to run daily and weekly cron jobs as part of the PR, please apply the "Extra CI" label. Codestyle issues can be fixed by the bot.
  • Is a change log needed? If yes, did the change log check pass? If no, add the "no-changelog-entry-needed" label. If this is a manual backport, use the "skip-changelog-checks" label unless special changelog handling is necessary.
  • Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied?
  • At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate "backport-X.Y.x" label(s) before merge.

Comment thread astropy/wcs/wcsapi/tests/test_fitswcs.py
@nabobalis nabobalis marked this pull request as ready for review March 31, 2026 00:20
@nabobalis nabobalis requested a review from astrofrog as a code owner March 31, 2026 00:20
@Cadair
Copy link
Copy Markdown
Member

Cadair commented Mar 31, 2026

It should be noted that this bug is only present in the high level API component:

In [25]: wcs.wcs_world2pix(*wcs.wcs_pix2world(0, 56, 0), 0)
Out[25]: [array(6.88338275e-15), array(56.)]

In [26]: wcs.world_to_pixel_values(*wcs.pixel_to_world_values(0, 56))
Out[26]: (array(6.88338275e-15), array(56.))

Your fix is in the wrong place though the bug must be in how wcs.WCS sets its world_axis_object_components property.

@nabobalis
Copy link
Copy Markdown
Member Author

So where should I move it to and what is the actual fix I need to implement?

@Cadair
Copy link
Copy Markdown
Member

Cadair commented Mar 31, 2026

From a cursory look, I'm pretty sure the bug is here:

components[self.wcs.lng] = ("celestial", 0, "spherical.lon.degree")
components[self.wcs.lat] = ("celestial", 1, "spherical.lat.degree")

it's always accessing the component in degrees which it shouldn't be.

@Cadair Cadair marked this pull request as draft March 31, 2026 15:19
@Cadair Cadair added the backport-v7.2.x on-merge: backport to v7.2.x label Mar 31, 2026
@Cadair Cadair added this to the v7.2.1 milestone Mar 31, 2026
@nabobalis nabobalis changed the title Fix world_to_pixel for preserve_units celestial WCS axes Fix unit change in fitswcs Mar 31, 2026
@nabobalis nabobalis changed the title Fix unit change in fitswcs Fix unit hardcode in fitswcs Mar 31, 2026
Comment thread astropy/wcs/wcsapi/fitswcs.py Outdated
Comment thread astropy/wcs/wcsapi/fitswcs.py Outdated
@nabobalis nabobalis force-pushed the main branch 3 times, most recently from c7b1810 to d202074 Compare March 31, 2026 17:09
@pllim pllim added the Bug label Mar 31, 2026
@pllim
Copy link
Copy Markdown
Member

pllim commented Mar 31, 2026

I started using preverse_units

Hopefully you meant preserve units, and not perverse units... 😹

@nabobalis
Copy link
Copy Markdown
Member Author

nabobalis commented Mar 31, 2026

I started using preverse_units

Hopefully you meant preserve units, and not perverse units... 😹

Woops!

@nabobalis nabobalis force-pushed the main branch 3 times, most recently from adb9d27 to 6a99e7c Compare March 31, 2026 18:38
@nabobalis nabobalis marked this pull request as ready for review April 1, 2026 17:31
Comment thread astropy/wcs/wcsapi/fitswcs.py Outdated
@Cadair Cadair changed the title Fix unit hardcode in fitswcs Fix hardcoded degree units in fitswcs APE 14 world to pixel Apr 2, 2026
Comment thread astropy/wcs/wcsapi/fitswcs.py Outdated
@nabobalis nabobalis force-pushed the main branch 4 times, most recently from 31944b7 to 6a79e8a Compare April 2, 2026 14:23
Comment thread astropy/wcs/wcsapi/fitswcs.py Outdated
b=48.25 * u.deg,
distance=0 * u.km,
radial_velocity=-(3.346e-3 / 2.725 * c).to(u.km / u.s),
radial_velocity=-(3.346e-3 / 2.725 * C_SI).to(u.km / u.s),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am stupid.

kwargs = {}
kwargs["frame"] = celestial_frame
# Very occasionally (i.e. with TAB) wcs does not convert the units to degrees
# Very occasionally (i.e. with TAB) wcs does not convert the units
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this comment need updating now that this is not the only way the units might not be degrees?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe?

@@ -0,0 +1,3 @@
def assert_celestial_component(component, index):
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like this change but I had no better ideas to avoid me repeating this pattern in the unit tests.

Also since its now a callable, I am not checking its correct either.

@nabobalis
Copy link
Copy Markdown
Member Author

That failure is:

FAILED ../../.tox/py311-test-oldestdeps-alldeps-cov-clocale/lib/python3.11/site-packages/astropy/io/fits/tests/test_core.py::TestFileFunctions::test_open_from_remote_url - TimeoutError: [Errno 110] Connection timed out

Comment thread docs/changes/wcs/19506.bugfix.rst Outdated
Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com>
@pllim
Copy link
Copy Markdown
Member

pllim commented Apr 2, 2026

test_open_from_remote_url - TimeoutError

I don't see how this is your fault. Might just be a transient failure. 🤞

Copilot AI review requested due to automatic review settings April 13, 2026 17:58
@nabobalis
Copy link
Copy Markdown
Member Author

nabobalis commented Apr 13, 2026

Sorry to ping, any chance of an update on this?

Edit: I forgot about some setting for copilot which I have now disabled.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes FITS WCS (APE 14) world_to_pixel behavior when preserve_units=True, ensuring non-degree celestial units (e.g., arcsec, mas) are respected instead of being implicitly converted/hardcoded to degrees.

Changes:

  • Update FITSWCS celestial component extraction to convert SkyCoord lon/lat to the WCS’ configured units rather than degrees.
  • Refactor multiple tests to avoid hardcoding "spherical.*.degree" component paths and add a regression test for arcsec/mas round-tripping.
  • Add a WCS changelog bugfix fragment.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
astropy/wcs/wcsapi/fitswcs.py Adjusts celestial component extraction logic to preserve configured lon/lat units.
astropy/wcs/wcsapi/tests/test_fitswcs.py Adds a regression test for non-degree units and updates component assertions to accept callables.
astropy/wcs/wcsapi/wrappers/tests/test_sliced_wcs.py Updates assertions to avoid degree-string coupling, using a helper assertion instead.
astropy/wcs/wcsapi/tests/helpers.py Introduces assert_celestial_component helper for reusable component checks.
docs/changes/wcs/19506.bugfix.rst Documents the bugfix in the WCS changelog.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +450 to +454
components[self.wcs.lng] = (
"celestial",
0,
lambda c: c.spherical.lon.to_value(lon_unit),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-v7.2.x on-merge: backport to v7.2.x Bug wcs.wcsapi

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants