1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
// $Header: /cvsroot/nco/nco/data/ncap.in,v 1.17 2002/02/03 08:40:07 zender Exp $ -*-C-*-
// Purpose: ncap netCDF Arithmetic Processor Demonstration/Test Script
/* Format of valid ncap script:
Syntax is C-like, and C++ comments also valid
Mathematical expressions use forward algebraic notation
Statements in scripts are terminated with semi-colons
Command-line definitions should omit semi-colons, e.g., -s "foo=bar"
Whitespace (blank lines, tabs) is ignored */
/* Usage:
ncap -O -d lat,0 -d lon,0 -d lev,0 -D 1 -s "a9=three_dmn_var" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -D 1 -v -s "a8[lat,lon,lev] = 1" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -s "prs_mdp[time,lat,lon,lev]=P0*hyam+hybm*PS" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -D 1 -v -S ${HOME}/nco/data/ncap.in ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncks -H -m ${HOME}/nco/data/foo.nc | m */
/* The ncap operator is a handy attribute editor.
Define new attribute:
ncap -s "one@new = 2*att_var@double_att" in.nc foo.nc
Re-define existing attribute in terms of itself:
ncap -s "att_var@double_att = att_var@double_att^2.0" in.nc foo.nc
Computation is performed at highest precision of RHS expression:
ncap -s "one@new = att_var@short_att * att_var@double_att - att_var@double_att" in.nc foo.nc
Use math functions (default result is of type double):
ncap -s "one@new = cos(1.0e-4) - 1" in.nc foo.nc
Result is now of type float:
ncap -s "one@new = cos(1.0e-4f)^2 + sin(1.0e-4f)^2" in.nc foo.nc
Assign string to attribute (use \" to escape quote from shell):
ncap -s "one@new=\"hello world\"" in.nc foo.nc
Add strings, and use C escape characters:
ncap -s "one@new=\"Hello\t\" + \"World\n\"" in.nc foo.nc
Set an attribute equal to a 0-dimensional variable:
ncap -s "one@new=one" in.c foo.nc
Set an attribute equal to a 1-dimensional variable:
ncap -s "one@new=mss_val" in.nc foo.nc
/* The ncap operators works with netCDF variables and attributes
Multiply an existing co-ordinate variable by 20:
ncap -s "lat=20*lat" in.nc foo.nc
Average variables of mixed types (result is of type double):
ncap -s "average=(three_dmn_rec_var+three_dmn_var_dbl+three_dmn_var_int)/3" in.nc foo.nc
Take log (to base e) of absolute value of variable:
ncap -s "abslog=log(abs(three_dmn_var_dbl))" in.nc foo.nc
The available maths functions are:
acos(); asin(); atan(); cos(); exp(); gamma(); log(); log10(); sin(); sqrt(); tan();
If argument precision is "less" than type float then result is type float
If argument is type double then result is also double
This also applies to pow() function, e.g, pow(var1,3.5) or var1^3.5, e.g.,
ncap -v -s "modulus=pow(sin(three_dmn_rec_var),2) + cos(three_dmn_rec_var)^2 - 1" in.nc foo.nc */
/* Modulus operator % can also be used with attributes and variables
Attributes are converted to variable's type prior to operation
Result of modulus is of type float:
ncap -v -s "mod = three_dmn_rec_var % 4.0" in.nc foo.nc
Result of modulus is of type int:
ncap -v -s "testa = three_dmn_var_int % 1.0f" in.nc foo.nc
Unary +/- signs work intuitively with attributes and variables:
ncap -v -s "sign = -three_dmn_rec_var" in.nc foo.nc */
// Charlie's Tests:
// p=hyam*PO + hybm*PS
a1 = one;
a1@a1 = global@history;
a1@julian_day = global@julian_day;
a2 = (1*(three_dmn_var-three_dmn_var+1)-1)^1;
a3[lat,lon,lev] = one;
a4[lat,lon,lev] = 1.0f-one;
a5 = time;
a6 = time+one_dmn_rec_var;
prs_mdp[time,lat,lon,lev] = P0*hyam + hybm*PS; // Works because prs_mdp in LHS cast
//prs_mdp = P0*hyam + hybm*PS; // Fails because prs_mdp dimension ordering is ambiguous
//prs_mdp = (four_dmn_rec_var-four_dmn_rec_var+1)*P0*hyam + (four_dmn_rec_var-four_dmn_rec_var+1)*hybm*PS; // Works because prs_mdp is typecast on RHS
// Henry's tests:
one@one=10+30;
one@two=sin(3.141/2);
one@three=cos(3.1415926)+one@one+one@two;
// Redefine attributes
one@one=23/4;
one@two=one@one+one@two;
one@eight=25.0%4.99;
one@nine=1.e10;
one@ten=val_half_half@missing_value%1000;
/* Standard netCDF postfix operators are used to typecast attributes/numbers
floats and doubles must include decimal point or exponent to be recognized */
one@byte=10b;
one@short=10s;
one@float=100.e2f;
one@double=2e3;
/* Type conversion follows C rules: expression is converted to highest type
Following expression is of type float: */
one@add = one@byte+one@short/one@float;
// Can create 0 dimensional variables (scalars)
nine=10000e2f;
one=10;
two=4;
val_half_half@missing_value = 21;
// Can use modulus operator with attributes and variables
twenty = four_dmn_rec_var % 8;
twentyone=sin(twenty)^2 + cos(twenty)^2;
twentytwo=10*9;
twentythree=1.0e9%2;
twentyfour = two_dmn_var@units;
twentyfive=three_dmn_var_dbl/4;
twentysix=pck;
/* Below multiplication is of individual elements in variables AND NOT
a matrix multiplication. Resulting matrix is of type double. */
twentyseven= three_dmn_var_int * three_dmn_var_dbl;
// Function atostr() evaluates an attribute and stores the result as a string
twenty@one = atostr(1.e10);
twenty@two = atostr(1/7.0);
// Function atostr() accepts an optional C-format
twenty@three = atostr(1/7.0,"\t%15f\n");
// Add two strings together
twenty@four = "Hello"+"\t World\n";
// Put a 0 or 1 dimensional variable into an attribute
twenty@five= fl_nm;
twenty@six = mss_val;
twenty@seven=one;
// Use UNARY -/+ and brackets
three= (-two_dmn_var + 5)^3;
testa= pow(sin(four_dmn_rec_var),2) + cos(four_dmn_rec_var)^2;
|