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
>>> import pycrates as pyc >>> cr = pyc.read_file("img.fits") >>> img = cr.get_image().values >>> sky = cr.get_transform("sky") >>> eqpos = cr.get_transform("eqpos") >>> yi, xi = np.where(img == img.max()) >>> plog = np.column_stack((xi, yi)) + 1.0 >>> psky = sky.apply(plog) >>> 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:
>>> print(xi) [208] >>> print(yi) [177] >>> print(plog) [[209. 178.]]
The psky values are the SKY coordinates corresponding to this location are:
>>> print(psky) [[3836.5 4188.5]]
and the equatorial coordinates are:
>>> print(peqpos) [[210.25789497 2.8788792 ]]
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
>>> import pytransform as pyt >>> cr = read_file('nvss.fits') >>> print(cr.get_axisnames()) ['POS', 'EQPOS', 'Z', 'STOKES', '#AXIS4', 'FREQ'] >>> pos = cr.get_transform('pos') >>> eqpos = cr.get_transform('eqpos') >>> print(pyt.get_transform_type(pos)) LINEAR2DTransform >>> print(pyt.get_transform_type(eqpos)) WCSTransform
The parameters of the transformation can be displayed (or read and changed individually); for instance
>>> 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 >>> 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
>>> 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):
>>>ivals = np.asarray([[1.0, 1.0], [61.0, 61.0]]) >>>print(ivals) [[ 1. 1.] [61. 61.]] >>>ovals = eqpos.apply(ivals) >>>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.