/*
Arithmetic operators: +, -, *, \, ^
Logic operators: <, >, <=, >=, !=, ==, <=>
Functions: abs, sqrt, exp, log, log10, sin, cos, tan, asin, acos, atan
Functions: min, max, avg, std, var
Constansts: M_PI, M_E
*/

@BeginModule
@NewPage
@Name      = Expr
@Title     = Evaluate expressions
@Section   = Arithmetic
@Class     = Arithmetic
@Arguments = ifile ofile
@Operators = expr exprf aexpr aexprf

@BeginDescription
This module arithmetically processes every timestep of the input dataset.
Each individual assignment statement have to end with a semi-colon.
Unlike regular variables, temporary variables are never written to the output stream.
To define a temporary variable simply prefix the variable name with an underscore (e.g. _varname)
when the variable is declared.

The following operators are supported:

@BeginTable4
 @bold{Operator}   & @bold{Meaning}             & @bold{Example}   & @bold{Result} 
     =      & assignment          & x = y     & Assigns y to x
     +      & addition            & x + y     & Sum of x and y
     -      & subtraction         & x - y     & Difference of x and y    
     *      & multiplication      & x * y     & Product of x and y 
     /      & division            & x / y     & Quotient of x and y
     \exp      & exponentiation      & x \exp y     & Exponentiates x with y 
     ==     & equal to            & x == y    &  1, if x equal to y; else 0
     !=     & not equal to        & x != y    &  1, if x not equal to y; else 0
     >      & greater than        & x > y     &  1, if x greater than y; else 0
     <      & less than           & x < y     &  1, if x less than y; else 0
     >=     & greater equal       & x >= y    &  1, if x greater equal y; else 0
     <=     & less equal          & x <= y    &  1, if x less equal y; else 0
     <=>    & less equal greater  & x <=> y   & -1, if x less y; 1, if x greater y; else 0 
     \and     & logical AND         & x \and y    &  1, if x and y not equal 0; else 0
     \or     & logical OR          & x \or y    &  1, if x or y not equal 0; else 0
     ?:     & ternary conditional & x ? y : z & y, if x not equal 0, else z 
@EndTable

The following functions are supported:

Math intrinsics:

@BeginList log10(x)
@Item = abs(x)
Absolute value of x
@Item = floor(x)
Round to largest integral value not greater than x
@Item = ceil(x)
Round to smallest integral value not less than x
@Item = int(x)
Integer value of x
@Item = nint(x)
Nearest integer value of x
@Item = sqr(x)
Square of x
@Item = sqrt(x)
Square Root of x
@Item = exp(x)
Exponential of x
@Item = log(x)
Natural logarithm of x
@Item = log10(x)
Base 10 logarithm of x
@Item = sin(x)
Sine of x, where x is specified in radians
@Item = cos(x)
Cosine of x, where x is specified in radians
@Item = tan(x)
Tangent of x, where x is specified in radians
@Item = asin(x)
Arc-sine of x, where x is specified in radians
@Item = acos(x)
Arc-cosine of x, where x is specified in radians
@Item = atan(x)
Arc-tangent of x, where x is specified in radians
@Item = rad(x)
Convert x from degrees to radians
@Item = deg(x)
Convert x from radians to degrees
@EndList

Coordinates:

@BeginList gridarea(x)
@Item = clon(x)
Longitude coordinate of x (available only if x has geographical coordinates) 
@Item = clat(x)
Latitude coordinate of x (available only if x has geographical coordinates) 
@Item = gridarea(x)
Grid cell area of x (available only if x has geographical coordinates) 
@Item = clev(x)
Level coordinate of x (0, if x is a 2D surface variable)
@EndList

Constants:

@BeginList missval(x)
@Item = ngp(x)
Number of horizontal grid points
@Item = nlev(x)
Number of vertical levels
@Item = size(x)
Total number of elements (ngp(x)*nlev(x))
@Item = missval(x)
Returns the missing value of variable x
@EndList

Statistical values over a field:

@mod{fldmin}(x), @mod{fldmax}(x), @mod{fldsum}(x), @mod{fldmean}(x), @mod{fldavg}(x), @mod{fldstd}(x), @mod{fldstd1}(x), @mod{fldvar}(x), @mod{fldvar1}(x)

Vertical statistical values:

@mod{vertmin}(x), @mod{vertmax}(x), @mod{vertsum}(x), @mod{vertmean}(x), @mod{vertavg}(x), @mod{vertstd}(x), @mod{vertstd1}(x), @mod{vertvar}(x), @mod{vertvar1}(x)

Miscellaneous:

@BeginList sellevidx(x,k)
@Item = sellevel(x,k)
Select level k of variable x
@Item = sellevidx(x,k)
Select level index k of variable x
@Item = remove(x)
Remove variable x from output stream
@EndList

@EndDescription
@EndModule


@BeginOperator_expr
@Title     = Evaluate expressions
@Parameter = instr

@BeginDescription
The processing instructions are read from the parameter.
@EndDescription
@EndOperator


@BeginOperator_exprf
@Title     = Evaluate expressions script
@Parameter = filename

@BeginDescription
Contrary to @oper{expr} the processing instructions are read from a file.
@EndDescription
@EndOperator


@BeginOperator_aexpr
@Title     = Evaluate expressions and append results
@Parameter = instr

@BeginDescription
Same as @oper{expr}, but keep input variables and append results
@EndDescription
@EndOperator


@BeginOperator_aexprf
@Title     = Evaluate expression script and append results
@Parameter = filename

@BeginDescription
Same as @oper{exprf}, but keep input variables and append results
@EndDescription
@EndOperator


@BeginParameter
@Item = instr
STRING  Processing instructions (need to be 'quoted' in most cases)
@Item = filename
STRING  File with processing instructions
@EndParameter


@BeginExample
Assume an input dataset contains at least the variables 'aprl', 'aprc' and 'ts'.
To create a new variable 'var1' with the sum of 'aprl' and 'aprc' and a variable 'var2'
which convert the temperature 'ts' from Kelvin to Celsius use:
@BeginVerbatim
   cdo expr,'var1=aprl+aprc;var2=ts-273.15;' ifile ofile
@EndVerbatim
The same example, but the instructions are read from a file:
@BeginVerbatim
   cdo exprf,myexpr ifile ofile
@EndVerbatim
The file @file{myexpr} contains:
@BeginListing
   var1 = aprl + aprc;
   var2 = ts - 273.15;
@EndListing
@EndExample
