astropy:docs

World Coordinate System (astropy.wcs)

Introduction

astropy.wcs contains utilities for managing World Coordinate System (WCS) transformations in FITS files. These transformations map the pixel locations in an image to their real-world units, such as their position on the sky sphere.

It is at its base a wrapper around Mark Calabretta’s wcslib, but also adds support for the Simple Imaging Polynomial (SIP) convention and table lookup distortions as defined in WCS Paper IV. Each of these transformations can be used independently or together in a standard pipeline.

Getting Started

The basic workflow is as follows:

  1. from astropy import wcs
  2. Call the WCS constructor with an astropy.io.fits header and/or hdulist object.
  3. Optionally, if the FITS file uses any deprecated or non-standard features, you may need to call one of the fix methods on the object.
  4. Use one of the following transformation methods:
    • all_pix2world: Perform all three transformations from pixel to world coordinates.
    • wcs_pix2world: Perform just the core WCS transformation from pixel to world coordinates.
    • all_world2pix: Perform all three transformations from world to pixel coordinates, using an iterative method if necessary.
    • wcs_world2pix: Perform just the core WCS transformation from world to pixel coordinates.
    • sip_pix2foc: Convert from pixel to focal plane coordinates using the SIP polynomial coefficients.
    • sip_foc2pix: Convert from focal plane to pixel coordinates using the SIP polynomial coefficients.
    • p4_pix2foc: Convert from pixel to focal plane coordinates using the table lookup distortion method described in Paper IV.
    • det2im: Convert from detector coordinates to image coordinates. Commonly used for narrow column correction.

For example, to convert pixel coordinates to world coordinates:

>>> from astropy.wcs import WCS
>>> w = WCS('image.fits')
>>> lon, lat = w.all_pix2world(30, 40, 0)
>>> print(lon, lat)

Using astropy.wcs

Loading WCS information from a FITS file

This example loads a FITS file (supplied on the commandline) and uses the WCS cards in its primary header to transform.

# Load the WCS information from a fits header, and use it
# to convert pixel coordinates to world coordinates.

from __future__ import division, print_function

import numpy
from astropy import wcs
from astropy.io import fits
import sys

def load_wcs_from_file(filename):
    # Load the FITS hdulist using astropy.io.fits
    hdulist = fits.open(sys.argv[-1])

    # Parse the WCS keywords in the primary HDU
    w = wcs.WCS(hdulist[0].header)

    # Print out the "name" of the WCS, as defined in the FITS header
    print(w.wcs.name)

    # Print out all of the settings that were parsed from the header
    w.wcs.print_contents()

    # Some pixel coordinates of interest.
    pixcrd = numpy.array([[0, 0], [24, 38], [45, 98]], numpy.float_)

    # Convert pixel coordinates to world coordinates
    # The second argument is "origin" -- in this case we're declaring we
    # have 1-based (Fortran-like) coordinates.
    world = w.wcs_pix2world(pixcrd, 1)
    print(world)

    # Convert the same coordinates back to pixel coordinates.
    pixcrd2 = w.wcs_world2pix(world, 1)
    print(pixcrd2)

    # These should be the same as the original pixel coordinates, modulo
    # some floating-point error.
    assert numpy.max(numpy.abs(pixcrd - pixcrd2)) < 1e-6


if __name__ == '__main__':
    load_wcs_from_file(sys.argv[-1])

Building a WCS structure programmatically

This example, rather than starting from a FITS header, sets WCS values programmatically, uses those settings to transform some points, and then saves those settings to a new FITS header.

# Set the WCS information manually by setting properties of the WCS
# object.

from __future__ import division, print_function

import numpy
from astropy import wcs
from astropy.io import fits

# Create a new WCS object.  The number of axes must be set
# from the start
w = wcs.WCS(naxis=2)

# Set up an "Airy's zenithal" projection
# Vector properties may be set with Python lists, or Numpy arrays
w.wcs.crpix = [-234.75, 8.3393]
w.wcs.cdelt = numpy.array([-0.066667, 0.066667])
w.wcs.crval = [0, -90]
w.wcs.ctype = ["RA---AIR", "DEC--AIR"]
w.wcs.set_pv([(2, 1, 45.0)])

# Some pixel coordinates of interest.
pixcrd = numpy.array([[0, 0], [24, 38], [45, 98]], numpy.float_)

# Convert pixel coordinates to world coordinates
world = w.wcs_pix2world(pixcrd, 1)
print(world)

# Convert the same coordinates back to pixel coordinates.
pixcrd2 = w.wcs_world2pix(world, 1)
print(pixcrd2)

# These should be the same as the original pixel coordinates, modulo
# some floating-point error.
assert numpy.max(numpy.abs(pixcrd - pixcrd2)) < 1e-6

# Now, write out the WCS object as a FITS header
header = w.to_header()

# header is an astropy.io.fits.Header object.  We can use it to create a new
# PrimaryHDU and write it to a file.
hdu = fits.PrimaryHDU(header=header)
# Save to FITS file
# hdu.writeto('test.fits')

Validating the WCS keywords in a FITS file

Astropy includes a commandline tool, wcslint to check the WCS keywords in a FITS file:

> wcslint invalid.fits
HDU 1:
  WCS key ' ':
    - RADECSYS= 'ICRS ' / Astrometric system
      RADECSYS is non-standard, use RADESYSa.
    - The WCS transformation has more axes (2) than the image it is
      associated with (0)
    - 'celfix' made the change 'PV1_5 : Unrecognized coordinate
      transformation parameter'.

HDU 2:
  WCS key ' ':
    - The WCS transformation has more axes (3) than the image it is
      associated with (0)
    - 'celfix' made the change 'In CUNIT2 : Mismatched units type
      'length': have 'Hz', want 'm''.
    - 'unitfix' made the change 'Changed units: 'HZ      ' -> 'Hz''.

Bounds checking

Bounds checking is enabled by default, and any computed world coordinates outside of [-180°, 180°] for longitude and [-90°, 90°] in latitude are marked as invalid. To disable this behavior, use astropy.wcs.Wcsprm.bounds_check.

Supported projections

As astropy.wcs is based on wcslib, it supports the standard projections defined in the WCS papers. These projection codes are specified in the second part of the CUNITn keywords (accessible through Wcsprm.cunit), for example, RA-TAN-SIP. The supported projection codes are:

  • AZP: zenithal/azimuthal perspective
  • SZP: slant zenithal perspective
  • TAN: gnomonic
  • STG: stereographic
  • SIN: orthographic/synthesis
  • ARC: zenithal/azimuthal equidistant
  • ZPN: zenithal/azimuthal polynomial
  • ZEA: zenithal/azimuthal equal area
  • AIR: Airy’s projection
  • CYP: cylindrical perspective
  • CEA: cylindrical equal area
  • CAR: plate carrée
  • MER: Mercator’s projection
  • COP: conic perspective
  • COE: conic equal area
  • COD: conic equidistant
  • COO: conic orthomorphic
  • SFL: Sanson-Flamsteed (“global sinusoid”)
  • PAR: parabolic
  • MOL: Mollweide’s projection
  • AIT: Hammer-Aitoff
  • BON: Bonne’s projection
  • PCO: polyconic
  • TSC: tangential spherical cube
  • CSC: COBE quadrilateralized spherical cube
  • QSC: quadrilateralized spherical cube
  • HPX: HEALPix
  • XPH: HEALPix polar, aka “butterfly”

See Also

Reference/API

astropy.wcs Module

Introduction

astropy.wcs contains utilities for managing World Coordinate System (WCS) transformations in FITS files. These transformations map the pixel locations in an image to their real-world units, such as their position on the sky sphere.

It is at its base a wrapper around Mark Calabretta’s wcslib, but also adds support for the Simple Imaging Polynomial (SIP) convention and table lookup distortions as defined in WCS Paper IV. Each of these transformations can be used independently or together in a standard pipeline.

Functions

find_all_wcs(header[, relax, keysel, fix, ...]) Find all the WCS transformations in the given header.
get_include() Get the path to astropy.wcs’s C header files.
validate(source) Prints a WCS validation report for the given FITS file.

Classes

DistortionLookupTable Represents a single lookup table for a Paper IV distortion transformation.
FITSFixedWarning The warning raised when the contents of the FITS header have been modified to be standards compliant.
InconsistentAxisTypesError The WCS header inconsistent or unrecognized coordinate axis type(s).
InvalidCoordinateError One or more of the world coordinates is invalid.
InvalidSubimageSpecificationError The subimage specification is invalid.
InvalidTabularParametersError The given tabular parameters are invalid.
InvalidTransformError The WCS transformation is invalid, or the transformation parameters are invalid.
NoSolutionError No solution can be found in the given interval.
NoWcsKeywordsFoundError No WCS keywords were found in the given header.
NonseparableSubimageCoordinateSystemError Non-separable subimage coordinate system.
SingularMatrixError The linear transformation matrix is singular.
Sip The Sip class performs polynomial distortion correction using the SIP convention in both directions.
Tabprm A class to store the information related to tabular coordinates, i.e., coordinates that are defined via a lookup table.
WCS([header, fobj, key, minerr, relax, ...]) WCS objects perform standard WCS transformations, and correct for SIP and Paper IV table-lookup distortions, based on the WCS keywords and supplementary data read from a FITS file.
WCSBase Wcs objects amalgamate basic WCS (as provided by wcslib), with SIP and Paper IV distortion operations.
WcsError Base class of all invalid WCS errors.
Wcsprm Wcsprm is a direct wrapper around wcslib. It

