Personal tools
You are here: Home Documentation Users Guide 3. Variables & Expressions 3.3 EMBEDDED EXPRESSIONS
Document Actions

3.3 EMBEDDED EXPRESSIONS

by Catherine Nunkai — last modified 2013-11-12 13:19

Ferret supports "immediate mode" mathematical expressions—that is, numerical expressions that may be embedded anywhere within a command line. These expressions are evaluated immediately by Ferret—before the command itself is parsed and executed. Immediate mode expressions are enclosed in grave accents, the same syntax used by the Unix C shell. Prior to parsing and executing the command Ferret will replace the full grave accent expression, including the accent marks, with an ASCII string representing the numerical value. For example, if the given command is

CONTOUR/Z=`temp[X=180,Y=0,Z=@LOC:15]` salt

Ferret will evaluate the expression "temp[X=180,Y=0,Z=@LOC:15]" (the depth of the 15-degree isotherm at the equator/dateline—say, it is 234.5 meters). Ferret will generate and execute the command

CONTOUR/Z=234.5 salt

Embedded expressions:

Embedded expressions: the expression must evaluate to a single number, a scalar, or Ferret will respond that the command contains an error. If the result is invalid the numerical string will be "bad" (see BAD= in following section). Region qualifiers that begin a command containing an embedded expression will be used in the evaluation of the expression. If multiple embedded expressions are used in a single command they will be evaluated from left to right within the command. This means that embedded expressions used to specify region information (e.g., the above example) may influence the evaluation of other embedded expressions to the right. When embedded expressions are used within commands that are arguments of a REPEAT command their evaluation is deferred until the commands are actually executed. Thus the embedded expressions are re-evaluated at each loop index of the REPEAT command. Grave accents have a higher priority than any other syntax character. Thus grave accent expressions will be evaluated even if they are enclosed within quotation marks, parentheses, square brackets, etc. Substitutions based on dollar-signs (command script arguments and symbols) will be made before embedded expressions are evaluated. A double grave accent will be translated to a single grave accent and not actually evaluated. Thus double grave accents provide a mechanism to defer evaluation so that grave accent expressions may be passed to the Unix command line with the SPAWN command or may be passed as arguments to GO scripts (to be evaluated INSIDE the script). The state of MODE VERIFY will determine if the evaluation of the embedded expression is echoed at the command line—similar to REPEAT loops.

The grave accent syntax may also be used to force immediate evaluation and substitution of a string variable in a command. Note that since region qualifiers that begin a command containing an embedded expression are used in the evaluation of the expression, the string variable may not contain a region qualifier.


3.3.1 Special calculations using embedded expressions

By default Ferret formats the results of embedded expressions using 5 significant digits. If the result of the expression is invalid (e.g., 1/0) the result by default is the string "bad". Controls allow you to specify the formatting of embedded expression results in both valid and invalid cases and to query the size and shape of the result.

The syntax to achieve this control is KEYWORD=VALUE pairs inside the grave accents, following the expression and set off by commas. The recognized keywords are "BAD=", "PRECISION=", and "RETURN=". Only the first character of the keyword is significant, so they may be abbreviated as "B=", "P=", and "R=".

PRECISION=, BAD=, and RETURN= may be specified simultaneously, in any order, separated by commas. If RETURN= is included, however, the other keywords will be ignored.

PRECISION=#digits

can be used to control the number of significant digits displayed, up to a maximum of 16. (Prior to Ferret v6.8 this limit was 10 digits but actually at most 7 digits were significant since Ferret calculations were performed in single precision.) Ferret will, however, truncate terminating zeros following the decimal place. Thus

SAY `3/10,PRECISION=7`

will result in

0.3

instead of 0.3000000.

If the value specified for #digits is zero or negative Ferret will interpret this as the desired number of decimal places rather than the number of significant digits. Thus

SAY `35501/100,P=-2`

will result in

355.01

And,

SAY `35501/100,P=0`

will result in

355

This also means that Ferret will always return at least one significant digit:

SAY `0.123,P=0`

will result in

0.1

In the case of a negative precision value, Ferret will again drop terminating zeros to the right of the decimal point.

Note that the precision of the embedded expression is used as the command is parsed, and any precision controls in the rest of the command are applied later. So, noting how the command is parsed before it is executed:

yes? LIST/PRECISION=10 `100000000 + 12300`
!-> list/prec=10 1.0001E+08
             VARIABLE : constant
          100010000.0

because the default precision is applied to the expression in the grave accents.


W= ZW= set width and set zero-filled width.

Formatting immediate mode expressions may be done by specifying the width or zero-filled width:

