Skip to content

Fix treatment of 'BLANK' and ignore_blank for uncompressed integer images#16636

Open
dhomeier wants to merge 3 commits into
astropy:mainfrom
dhomeier:uncompressed-blanks
Open

Fix treatment of 'BLANK' and ignore_blank for uncompressed integer images#16636
dhomeier wants to merge 3 commits into
astropy:mainfrom
dhomeier:uncompressed-blanks

Conversation

@dhomeier
Copy link
Copy Markdown
Contributor

@dhomeier dhomeier commented Jun 29, 2024

Description

Discussion of appropriate treatment of BLANK values in compressed image HDUs in #16550 revealed that in the uncompressed case integer data with the 'BLANK' keyword present are not handled consistently either, being converted to float with the invalid pixels set to NaN for signed integers, but left unmodified in the case of (unsigned) "scaled" integers. On updating the tests I also found that in the former case, the ignore_blank=True parameter setting for leaving the integer data unmodified is only honoured for PrimaryHDU, but silently ignored for images in an ExtensionHDU. I could not find any rationale for this other than ImageHDU having been missed when this kwarg was introduced in #2307.
There was one suggestion that these operations should be set on a per-HDU basis, but since the arguments are passed at the fits.open level, this would be non-straightforward to implement.

This PR therefore leaves all integer-type HDU data unmodified for ignore_blank=True, and converts them to float otherwise, if a valid 'BLANK' is set in the header (as per the documentation, and as implemented for compressed HDUs in #16550).

Addresses #7789 insofar as conversion can now be reliably avoided with ignore_blank.
Should be reviewed and pulled in as appropriate before merging #15474 to ensure that blank treatment stays consistent in CompImageHDU as well (which does not have an ignore_blank option yet / in 6.1.x).

  • 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.

@dhomeier dhomeier added this to the v6.1.2 milestone Jun 29, 2024
@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.

@github-actions
Copy link
Copy Markdown
Contributor

👋 Thank you for your draft pull request! Do you know that you can use [ci skip] or [skip ci] in your commit messages to skip running continuous integration tests until you are ready?

@dhomeier dhomeier force-pushed the uncompressed-blanks branch 2 times, most recently from 28a530b to f132a93 Compare June 29, 2024 00:25
@dhomeier dhomeier force-pushed the uncompressed-blanks branch from f132a93 to 9e58bb0 Compare June 29, 2024 01:21
@dhomeier dhomeier marked this pull request as ready for review July 4, 2024 14:52
@dhomeier dhomeier requested a review from saimn as a code owner July 4, 2024 14:52
@astrofrog astrofrog modified the milestones: v6.1.2, v6.1.3 Jul 25, 2024
@pllim pllim modified the milestones: v6.1.3, v6.1.4 Aug 30, 2024
@pllim pllim modified the milestones: v6.1.4, v6.1.5 Sep 27, 2024
raw_data = data
data = None
self._uint = False # Reset this to enable conversion to float
self._blank += self._orig_bzero # Same scaling to uint as for data
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @dhomeier,

Sorry it took me too long to come to this PR but I was focused on the compression refactor :)
I would prefer to avoid the few lines above which are making this function harder to understand (tweaking the hdu to make it behaves as integer data). I think we can handle directly the blank case for unsigned integer in _convert_pseudo_integer, something like this:

--- astropy/io/fits/hdu/image.py
+++ astropy/io/fits/hdu/image.py
@@ -795,6 +795,11 @@ class _ImageBaseHDU(_ValidHDU):
             data = np.array(data, dtype=dtype)
             data -= np.uint64(1 << (bits - 1))
 
+            if self._blank is not None:
+                data = np.array(data, dtype=np.float32)
+                blanks = data.flat == self._blank + self._orig_bzero
+                data.flat[blanks] = np.nan
+
             return data
 
     def _get_scaled_image_data(self, offset, shape):
@@ -827,11 +832,6 @@ class _ImageBaseHDU(_ValidHDU):
         data = None
         if not (self._orig_bzero == 0 and self._orig_bscale == 1):
             data = self._convert_pseudo_integer(raw_data)
-            if not (self._blank is None or data is None or data.dtype.kind != "u"):
-                raw_data = data
-                data = None
-                self._uint = False  # Reset this to enable conversion to float
-                self._blank += self._orig_bzero  # Same scaling to uint as for data

Does is it reasonable ?

@bsipocz bsipocz modified the milestones: v6.1.5, v6.1.7 Nov 12, 2024
@saimn saimn modified the milestones: v6.1.7, v7.0.1 Nov 22, 2024
@github-actions github-actions Bot added the Close? Tell stale bot that this issue/PR is stale label Nov 26, 2024
@github-actions
Copy link
Copy Markdown
Contributor

Hi humans 👋 - this pull request hasn't had any new commits for approximately 4 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.

@saimn
Copy link
Copy Markdown
Contributor

saimn commented Nov 26, 2024

@dhomeier - ping, can you rebase (and have a look at my comment above if you missed it) ?

@github-actions github-actions Bot removed the Close? Tell stale bot that this issue/PR is stale label Nov 27, 2024
@saimn saimn modified the milestones: v7.0.1, v7.0.2 Feb 6, 2025
@saimn saimn modified the milestones: v7.0.2, v7.1.1 May 12, 2025
@astrofrog astrofrog modified the milestones: v7.1.1, v7.1.2 Oct 10, 2025
@astrofrog astrofrog modified the milestones: v7.1.2, v7.2.0 Nov 3, 2025
@astrofrog astrofrog added backport-v7.2.x on-merge: backport to v7.2.x and removed backport-v7.1.x labels Nov 3, 2025
@pllim pllim modified the milestones: v7.2.0, v7.2.1 Dec 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants