NCL language syntax

Overview

Teaching: 0 min
Exercises: 0 min
Questions
  • What is NCL syntax?

Objectives
  • Learn about NCL syntax

  • Learn to read a netCDF file

  • Learn to write variables to netCDF file

  • Learn to iterate over files

Language Syntax

NCL control construct

The syntax is very close to the Fortran syntax:

if (a.eq.b) thenelse
…
end if

A simple do loop:

do i=0,99
…
end do

Or you can use a while loop with a condition to exit the loop:

do while(a.gt.0)
...
end do

The condition is specified in brackets and must be a logical (TRUE/FALSE).

For example, let’s loop over all the netCDF files available in the current directory:

files = systemfunc("ls *.nc") ; NetCDF file names 

do nf=0,dimsizes(files)-1
  print(files(nf))
end do

We used the built-in NCL function systemfunc which allows to make system calls i.e. any available bash statement. In our example, it returns a vector containing the names of all the netCDF files listed in the current directory.

Then to access a single element, use the NCL array syntax i.e. index specified within brackets.

Built-in functions

We used a built-in function (systemfunc) and NCL is a very rich language containing a large number of built-in functions. It would not be possible to enumerate all of them here, so the best is to refer to the NCL documentation here.

User-defined functions

To make your code more modular, you can define your own functions:

function plus2(i)
begin
  return i+2
end

Then you can call this function:

print(plus2(3))
(0)     5

NCL main syntax characters

aInt= (/1,3,4/)
print(aInt)
aInt=5  ; assign all the 3 values to 5 but keep aInt vector dimension
print(aInt)
aInt:=5 ; erase aInt and create a new scalar variable containing one value only
print(aInt)
ncl 9> aInt = (/1,3,4/)
ncl 10> print(aInt)
Variable: aInt
Type: integer
Total Size: 12 bytes
            3 values
Number of Dimensions: 1
Dimensions and sizes:   [3]
Coordinates:
(0)     1
(1)     3
(2)     4
ncl 11> aInt=5
ncl 12> print(aInt)


Variable: aInt
Type: integer
Total Size: 12 bytes
            3 values
Number of Dimensions: 1
Dimensions and sizes:   [3]
Coordinates:
(0)     5
(1)     5
(2)     5
ncl 13> aInt:=5
ncl 14> print(aInt)


Variable: aInt
Type: integer
Total Size: 4 bytes
            1 values
Number of Dimensions: 1
Dimensions and sizes:   [1]
Coordinates:
(0)     5

; This is a comment on one single line
x=10 ; this is also a comment
/; this is a comment
   and you can expand it over several lines
;/
f = addfile("f2000.T31T31.control.cam.h0.0008-12-22-00000.nc","r")
T = f->T
print(T@units)
print(T@long_name)
print(T!0)
(0)     time
print(T&time)
Variable: time (coordinate)
Type: double
Total Size: 88 bytes
            11 values
Number of Dimensions: 1
Dimensions and sizes:   [time | 11]
Coordinates:
Number Of Attributes: 4
  long_name :   time
  units :       days since 0001-01-01 00:00:00
  calendar :    noleap
  bounds :      time_bnds
(0)     2910
(1)     2911
(2)     2912
(3)     2913
(4)     2914
(5)     2915
(6)     2916
(7)     2917
(8)     2918
(9)     2919
(10)    2920

It allows to access an array using the values of its coordinates. For instance, to access T for time=2914, you can either use subscript 4 or:

print(T({2914},0,0,0))
Variable: T (subsection)
Type: float
Total Size: 4 bytes
            1 values
Number of Dimensions: 1
Dimensions and sizes:   [1]
Coordinates:
Number Of Attributes: 8
  lon :    0
  lat : -87.15909455586285
  lev : 3.64346569404006
  time :        2914
  cell_methods :        time: mean
  long_name :   Temperature
  units :       K
  mdims :       1
(0)     260.7312
dimnames = (/"time","lev","lat","lon"/)
attnames = (/"long_name"/)

;
; access to attribute
;	
att0 = T@$attnames(0)$

;
; Example of referencing a coordinate variable 
; without knowing the dimension name
;
coord0 = T&$T!0$
x=(/10,20,30/)
print(x)
x=[/10,20,30/]
print(x)
print(x[:])
print(T(1:2,0,0,0))
print(T(time|0,lev|0,lat|0,lon|0))
print(T \
(1:2,0,0,0))

Arrays and Lists

Arrays

List:

a_int = 1
a_float = 2.0 ; 0.00002 , 2e-5
a_double = 3.2d ; 0.0032d , 3.2d-3
a_string = "a"
a_logical = True ; or False note capital T/F
– a_integer = (/1, 2, 3/) ; ispan(1,3,1)
– a_float = (/2.0, 5 , 8.0/) ; fspan(2,8,3)
– a_double = (/12 , 2d0 , 3.2 /) ; (/12,2 ,3.2 /)*1d0
– a_string = (/"abcd", "e", "Hello, World”/)
– a_logical = (/True, False, True/)
– a_2darray = (/ (/1,2,3/), (/4,5,6/), (/7,8,9/) /)

Variables creation and deletion

a = 2.0
pi = 4.0*atan(1.0)
s = (/ "Paris", "Oslo", "London", "Berlin" /)
r = f->precip ; (time,lat,lon)
R = random_normal(20,7, (/N,M/) ) ; R(N,M)
q = new ( (/ntim, klev, nlat, mlon/), "double" )
; free memory; Generally, do not need to do this
; delete each variable individually
delete(a)
delete(pi)
delete(s)
delete(r)
delete(R)
; delete multiple variables in one line
delete( [/ a, pi, s, r, R, q /] ) ; [/…/] list syntax 

Datatypes

numeric (classic netCDF3)

enumeric (netCDF4; HDF5)

non-numeric

Conversion between datatypes

Array subsetting

Standard Array Subscripting (Indexing)

Consider T(time,lev,lat,lon)

Tips

Good programming: Use variables not hard wired ; time index tstrt:tlast, all lev, all lat :, ; longitude index values ln1:ln2 T(tstrt:tlast, :, : , ln1:ln2 )

Arrays: Indexing & Dimension Numbers

Consider T(:, :, :, :) –> T (0, 1, 2, 3)

Some processing functions operate on dimension numbers

Example: T(ntim, klev, nlat, mlon) –> T(0, 1, 2, 3)

Debugging and Error Messages

Help and Support

Documentation and Examples

Key Points

  • NCL main syntax language

  • Read and write netCDF files with NCL

  • Loop over a large number of netCDF files