Next: , Previous: Left hand casting, Up: ncap2 netCDF Arithmetic Processor


4.1.5 Arrays and hyperslabs

Hyperslabs in ncap2 are a bit more limited than hyperslabs with the other nco operators. There is no per-se multi-slabs, wrapped co-ordinates, negative stride or co-ordinate value limits. However with a bit of syntactic magic they are all are possible.

       var1( hyper_arg1, hyper_arg2 .. hyper_argN)

A hyperslab argument is specified using the following notation

     start:end:stride

if "start" is omitted - then default = 0
if "end" is omitted - default = dimension size less one
if "stride" is omitted - default = 1


If a single value is present then it is assumed that that dimension collapses to a single value (ie a cross-section). The number of hyperslab arguments MUST be equal to the number of dimensions of the variable.

Hyperslabs on the Right Hand Side of an assign

A simple 1D example:

     ($time.size=10)
     od[$time]={20,22,24,26,28,30,32,34,36,38};
     
     od(7);     // 34
     od(7:);    // 34,36,38
     od(:7);    // 20, 22, 24, 26, 28, 30, 32, 34
     od(::4);   // 20.28,36
     od(1:6:2)  //  22,26,30
     od(:)      //  20,22,24,26,28,30,32,34,36,38

A more complex 3D example

     ($lat.size=2, $lon.size=4 )
     th[$time,$lat,$lon]=
                               {1, 2, 3, 4, 5, 6, 7, 8,
                               9,10,11,12,13,14,15,16,
                               17,18,19,20,21,22,23,24,
                               -99,-99,-99,-99,-99,-99,-99,-99,
                               33,34,35,36,37,38,39,40,
                               41,42,43,44,45,46,47,48,
                               49,50,51,52,53,54,55,56,
                               -99,58,59,60,61,62,63,64,
                               65,66,67,68,69,70,71,72,
                               -99,74,75,76,77,78,79,-99 };
     
     th(1,1,3);        // 16
     th(2,0,:);        // { 17, 18, 19, 20 };
     th(:,1,3);        // 8, 16, 24, -99, 40, 48, 56, 64, 72, -99
     th(::5 ,:,0:3:2); // 1, 3, 5, 7, 41, 43, 45, 47 ;
     

If any of the hyperslab arguments collapse to a single value ( a cross-section has been specified), then that dimension is removed from the returned variable. If all the values collapse then a scalar variable is returned

So for example: the following is valid:

     th_nw=th(0,:,:) +th(9,:,:);
     th_nw  has dimensions $lon,$lat
     nb the time dim has become degenerate

The following is not valid:

     th_nw=th(0,:,0:1) +th(9,:,0:1);

As the $lon now only has two elements. The above can be calculated by using a LHS cast with $lon_nw as replacement dim for $lon.

     defdim("lon_nw",2);
     th_nw[$lat,$lon_nw]=th(0,:,0:1) +th(9,:,0:1);

Hyperslabs on the Left Hand Side of an assign
When hyperslabing on the LHS ,the expression on the RHS must evaluate to a scalar or a variable/attribute with the same number of elements as the LHS hyperslab

Sets all elements of the last record to zero.

     th(9,:,:)=0.0;

Set first element of each lon element to 1.0.

     th(:,:,0)=1.0;

Can hyperslab on both sides of an assign.
Sets the last record to the same as the first record

     th(9,:,:)=th(0,:,:);

th0 represents pressure at height=0
th1 represents pressure at height=1
Then its possible to hyperslab in the records

     P[$time,$height,$lat,$lon]=0.0;
     P(:,0,:,:)=th0;
     P(:,1,:,:)=th1

Reverse method
If you want to reverse a dimension's elements in an variable use the reverse() method with at least one dimension argument (this is equivalent to applying a negative stride) e.g

     th_rv=th(1 ,:,:).reverse($lon); // { 12,11,10,9 } ,{16,15,14,13 }
     od_rv=od.reverse($time);        // {38, 36, 34, 32, 30, 28, 26, 24, 22, 20 }

Permute method
If you want to swap about the dimensions of a variable use the the permute() method. The number and names of dimension arguments must match the dimensions in the variable. If the first dimension in the variable is of record type then this must remain the first dimension. If you want to change the record dimension consider using ncpdq .

Consider the variable:

     float three_dmn_var(lat,lev,lon);
     
     three_dmn_var_pm=three_dmn_var.permute($lon,$lat,$lev);
     
     three_dmn_var_pm=
       0,4,8,
       12,16,20,
       1,5,9,
       13,17,21,
       2,6,10,
       14,18,22,
       3,7,11,
       15,19,23;