yes? SAY Answer: `5.3,w=8`
Answer: 5.3
yes? SAY Answer: `5.3,zw=8`
Answer: 000005.3

BAD=string

can be used to control the text which is produced when the result of the immediate mode expression is invalid. Thus

SAY `1/0,BAD=missing`

will result in

missing

or

SAY `1/0,B=-999`

will result in

-999

RETURN=

The keyword RETURN= can reveal the size and shape of the result. RETURN= may take arguments

  • size
  • istart, jstart, kstart, lstart, mstart, nstart
  • iend, jend, kend, lend, mend, nene
  • xstart, ystart, zstart, tstart, estart, fstart
  • xend, yend, zend, tend, eend, fend
  • isize, jsize, ksize, lsize, msize, lsize
  • bad
  • calendar
  • T0
  • units
  • iunits, junits, kunits, lunits, munits, nunits
  • xunits, yunits, zunits, tunits, eunits, funits
  • title
  • grid
  • iaxis, jaxis, kaxis, laxis, maxis, naxis
  • xaxis, yaxis, zaxis, taxis, eaxis, faxis
  • dset, dsetnum, dsetpath, dsettitle
  • nc_scale, nc_off
  • user_scale, user_off
  • dtype
  • xmod
  • tmod
  • isDepth
  • status
  • isReady


The RETURN= option in immediate mode expressions does not actually compute the result unless it must. For example, the expression

`sst, RETURN=TEND`

will return the formatted coordinate for the last point on the T axis of variable sst without actually reading or computing the values of sst. This allows Ferret scripts to be constructed so that they can anticipate the size of variables and act accordingly.

Note that this does not apply to variable definitions which involve grid-changing variables that return results on ABSTRACT axes. For those variables the size and shape of the result may depend on data values, so the entire result must be computed in order to determine many of the return= results

RETURN=SHAPE

Returns the 4-dimensional shape of the result—i.e., a list of those axes along which the result comprises more than a single point. For example, a global sea surface temperature field at a single point in time:

SAY `SST[T=1-JAN-1983],RETURN=SHAPE`

will result in

XY

See Symbol Substitutions in the chapter "Handing String Data Symbols" for examples showing the special utility of this feature.

RETURN=SIZE

Returns the total number of points in the variable -- Nx*Ny*Nz*Nt*Ne*Nf

RETURN=ISTART (and similarly JSTART, KSTART, and LSTART, MSTART, NSTART)

Returns the starting index of the result along the indicated axis: I, J, K, L, M, N. For example, if CAST is a vertical profile with points every 10 meters of depth starting at 10 meters then Z=100 is the 10th vertical point, so

SAY `CAST[Z=100:200],RETURN=KSTART`

will result in

10

RETURN=IEND (and similarly JEND, KEND, LEND, MEND, NEND)

Returns the ending index of the result along the indicated axis: I, J, K, L, M, N. In the example above

SAY `CAST[Z=100:200],RETURN=KEND`

will result in

20

The size and shape information revealed by RESULT= is useful in creating sophisticated scripts. For example, these lines could be used to verify that the user has passed a 1-dimensional field as the first argument to a script

LET my_expr = $1
DEFINE SYMBOL SHAPE `my_expr,RESULT=SHAPE`
QUERY/IGNORE ($SHAPE%|X|Y|Z|T|<Expression must be 1-dimensional%)

RETURN=XSTART (and similarly YSTART, ZSTART, TSTART, ESTART, FSTART)

Returns the first grid point in the current region, in world coordinates. Note that the format of the result can be controlled by setting or canceling MODE LONG_LABEL for the X axis, MODE LAT_LABEL for the Y axis, or MODE CALENDAR for a time axis.

RETURN=XEND (and similarly YEND, ZEND, TEND, EEND, FEND)

Returns the last grid point of specified world coordinate region, in world units.

RETURN=ISIZE (and similarly JSIZE, KSIZE, LSIZE, MSIZE, NSIZE)

Returns the number of points along one axis, within the currently defined region. Note for an ascii dataset, you can get the actual size of the data as follows. You must define a grid - the default abstract axis for reading ascii data will return the length of the abstract axis. The data must be loaded to get the length of the variable.

yes? DEFINE SYMBOL maxobs = 100000
yes? define axis/x=1:($maxobs):1 inaxis
yes? define grid/x=inaxis ingrid
yes? file/grid=ingrid/var=A file.dat

yes? load A
yes? let npts= `A,return=isize`


RETURN=BAD

Returns the missing value flag from the expression

RETURN=T0

Returns the T0 string from the time axis of the variable

RETURN=CALENDAR

Returns the calendar name from the time axis of the variable

RETURN=UNITS

Returns the units string from the variable

RETURN=XUNITS (and similarly YUNIT, ZUNIT, TUNIT, EUNIT, FUNIT)

Returns the units string from the axis

RETURN=IUNITS (and similarly JUNIT, KUNIT, LUNIT, MUNIT, NUNIT)

Returns the units string from the axis

Example:

yes? say `sst, RETURN=UNIT`
!-> MESSAGE/CONTINUE Deg C

yes? say `sst, RETURN=TUNIT`
!-> MESSAGE/CONTINUE DAYS

RETURN=TITLE

Returns the title of a variable

RETURN=GRID

Returns the grid name of a variable

RETURN=IAXIS (and similarly JAXIS, KAXIS, LAXIS, MAXIS, NAXIS)

Returns the name of an axis on which the variable is defined.

RETURN=XAXIS (and similarly YAXIS, ZAXIS, TAXIS, EAXIS, FAXIS)

Returns the name of an axis on which the variable is defined.

RETURN=DSET

Returns data set name. This is the data set name without the file pathname.

Example:

yes? USE "/home/rmb_dat/testfile.nc"
yes? SAY `sst,RETURN=dset`
!-> MESSAGE/CONTINUE testfile
testfile

RETURN=DSETNUM

Returns data set number from the expression.

yes? SAY `sst,RETURN=dsetnum`
!-> MESSAGE/CONTINUE 1
1

RETURN=DSETPATH

Returns the path of the data set information from the expression. A leading slash on the pathname can cause trouble when the result is parsed by Ferret. Putting the result in a string variable is one way to deal with this.

yes? LET a = "`sst,RETURN=dsetpath`"
!-> DEFINE VARIABLE a = "/home/rmb_dat/testfile.nc"

RETURN=DSETTITLE

Returns data set title from the expression, if it exists. This returns the title in a netCDF file which is specified as a global attribute :title= "Title text";

yes? LET a = "`sst,RETURN=dsettitle`"
!-> DEFINE VARIABLE a = "MERCATOR SECTION ATL Gulf Cadiz"


RETURN=DTYPE

Returns the netCDF type of the variable in the dataset, e.g. FLOAT, or CHAR.

RETURN=NC_SCALE, NC_OFF

Returns the scale and offset that were defined by a netCDF attribute for the variable. If the stepfiles of a multi-file netCDF file have different scale and offset values, these commands return the latest values that were applied.

RETURN=USER_SCALE, USER_OFF

Returns the scale and offset that were set using a SET VARIABLE command with the /SCALE= or /OFFSET qualifiers.

RETURN=XMOD, TMOD

Returns the modulo length of the X or T axis of the variable, if it is modulo, in terms of the units of the axis.

yes? USE coads_climatology
yes? SAY `sst,RETURN=xmod`
!-> MESSAGE/CONTINUE 360
360

yes? SAY `sst,RETURN=tmod`
!-> MESSAGE/CONTINUE 8765.8
8765.8

yes? SAY `sst,RETURN=tunits`
!-> MESSAGE/CONTINUE hour
hour
RETURN=ISDEPTH

Returns 1 if the vertical axis of the variable is a depth (positive-down) axis, or 0 if it is increasing upwards.

RETURN=STATUS
Returns the computability status of the expression(s) given inside the grave accents.  The status that is returned reflects the state of the entire tree of LET variables and file variables that must be read or computed.  (See SHOW VARIABLE/TREE).  Note that a unique feature of this RETURN option and RETURN=isReady is that it is allowable to include a comma-separated list of expressions enclosed in a single grave accent pair with the RETURN option.  The value returned will reflect the overall status of the group of expressions.  If multiple error conditions are found, the worst one among them will be reported.  Possible return strings are

      AVAILABLE                                     -- all variables are known and available for access

      UNKNOWN VARIABLE                    -- the unrecognized name will be displayed

      UNKNOWN DATASET                     -- the unrecognized name will be displayed

      UNKNOWN GRID                            -- the unrecognized name will be displayed

      ERROR in EXPRESSION                  -- the offending expression will be displayed

      ILLEGAL RECURSIVE VARIABLES   -- the variable on which the recursive loop was detected will be named

      UNKNOWN AUXILIARY VARIABLE -- the unrecognized name will be displayed


RETURN=isReady
Closely related to RETURN=STATUS (above), this option returns a 1 or a 0 (TRUE vs FALSE) indicating whether the STATUS is AVAILABLE.  A typical usage of this RETURN option would be lines in a journal file such as these

 IF `my_var,RETURN=isReady` THEN 
    PLOT my_var
 ELSE
    MESSAGE my_var is not available because of `my_var,RETURN=status`
 ENDIF

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: