Skip to content

wcs.WCS.slice() does not modify NAXISj values #4498

Closed

Description

@AnthonyHorton

The current implementation of WCS slicing appropriately modifies the CRPIX and CDELT values but does not modify the NAXIS values. Consequently the sliced WCS is not valid for the correspondingly sliced data array; the NAXIS values do not match the dimensions of the data. Example:

In [5]: image = fits.getdata(path)

In [6]: w = wcs.WCS(fits.getheader(path))
WARNING: FITSFixedWarning: 'datfix' made the change 'Changed '' to '2014-10-17'' [astropy.wcs.wcs]

In [7]: image.shape
Out[7]: (2883, 4279)

In [8]: w
Out[8]: 
WCS Keywords

Number of WCS axes: 2
CTYPE : 'RA---TAN'  'DEC--TAN'  
CRVAL : 12.56281278668  -25.916806236839999  
CRPIX : 2141.0  1450.5  
CD1_1 CD1_2  : -0.00097191601525989998  0.0  
CD2_1 CD2_2  : 0.0  0.00097191601525989998  
NAXIS    : 4279 2883

In [9]: image[100:500,250:850].shape
Out[9]: (400, 600)

In [10]: w[100:500,250:850]
Out[10]: 
WCS Keywords

Number of WCS axes: 2
CTYPE : 'RA---TAN'  'DEC--TAN'  
CRVAL : 12.56281278668  -25.916806236839999  
CRPIX : 1891.0  1350.5  
CD1_1 CD1_2  : -0.00097191601525989998  0.0  
CD2_1 CD2_2  : 0.0  0.00097191601525989998  
NAXIS    : 4279 2883

This is a problem for code that attempts to use slicing to trim an image with WCS, e.g. astropy/ccdproc#281

Activity

  1. astrofrog commented on Jan 15, 2016

    @astrofrog
    Member

    I think NAXIS was removed for a while then added back, so maybe we forgot to include it in the slicing.

    @nden - do you have any thoughts on this?

  2. mcara commented on Jan 18, 2016

    @mcara
    Contributor

    Technically, NAXIS (WCS.naxis) stays the same (as it should). What changes are WCS._naxis1 and WCS._naxis2. What you see as NAXIS when you print WCS are the values of WCS._naxis1 and WCS._naxis2. My understanding is that while NAXIS and NAXISj are parts of the FITS standard, they are not part of FITS WCS standard and thus maybe NAXISj should not even be part of the astropy.WCS object. For example, what is the meaning of naxis1 in a WCS that is all by itself and detached from underlying image (data)? The private values of WCS._naxis1 and WCS._naxis2 have no effect on computed transformations by the WCS object as they play no role in defining a WCS.

    I wonder if the correct solution would be to remove printing NAXIS from __repr__() and remove WCS._naxis1 and WCS._naxis2 from WCS object. If these members must be kept in WCS, then indeed WCS.slice() should update them.

  3. mcara commented on Jan 18, 2016

    @mcara
    Contributor

    I also wonder why there are so many functions that do the same thing in astropy... For example, WCS.slice() functionality seems to be replicated in the astropy.nddata.Cutout2D (see #3594). Now I see that the same thing is being implemented in astropy.ccdproc.trim_image(). It seems that this duplication makes the code difficult to maintain and confusing to use.

  4. AnthonyHorton commented on Jan 18, 2016

    @AnthonyHorton
    Author

    @mcara I can't speak about nddata.Cutout2d() but ccdproc.trim_image() doesn't duplicate anything from WCS.slice(), it makes use of it. ccdproc.trim_image() is a convenience function for extracting a slice of an image (in the form of a ccdproc.CCDData object, a subclass of ndddata.NDDataArray) along with all associated metadata (including WCS, if present). The actually slicing is handled by the methods implemented in the classes of the individual metadata attributes, i.e. ccdproc.trim_image() ends up calling WCS.slice() to slice the WCS.

  5. changed the title [-]wcs.WCS.slice() does not modify NAXIS values[/-] [+]wcs.WCS.slice() does not modify NAXISj values[/+] on Jan 18, 2016
  6. nden commented on Jan 18, 2016

    @nden
    Contributor

    The WCS._naxisj values have been discussed several times on this list. Yes, they are not part of the FITS WCS standard but the consesnus was that they should be included for practical purposes. As @astrofrog said not modifying them in WCS.slice() is just an oversight.
    @mcara A WCS without an image attached to it has the values set to 0.

    Similarly, the GWCS object has an attribute domain which defines the region of validity of the WCS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions