Chandra X-Ray Observatory
	(CXC)
Skip to the navigation links
Last modified: December 2015

URL: http://cxc.harvard.edu/ciao/ahelp/transform.html
AHELP for CIAO 4.9

transform

Context: transform

Synopsis

TRANSFORMS - Coordinate transforms in Python

Description

TRANSFORMS is a software package developed by the Chandra X-Ray Center (CXC) to provide a means of applying mathematical operations to data in order to convert it from one reference frame to another. Various Transform objects can be strung together to create complex operations.

The library can be used as a standalone system, and is incorporated into the CRATES package to support the generation and use of "virtual" data objects (see "ahelp cratedata").

Supported transforms

Type Description
LINEARTransfrom A 1D affine transform.
LINEAR2DTransfrom A 2D affine transform.
WCSTransform A WCS projection; most of the WCS types such as TAN and SIN are supported (see the "Supported WCS projections" section below).
WCSTANTransform This is deprecated and WCSTransform should be used instead.

There are help files for each of the Transform commands:

"ahelp -c transform"

Example

chips> import pycrates as pyc
chips> cr = pyc.read_file("img.fits")
chips> img = cr.get_image().values
chips> sky = cr.get_transform("sky")
chips> eqpos = cr.get_transform("eqpos")
chips> (yi, xi) = np.where(img == img.max())
chips> plog = np.column_stack((xi, yi)) + 1.0
chips> psky = sky.apply(plog)
chips> peqpos = eqpos.apply(psky)

Here we get the coordinates of the maximum value in the image in the 1D numpy arrays xi and yi. As the apply routine requires a single array, we use the column_stack routine from NumPy to combine the two arrays, adding on 1.0 to

  • convert from the 0-based scheme used by NumPy to the 1-based scheme used by the logical coordinate system,
  • and convert from an integer value to floating-point, since apply uses the data type of the input coordinates for its output values.

The comparison of xi, yi and plog for this particular dataset looks like:

chips> print(xi)
[1030]
chips> print(yi)
[398]
chips> print(plog)
[[ 1031.   399.]]

The psky values are the SKY coordinates corresponding to this location are:

chips> print(psky)
[[ 4069.5  3945.5]]

and the equatorial coordinates are:

chips> print(peqpos)
[[ 116.07298861   37.88802783]]

Supported WCS projections

The WCSTransform class supports the following projections:

Supported projections

Code Description
TAN Gnomonic = Tangent Plane
SIN Orthographic/synthesis
STG Stereographic
ARC Zenithal/azimuthal equidistant
ZEA Zenithal/azimuthal Equal Area
CAR Cartesian (NOTE: this may give incorrect results)
MER Mercator
PCO Polyconic
SFL Sanson-Flamsteed
PAR Parabolic
AIT Hammer-Aitoff equal area all-sky
MOL Mollweide
CSC COBE quadrilateralized Spherical Cube
QSC Quadrilateralized Spherical Cube
TSC Tangential Spherical Cube
NCP North celestial pole (special case of SIN)
GLS GLobal Sinusoidal (Similar to SFL)
PIX Pixel WCS
LIN Linear projection
DSS Digitized Sky Survey plate solution
PLT Plate fit polynomials (SAO)
TNX Gnomonic = Tangent Plane (NOAO with corrections)

A number of WCS projection types are currently unsupported:

WCS projections that return invalid results

Code Description
AIR Airy
AZP Zenithal (Azimuthal) Perspective
BON Bonne
HPX HealPix
SZP Slant Zenithal Perspective
ZPN Zenithal/azimuthal PolyNomial

The following projections may cause the Python interpretor to crash:

These WCS transformations that may cause a crash

Code Description
CYP CYlindrical Perspective
CEA Cylindrical Equal Area
COP COnic Perspective
COD COnic equiDistant
COE COnic Equal area
COO COnic Orthomorphic

Example using the SIN projection

As an example, consider the following file from NVSS:

unix% dmlist nvss.fits cols
 
--------------------------------------------------------------------------------
Columns for Image Block PRIMARY
--------------------------------------------------------------------------------
 
ColNo  Name                 Unit        Type             Range
   1   PRIMARY[61,61,1,1]   JY/BEAM      Real4(61x61x1x1) -Inf:+Inf            
 
