Go to the previous, next section.

Introduction

The idea behind Ingrid is to provide a language where a basic element is the dataset. The language should then be able to manipulate datasets in useful ways, like printing, plotting, saving, and doing simple calculations.

A dataset, in this context, consists of a large multidimensional array of numbers, along with a fair amount on ancillary information, like where the data came from and what manipulations have been done to it.

On the other hand, most calculations that are to be performed on this dataset do not required the entire dataset at once. If, for example, we want the natural log of each element of the dataset, we are perfectly happy getting one number at a time. In plotting, too, we only want the data that appears on the picture we are creating at the moment.

In order to provide this basic element, Ingrid contains an object called a stream. It is implemented as an Ingrid object one of Ingrid's fundemental data types (see section Ingrid elements). A stream object contains all the ancillary information for a dataset, plus it contains the basic information needed to access the actual data. The dataset is viewed as a series of chunks. For example, if the actual data is a function of XYT, we may want to consider it to be a series of XY chunks, with each chunk corresponding to a different T. This would be the appropriate level of chunking, for example, for making color XY plots. If, on the other hand, we were interested in making XT plots, we would like to consider the data to be ordered XTY, and have XT chunks. Built in to Ingrid are the operators necessary to reorder and rechunk data, Thus each filter or other operator added to Ingrid merely needs to specify the size and content of the chunks of data that it would like to receive, and Ingrid organizes the flow of data so that function gets the data it needs for each step of the calculation.

This manipulation of data is mostly transparent to the user. A simple example of an Ingrid session would be something like

\begin{ingrid}
PS SOURCES                  % access PS definitions and data catalog entries
LEVITUSMEAN temp            % gets a stream of LEVITUS temperature data
    X -180 VALUE            % restricts the stream to one particular X value
    Z 1000 0 RANGE          % restricts the stream to the upper water column
    Y Z CONTOUR             % generates an YZ contour plot
\end{ingrid}
These commands do make some sense without knowing the stack behavior. But knowing the stack behavior allows advancing to more powerful uses of Ingrid. Each word in the command file is interpreted individually. The resulting actions are given below
PS
( -- object) PS is an object that contains the basic plotting words (such as COLOR). It is a separate object because it is possible that someday there may be another graphics format supported (such as X-windows or gl), and a COLOR plot may be moved from PostScript to X-windows simply by replacing PS by X11. But at the moment PS is the only set of graphics words.

As long as the PS object is on the stack, the PS words are available.

SOURCES
( -- object ) SOURCES is an object that contains all the entries in the data catalog, as well as the entry MODEL that contains streams that correspond to a model that Ingrid is attached to (if Ingrid is attached to a model).

As long as the SOURCES object is on the stack, the SOURCES words are available.

LEVITUSMEAN
( -- object ) In the current implementation, LEVITUSMEAN is a stream which contains two special filters temp and sal.

In the future this will be changed so that LEVITUSMEAN is an object that contains two streams temp and sal. This new behavior is more consistent with the MODEL object and the netcdf objects that readCDF returns. At that point the phrase LEVITUSMEAN temp would become LEVITUSMEAN >temp. This works because >temp is a special Ingrid shorthand that executes temp, then rmoves LEVITUSMEAN from the stack. Thus > can be thought of as "extract".

temp
(stream -- stream') restricts the LEVITUSMEAN stream to be only temperature.
X
( -- grid) gets the X grid from the stream. Since the restricted LEVITUSMEAN stream is the top object on the stack, the definition of X is taken from there (in this case, 360 pts spaced every degree).

grids are implemented as special stream objects.

VALUE
(stream grid num -- stream' ) restricts the stream so that the X grid has only the single value num (in this case, -180). Note that if we said X at this point, we would get back a grid with a single point in it.
Z
( -- grid ) gets the Z grid from the stream.
RANGE
( stream grid low high -- stream' ) modifies the stream to only have Z values between 1000 and 0. Note that the original grid went from 0 to 5500, i.e. we have reversed the grid as well.
CONTOUR
( stream grid1 grid2 -- ) CONTOUR takes the stream and two grids from the stack, generating a contour plot of the data.

In fact, what CONTOUR does first is reorder the stream so that X is the fastest varying index and Y is the second fastest; the routine that does the actually plotting is then handed chunks of data that are easy to plot, and the routine is called once for each plot it needs to make.

At this point the stack contains Ingrid: PS SOURCES, and another plot could be made.

Go to the previous, next section.