next up previous contents
Next: Use Outside of a Up: Converting Between Multiple Coordinate Previous: Converting Between Multiple Coordinate

Basic Use

 

A CoordTransform object is most commonly used by attaching it to a CoordinateSystem via one of the latter's attachTransform() methods. This causes the CoordinateSystem to automatically apply the transform everytime positions are requested from the system. For example, suppose we have a CoordinateSystem that calculates positions in some space that is defined by a reference point:

CoordinateSystem csys;
...
Metadata md = csys.getMetadata();
System.out.println( "reference point for first axis: " + 
	            md.getMetadata("Axes[0].refposition"));
/* 
 * OUTPUT:
 * reference point for first axis: 7.0
 */

double[] datapos = { 1.0, 2.5, 5.0 };
CoordPos cpos = csys.getCoordPos(datavox);
System.out.println( cpos.getValueString(0) )  

/* 
 * OUTPUT:
 * 7.0
 */
Suppose further that we would like the positions that are printed out to be relative to the reference point, rather than absolute positions. We can think of this as transforming the positions to a new coordinate system; that is, we will convert them from from an absolute system to a relative system. To do this we can apply the AbsToRelCoordTransform to the CoordinateSystem:
// we want to convert positions along 3 of the axes
CoordTransform conversion = new AbsToRelCoordTransform(3);

// attach the transform to the coordinate system
try{ 
    csys.attachTransform(conversion);
} 
catch (IllegalTransformException ex) {
    System.err.println("Unable to attach transform: " + ex.getMessage());
}

// the transform get automatically applied
datapos = { 1.0, 2.5, 5.0 };
cpos = csys.getCoordPos(datavox);
System.out.println( cpos.getValueString(0) )  

/* 
 * OUTPUT:
 * -6.0
 */
When the tranform object conversion in this example was ``attached'' to the coordinate system, it took a peek into the system's metadata to find out what its native reference position was and then adjusted its own internal parameters so that it can properly perform the conversion to relative coordinates.

Now suppose we no longer want to positions relative to the system's native reference point, but rather relative to some other point:

// First remove the previous transform we just applied
csys.popTransform();

// Create a new transform using our reference point.  The third
// argument to the constructor tells the transform not to use 
// the native reference position when it is attached to a coordinate 
// system (see API for details).  
//
double[] refpos = { 5.5, 1.98, 10 };    // our referenct point
conversion = new AbsToRelCoordTransform(3, refpos, false);

// attach new transform
try{ 
    csys.attachTransform(conversion);
} 
catch (IllegalTransformException ex) {
    System.err.println("Unable to attach transform: " + ex.getMessage());
}

// now the new transform will be used
datapos = { 1.0, 2.5, 5.0 };
cpos = csys.getCoordPos(datavox);
System.out.println( cpos.getValueString(0) )  

/* 
 * OUTPUT:
 * -4.5
 */

In the above example, the transform applies (by default) itself to (at most) the first three axes of the system. However, sometimes the desired application of a transform is a little more complicated. Consider for example a 3-dimensional astronomical image whose axes are frequency, right ascension, and declinationgif:

Viewable astroimage;
...
CoordinateSystem csys = astroimage.getCoordinateSystem();

// display coordinates of the dataset origin
double origin = {0.0, 0.0, 0.0};
CoordPos cpos = csys.getCoordPos(origin);
System.out.prinln( cpos.getAxisLabel(0) + ": " + cpos.getValueString(0) );
System.out.prinln( cpos.getAxisLabel(1) + ": " + cpos.getValueString(1) );
System.out.prinln( cpos.getAxisLabel(2) + ": " + cpos.getValueString(2) );

/*
 * OUTPUT:
 * Frequency: 115.98 GHz
 * Right Ascension: 14:32:42.05
 * Declination: 27:02:13.3
 */
Suppose now that instead of right ascension and declination, we would like positions in terms of Galactic longitude and latitude. We might do the following:
CoordTransform conversion = new CelToGalCoordTransform();

// attach the transform to the coordinate system
try{ 
    csys.attachTransform(conversion);
} 
catch (IllegalTransformException ex) {
    System.err.println("Unable to attach transform: " + ex.getMessage());
}

// now the new transform will be used
CoordPos cpos = csys.getCoordPos(origin);
System.out.prinln( cpos.getAxisLabel(0) + ": " + cpos.getValueString(0) );
System.out.prinln( cpos.getAxisLabel(1) + ": " + cpos.getValueString(1) );
System.out.prinln( cpos.getAxisLabel(2) + ": " + cpos.getValueString(2) );

/*
 * OUTPUT:
 * Frequency: 115.98 GHz
 * Galactic Longitude: 38.123513
 * Galactic Latitude: 66.984528
 */
The transform object did more than just convert right ascension and declination into Galactic longitude and latidute, updating the labels appropriately. When it was attached, it actually had to figure out which axes were the ones it needed to operate on. That is, the transform knows that converts between celestial coordinates and galactic coordinates, and therefore looked for axes named ``Right Ascension'' and ``Declination'' (by examining the CoordinateSystem's metadata); if it did not find them, a IllegalTransformException would have been thrown during attachment.

What if the coordinate system was already in terms of Galactic longitude and latitude and you wanted to convert positions to celestial coordinates? One can attach CoordTransform objects backwards to have the reverse transform applied. For example:

// attach the transform to the coordinate system; the second argument 
// tells the system to attach the transform in the reverse direction.
try{ 
    csys.attachTransform(conversion, false);
} 
catch (IllegalTransformException ex) {
    System.err.println("Unable to attach transform: " + ex.getMessage());
}

Instead of having the CoordTransform figure out how it is suppose to be applied, you can give explicit instructions via the CoordTransformConstraints class. This class can provide the two basic pieces of information needed, namely the direction the transform should be applied and something referred to as the Axis Index List which indicates which axes should be transformed and the order in which they should be interpreted.

To understand the Axis Index List, consider our example above converting celestial coordinates to galactic coordinates. The CelToGalCoordTransform by default expects that its first axis (axis # 0) will be a right ascension axis and the second axis (axis # 1) will be declination. That of course is not the order in which they actually appear in our data set. The CoordTransformConstraints class allows us to indicate that the axis that our transform expects at position 0 is actually at position 1:

// Create a CoordTransformConstraint to describe how to apply the 
// transform:
CoordTransformConstraint constraints = new CoordTransformConstraint();

// the transform will be attached in the forward direction
constraints.forward = true;

// The transform by default wants the right ascension axis at axis
// position 0;  indicate that instead this axis will be at position 1.
constraints.setAxisAt(0, 1);

// The transform by default wants the declination axis at axis
// position 1;  indicate that instead this axis will be at position 2.
constraints.setAxisAt(1, 2);

// Now attach our transform
csys.attachTransform(conversion, constraints);
Note that when we attach a tranform using a CoordTransformConstraints object, we do not need to be prepared to catch an IllegalTransformException. With the constraints, the CoordTransform does not need to check the system's metadata; thus, we have essentially ``forced'' the transform onto the system.


next up previous contents
Next: Use Outside of a Up: Converting Between Multiple Coordinate Previous: Converting Between Multiple Coordinate

Ray Plante
Mon Aug 25 15:16:12 CDT 1997