next up previous contents
Next: Metadata Lexicons Up: Putting It All Together: Previous: Updating the coordinate display

The Viewable: Loading the Proper Metadata

 

You might wonder how the coordinate system was created in first place for it to be used by our viewer. Creating a CoordinateSystem object is usually the job of a Viewable implementation whose job is to be a format-independent interface between the application and a format-specific reader. It needs to read the relevent data from the formatted data source, load them into a Metadata list, and then turn them into the proper CoordinateSystem. Because of the relationship between a Viewable implementation and the specific data format it sits on top of, one normally would only need to mess with the details of creating new CoordinateSystem objects when integrating a new data format with the Horizon package.

Our demonstration applet, CoordDemoApplet illustrates how to create CoordinateSystem
[0] objects. As mentioned in §3.2.1, GIF and JPEG images are usually given the simplest
[3] CoordinateSystems which are simply pixel based; this is because these data formats do not include anymore complex information about the coordinate system the pixels reside in. In principle, however the coordinate system information could exist somewhere other than in the file containing such an image. In our example, we show how we might use externally obtained coordinate metadata to apply complex coordinate systems to a selection of predefined GIF and JPEG images. This is done by wrapping the images in a special implementation of the Viewable interface (whose definition is given within the CoordDemoApplet.java file).

In this section, we will look at one of those images, an image of the center of the Milky Way taken at radio frequencies. The implementation of the Viewable's getCoordSys first checks to see there is coordinate metadata available for the image. If not, it returns a simple CoordinateSystem object just like we saw in §3.2.1. If the image is one it recognizes, it declares its coordinate metadata:

    // GalacticCenter.gif
    if (id.equals("GalacticCenter.gif")) {

        // here's the basic data that applies to this image; this 
        // information would usually be obtained from the input
        // data itself using a reader that understands the data's 
        // format
        //
        // Number of axes
        int naxes = 2;

        // Reference position in degrees
        double[] refval = { 265.604165196, -28.9583335072 };

        // Reference voxel: the voxel whose position is the reference 
        // position
        double[] refpos = { 265.0, 182.0 };

        // Voxel size in absolute degrees
        double[] voxelsize = { -2.777777845E-04, -2.777777845E-04 };

        // Names for the axes:
        String[] axisnames = { "R.A.", "Dec." };

        // Projection code: type of projection used
        String projcode = "SIN";
For typical scientific formats, this data would come from the format-specific reader which would have extracted the data from the file itself.

Next we load the data into a Metadata list:

        // Before we create the CoordinateSystem object, we need to 
        // load the parameters into a Metadata object.  This is best
        // done using a CoordMetadata object.
        CoordMetadata cmdata = new CoordMetadata(2);

        // The CoordMetadata class is aware of the metadata that 
        // CoordinateSystems look for and helps ensure that the data
        // is loaded with the correct metadata name and type.  It 
        // does this by providing special set methods for the 
        // Coordinate related metadata.  See the API documentation for
        // CoordMetadata for more information.
        //
        cmdata.setAxisRefposition(0, refpos[0]);
        cmdata.setAxisRefposition(1, refpos[1]);
        cmdata.setAxisRefvalue(0, refval[0]);
        cmdata.setAxisRefvalue(1, refval[1]);
        cmdata.setAxisStepsize(0, voxelsize[0]);
        cmdata.setAxisStepsize(1, voxelsize[1]);

        cmdata.setAxisType(0, "longitude");
        cmdata.setAxisType(1, "latitude");

        // If we know what the correct data Metadata key name and type
        // for the data we are setting, we could alternatively use a 
        // method of the super-class Metadata (see API documentation
        // for CoordMetadata for details):
        // 
        cmdata.setAxisName(axisnames);

        // We should choose formatter objects of type CoordAxisPos.
        // This object converts a double into a formatted String.
        // If we do not set this, a default formatter will be set
        // that prints the position as normal double values.
        // 
        // For this dataset, we want the positions printed with a 
        // special format.  RA should be printed in 
        // hours:minutes:seconds format and Dec should be printed 
        // in degrees:minutes:seconds format.
        cmdata.setAxisFormatter(0, new HHMMSSAxisPosFormatter());
        cmdata.setAxisFormatter(1, new DDMMSSAxisPosFormatter());

        // Now we create the desired CoordinateSystem.  Our reader tells
        // us (or assumes) that the coordinate system is a sphere 
        // projected on a plane; thus we will use the 
        // ProjectedSphericalCoordinateSystem.  
        //
        // This CoordinateSystem requires a metadatum called "projection",
        // the code that identifies the projection type. (See 
        // ProjectedSphericalCoordinateSystem API documentation.)
        //
        cmdata.put("projection", projcode);
We used the CoordMetadata class to help us load the data in accordance with the horizon schema so that the data can be used by the coordinate classes. Note, however, that this GIF image was originally created from a FITS file. If we were reading the FITS file directly, we could use the FITSCoordMetadata class to load the data. This class takes the FITS metadata in its native form and automatically converts it to the horizon schema before saving them in the metadata list.

Finally, we can create the CoordinateSystem:

        // We tell the constructor that axis 0 is the longitude axis and 
        // axis 1 is the latitude axis.
        //
        try {
            coord = new SphLinCoordinateSystem(cmdata);
        } catch (IllegalTransformException ex) {
            System.err.println("Warning: " + ex.getMessage() + "\n" +
                               "Using a default coordinate system.");
            coord = new CoordinateSystem(new CoordMetadata(2));
        }
    }
We chose the ncsa.horizon.coordinates.systems.SphLinCoordinateSystem implementation because our image has two spherical axes in it, right ascension and declination, which represent longitude and latitude on the sky. The try block is used to catch an exception that might be thrown if the collection of metadata do not describe any definable coordinate system. This might happen if some of the metadata have erroneous or inconsistent values or if needed metadata do not exist in the metadata list. In this case, we resort to a simple pixel-based coordinate system.

As a summary, we can trace the procedure of coordinate tracking from the initial metadata to the display of coordinate systems by a viewer. First the coordinate-related metadata are read in from a format-specific file and loaded into a Metadata list using the horizon schema. These metadata are then used to create a CoordinateSystem object which is handed to the Viewer via the Viewable's getCoordSys method. The Viewer keeps track of how the data is displayed in its display region using an ImageDisplayMap object. When the user requests the coordinate position from a displayed pixel (say, by moving the mouse over the pixel), the display pixel is first converted to a data voxel by passing it through the ImageDisplayMap; that voxel is then sent through the CoordinateSystem to get the coordinate position. When it is displayed for the user, it is automatically printed in a coordinate system-specific format.


next up previous contents
Next: Metadata Lexicons Up: Putting It All Together: Previous: Updating the coordinate display

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