Repository navigation
SPHEREx cleanup: refactor cutouts/psf, preserve MEF headers, drop redundant SDT README - #396
Conversation
…rve MEF headers Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…h-IPAC#129) Read every extension into memory inside the `with` block so the existing downstream `hdulist[...]` cells (including the WAVE-TAB spectral WCS, which needs `fobj=hdulist`) keep working after the file is closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README was folded into the notebook and deleted in 00c9664, which left the manifest pointing at a missing file and failed the manifest check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI hit http.client.RemoteDisconnected while reading SPHEREx images; catch it alongside the other transient errors so cutouts skips the image and psf retries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Added update to fix the failing notebook test. CI hit |
troyraen
left a comment
There was a problem hiding this comment.
Thank you! These issues will be good to have resolved. I know we've been asked about the version metadata. My biggest comment is about the primary header, which shouldn't include the version IMO since it will be wrong for some extensions.
| # Load the data, reading every extension into memory so that | ||
| # hdulist stays usable after the file is closed. | ||
| with fits.open(spectral_image_url, memmap=False) as hdulist: | ||
| for hdu in hdulist: | ||
| hdu.data |
There was a problem hiding this comment.
I think this needs to be saved to a variable with .copy() to be robust. I recall doing something similar and finding that the code would sometimes error because the data disappeared (I suspect that because the file is closed the next garbage collection removes it from memory). But if I'm wrong I'd love to see some documentation (if any exists) because this comes up for me occasionally.
| # Load the data, reading every extension into memory so that | |
| # hdulist stays usable after the file is closed. | |
| with fits.open(spectral_image_url, memmap=False) as hdulist: | |
| for hdu in hdulist: | |
| hdu.data | |
| # Load the data, reading every extension into memory so that | |
| # hdulist stays usable after the file is closed. | |
| with fits.open(spectral_image_url, memmap=False) as hdulist: | |
| for hdu in hdulist: | |
| hdu_data = hdu.data.copy() |
(and then use hdu_data in place of hdu.data below)
There was a problem hiding this comment.
I looked into this and I think the current code is OK as is. With memmap=False, touching hdu.data reads the array into ordinary memory and stores it on the HDU. hdulist keeps a reference to every HDU, so garbage collection can't free the data after the file closes. To test it, I built a 5-extension file (float image, int image, scaled image, and a table like WCS-WAVE). I opened it this way, let the with block close it, forced gc.collect() while allocating other memory, and compared. Every extension was still intact, and none of the arrays were backed by a memory map or file buffer.
The failure I could reproduce is lazy loading: an HDU that isn't touched before the file closes raises "file was closed before all HDUs were read" afterwards. That's why the loop touches every .data. The usual .copy() advice is for the default memmap=True (astropy FAQ, "Too many open files").
Docs: https://docs.astropy.org/en/stable/io/fits/index.html says that after closing, "the headers and data may or may not be accessible depending on whether the data are touched and if they are memory-mapped". The FAQ (https://docs.astropy.org/en/stable/io/fits/appendix/faq.html) says memmap=False "will force data to be read entirely into memory."
Also, the later cells use hdulist[...] directly, including WCS(..., fobj=hdulist), so one hdu_data variable in the loop would keep only the last extension's data.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SPHEREx cleanup: refactor cutouts/psf, preserve MEF headers, drop redundant SDT README b4e0c35
Conflicts in spherex_cutouts.md and spherex_psf.md: kept the DR1 test-host block and release filter, took main's reviewed Caltech-IPAC#150/Caltech-IPAC#238 changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In preparation for the upcoming DR1 updates. Closes #150, closes #238, closes #275.
Summary
pyvotoastroquery.ipac.irsa.Irsa.query_tapSkyCoordinstead of separatera/decfloatswriteto(..., overwrite=False)so output isn't silently clobberedQuantityinstead of a bare floatVERSION) in the combined MEF'sprimary HDU instead of writing a blank one, and record each cutout's version in
CUTOUT_INFO(the rest of the README was already duplicated there) and remove the README
memory so the downstream cells work after the file is closed (spherex_intro.md part of Make all
fits.open()calls use a context manager #129)http.client.RemoteDisconnectedas a transient read error in spherex_cutouts.md(skip that cutout) and spherex_psf.md (retry), after CI failed on a server disconnect
mid-read
Note on #129
spherex_cutouts.md, spherex_psf.md, and the SDT notebook already use context managers for
every
fits.open()call. spherex_intro.md's barefits.open()call is fixed here too (purelymechanical, does not touch the QR3-stale content next to it, which stays for #374). The two
Euclid notebooks and the Roman notebook also listed in #129 are untouched -- out of scope for
this PR.
Test plan
(
jupytext --to notebook --execute); no errorsVERSIONis present in the output MEF's primary headerexecution needs SExtractor/Firefly/bokeh, not run here)