Go to the previous, next section.

Language

The Ingrid language has both elements and objects. Elements are a small set of datatypes, fixed in number, which form the nucleus of the Ingrid language. Objects are one of those elements, and they are the basis of most of the power that Ingrid has. At one level, objects, can be used as dictionaries, i.e. lists of words and their definitions. Ingrid:, PS, SOURCES are examples of such objects. In these cases the words are kept in separate lists merely to attain some neatness that would be lost with a single long list of words.

But the streams themselves are also objects. And while many streams contain the word X signifying one of their grids, in fact the X grid for many of the streams differ, so the fact that the definition of X is contained within its parent stream allows the proper grid to be retrived relatively automatically.

There are three sections that follow. The first gives the objects that should be included in almost all Ingrid input files, so that the needed words are available. The second gives the basic Ingrid elements. And the third gives the basic Ingrid Objects.

Starting an Ingrid file

When FGFILE starts interpreting a file, the stack is set to be just the Ingrid: object. Thus most files should start with
\begin{ingrid}
PS SOURCES MODEL
\end{ingrid}

SOURCES' so that the data catalog and MODEL' are available, MODEL' so that model variables can be accessed by name (SSTT', for example), and PS', so that laser plots can be generated. If you wish to define any words, it is a good idea to do it before PS SOURCES MODEL so that the definitions go into Ingrid:, otherwise the definitions go into MODEL, which may not be what you want.

Syntax

As far as syntax is concerned, Ingrid is very close to PostScript, and a close reading of the PostScript reference manual will give you an adequate understanding of the subject. Here we present a brief summary, in part from that manual.

File scanning

When given a file to interpret, Ingrid scans the entire file before performing any calculations on the data contained in streams. Ingrid ignores all text outside of \begin{ingrid} \end{ingrid} pairs, i.e. all such text is considered as comments. Note that \begin{ingrid} must be a line by itself, and it must be at the beginning of the line (i.e. text column 1).

All text between \begin{ingrid} and \end{ingrid} is broken down into tokens, and those tokens are interpreted.

Special Characters

The characters SPC, TAB, and LFD are considered whitespace and are treated equivalently outside of comments and strings. Whitespace separates tokens.

The characters (, ), /, >, [, ], {, }, and % are special: they delimit syntactic entities such as strings, procedures, literal names, and comments. Any of these characters terminate the token preceeding it and are not part of that preceeding token.

All other characters are regular characters.

Comments

Any text between a % and the end of that line is considered a comment. (The only exception is that % can be within a string). Thus lines that begin with % are comments. As mentioned before, any text outside of a \begin{ingrid} \end{ingrid} pair is also considered a comment.

Ingrid elements

Like PostScript, the elements that can be on the stack are typed. The types supported in Ingrid are
arraytype
This is an array of other Ingrid elements. Most commonly created by enclosing elements in []. Like PostScript, an executable array is a procedure.
booleantype
Either true or false.
integertype
A numeric integer.
marktype
Like the PostScript mark, used to hold a position on the stack.
nametype
Sequences of characters in the input file that cannot be converted to numbers are converted to names, like RANGE or LEVITUSMEAN. These names are used to extract entries from objects, and sequences of names are used to create procedures. A name preceded by a / is treated as a literal, and simply placed on the stack. Otherwise the name is executed. If the name is preceded by a >, then whatever is currently on top of the stack is removed (popped) after name is executed. This allows one to execute name within an object and not leave that object cluttering the stack.

Internally, names are kept as a single integer (a fact that should not turn up in ordinary coding).

nulltype
Used as a placeholder, i.e. initial values of an array or unset values of some parameter.
operatortype
Ingrid functions that are built-in, i.e. written in FORTRAN or C.
realtype
A real numeber.
stringtype
A sequence of characters, delimited by () in the interpreter.
objecttype
Similar to the PostScript dictionary, an object contains a list of name--any pairs, where any is any Ingrid element. Objects are used in two important ways. First of all, objects contain the executable code that makes Ingrid work (the object Ingrid:, for example, contains all the basic Ingrid words, like add and pop, etc). Objects also contain the information to access data (streams are implemented as objects).

Objects differ from dictionaries in two important ways. First of all, objects have parents, so that a child object can access all the definitions of its parent. Streams, for example, are implemented by having a parent object STREAM, which contains all the operators that can operate on streams, and each stream is then a child object of STREAM.

Secondly, objects are active when they are on the data stack (in PostScript they have to be moved to the dictionary stack before they are searched). Thus, if I want the X grid of the HELLERMAN taux data, I simply say

HELLERMAN taux X

This also means that the defintions of PS and Ingrid: are made available simply by placing them on the stack at the beginning of the session.
realarraytype
This is an array of real numbers, making it possible for Ingrid to directly access Fortran real arrays.
integerarraytype
This is an array of integers, making it possible for Ingrid to directly access FORTRAN integer arrays.
namearraytype
This is an array of FORTRAN integers, interpreted by Ingrid as names.

Major objects

What follows is essentially a dictionary, giving the definitions of all the major words within Ingrid. These words are grouped into several objects: Ingrid: which contains all the basic words plus the remaining major objects, SOURCES which contains all the data files in the data catalog plus MODEL, PS which contains the words used to make PostScript (laserwriter) plots, and MODEL which contains all the variables in the model the library is currently attached to (possibly none, in the case of a program that just operates on the data catalog).

Ingrid:

Ingrid: is broken into two parts: FastGrid:, which contains the basic words, and Ingrid:, which contains less fundemental but generally useful words.

Eventually, FastGrid: will contain all the words in PostScript that are appropriate, plus the words that are unique to Ingrid but in some sense just as fundemental. These definitions are contained in FastGrid: which is the parent of Ingrid:: to get a list of the currently defined words in FastGrid: one must type within Ingrid:

parent ===


Basic words

The basic words of Ingrid as as follows:

