question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unpickling WCS object raises warning

See original GitHub issue

Description

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:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
svankcommented, Feb 9, 2022

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 from reproject 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 the multiprocessing module, which uses pickle 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.

0reactions
mcaracommented, Feb 25, 2022

@Russell-Ryan Yes, there is a fix: https://github.com/astropy/astropy/pull/12844. It has not yet been merged as it awaits reviews.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Source code for astropy.wcs.wcs
Wcsprm ` object) # STDLIB import builtins import copy import io import ... [docs]class FITSFixedWarning(AstropyWarning): """ The warning raised when the ...
Read more >
astropy.wcs.wcs — Astropy v0.4.2
Wcsprm.fix` on the resulting object to fix any non-standard uses in the header. `FITSFixedWarning` Warnings will be emitted if any changes were made....
Read more >
python-astropy-4.0.2-bp153.1.10
Passing a NaN to ``Distance`` no longer raises a warning. ... All WCS objects are converted to a high level WCS object, so...
Read more >
Source code for galsim.wcs
If it is not implemented for a particular WCS class, a NotImplementedError will be raised. The ``image_pos`` parameter should be a `PositionD`.
Read more >
astropy Changelog - pyup.io
issues a warning and drops the column instead of raising an exception. [12825] ... unpickling WCS objects originally created using non-default values for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found