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 declination
:
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.