==
( any -- ) print FGIelement to stdout. If ==alias or ==do exist within an object, they are used to print the object, i.
===
( any -- ) print FGIelement to stdout (long representation).
NaN
( -- real ) real constant equal to NaN.
add
( num num -- num ) adds two numbers.
aload
( array -- any1, ... , anyn array ) gets FGIelements from array.
and
( bool bool -- bool ) logical and' of two booleans.
append
( string/array_1 string/array_2 -- string/array ) combines two strings or arrays into one by concatenation.
array
( n -- array ) makes array of size n.
astore
( any1, ... , anyn array -- array ) stores FGIelements into array.
begin
( object -- ) pushes object onto dictionary stack. This stack is searched for definitions before searching the regular stack.
cleartomark
( mark any ... -- ) clears to most recent mark on stack.
copy
( any_1 ... any_n n -- any_1 ... any_n any_1 ... any_n ) duplicates the top n elements on the stack.
counttomark
( mark any_1 ... any_n -- n ) counts items to mark.
cvi
( real -- int ) converts real to int.
cvlit
( any -- any ) makes any literal rather than executable.
cvn
( string -- name ) converts string to name.
cvntos
( name -- string ) converts name to a string.
cvx
( any -- any ) marks any executable.
def
( name any -- ) defines name to be any in the current object. If the object is full, extends it and places the new definition in the extension.
div
( num num -- num ) divides.
dup
( any -- any any ) duplicates.
end
( -- ) removes an object from the dictionary stack.
eq
( any_1 any_2 -- bool ) returns true if the two objects are equal. strings, objects, and arrays must be duplicates of the same array: having the same values is not sufficient.
exch
( any_1 any_2 -- any_2 any_1 ) swaps two elements on the stack.
exec
( any -- ) executes top element on the stack.
false
( -- bool ) returns false.
for
( lo step hi proc -- ) loops from lo to hi by step by pushing the current value on the stack and executing proc.
forall
( array proc -- ) executes proc for each element in array by pushing the first element onto the stack, executing proc, pushing the second element onto the stack, etc.
forsome
( object botobject skipobject proc -- ) Like forall in that each entry in object is pushed on the stack (name and value) and proc is executed, but some entries are not executed. If botobject is a parent object to object or any of its parents, object is considered to end above botobject. skipobject is a list of names (their definitions are ignored) that are also not operated upon. botobject can be null, in which case the whole object is processed. skipobject can be null, in which case no definitions are skipped. \par skipobject must have parent null.
ge
( bool bool -- bool ) greater than or equal to.
get
( array index -- any ) extracts any from array: array can also be a string, a realarray, an integerarray, or a namearray. Also works on objects: ( object key -- any ).
getinterval
( array index count -- subarray ) extracts subarray from array: array can also be a string, a realarray, an integerarray, or a namearray.
gt
( num num -- bool ) greater than.
if
( bool proc -- ) executes proc if bool is true.
ifelse
( bool proc_1 proc_2 -- ) executes proc_1 if true, proc_2 if false.
index
( any_n ... any_0 n -- any_n ... any_0 any_n ) copies nth element to top of stack.
integerarray
( n -- integerarray ) makes an integer array of size n.
known
( object name -- bool ) returns true if name is defined in object.
le
( num num -- bool ) less than or equal to.
length
( array/string -- int ) returns length of array or string.
lt
( num num -- bool ) less than.
mark
( -- mark ) returns a mark.
max
( num num -- num ) returns maximum.
maxlength
( object -- int ) returns maximum length of object.
max==array
( -- int/null ) maximum number of array elements to print.
min
( num num -- num ) returns minimum.
mul
( num num -- num ) returns product.
namearray
( n -- namearray ) makes a name array of size n.
ne
( num num -- bool ) not equal.
not
( bool -- bool ) logical not.
null
( -- null ) returns a null element.
object
( parent size -- newobject) creates a new object from parent of size.
parent
( object -- parent) returns parent of object, null if no parent.
pop
( any -- ) removes object from stack.
print
( string -- ) prints string to stdout.
pstack
( any_1 ... any_n -- any_1 ... any_n) prints stack without changing it.
put
(array/string/dict index/key any -- ) puts any into array/string/dict with given index/key.
putinterval
( array/string index array/string_2 -- ) puts array_2 into array_1 at index (first element is zero).
realarray
( n -- realarray ) makes a real array of size n.
repeat
( i proc -- ) repeats proc i times.
roll
( any_{n-1} ... any_0 n j -- any_{(j-1) \mod n} ... any_0 any_{n-1} ... any_{j \mod n} ) performs circular shift on stack.
round
( num -- num ) rounds number to nearest integer (but real in implies real out).
setmax==array
( int/null -- ) sets maximum number of array elements to print, null means print all the values.
split
( any [ proc_1 ... proc_n ] -- ) applies each of the procedures in the array [ ] to any, i.e. for each procedure pushes any onto the stack and then executes proc. Usually used to split a stream into substreams.
string
( int -- string ) creates a string of the specified length.
sub
( num num -- num ) subtracts.
type
( any -- name ) returns name of type of any.
true
( -- bool ) returns true.
xor
( bool bool -- bool ) logical eXclusive OR.

Utility words

There are some generally useful words that are in the object Ingrid: but are not really fundemental.
!
( any name object -- ) defines any as name in object, i.e. it is put with the arguements are reversed.
concat
( [ string1 \dots stringn ] -- string ) concatenates an array of strings together.
ensotime
( day month year -- time ) Converts day month year into ensotime (months since 1 Jan 1960). Month can be given as an integer between 0 and 11 or a three-letter capitalized abbreviation: Jan, Feb, Mar, ....
leftlines
( array/string -- ) prints an array of strings with each string on a separate line.
inputs
( arg1 ... argn { nam1 ... namn } -- object ) names n input arguments arg1 ... argn with the n names nam1 ... namn. Returns the names in an object.
outputs
( object { nam1 ... namn } -- out1 ... outn ) extracts the list of outputs from object. One can then write programs of the form
/myprog {
{ in1 in2 in3 } inputs

/outa in1 in2 add def
/outb in2 in3 sub def

{ outa outb } outputs
} def

Note this example could be written as
/myprog {
{in1 in2 in3 } inputs
begin
in1 in2 add % outa
in2 in3 sub % outb
end
} def

with only a slight loss of clairity, and a gain in efficiency. It is your choice.
putget
( object name any -- any ) stores any in object with name, preserving a copy of any.
set.
( -- mark ) puts a mark on the stack for ..
.
( mark any ... -- mark ) clears the stack back to a mark.

set. and . are intended to simplify command writing by removing garbage from the stack. For example,

\begin{ingrid}
PS SOURCES set.

HELLERMAN2 taux tauy X Y VECTOR .

HELLERMAN taux X Y CONTOUR .
\end{ingrid}

By ending each command with ., we can be assured that leftover objects are not accumulating on the stack. Purely a matter of style.

Structures

Structures are implemented with a set of words that are in structureWords. They are intended to be used to communicate with FORTRAN programs, i.e. a structure containing various parameters is passed in as the first argument of a FORTRAN subroutine when it is called as the result of a FGIoper call. Structures are first created, then used, i.e.
/regridS
structure
/N1 integer
/N2 integer
/N3 integer
/icoor integer
/si integer
/ra 4 realarray
endstructure
def

This structure can now be used to create a realization (called a RECORD in FORTRAN).
/fred
regridS new def % creates a new realization called fred
fred store begin  % goes into a mode where each word stores its value
1 N1              % stores a value for N1
2 N2              % stores a value for N2
3 N3
4 icoor
5 si
1. 2. 3. 4. ra    % stores 4 real values into the realarray ra
% the last element must be real
end               % gets out of store' mode

We can now use fred where a structure is required (i.e. FGIfunc routines) or to extract individual values or to print. fred is now an object whose definitions return values from the structure realization's record.
fred
N1 N2 add ==		% adds N1 and N2 and prints
0. ra { add } forall == % sums the elements of ra
==                      % prints fred

One can also create structures that are equivalent to FORTRAN common blocks. To continue our example with fred, suppose there is a FORTRAN common block declared as
COMMON/fredblk/N1, N2, N3, icoor, si, ra(4)

We could then create a realization of regridS that is equivalent to this common block, namely
CALL FGIcommon('fredblk','regridS',N1)

N1 being the first location in the common block. We can now place values in the common block by using Ingrid,
fredblk
store begin        % puts fredblk into 'store' mode
10 N1
20 N2
30 N3
40 icoor          % stores an integer into icoor
50 si             % stores an integer into si
1. 2. 3. 4. ra    % stores real data in fredblk
end                % takes fredblk out of 'store' mode
N1 ==              % prints the value of N1
==                 % prints the common block fredblk


The words available are as follows.

