Unpickling WCS object raises warning
See original GitHub issueDescription
When a WCS object is unpickled, a warning is raised:
>>> pickle.loads(pickle.dumps(wcs))
WARNING: FITSFixedWarning: The WCS transformation has more axes (2) than the image it is associated with (0) [astropy.wcs.wcs]
I’ve dug into it a bit, though I don’t have the expertise to know for sure what’s happening. The warning appears to be raised here, based on a comparison of wcsprm.naxis
and header.get('NAXIS', None)
. The WCS class supports pickling by implementing the __reduce__()
method, which serializes the WCS object by calling its to_fits()
method, which in turns calls to_header()
. The documentation of to_header()
makes clear it does not include an NAXIS
key in the generated header. to_fits()
passes the header into a new PrimaryHDU
, and the header of this generated PrimaryHDU
has the NAXIS
key present with a value of 0. The HDUList
generated by to_fits()
is returned by __reduce__()
. The unpickling goes through the __WCS_unpickle__
function, which extracts the header from that hdulist and uses it to create a new WCS. header.get('NAXIS', None)
therefore is 0, the value that showed up during to_fits()
, while wcsprm
must detect some other way that there are two axes.
Within to_fits()
, changing the line
hdu = fits.PrimaryHDU(header=header)
to
hdu = fits.PrimaryHDU(header=header, data=np.empty([0]*self.naxis))
eliminates the warning (by ensuring a correct value is detected when NAXIS
is added to the header, I suppose), but I don’t know if that change could be problematic in some other way. That change does cause six tests in wcs/tests/test_pickle.py
to fail. Five of them appear to be failing because they expect this warning to be raised (e.g. FAILED wcs/tests/test_pickle.py::test_basic - Failed: DID NOT WARN. No warnings of type (<class 'astropy.wcs.wcs.FITSFixedWarning'>,) were emitted. The list of emitted warnings is: [].
), and I’m afraid I don’t understand why the sixth fails (FAILED wcs/tests/test_pickle.py::test_subclass - AttributeError: 'Sub' object has no attribute 'naxis'
).
The fact that some tests seem to require this warning to be raised makes me wonder if this is intended behavior. But the fact that NAXIS=0
is being inserted within to_fits()
feels like it might be a default value that’s inappropriate for this case, and I think it seems reasonable to expect to pickle and unpickle WCS
objects without warnings.
Expected behavior
Unpickling WCS
objects doesn’t raise errors
Actual behavior
In [1]: from astropy.wcs import WCS
In [2]: import pickle
In [3]: wcs = WCS(naxis=2)
In [4]: pickled = pickle.dumps(wcs)
In [5]: pickle.loads(pickled)
WARNING: FITSFixedWarning: The WCS transformation has more axes (2) than the image it is associated with (0) [astropy.wcs.wcs]
Out[5]:
WCS Keywords
Number of WCS axes: 2
CTYPE : '' ''
CRVAL : 0.0 0.0
CRPIX : 0.0 0.0
PC1_1 PC1_2 : 1.0 0.0
PC2_1 PC2_2 : 0.0 1.0
CDELT : 1.0 1.0
NAXIS : 0 0
In [6]:
System Details
>>> import platform; print(platform.platform())
macOS-12.2-arm64-arm-64bit
>>> import sys; print("Python", sys.version)
Python 3.10.2 | packaged by conda-forge | (main, Feb 1 2022, 19:29:01) [Clang 11.1.0 ]
>>> import numpy; print("Numpy", numpy.__version__)
Numpy 1.22.2
>>> import erfa; print("pyerfa", erfa.__version__)
pyerfa 2.0.0.1
>>> import astropy; print("astropy", astropy.__version__)
astropy 5.1.dev551+g314dbe860
>>> import scipy; print("Scipy", scipy.__version__)
Scipy 1.8.0
>>> import matplotlib; print("Matplotlib", matplotlib.__version__)
Matplotlib 3.5.1
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:8 (7 by maintainers)
Top GitHub Comments
I saw this warning when making composite images from the two imagers on Parker Solar Proble’s WISPR instrument. I load in data and headers from a pair of FITS files and generate a WCS object from scratch (like in this example) to describe the composite field of view. I pass each input image into the
reproject
module along with that generated WCS and an output size, combine the two output arrays fromreproject
into the final composite image, and return the final composite image array and the WCS object describing it. To speed this up for long lists of image pairs, I’m using themultiprocessing
module, which usespickle
to transport return values back to the main process, and so that’s why I’m pickling plain WCS objects (each in a tuple alongside its associated image array). I suppose I could join the image array and WCS object in a FITS HDU before it gets pickled, but for how I’m using the data right now, I’d just be pulling them right back apart after the unpickling, so that feels to me like an unnecessary extra step.This is my first time using some of these modules, so do let me know if at first glance you think that’s an unintended way of using these tools.
@Russell-Ryan Yes, there is a fix: https://github.com/astropy/astropy/pull/12844. It has not yet been merged as it awaits reviews.