Table of Contents Previous Chapter

CHAPTER 10 Depictables


10.1 What is a depictable?

A depictable is a software object that contains data and a method for turning those data into a viewable display (referred to herein as `rendering'). The basic defining characteristics of a depictable are its depictable key and DataTime. A depictable key is just a number that points to a table entry describing a particular combination of depictable type, data sets to use, and other items that characterize a particular displayable product. A DataTime object contains information about both valid time and forecast time. A depictable receives data in a relatively unprocessed format, and is responsible for any remapping and graphics generation.

10.2 The depictable class hierarchy

All depictable objects are derived from the Depictable base class. The Depictable class itself contains no hydro-met data, only the metadata that identifies the basic characteristics of the particular instance of the depictable.

Derived from the Depictable class are the two major subclasses, ImageDepictable and GraphicDepictable; all of the concrete depictable types are derived from one of these two. Neither of these classes carries any data at all; they serve just to functionally separate images from graphics. The major difference in the public interface between the two is that ImageDepictable has routines that support doing image combination and drawing color bars.

There are currently just over 50 different concrete depictable types available. Some depictable types have an additional sub-hierarchy beyond just inheriting GraphicDepictable or ImageDepictable. This can result from two or more depictable types sharing a data source, a rendering strategy, or a frame of reference. In a case where two depictables share one or more of these characteristics, but one is an image and one a graphic, they currently need to be in separate sub-hierarchies.

10.3 Support software

This section describes seven different categories of support software that depictables use to do their job of creating viewable displays. Some of these represent class hierarchies and others just groups of related routines.

10.3.1 The Painter class

The Painter class provides an abstract interface for drawing graphics in depictables. The Painter class also contains methods that generate text and symbols using scalable stroke fonts. It does no mapping; it deals only in raw device coordinates. The Painter class is an abstract base class which currently has three concrete derived classes: one that draws to an X drawable (bitmap or pixmap), one that draws to an image (array of char), and one that creates PostScript output. The concrete Painter that writes to X is what is used to create mono-color graphics. The concrete Painter that writes to an image is used for multi-color graphics and for creating color bars in images. The concrete Painter that creates PostScript output is used for hard copy. When the `paint' method is called an object referred to as a `GraphicsTarget' is passed to the depictable and the depictable creates the correct type of painter based on it. The Depictable base class then holds a pointer to this object and uses it to do all of its graphics.

10.3.2 The Depictor class

A depictor (not depictable) is a software object that describes a physical frame of reference. The Depictor class is an abstract base class which has three concrete derived classes: the MapDepictor, the ThermoDepictor, and the XsectDepictor. The MapDepictor class describes a geographic frame of reference (such as a polar stereographic projection); the ThermoDepictor class describes a thermodynamic frame of reference (such as a skew-T diagram); the XsectDepictor describes either a time-height or space-height cross section frame of reference. A Depictor object is generally constructed from a file: *.sup files are used for the MapDepictor, *.thermo files are used for the ThermoDepictor, and *.xsect files are used for the XsectDepictor. A Depictor object carries with it methods for mapping back and forth from a physical coordinate system (lat-lon, pressure-temperature, or distance-height) to an arbitrary cartesian (x-y) coordinate system. A Depictor object also carries with it a domain in arbitrary cartesian space, so it can completely describe a physical frame of reference, such as the Northern Hemisphere scale. A depictor can also be used to describe the frame of reference of raw data sets, such as gridded or image data. Individual depictable keys also have depictors associated with them. By default they are associated with the depictor of the currently selected scale, but an entry in the depictable information table might associate them with, for example, a skew-T diagram. Any time the depictor associated with the depictable being loaded is not equivalent to the depictor associated with the depictable in the display, an implicit clear is generated. This is how the WFO-Advanced knows not to overlay soundings on top of satellite data.

10.3.3 The Xform class

The Xform class is a software object that handles mapping from one frame of reference to another. In this case, a frame of reference could be index coordinates in a grid, latitude and longitude, pressure and temperature, or pixel coordinates in an X window. In the most general case, an Xform is constructed with and data domain, a data depictor, a display depictor, and a display domain. An example of a data domain would be a range of grid indices (e.g. 1 to 95 by 1 to 65 for the AWIPS 211 grid). The data depictor in this case would be one describing the geographic area covered by the grid, and the display depictor would be one describing the output scale. The display domain would be one describing the range of pixel coordinates in the display (e.g. 0 to 919 by 0 to 919 for the big IGC). In this example, the Xform created would provide a mapping from a grid index to a pixel on the display.

The Xform object also allows the user to define an offset origin in data coordinates. There are then methods that allow the user to map points relative to that offset, including the ability to automatically account for any local rotation of the coordinate system rotation. These features are especially useful for plotting station model plots and vector data.

10.3.4 The XformFunctions module

Most of the time, the code that creates Xform objects that depictables use is not actually in the code for depictables. Rather, it is in one of a set of free functions that reside in the module XformFunctions.C. Whatever Xform object is provided by these routines also has the zoom state incorporated into it.

10.3.5 Remapping tables

There are two separate remapping tables classes, ImageTable and GridTable, both of which map data from one grid to another. ImageTable works with grids of bytes and simply copies values from one grid to the other, whereas GridTable works with grids of floats and does bilinear interpolation. GridTable also has the ability to map vector data in a way that handles component rotation from one grid-relative coordinate system to another. In order to operate, both classes require that the size, area, and projection of both the input and output grids be fixed and known. When a remapping table is requested, an attempt will be made to find the table in memory first. If the table is not found in memory, an attempt will be made to read it off of the disk.

10.3.6 Fortran Graphics module

There are many Fortran-based graphics creation routines that we have borrowed from FSL's previous meteorological workstation effort (DARE-II). The FortranGraphics module allows these Fortran routines to make use of the Xform and Painter classes to do graphics. All of the routines in FortranGraphics are free functions. In order to use the FortranGraphics module, a depictable must first give FortranGraphics a Painter and an Xform using the FGinitialize routine. The FortranGraphics module then provides an interface to Fortran routines that has all of the capabilities of the Painter. All coordinates are automatically passed through the Xform that was provided, and the user can specify that coordinates be treated as absolute or offset.

10.3.7 Current usage of Fortran in depictables

There are some general principles followed for interfaces between Fortran and C or C++ in depictables. All C or C++ routines that are intended to be callable from Fortran are global in scope, have all lower case names, are declared as extern "C", and have all variables passed as pointers. It is straightforward to build C strings in Fortran, but difficult to do the reverse. Thus all strings passed to C or C++ from Fortran are declared as simple character arrays, and it is up to the Fortran caller to build an array of bytes with a null terminator. Conversely, if a Fortran routine needs a string passed in from C or C++, it should be declared as a byte array, and it is up to the Fortran routine to convert it to a Fortran string internally. Fortran and C or C++ should never try to exchange C style multi-dimensional arrays (pointers to pointers).

Fortran modules borrowed from DARE-II include the contouring routine, the streamline routine, and the routines that draw fields of wind barbs and arrows from gridded data. Also borrowed from DARE-II are some thermodynamics routines, sounding diagnostics routines, and some horizontal finite differencing routines. We also have adapted a Fortran Redbook decoder from NCEP.

10.4 How depictables work

10.4.1 How depictables create viewable displays

When a depictable is constructed, it generally only gathers metadata. This metadata might include, among other things, information about which specific data sets it needs, or style information. Part of gathering information about data sets usually includes obtaining a depictor (not depictable) object that describes the geographic frame of reference of the data. Examples of style information would be a contouring interval or how to label a color bar.

When a depictable object renders itself, the method used in the depictable is called `paint.' One of the arguments to `paint' is a graphics target. From the graphics target, the depictable obtains a Painter object appropriate to whether it is an image or graphic depictable. Other arguments to `paint' include the size of the display, a depictor that describes the geographic frame of reference of the display scale, and the zoom state.

The hydro-met data needed for creating a display are read in the first time a depictable renders itself. These data are then held within the depictable until the object is destroyed. If the user zooms or roams and the same depictable object needs to render itself again, the depictable does not need to go out and reread the data. Occasionally, the act of acquiring the data held within the depictable might also involve performing some coordinate transformations on the data.

Once a depictable has its data, the process of creating a viewable display begins by creating an Xform from the display and data depictors, the display size, and the zoom state. The location in its native coordinates of each pertinent piece of data is passed through the Xform in order to get its location in display coordinates, and then those display coordinates are passed to a Painter method to plot graphical information representing that data at the proper location on the display. This description is obviously highly simplified, but it is, in essence, what happens.

10.4.2 A specific example

As an aid to understanding how depictables create viewable displays, it is helpful to have a specific example. The depictable that will be used for this example is the depictable that creates a plan view raster image display of satellite data.

The actual C++ class name of this depictable is the SatPVImageDepict. It is directly subclassed from the PVImageDepict, which is subclassed from ImageDepictable. As far as creating a viewable image goes, the SatPVImageDepict only provides a method for retrieving the data; the work of changing this data into an image all happens in the base class PVImageDepict. SatPVImageDepict currently has one sibling class that makes plan view images out of raster data from the Nexrad radar.

During construction, SatPVImageDepict gathers a substantial amount of metadata, but no satellite data. It stores internally the depictable key and DataTime on whose behalf it was constructed. Based on its depictable key, it retrieves depictable information and style information. The most important item of depictable information for this depictable is the list of data keys that refer to the data sets this depictable needs to obtain. The style information determines how the color bar is labeled and how data are scaled and formatted for cursor sampling. Using the data key, the depictable also looks up the name of a file that allows it to construct a depictor (not depictable) that describes the projection and area of the satellite data it is to retrieve.

Most commonly, this depictable has only one associated data key. The first time it renders itself, the depictable passes this data key and the time to a satellite accessor to retrieve an array of bytes that represents the satellite data. The accessor also returns the dimensions of this array, and these dimensions along with the data depictor provide a complete description of the geographic frame of reference of this data.

If the depictor of the display scale and the depictor of the data are determined to have different scales, an image remapping table is used to remap the data to a new geographic frame of reference which has the same projection as the display scale and roughly preserves the areal coverage and resolution of the original. This remapped grid then becomes that which is cached in the depictable and the original data from the accessor are discarded.

Once the display and data are determined to have the same projection, the depictor and dimensions of the display scale, the zoom information, and the depictor and dimensions of the data are passed to one of the modules in XformFunctions called getPVImageXform to get an Xform object that maps from data pixels to display pixels. For image depictables, another item that can be obtained from the graphics target is a pointer to the character buffer in which the IGC expects to receive the output image. This Xform is used to perform a linear mapping from the data to the output character buffer. Finally, using the style information and the Painter, the depictable creates the appropriate color bar.

10.5 Managing depictables

10.5.1 Context of depictables

In order to understand how to manage depictables, it is helpful to understand the context in which they operate. The following is a generalized description of what happens when data are displayed on the WFO advanced.

When the user selects a product button from a data menu, the correct depictable key to load is looked up in the product button info based on the current scale. The user interface process sends this depictable key to the IGC (display process) with a load command. The IGC does an inventory based on this depictable key, and if there are currently no items in the inventory for this depictable key, load processing stops. Otherwise, using the depictable information table, the correct depictor for this depictable key is obtained and compared to what is currently in the display; if they differ, an implicit clear is generated. Next, the inventory that was previously obtained on the depictable key is passed to the time matching routines, which determine which frame gets data for which time. The IGC requests from the DepictableServer a Depictable object for each frame that needs one. A Depictable object is created based on a depictable key and a DataTime. Finally, each depictable object is rendered to its frame.

10.5.2 Adding new depictables

The section will discuss several items with which one needs to be concerned when adding a new depictable to WFO-Advanced. Not all of these tasks need to be performed every time a depictable is added. The discussion here will be at a higher level of detail than has been true up to now, with more references to specific files in the WFO-Advanced software tree. All file name are assumed to begin with ${FXA_HOME}/.

10.5.2.1 Accessor for a new data type

Accessors in general have three methods that need to be available for depictables: constructor, inventory, and access. A very common paradigm is to construct an accessor object based on a data access key, and then the inventory method has no input arguments, and the access method has only a DataTime as an input argument. Some accessors, such as the METAR accessor, don't deal with data access keys at all, since they always deal with only one data set. Often it is possible to make a new depictable type that is only a different way to render an existing data set, in which case a new accessor is not needed.

10.5.2.2 Formally define a new depictable type

The file src/dataMgmt/DM_DepictableInfo.H contains an enumeration called DEPICT_TYPE which is the formal list of all depictable types which can be instantiated. A new item in this enumeration is always required when a new depictable type is created. New items in this enumeration should always be added to the end of the enumeration; changing any of the existing numbering can break things.

10.5.2.3 Code for the new depictable type

The source code for all depictables lives in the directory src/depict. All concrete depictables are derived from either the GraphicDepictable or ImageDepictable class, which are both derived from Depictable. Some depictable types have an additional sub-hierarchy beyond just inheriting GraphicDepictable or ImageDepictable. This can result from two or more depictable types sharing a data source, a rendering strategy, or a frame of reference. In a case where two depictables share one or more of these characteristics, but one is an image and one is a graphic, they currently need to be in separate sub-hierarchies.

10.5.2.4 Enable instantiation of the new depictable type

The source code file src/dataMgmt/DepictableServerDepicts.C contains the routine DepictableServer::newDepictable. This routine returns a depictable object of the desired type as a pointer to the base class Depictable. The depictable information table is used to determine the value of DEPICT_TYPE for a given depictable key; a huge case statement has an entry for each possible displayable depictable type.

10.5.2.5 Enable inventories for the new depictable type

The source code file src/dataMgmt/DepictableInventory.C contains the routine DepictableInventory::allTimes. This routine returns a list of DataTimes based on a depictable key. Just as with DepictableServer::newDepictable, the depictable information table is used to determine the value of DEPICT_TYPE, which then goes to a case statement. In this routine, it is often possible for different depictable types to use the same branch of the case statement. This happens most often when two depictables types are just different ways of displaying the same data set.

10.5.2.6 New data key entries

The file src/dataMgmt/dataInfo.manual is the base data for the data access information for all data types except for gridded data. When changes are made to this file, one needs to rerun the data target in this directory, which will cause gridded data keys to be generated and be put together with the keys in dataInfo.manual to create dataInfo.txt, the file that the workstation reads at start-up to get its data access key information. dataInfo.manual's header documentation describes what each column in the table means. Some columns can have different meanings for different data types. It is assumed that inside a depictable object, the depictable knows what kind of depictable it is and what kind of data it needs, and thus which methods in the DM_DataAccessInfo class (defined in file src/dataMgmt/DM_DataAccessInfo.H) are valid for that data type. It is possible that a new depictable type will require new kinds of data access info; this will require modifying the code for the DM_DataAccessInfo class and adding additional header documentation to dataInfo.manual. In a case where a new depictable type is just a different way of displaying an existing data set, it is possible that no modification needs to be made to this file.

10.5.2.7 New depictable key entries

The file src/dataMgmt/depictInfo.manual is the base data for the depictable information for all depictables except those for gridded data. When changes are made to this file, one needs to rerun the data target in this directory, which will cause gridded data keys to be generated and be put together with the keys in depictInfo.manual to create depictInfo.txt, which the workstation reads at start-up to get its depictable key information.depictInfo.manual's header documentation describes what each column in the table means. While different types of depictables might leave certain columns unused that others do not, in general each column in the depictable information retains the same meaning for all depictable types. Adding a new type of depictable will always result in at least one new line being added to this file.

10.5.2.8 New product buttons

The file src/dataMgmt/productButtonInfo.txt is a table where product buttons are made known to the workstation. Header documentation in this file describes what each column in the table means. For each product button, this file contains a list of which depictable keys get loaded for each scale. Adding a new type of depictable will generally result in at least one new product button being created. In general, there is a one-to-one relationship between product buttons and depictable keys, but it is possible for the same product button to load different depictable keys at different scales and for two or more different product buttons to load the same depictable key.

10.5.2.9 Place new product buttons on the menu

The file src/uiProc/dataMenus.txt determines the layout of the data selection menus. Header documentation describes how to make changes to the file. Any product button needs to be entered in the dataMenus.txt file in at least one place for it to be used to load data. There is in general a one-to-one relationship between product buttons and entries in the dataMenus.txt file, but it is possible for the same product button to occur in two or more places in the data menus.

 
Table of Contents Next Chapter


This document is maintained by Joe Wakefield. Last updated 9 Jan 97.