FGIcommon(NAME,STRUC,COMM)
( -- ) Creates a realization of STRUC named NAME that is equivalent to Fortran Common block COMM (COMM should be the first element of the common block).
structure
( -- object ) starts a new structure.
endstructure
( object -- object ) ends the defining mode of a new structure.
byte
( name -- ) adds a one byte integer to the structure. This is FORTRAN INTEGER*1.
element
( name -- ) adds an FGIelement (eight bytes) to the structure. This can hold any Ingrid object, though such an element would almost always need to be passed back into Ingrid to be useful. This is a FORTRAN RECORD of type FGIelement (defined in an Ingrid header file).
integer
( name -- ) adds an integer to the structure. This is equivalent to FORTRAN INTEGER*4.
integerarray
( name length -- ) adds an integer array to the structure. This is equivalent to FORTRAN INTEGER*4
myname
( name -- ) names the structure (quite optional).
name
( name -- ) adds an integer to the structure which is considered to be a name in Ingrid.
namearray
( name length -- ) adds an integer array to the structure which is considered to be an array of names in Ingrid.
real
( name -- ) adds a real number to the structure. This is equivalent to FORTRAN REAL*4.
realarray
( name length -- ) adds a real array to the structure. This is equivalent to FORTRAN REAL*4.
short
( name -- ) adds a short (two byte) integer to the structure. This is equivalent to FORTRAN INTEGER*2.
string
(name length -- ) adds a string of length characters to the structure. This is equivalent to FORTRAN CHARACTER.

STREAM

STREAM is the parent object to all streams (and indirectly all grids, since grids can be treated as streams). While the object STREAM is never needed directly, the definitions it contains are available whenever a stream is on the stack, and the words can be used to manipulate streams in a number of ways.

stream/netCDF attributes

In the spirit of minimizing differences, we want to support most of the commonly used' netCDF attributes. These attributes allow one to label datasets with ancillary information, and also allow STREAM filters to carry that information along.

The attributes that have string values (fullname, title, history) allow one to use a math escape (see section Math Mode) to put simple mathematical expressions into labels.

A stream can have other attributes as well, these are simply the standard ones that the built-in filters in Ingrid process. Other attributes will be carried along even if they are primarily ignored.

See section Setting STREAM attributes for more explanation of how to modify these attributes for a particular stream.

history
( -- array ) returns a nested array of strings which contain the history of manipulations of the current stream. history starts with a null definition.
name
( -- name ) short name of stream.
fullname
( -- array of names/strings ) full name of stream. This is not a standard netCDF attribute, but because it is a list of names, it allows filters that combine multiple streams to keep common names common, making the labels on the streams much more useful.
longname
( -- string ) returns a string describing the current stream: defaults to string version of fullname. Because of the added utility of fullname, keeping the default behavior is strongly recommended.
long_name
( -- string ) returns longname. Exists because it is the standard netCDF name.
title
( -- string) returns a short description of the stream: defaults to null.
units
( -- name ) units of data in the current stream: units defaults to real. See section Units for a discussion of appropriate values.
missing_value
( -- null/real ) value to use as a missing data flag. Many stream filters changed this to NaN. It defaults to null, which means there is no missing data flag.
scale_factor
( -- real ) simple data compression scale factor.
add_offset
( -- real ) simple data compression offset (applied after scale_factor).
FORTRAN_format
( -- string ) FORTRAN format to use while printing data values. It is normally the format for printing a single number, though this is not necessarily the case. For more information, See section STREAM printing.

Setting STREAM attributes

STREAM attributes are set by defining the corresponding attribute within the stream. For example
HELLERMAN taux
/title (This is HELLERMAN wind stress) def
/fullname ($tau sub x$) cvn def

adds a title to the HELLERMAN data and modifies the name used for labelling plots.

It is important to make these definitions within the stream: a definition made elsewhere will just be ignored.

Math Mode

Within some of the attribute strings, a pair of $signs is used to delimit a "math mode", where words are interpreted specially to create mathematical expressions. Within the pair$ $, words are blank delimited, and each word is checked against a list of symbol names (the names of the characters in the PostScript symbol font, see the PostScript reference manual), to be replaced by the corresponding symbol if it exists. Two special words, sub and sup are used for subscripts and superscripts, i.e. $ alpha sub i $ will give an alpha with a subscript i. Words that are not translated to a symbol are printed in an italic font. Outside the pair$ $, text is interpreted normally and printed in the usual font. For example /title (This is$partialdiff sub x phi + partialdiff sub y theta\$.) def

will give @math{@partial @sub x @phi + @partial @sub y @theta}. This expansion is done in the PostScript printer or in the PostScript previewer, so the strings will appear as you have typed them everywhere else (i.e. netCDF files, the l... files, etc).

Units

While any word is a legal choice for the units attribute, some units are understood by Ingrid and are handled specially.
C
Temperature in degrees Celsius.
K
Temperature in degrees Kelvin.
latitude
Latitude, i.e. positive values have a trailing N and negative values have a trailing S.
longitude
Longitude, i.e. postive values have a trailing E and negative values a trailing W. Values are treated mod 360.
integer
Printed as an integer number, if close to an integral value.
real
Printed as a real number. This is the default, i.e. any units attribute that is not recognized is printed as a real number.

Julian day is defined to be the number of each day, as reckoned consecutively since the beginning of the present Julian period on January 1, 4713 B.C.; the Julian day begins at noon, 12 hours later than the corresponding civil day. Ingrid has several functions to allow using Julian day as units, to allow some control over printing appearance.

julian_day
Prints as day month year.
julian_day.day
Only prints day.
julian_day.month
Only prints month.
julian_day.year
Only prints year.

In this climate prediction group, we have traditionally used units of 'monthtime', i.e. months since January 1960. There are several choices of units which correspond to monthtime: they differ only in print format.

monthtime
prints as month year.
date
prints as day month year.
day
prints as day.
month
prints as month.
year
prints as year.
daymonth
prints as day month.

There is a minimal facility for converting data to standard units (MKS). There is a simple access

convertunits
( real/stream units -- real/stream ) converts real/stream according to units.
New conversions can be added to the object UnitsConversion.

STREAM selection

STREAM
( -- object ) parent object for streams.
The following words are generally useful and found within the STREAM object. Since STREAM is the parent object for all streams, these words will always be available if there is a stream on the stack.

These words allow one to select portions of the data contained in the STREAM.