--------------------------------------------------------------------------------
Physical Axis Transforms for Image Block PRIMARY
--------------------------------------------------------------------------------
 
Group# Axis# 
   1   1,2    POS(X) = (#1) 
                 (Y)   (#2)
   2   3      Z                    = #3 
   3   4      #AXIS4               = #4 
 
--------------------------------------------------------------------------------
World Coordinate Axis Transforms for Image Block PRIMARY
--------------------------------------------------------------------------------
 
Group# Axis# 
   1   1,2    EQPOS(RA ) = (+109.1846) +SIN[(-0.0042)* (POS(X)-(+31.0))]
                   (DEC)   (+37.6656 )      (+0.0042)  (   (Y) (+31.0)) 
   2   3      STOKES               = Z 
   3   4      FREQ                 = +1.4E+09  +100000000.0 * (#AXIS4  -1.0)

for which the physical and WCS projections can be handled by saying

chips> import pytransform as pyt
chips> cr = read_file('nvss.fits')
chips> print(cr.get_axisnames())
['POS', 'EQPOS', 'Z', 'STOKES', '#AXIS4', 'FREQ']
chips> pos = cr.get_transform('pos')
chips> eqpos = cr.get_transform('eqpos')
chips> print(pyt.get_transform_type(pos))
LINEAR2DTransform
chips> print(pyt.get_transform_type(eqpos))
WCSTransform

The parameters of the transformation can be displayed (or read and changed individually); for instance

chips> print(pos.print_parameter_list())
Name: SCALE	Type: dmDOUBLE	Value: 1.000000, 1.000000	   	Desc: Scale	Parent: POS
Name: ROTATION	Type: dmDOUBLE	Value: 0.000000	   	Desc: Rotation Angle	Parent: POS
Name: OFFSET	Type: dmDOUBLE	Value: 0.000000, 0.000000	   	Desc: Origin Offset	Parent: POS

chips> print(eqpos.print_parameter_list())
Name: CRPIX	Type: dmDOUBLE	Value: 31.000000, 31.000000	   	Desc: Reference Point Pixel Coordinates	Parent: EQPOS
Name: CRVAL	Type: dmDOUBLE	Value: 109.184583, 37.665556	   	Desc: Center Coordinate in decimal degrees	Parent: EQPOS
Name: CDELT	Type: dmDOUBLE	Value: -0.004167, 0.004167	   	Desc: Transform Scale in degrees/pixel	Parent: EQPOS
Name: CROTA	Type: dmDOUBLE	Value: 0.000000	   	Desc: Rotation Angle	Parent: EQPOS
Name: EQUINOX	Type: dmSHORT	Value: 2000	   	Desc: Equinox of Coordinates	Parent: EQPOS
Name: EPOCH	Type: dmDOUBLE	Value: 2000.000000	   	Desc: Epoch of Coordinates	Parent: EQPOS
Name: CTYPE	Type: dmCHAR	Value: RA---SIN   , DEC--SIN	   	Desc: Coordinate Projection Type	Parent: EQPOS

and we can use them to convert from a logical coordinate of (1,1); the bottom-left pixel in the image to a physical coordinate of

chips> print(pos.apply([[1.0, 1.0]]))
[[ 1. 1.]]

which in this case happens to be the identity transform (note how the input was given as an array of arrays, and the input coordinates were floating-point values, not integers). We can now convert to an equatorial position using the eqpos transform (in this case using the centers of both the bottom-left and top-right corners):

chips> ivals = np.asarray([[1.0, 1.0], [61.0, 61.0]])
chips> print(ivals)
[[  1.   1.]
 [ 61.  61.]]
chips> ovals = eqpos.apply(ivals)
chips> print(ovals)
[[ 109.34222803   37.54045037]
 [ 109.02640676   37.79045023]]

Bugs

See the bug pages on the CIAO website for an up-to-date listing of known bugs.

Refer to the CIAO bug pages for an up-to-date listing of known issues.


Last modified: December 2015
Smithsonian Institute Smithsonian Institute

The Chandra X-Ray Center (CXC) is operated for NASA by the Smithsonian Astrophysical Observatory. 60 Garden Street, Cambridge, MA 02138 USA.   Email:   cxchelp@head.cfa.harvard.edu Smithsonian Institution, Copyright © 1998-2017. All rights reserved.