Class Inheritance Diagram

digraph inheritance54d1987e0c { rankdir=LR; size="8.0, 12.0"; "AstropyWarning" [style="setlinewidth(0.5)",URL="../api/astropy.utils.exceptions.AstropyWarning.html#astropy.utils.exceptions.AstropyWarning",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="The base warning class from which all Astropy warnings should inherit.",height=0.25,shape=box,fontsize=10]; "DistortionLookupTable" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.DistortionLookupTable.html#astropy.wcs.DistortionLookupTable",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="DistortionLookupTable(*table*, *crpix*, *crval*, *cdelt*)",height=0.25,shape=box,fontsize=10]; "FITSFixedWarning" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.FITSFixedWarning.html#astropy.wcs.FITSFixedWarning",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="The warning raised when the contents of the FITS header have been",height=0.25,shape=box,fontsize=10]; "AstropyWarning" -> "FITSFixedWarning" [arrowsize=0.5,style="setlinewidth(0.5)"]; "InconsistentAxisTypesError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.InconsistentAxisTypesError.html#astropy.wcs.InconsistentAxisTypesError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "InconsistentAxisTypesError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "InvalidCoordinateError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.InvalidCoordinateError.html#astropy.wcs.InvalidCoordinateError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "InvalidCoordinateError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "InvalidSubimageSpecificationError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.InvalidSubimageSpecificationError.html#astropy.wcs.InvalidSubimageSpecificationError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "InvalidSubimageSpecificationError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "InvalidTabularParametersError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.InvalidTabularParametersError.html#astropy.wcs.InvalidTabularParametersError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "InvalidTabularParametersError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "InvalidTransformError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.InvalidTransformError.html#astropy.wcs.InvalidTransformError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "InvalidTransformError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NoSolutionError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.NoSolutionError.html#astropy.wcs.NoSolutionError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "NoSolutionError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NoWcsKeywordsFoundError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.NoWcsKeywordsFoundError.html#astropy.wcs.NoWcsKeywordsFoundError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "NoWcsKeywordsFoundError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NonseparableSubimageCoordinateSystemError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.NonseparableSubimageCoordinateSystemError.html#astropy.wcs.NonseparableSubimageCoordinateSystemError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "NonseparableSubimageCoordinateSystemError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "SingularMatrixError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.SingularMatrixError.html#astropy.wcs.SingularMatrixError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "WcsError" -> "SingularMatrixError" [arrowsize=0.5,style="setlinewidth(0.5)"]; "Sip" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.Sip.html#astropy.wcs.Sip",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="Sip(*a, b, ap, bp, crpix*)",height=0.25,shape=box,fontsize=10]; "Tabprm" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.Tabprm.html#astropy.wcs.Tabprm",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="A class to store the information related to tabular coordinates,",height=0.25,shape=box,fontsize=10]; "WCS" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.WCS.html#astropy.wcs.WCS",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="WCS objects perform standard WCS transformations, and correct for",height=0.25,shape=box,fontsize=10]; "WCSBase" -> "WCS" [arrowsize=0.5,style="setlinewidth(0.5)"]; "WCSBase" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.WCSBase.html#astropy.wcs.WCSBase",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="Wcs(*sip, cpdis, wcsprm, det2im*)",height=0.25,shape=box,fontsize=10]; "WcsError" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.WcsError.html#astropy.wcs.WcsError",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape=box,fontsize=10]; "Wcsprm" [style="setlinewidth(0.5)",URL="../api/astropy.wcs.Wcsprm.html#astropy.wcs.Wcsprm",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",tooltip="Wcsprm(header=None, key=' ', relax=False, naxis=2, keysel=0, colsel=None)",height=0.25,shape=box,fontsize=10]; }

Acknowledgments and Licenses

wcslib is licenced under the GNU Lesser General Public License.