RANGE
( stream grid low high -- stream' ) samples stream along one coordinate, restricting the stream to a range of values. low is rounded down and high is rounded up, so that the range requested will be within the stream.
RANGESTEP
( stream grid low high step -- stream' ) samples stream along one coordinate, first restricting the stream to a range of values and then sampling at the interval step. low is rounded down and high is rounded up, so that the range requested will be within the modified stream.
SAMPLE
( stream grid grid2 -- stream' ) samples stream along one coordinate grid according to grid2. Each element of grid2 is moved to the nearest grid value.
STEP
( stream grid step -- stream' ) samples stream along one coordinate. step is rounded according to the grid.
VALUE
( stream grid value -- stream' ) samples stream along one coordinate. value is moved to the nearest grid value.
VALUES
( stream grid array -- stream' ) samples stream along one coordinate. Each element of array is moved to the nearest grid value.
sirecord==
( stream -- stream ) print sirecord of the current stream. Used primarily to check whether the current stream has the correct set of grids.
makeperiodic ( stream grid period -- stream' ) makes a stream
periodic in grid with period.

Stream filters

In addition to the basic selection words -- RANGE, VALUE and STEP (see section STREAM selection) -- there are a number of STREAM filters. These are words who take one or more streams as input, and return a stream as output. Some functions also work on real numbers.

Other functions can be added. Read the section on FGIscalarFilter (see section FGIscalarFilter) if you would like to add scalar functions, or read the section on FilterVector (see section FORTRAN routines) to add functions of vectors. More complicated functions require more understanding of Ingrid.

Functions

chunkaverage
( stream -- stream ) averages the chunk of a stream to a single number.
chunkmin
( stream -- stream ) returns the minimum value within the chunk, ignoring NaN.
chunkmax
( stream -- stream ) returns the maximum value within the chunk, ignoring NaN.
chunksum
( stream -- stream ) returns the sum over the chunk, ignoring NaN.
cos
( stream/num -- stream/real ) cosine of a stream or number. Argument in radians.
cosd
( stream/num -- stream/real ) cosine of a stream or number. Argument in degrees.
eexp
( stream/num -- stream/real ) power base e of a stream or number.
ln
( stream/num -- stream/real ) natural log of a stream or number.
log
( stream/num -- stream/real ) log (base 10) of a stream or number.
pi
( -- pi ) returns 3.14159265.
sin
( stream/num -- stream/real ) sine of a stream or number. Argument in radians.
sind
( stream/num -- stream/real ) sine of a stream or number. Argument in degrees.
sqrt
( stream/num -- stream/real ) square root of a stream or number.
sqrtsgn
( stream/num -- stream/real ) square root of a stream or number, negative arguments result in a negative answer.
min
( stream/num stream/num -- stream/real ) minimum of corresponding elements in two streams.
max
( stream/num stream/num -- stream/real ) maximum of corresponding elements in two streams.
GRID
( stream grid low step hi -- stream' ) Using linear interpolation, regrids stream to an evenly--spaced grid [ low to high by step ] in variable grid.
REGRID
( stream grid1 grid2 -- stream' ) Using linear interpolation, regrids stream from grid1 to grid2.
RESCALE
( stream scale offset -- stream' ) multiplies data by a scalar and adds a scalar. Alternatively, one can use mul and add, see below.
SAMPLE
( stream grid grid2 -- stream' ) samples stream along one coordinate grid according to grid2. Each element of grid2 is moved to the nearest grid value.
toNaN
( stream -- stream' ) modifies a stream so that if it has a missing data flag that flag is changed to NaN.
FillNaN
( stream grid default -- stream' ) modifies a stream so that if it has a missing data flag the missing data is filled in. The missing data is filled in with the nearest valid data along 'grid': if the entire vector is invalid data the default value is used. For example, if the stream is two dimensional, with X zonal and Y meridional, then
stream X 0. FillNaN

fills in missing data by carrying data zonally; 0. is used if an entire latitude is invalid data. The function is symmetric: land with ocean on both sides is replaced by values that have a sharp transition in the middle of what used to be land.
removeGRID
( stream grid -- stream' ) returns a stream where grid is removed. Will only remove single point grids. The distinction between a stream with a single point grid and one without is best explained by example: If you subtract a stream with a single T point from a stream with many T points, you will get a stream with the single T point. If you subtract a stream without a T grid from a stream with many T points, you will get a stream with many T points.
renameGRID
( stream grid newname -- stream' ) returns a stream where grid is renamed to newname.
replaceNaN
( stream default -- stream' ) modifies a stream so that if it has a missing data flag the missing data is filled in by default. The stream then no longer has a missing data flag.
setmissing_value
( stream value -- stream' ) modifies a stream so that if it has a missing data flag, the missing data is filled in by value. The stream then has a missing data flag of value.
SM121
( stream grid1 grid2 n -- stream' ) applies n passes of two-dimensional 121 smoothing to a stream. grid1 and grid2 are the two dimensions that are smoothed over.
add
( stream1 stream2 -- stream' ) adds two streams value by value. Works for any combination of streams and scalars.
sub
( stream1 stream2 -- stream' ) subtracts two streams value by value. Works for any combination of streams and scalars.
mul
( stream1 stream2 -- stream' ) multiplies two streams value by value. Works for any combination of streams and scalars.
div
( stream1 stream2 -- stream' ) divides two streams value by value. Works for any combination of streams and scalars.
distrib
( stream min step max -- stream' ) gives the distributions of values for a given stream @math{d(x,y,z,t)} by returning a new stream @math{f(d)} which gives the number of occurrences of data points nearest the values @math{d @sub i} which are equally spaced from min to max in steps of step.
distrib2D
(stream1 DATA low high step RANGESTEP stream2 DATA low high step RANGESTEP -- stream1 ) returns bivariate distribution cnt(stream1,stream2).
gridtomatch
( stream1 stream2 -- stream1' ) Using linear interpolation, regrids stream1 to match the grids (and chunking) of stream2. This is particularly useful for reading data into models, e.g. one can write

CALL SetIVAR1('X','longitude',NX,XS,XE)   ! defines X grid
CALL SetIVAR1('Y','latitude',NY,YS,YE)    ! defines Y grid
CALL SetIVAR1('T','real',NT,TS,TE)        ! defines T grid

IDH = NewVar('H','/MODEL /H','XYT','XY')  ! defines stream H

IDHIN = IDSTREAM('Hin H gridtomatch')     ! defines a stream which is
! Hin regridded to match H

...

DO I = 1 , NT                  ! loop to retrive the regridded Hin
CALL FGGET(IDHIN,H)         ! in blocks of XY, one block for each T
END DO

to read in the stream Hin into the array H, regridded as needed.

gridtomatch can also be used to control regridding in other situations. For example, if you would like to regrid a climatology to an anomaly before adding them together,

\begin{ingrid}
GL SOURCES                  % accesses X/GL graphics and data catalog

CACSSTA ssta                   % gets sst anomaly
OSUSFC.DATA sstt
CACSSTA ssta gridtomatch   % regrids climatology to anomaly's grid
add                            % adds regridded climotology to anomaly

DATA 20 30 2 RANGESTEP         % specifies color scale
X Y COLORCONTOUR               % color contour plot
\end{ingrid}


gridtomatchnamed
( stream1 stream2 object name -- stream1' ) Using linear interpolation, regrids stream1 to match the grids (and chunking) of stream2 (using gridtomatch). Also names that stream as name in object.

If verbose is true, then a message is printed describing the input stream. verbose defaults to false.


CALL SetIVAR1('X','longitude',NX,XS,XE)   ! defines X grid
CALL SetIVAR1('Y','latitude',NY,YS,YE)    ! defines Y grid
CALL SetIVAR1('T','real',NT,TS,TE)        ! defines T grid

IDH = NewVar('H','/MODEL /H','XYT','XY')  ! defines stream H

IDHIN = IDSTREAM('Hin H MODEL /Hin2 gridtomatchnamed')
...

DO I = 1 , NT                  ! loop to retrive the regridded Hin
CALL FGGET(IDHIN,H)         ! in blocks of XY, one block for each T
END DO


AVERAGE
( stream grid -- stream ) averages data in stream over grid.
SUM
( stream grid -- stream ) sums data in stream over grid.
mean
( A -- C ) or ( A [ grid1 grid2 ... ] qual -- AM ) returns mean of A values. If [ grid1 ... ] is given, then the mean AM will depend on those grids, i.e. AM(grid1, ...). qual is the minimum fraction of data that must be present to return a value, e.g. if qual is .5, then all points which had more than half the data missing are marked missing.

meansq
( A -- C ) or ( A [ grid1 grid2 ... ] qual -- AM ) returns mean square of A values. If [ grid1 ... ] is given, then the mean AM will depend on those grids, i.e. AM(grid1, ...). qual is the minimum fraction of data that must be present to return a value, e.g. if qual is .5, then all points which had more than half the data missing are marked missing.

rms
( A -- C ) or ( A [ grid1 grid2 ... ] qual -- AM ) returns mean of A values. If [ grid1 ... ] is given, then the mean AM will depend on those grids, i.e. AM(grid1, ...). qual is the minimum fraction of data that must be present to return a value, e.g. if qual is .5, then all points which had more than half the data missing are marked missing.

average
( A [ grid1 grid2 ... ] qual -- AM ) returns the average over the specified grids, skipping missing_values. qual is the minimum fraction of data that must be present to return a value, e.g. if qual is .5, then all points which had more than half the data missing are marked missing.

rmsover
( A [ grid1 grid2 ... ] qual -- AM ) returns the rms averaged over the specified grids, skipping missing_values. qual is the minimum fraction of data that must be present to return a value, e.g. if qual is .5, then all points which had more than half the data missing are marked missing.

standardize
( A [ grid1 grid2 ... ] qual -- AM ) returns the renormalized time series; mean and rms is computed over the specified grids, skipping missing_values. qual is the minimum fraction of data that must be present to return a value, e.g. if qual is .5, then all points which had more than half the data missing are marked missing.

correlate
( A B [ grid1 grid2 ... ] qual -- C ) returns the correlation computed over the specified grids, skipping missing_values. qual is the minimum fraction of data that must be present to return a value, e.g. if qual is .5, then all points which had more than half the data missing are marked missing. Note that the time series are first renormalized separately, so that if there is a lot of missing data then the means and standard deviations for the time series could be computed over very different subdomains of the data, a long-winded way of saying that in pathological cases you could get correlations greater than 1.

boxAverage ( stream grid interval -- stream ) reduces grid
to step interval by averaging.
regridAverage ( stream grid grid2 -- stream ) changes grid
to grid grid2. The grid change is done by averaging, effectively using fractional weights at the edges of intervals if necessary to center the intervals on the output grid.
evengridAverage ( stream grid low step high -- stream ) changes
grid to an even grid that goes from low to high by step. This uses regridAverage.
yearly-climatology
( stream -- stream' ) creates a climatology by averaging the T grid with a step of 12, i.e. a yearly average.
splitstreamgrid
( stream grid period -- stream' ) splits grid into a grid that steps within period and a grid that has step period using word splitgrid, then alters the stream so that it corresponds to the new grids. The second grid is renamed by appending a 2. Data beyond an integral multiple of period is truncated. The values of the second grid are multiples of the period; the sum of the value of the first grid and the value of the second grid give the original grid value for any particular data point.
integral
( stream grid/stream -- stream ) integrates stream with respect to grid. This shifts the grid in the opposite sense of partial, so that the two operators cancel each other, i.e. partial and integral are inverse operators (modulo the integration constant if you take the partial first).

Simple 1D streams can be used as grids, i.e. you can fix the units on the grid by multiplication.

definite-integral
( stream grid low high -- stream ) integrates stream with respect to grid from low to high. It interpolates the end points if necessary, i.e. the limits do not have to be grid points.
partial
( stream grid/stream -- stream ) takes partial derivative of stream with respect to grid. The partial derivative is computed by taking the difference between two values of the input stream, normalized by the grid distance between them. The grid is shifted so that each value of the new stream is centered between two values of the old stream.

Simple 1D streams can be used as grids, i.e. you can fix the units on the grid by multiplication.

differences
( stream grid -- stream ) takes differences of stream along grid. These are the pairwise differences that would be normalized by the grid widths in order to calculation the partial derivative along grid. The grid is shifted so that each value of the new stream is centered between two values of the old stream.
sums
( stream grid -- stream ) takes successive sums of stream along grid. The first value is always zero, the remaining are successive partial sums. The grid is shifted in the opposite sense to differences. In fact, this is the inverse function to differences.
toS
( @math{T(X)} @math{S(X)} @math{S @sub 0/[ s @sub 1 @ldots s @sub n ]} @math{X} -- @math{T(S @sub 0)} ) changes a stream @math{T(X)} to a stream @math{T(S)}. The four inputs are the input stream @math{T(X,@ldots )}, the coordinate stream @math{S(X,@ldots )}, the values of @math{S} that should be used specified as either a grid @math{S_0} or as simply an array of values (which toS will then convert to a grid), and @math{X} the grid that is being replaced by @math{S @sub 0}. The output is the new stream @math{T(S @sub 0)}.

For example, to get depth of the @math{20 @sup @circ} isotherm, you would say

temp Z exch 20 Z toS

To get the depth of several isotherms, you would say
temp Z exch [ 20 21 22 ] Z toS

To get the salinity of the @math{20 @sup @circ} isotherm, you would say
sal temp 20 Z toS


transit
( D(X,Y) X(S) Y(S) S -- D(S) ) given a stream D(X,Y) and a ship track X(S), Y(S), returns D(S).

There are also filters for the oceanic equation of state. These are included in the program ingrid: they will be included in a model only if createEOS is called in addition to calling createIngrid.

abrat
( @math{@theta} S P -- @math{@alpha /@beta} ) ratio of @math{@alpha} to @math{@beta}.

It is an empirical fit from McDougall, T.J. 1987 Neutral Surfaces, JPO, 17:1950-1964.

beta
( @math{@theta} S P -- @math{@beta} ) @math{@beta = {1 @over @rho }{@left.{@partial @rho @over @partial S}@right)}_{@theta,p}}.

It is an empirical fit from McDougall, T.J. 1987 Neutral Surfaces, JPO, 17:1950-1964.

dens
( T S P -- density ) unecso'81 density (insitu) of seawater.
densa
( T S P -- density ) unecso'81 density (insitu) of seawater minus 1.
depth
( P -- depth ) depth from pressure, ignoring density anomaly.
potemp
( T S P -- @math{@theta} ) calculates potential temperature.
pressure
( T S Z -- P ) computes hydrostatic pressure by integrating from the surface.

Looping

Looping with streams is possible in an iterative sense. The idea is to create a filter than gives future realizations from earlier ones. Four words are used to implement this: beginLoop, endLoop, and for convenience, loopStream and fullloopStream. In a simple case, you only need beginLoop and endLoop. For example,

PS SOURCES
OSUSFC.DATA sstt
T 3.5 VALUE				% extracts an initial condition
/A /integer ordered 1 1 5 NewEvenGRID   % loop will iterate 5 times
beginLoop
1000 add				% x = x + 10000
endLoop
X Y CONTOUR

loopStream furnishes an additional copy of the stream that beginLoop returns; fullloopStream furnishes an additional copy of the stream that endLoop will return (fullloopStream includes the final realization; loopStream does not).
beginLoop
( stream grid -- stream' ) marks the beginning of a loop. The loop will execute once for each element in grid. Can be thought of as a filter than maps x0 to x. Note that the stream output by beginLoop contains only the first n-1 realizations because the interative filter only needs to be run on those realizations.
endLoop
( stream -- stream ) appends stream to the stream most recently marked by beginLoop. Can be thought of as a filter than maps x' to x. Unlike beginLoop, the stream output by endLoop contains all the realizations.
loopStream
( -- stream ) within a loop, returns the same stream as beginLoop i.e. the first n-1 realizations.
fullloopStream
( -- stream ) within a loop, returns the same stream as endLoop i.e. all the realizations.
Explicit:endLoop
( dh/dt -- h ) ends an explicit integration loop started by beginLoop. Computes new h by hnew = h + (dh/dt)*dt.
L4cycle:endLoop
( dh/dt -- h ) ends a Lorenz 4-cycle scheme integration loop started by beginLoop. Computes new h by using the Lorenz 4-cycle scheme.

Grids

NewGRIDdef
( stream name units type array -- stream ) defines a new grid within the current stream.
NewGRID
( name units type array -- grid ) returns a new grid.

Both name and units should be names. type should be either ordered, periodic, or unordered. The array can either be an array of numbers or of names; if it is names the type should be unordered. If there is only a single element in the array, the [] can be omitted.

NewEvenGRID
( name units type low step high -- grid ) returns a new grid.
partialgrid
( grid -- grid' ) The grid is shifted so that each value of the new grid is centered between two values of the old grid.
integralgrid
( grid -- grid' ) The grid is shifted so that each value of the old grid is centered between two values of the new grid, i.e. it is the opposite of partialgrid.
splitgrid
( grid period -- grid' grid2 ) splits a grid into two grids such that the first grid indexes within period and the second grid has step period. The second grid is renamed by appending a 2 to the name of the original grid. If the original grid has units monthtime', the output grids have units month' and year' respectively (these units differ only in how they are printed, all correspond to monthtime values).
first
( -- firstvalue ) returns first value of a grid.
second
( -- secondvalue ) returns second value of a grid.
last
( -- lastvalue ) returns last value of a grid.
low
( -- lowvalue ) returns low value of a grid.
high
( -- highvalue ) returns high value of a grid.
step
( -- step ) returns average step of a grid. If the grid is evenly spaced, then this average step is the step size.
name
( -- name ) returns grid name.
npts
( -- npts ) returns grid number of points.
grideven
( -- flag ) returns true if grid is evenly spaced.
gridtype
( -- type ) returns grid type: ordered, periodic, or unordered.
setgridtype
( type -- ) sets grid type: ordered, periodic, or unordered.
gridvalues
( -- array ) returns array of grid values.
units
( -- units ) returns grid units. See section Units for a discussion of appropriate values.
setunits
( units -- ) sets grid units. See section Units for a discussion of appropriate values.
buffer
( grid -- grid bufferid ) returns buffer of a grid.
SIRecord ( grid -- grid SIRecordid ) returns SIRecord of a grid.
bufferSIRecord ( grid -- grid SIRecordid ) returns SIRecord of a
grid (Internal Use Only).

STREAM printing

PrintStream
( stream -- ) prints all information for a stream, including data values. PrintStream uses FORTRAN_format to format the data values.

To be more exact, PrintStream constructs a FORTRAN format by inserting FORTRAN_format into a format string

FORMAT(99(FORTRAN_format):/)

and it uses this FORMAT to print each line of the table. So if you set FORTRAN_format to print a single number, it will print up to 99 numbers per line. If you want fewer numbers per line, set FORTRAN_format accordingly:
   /FORTRAN_format (10F10.0:/) def

will print 10 numbers per line, for example.
See section Setting STREAM attributes for more explanation of how to set FORTRAN_format.

netCDF and HDF files

The information carried along with a stream is similar in concept to the information carried along in a netCDF file. Consequently reading a netCDF file merely requires specifying a file name; writing a netCDF file additionally requires specifying an input stream.

netCDF files are portable binary files: they can be moved to other kinds of machines and read without modification. There are two basic utilities that allow one to examine and create netCDF files.

ncdump is a utility that prints out the header information and (optionally) the data from a netCDF file (see section 'ncdump' in netCDF User's Guide).

ncgen is a utility that helps generate either netCDF files or the FORTRAN (or C) code to produce netCDF files (see section 'ncgen' in netCDF User's Guide).

You may, however, find it easier to use Ingrid to read and generate netCDF files.

In each case the file name is specified as a string.

writeCDF
( stream string -- ) creates an CDF file.
appendCDF
( stream -- ) appends to the last writeCDF file.
readCDF
( string -- object ) reads a netCDF file, converting it to an object which contains several streams. If the NASACDF module is installed, will also read a NASA CDF file.

For example,

SOURCES
GLOBALHELLERMAN taux (hellerman.cdf) writeCDF
GLOBALHELLERMAN tauy appendCDF


This CDF file can be used later to make plots, namely

PS
(hellerman.cdf) readCDF
taux
T 5.5 VALUE
X Y COLOR


To read NASA CDF files, createNASACDF is required after the createIngrid call, and the /usr/local/CDF/lib/libcdf.a library must be included when linking.

writeGrADS
( stream string -- ) creates a GrADS control file (input data file for GrADS software) with name string and a GrADS data file with name string.data (GrADS data files are binary direct access in XYZT order). At present will only handle a single variable/stream.

writeHDF
(stream string -- ) appends to an existing HDF file, or creates a new one. Not all of the stream information is included in this file.

HDF files are not necessarily portable. They can, however, be moved to the Macs, and are probably portable to many other machines as well.

writeHDF is not necessarily available with a model. createHDF is required after the createIngrid call, and the -ldf library must be included when linking.

STREAMDOC

These words manipulate STREAM documentation.
STREAMDOC
( -- object ) documentation words for STREAMs.
addhistory
( string -- ) adds to the history (see below).
2combinehistory
( stm1 stm2 -- string/array ) combines the histories of two streams.
combinehistory
( stm1 ... stmn n -- string/array ) combines the histories of n streams.
combinefullname
( stm/fullname_1 ... stm/fullname_n n OP -- array ) combines n fullname arrays using the operator OP which can be either a name or string.

If the arguments are streams rather than fullnames, then single point grids are appended to the name under special circumstances. If n<0, then all the single point grids are appended. If n>0, then only the single point grids that have different values in different streams are appended to the name. The latter behavior means that single point grids which have the same value for all the input streams remain a (single point) grid for the output stream: single point grids that have different values in different streams become part of the label. This way

H Z 0 VALUE  H Z 100 VALUE sub

is labeled 'H ( Z=0 - Z=100)' while
H Z 0 VALUE U Z 0 VALUE mul

is labeled 'H * U' and has a Z grid with one point (Z=0).

Internal STREAM words

These words are all contained within the STREAM object. They are not called by the ordinary user.

They also have little in the way of safeguards built in. For example, ReplaceGRID will let you change a grid in the stream. It does not check, however, whether the new grid has the proper number of points in it to represent the stream (it assumes you know better than it, and thus assumes you have written a filter that changes the number of points in that particular dimension of the stream). So be careful!

TaskStreams
( -- array ) returns an array containing the input streams for the fortran function most recently called (only works for functions attached to Ingrid by using FGIfunc). For example
TaskStreams 0 get

returns the first input stream for the function. Frequently used with NewBuffer to define functions which filter streams.
TaskParameterBlock
( -- any ) returns the parameter block for the FORTRAN function most recently called (only works for functions attached to Ingrid by using FGIfunc).
LastStream
( -- stream ) returns the last stream used by InStream
NewBuffer
(stream nsize -- stream' ) makes a new buffer object with buffersize nsize and whose parent is stream. This buffer is filled by the task currently being defined, i.e. a word defined by FGIfunc. Frequently followed by
SetStreamIndex* ... *


SetStreamIndex*
( nrdim -- object nrdim mark ) This word is used to set 'SIRecord' with a new streamidex pointer.
*
( object nrdim mark grid1 ... gridn -- ) This pair of words is used to set 'SIRecord' with a new streamindex pointer.

For example, to modify a stream that is on the top of the stack to have grids XYZ in chunks of XY,

2 SetStreamIndex* X Y Z *


gridno
( stream grid -- stream int ) returns dimension index of grid in stream.
gridstride
( stream grid -- stream int ) returns stride of grid in stream.
ndim
( -- n ) returns number of dimensions in a stream.
nrdim
( -- m ) returns number of dimensions in the chunk of a stream.
chunk
( stream -- stream grid_1 ... grid_m m ) returns grids and number of dimensions in the chunk of a stream.
>chunk
( stream -- grid_1 ... grid_m m ) returns grids and number of dimensions in the chunk of a stream.
achunk
( stream -- stream grid_1 ... grid_n n ) returns grids above the chunk and ndim-nrdim for the current stream.
>achunk
( stream -- grid_1 ... grid_n n ) returns grids above the chunk and ndim-nrdim for the current stream.
streamgrids
( stream -- stream grid_1 ... grid_n ) returns stream grids.
>streamgrids
( stream -- grid_1 ... grid_n ) returns stream grids, dropping stream from the stack.
chunksize
( -- nsize ) returns number of elements in a chunk of the stream.
nchunk
( -- n ) returns number of chunks in the stream.
GRIDParent
( -- object ) is the parent object for all the grid objects.
NewStreamPtr
( nrdim mark grid1 ... gridn -- pointer ) This routine returns a new streamindex pointer given an array of independent variables and the number of dimensions in a chunk.
replaceGRID
( stream oldgrid newgrid -- stream' ) returns a stream where oldgrid is replaced by newgrid in the SIRecord. If the newgrid is null, removes the grid.
setIthGrid
( stream grid i -- stream' ) makes a child stream which has the ith grid grid.
STREAMGRID
( stream array -- stream grid ) creates a grid that matches a stream in name and units with a set of values array.
REORDER
( stream grid1 ... gridn n -- stream' ) reorders stream so that the chunk for the stream has n dimensions and is ordered with the fastest varying dimension corresponding to grid1, the second to grid2, etc.
MATCH
( stream_1 stream_2 ... stream_n n grid_1 ... grid_m m -- stream_1' stream_2' ... stream_n' ) makes a set of n streams all have the same grid. The chunksize is set to contain the m dimensions grid_1 ... grid_m in that order. Alternatively, you can specify null for the chunk, in which case the chunk of the last stream is used. Ranges on common grids are shrunk to match the smallest; a stream that doesn't depend on a particular grid has the same data for all values of that grid. The matching is not complete: within the chunk data is not repeated.
CommonStream
( stream_1 ... stream_n n -- stream) Returns a stream which has only the common grids of the set.
CopyStream
( stream -- stream' ) copies a stream. Used mostly to force the bufferSIRecord and the SIRecord to be the same.

FORTRAN routines

InStream
( stream -- ) makes the stream the next input sequence for the task currently being defined.
FilterStream(NWORDS)
( stream -- stream' ) adds an input and output stream to the task currently being defined. NWORDS is the amount of extra space in the output stream object. It should be at least one, so that you can change longname or run addhistory and tells us what you did to the input stream.
FilterNaNStreams(NSTREAM,NSPACE)
( stream_1 ... stream_n -- stream' ) adds input streams and an output stream to the task currently being defined. The input streams are the inputs, the stream stream' is the output.
NSTREAM
number of input streams
NSPACE
extra space in output stream object. Should be at least one so that you can run addhistory and let the rest of us know what you just did to the data.

Any missing_value's are changed to NaN.

• FilterStreamsNewSize(NSTREAM,NSPACE,NSIZE) ( stream_1 ... stream_n -- stream' ) adds input streams and an output stream to the task currently being defined. The input streams are the inputs, the stream stream' is the output.

The order of the input streams is the order of the arguments.

NSTREAM
number of input streams
NSPACE
extra space in output stream object. Should be at least one so that you can run addhistory and let the rest of us know what you just did to the data.
NSIZE
chunksize of output buffer.

Any missing_value's are changed to NaN.

• NewStreamTask1(ROUTINE,NPTS,N,NSPACE) ( stream_1 ... stream_n -- stream ) starts a task which filters N streams and returns one output stream.
ROUTINE
name of subroutine which should be called. It should have arguments ROUTINE(NPTS,AINN, ... ,AIN1,AOUT), where AINi is an array of values from stream_i. ROUTINE needed to be declared EXTERNAL in the calling subprogram.
NPTS
number of points (passed to routine).
N
number of input streams
NSPACE
extra space in output stream object. Should be at least one so that you can run addhistory and let the rest of us know what you just did to the data.

Any missing_value's are changed to NaN.

• Filtervector(SUBROUTINE,N,M,DGRID,DEFS) ( stream_1 ... stream_n grid -- stream'_1 ... stream'_m) applies a vector function to n input streams along the coordinate grid, returning m output streams.
SUBROUTINE
Fortran subroutine (NX,A1, ... ,AN,GRID). Must be declared EXTERNAL in order for the call to Filtervector to be successful.
N
number of input streams.
M
number of output streams.
DGRID
a string contains commands to transform the input grid into the output grid. Blank will leave that grid unchanged.
DEFS
a string containing the commands to document. Usually '/name /functionname def'.

Filtervector combines the histories and fullnames of the input streams in the same way as FGIscalarFilter.

• Debugging Words

These words are useful for debugging. Some, however, require a fairly good understanding of how Ingrid works to be of any use.
DoTasks
( -- ) executes any currently scheduled tasks, sometimes useful for debugging.
DebugTasks
( -- ) executes any currently scheduled tasks, tracing the task queue. Sometimes useful for debugging.
TestStream
( -- stream ) generates a test stream.
TraceStream
( stream -- ) prints chain of buffers for a stream.
StreamTree
( stream -- ) prints chain of buffers for a stream.
LastTaskTree
( -- ) prints chain of buffers for the most recently defined task.

SOURCES

SOURCES contains streams for all the data sets in the data catalog. It also contains MODEL, the object that contains all the variables defined in a model directly attached to Ingrid.

At the moment, a dataset from the data catalog is returned as a stream. For example, 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 to first execute temp, then remove LEVITUSMEAN from the stack. Thus > can be thought of as "extract".

MODEL

MODEL contains all the variable names for the model. Normally it is put on the stack near the beginning of the command file. It also contains the more internal words that actually implement MODEL variables.
MODEL
( -- object ) an object containing the names of all the model variables.
GRIDList
( -- object ) contains the current values for the default grid names as last set by SetIVAR1 or SetIVAR2.
RVARParent
( -- object ) is the parent object for all the RVAR objects.
NewModel(NAME)
( -- ) This subroutine starts a new model with name NAME. Within Ingrid it can be refered to by MODEL or NAME (until the next NewModel call, at which point it can only be refered to by NAME).
ModelDESC(STRING)
( -- ) This subroutine sets the description string for the model.
VarDESC(VarName,STRING)
( -- ) This subroutine sets the description string for a variable.
SetIVAR1(COORD,UNITS,NX,XS,XE)
( -- ) This subroutine accepts independent variable grid information, making it possible to have data depending on that variable.

Inputs

COORD
name of independent variable
UNITS
units (latitude, longitude, monthtime, or real) See section Units for a discussion of appropriate values.
NX
number of points
XS
starting value
XE ending value

• SetIVAR2(COORD,UNITS,NX,XSS) ( -- ) This subroutine accepts independent variable grid information, making it possible to have data depending on that variable. Inputs
COORD
single character name of independent variable
UNITS
units (latitude, longitude, monthtime, or real) See section Units for a discussion of appropriate values.
NX
number of points
XSS
array of values
• NewRVAR(VAR4,VARL,IVARS,IRECEEP) ( -- ) This subroutine accepts some grid information for a RECEEP variable, making it possible to use the data corresponding to that variable. Inputs
VAR4
short variable name
VARL
full variable name (printed) If it starts with a '/', VARL will be interpreted within an array and that array will be used as the fullname, which means that the names can be treated independently when combined with the names of other streams. Otherwise, VARL is taken to be a string. e.g. VARL = "/MODEL /SSTA" or VARL = "MODEL SST". If the former, SSTA SSTM add will result in MODEL SSTA + SSTM, if the latter, it will result in MODEL SSTA + MODEL SSTM.
IVARS
independent variables (i.e. 'XY' or 'XYZT')
IRECEEP
index to use with RECEEP
• DoRVARs ( -- ) This subroutine should be called once per time step if a RVAR has been defined.
• NewVAR(VAR4,VARL,IVARS,BVARS) ( -- ) This integer function accepts some grid information for a model variable, making it possible to use the data corresponding to that variable.

Inputs

VAR4
short variable name (used to request)
VARL
full variable name (printed) If it starts with a '/', VARL will be interpreted within an array and that array will be used as the fullname, which means that the names can be treated independently when combined with the names of other streams. Otherwise, VARL is taken to be a string. e.g. VARL = "/MODEL /SSTA" or VARL = "MODEL SST". If the former, SSTA SSTM add will result in MODEL SSTA + SSTM, if the latter, it will result in MODEL SSTA + MODEL SSTM.

IVARS
independent variables (i.e. 'XY' or 'XYZT')
BVARS
independent variables in a single block (must be an initial subset of IVARS.
Output
NewVar
ID to be used with FGPUT.
See section Setting STREAM attributes for more explanation of how to set stream attributes such as history, title, or missing_value.
• See section Setup routines for a more complete explanation of how to use the routines of this section.

PS -- PostScript plotting

The routines within PS are used to make PostScript plots. Each plot is put in a separate file: the files are numbered .001 ... .nnn. The files are numbered in the order requested, not in the order generated.

Some of the words--like XOVY, linetype, and linetypelist--are parameters that have default values and need to be set if you wish an alternate value. The simplest way to do this is to extend the current stream and then redefine the values you wish to change. For example,

/XOVY 2 def /linetype KeyLines def

redefines XOVY and linetype.

The remaining words--LINEX, LINE, CONTOUR, DATA xx yy RANGE, and DATA xx STEP-- operate directly on streams.

setplotname
( string -- ) lets you specify the basename for the laser plot files: the default is to make up a name using the date and time.
AUTO
( -- null ) AUTO is used for some parameter settings. Its implementation is to return a null element -- the programs have to deal with it from there.
XOVY
( -- real ) ratio of the X axis length to the Y axis length. AUTO means the axes will have the same scale.
CSCALE
( -- real ) scale factor used for length of vectors in VECTOR plot.
arrowsperinch
( -- integer ) The target number of arrows per inch in a VECTOR plot. If the arrow density gets higher than this amount, VECTOR averages to reduce the arrow density.
linetype
( -- name ) specifies type of key for line, scatter, and contour plots: possible values are AUTO, UnlabelledLines, LabelledLines, and KeyLines.
PLOTGRID
( -- integer ) If non-zero, will plot the data grid underneath the contour plots. One means plot every point, higher values subsample. Negative values mean the grid will be plotted on top of land; positive values mean the grid will be underneath the land.
PLOTCOAST
( -- flag ) If true, will plot the coasts on contour and color plots.
color_smoothing
( -- integer ) If greater than 1, will linearly interpolate colors within each grid box (the value gives the number of times). The default value is 1 (no interpolation).
linetypelist
( -- array ) array of line types used on lines labelled in a key. Line types are an argument to dashtype: i.e. either a number, a character, or both: a number specifies a linewidth and pattern, a character is enclosed in parentheses, (\nnn) specifying special PostScript characters with an octal escape, and square brackets allow one to have both, e.g. [10 (a)] gives a plain line with an 'a' marking each point, and [20 (\267)] gives a wider plain line with a bullet marking each point. Successive line types are separated by spaces
/linetypelist [ 20 (\267) [11 (a)] ] def

specifies three line types, a plain line, bullets, and a line marked with a's. You can also invoke arbitrary PostScript code, so that you can specify linetypes other than the 10 built-in patterns or colors. For example, to specify varying patterns and colors for three lines, the following declaration will do,
/linetypelist
[
[ 0 { 1 0 0 setrgbcolor } ]
[ 1 { 0 1 0 setrgbcolor } ]
[ 2 { 0 0 1 setrgbcolor } ]
] def


averaging_type
( -- type ) sets type of averaging used in computing mean and s.d. labels on plots. Possible values are point, dxdy, and area.
DATA
( -- object ) fake grid to do contouring limits.
RANGE
( stream DATA lo hi -- stream' ) modifies stream to have the given contouring limits.
STEP
( stream DATA step -- stream' ) modifies stream to have the given contouring interval.
VALUES
( stream DATA [ con1 ... conn ] -- stream' ) modifies stream to have contours at the specified values.
LINEX
( stream gridx gridl -- ) Line plot with dependent variable on horizontal axis. Functions of grids are allowed as grids.
LINE
( stream gridx gridl -- ) Line plot with dependent variable on vertical axis. Functions of grids are allowed as grids.
CONTOUR
( stream gridx gridy -- ) Contour plot. Functions of grids are allowed as grids.
COLOR
( stream gridx gridy -- ) Color plot, with scaled colors representing different data values. Functions of grids are allowed as grids.
VECTOR
( stream1 stream2 gridx gridy -- ) vector plot.
HISTOGRAM
( stream min step max -- ) plots the distributions of values for a given stream d(x,y,z,t) by plotting the number of occurrences of data points nearest the values of d which are equally spaced from min to max in steps of step.
SCATTER
( stream1 stream2 grid1 grid2 -- ) scatter plot of stream1 vs. stream2 where data corresponding to different values of grid2 are plotted with different symbols, (different values of grid1 are not distinguished with different symbols). grid1 can be an array of grids, i.e. U V [ X Y ] Z SCATTER will give scatter plots of U vs. V with different symbols for each Z.

Additionally, some of the netCDF attributes are used in creating labels, namely longname, title, and history.

startcolormap
( stream -- stream mark ) marks start of colormap specification
endcolormap
( stream mark -- stream ) marks end of colormap specification

See section Color Plot.

Within startcolormap and endcolormap, the following words are allowed:

RANGE
( low high -- ) sets range of colormap
RGB
( R G B -- int ) adds one color to the colormap
steps
( RGB n -- [ RGB n ]) adds n colors to the colormap, interpolating between the last RGB value and this one.
0 0 255 RGB
23 34 0 RGB 10 steps


value
( RGB value -- [ RGB n] ) adds enough colors to the colormap to make it to value, interpolating between the last RGB value and this one.
stripe
( color -- ) makes a stripe at the previously specified value. As an example of this, consider the following code extracted from a colormap specification:
...
green
blue 0 value white stripe
blue
darkgrey 10 value
...

This inserts a white stripe at zero in a colormap that smoothly varies from green to blue to darkgrey otherwise.
RGBdef
( name R G B -- ) defines a color with RGB values R G B and name name. Can later be used in a colormap.

There are also a number of colors predefined: they can be used instead of R G B RGB. The colors are: beige, black, blue, brown, burlywood, cyan, darkgrey, gold, green, grey, khaki, maroon, orange, peru, purple, red, sienna, turquoise, wheat, white, yellow ... . You can also get a list of the colornames by typing PS ColorMap {pop ==} forall in Ingrid.

There are two predefined colormaps in Ingrid.
rainbowcolormap
sets the colormap to go from purple to green to red, with black for missing data (land) and two levels of gray for too high and too low respectively.
grayscale
greyscale`
Sets the colormap to go from almost black to white, black is used for missing data.

Go to the previous, next section.