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 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
// $Header: /cvsroot/nco/nco/data/ncap.in,v 1.37 2007/08/29 20:45:46 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
Nested files allowed with #include file syntax */
//#include ncap.in2
/* Usage:
ncap -O -D 1 -v -S ${HOME}/nco/data/ncap.in ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -D 1 -d lat,0 -d lon,0 -d lev,0 -s "a9=three_dmn_var" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -D 1 -v -s "upk=pck*pck@scale_factor+pck@add_offset" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -D 1 -v -s "upk=pck" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -D 1 -v -s "pck=pack(three_dmn_var)" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -O -D 1 -s "prs_mdp[time,lat,lon,lev]=P0*hyam+hybm*PS" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncks -H -m ${HOME}/nco/data/foo.nc | m */
/* ncap is a handy attribute editor:
Define new attribute:
ncap -O -v -s "one@new=2*att_var@double_att;one@test=two@long_name;" in.nc foo.nc
Re-define existing attribute in terms of itself:
ncap -O -v -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 -O -v -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 -O -v -s "one@new=cos(1.0e-4) - 1" in.nc foo.nc
Result is now of type float:
ncap -O -v -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 -O -v -s "one@new=\"hello world\"" in.nc foo.nc
Add strings, and use C escape characters:
ncap -O -v -s "one@new=\"Hello\t\"+\"World\n\"" in.nc foo.nc
Set an attribute equal to a 0-dimensional variable:
ncap -O -v -s "one@new=one" in.c foo.nc
Set an attribute equal to a 1-dimensional variable:
ncap -O -v -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 -O -v -s "lat=20*lat" in.nc foo.nc
Average variables of mixed types (result is of type double):
ncap -O -v -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 -O -v -s "abslog=log(abs(three_dmn_var_dbl))" in.nc foo.nc
The available maths functions are:
acos(), asin(), atan(), cos(), exp(), erf(), erfc(), 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 -O -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 -O -v -s "mod=three_dmn_rec_var % 4.0" in.nc foo.nc
Result of modulus is of type int:
ncap -O -v -s "testa=three_dmn_var_int % 1.0f" in.nc foo.nc
Unary +/- signs work intuitively with attributes and variables:
ncap -O -v -s "sign=-three_dmn_rec_var" in.nc foo.nc */
/* Packing and unpacking:
Manual unpacking is relatively straightforward but works only with -D 3
because automatic unpacking is now default on ncap. It is now broken
because ncap_var_write() tries to write bogus attributes automatically
because pck_ram is set in pck_dsk_inq()
ncap -D 3 -O -v -s "upk=pck*pck@scale_factor+pck@add_offset" -s "upk_arr=pck_arr*pck_arr@scale_factor+pck_arr@add_offset" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
Automatic unpacking works for scalars, not for arrays
ncap -D 1 -O -v -s "upk=pck" -s "upk_arr=pck_arr" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
Automatic packing does not yet work
ncap -D 1 -O -v -s "pck=pack(ORO)" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -D 1 -O -v -s "pck=pack(upk)" -s "pck_arr=pack(upk_arr)" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -D 1 -O -v -s "pck=pack(pck)" -s "pck_arr=pack(pck_arr)" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncap -D 1 -O -v -s "upk=unpack(pack(unpack(pack(pck))))" -s "upk_arr=unpack(pack(unpack(pack(pck_arr))))" ${HOME}/nco/data/in.nc ${HOME}/nco/data/foo.nc
ncks -H -m ${HOME}/nco/data/foo.nc | m
ncks -H -v pck,pck_arr -m ${HOME}/nco/data/foo.nc | m
ncks -H -v upk,upk_arr -m ${HOME}/nco/data/foo.nc | m
*/
// Charlie's Tests:
// p=hyam*PO+hybm*PS
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
a7=erf(1.0);
a8=erfc(1.0);
a9[time,lat,lev]=3.141d;
// 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@_FillValue%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@_FillValue=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;
//Put an attribute/number into a variable
thirty=1.e19f;
thirtyone=one@one;
// With a string ONLY the first char is put into varible
thirtytwo="Hello world";
// use varibles defined in output
thirtythree=twentyfive*4.001;
// Use UNARY -/+ and brackets
three=(-two_dmn_var+5)^3;
testa=pow(sin(four_dmn_rec_var),2)+cos(four_dmn_rec_var)^2;
/* Conversion functions are available for variables AND attributes
Standard C type conversion rules are used
Converting "down" produces interesting results!
byte(),char(),short(), int(), float(), and double() */
// Convert float to byte
ex_byte=byte(two_dmn_var);
// Convert int to short
ex_short=short(three_dmn_var_int/5);
// Convert short to float
ex_float=float(three_dmn_var_sht);
// Convert float to double
ex_double=double(weight);
// Convert attribute to double
bnd_var@att_double=double(bnd_var@float_att);
// Convert double attribute to int
bnd_var@att_int=double(4*bnd_var@float_att);
|