Variable names must begin with an alphabetic character, but they can contain any mix of numeric and alphabetic characters. The underscore ('_') is also allowed. Variable names are also case sensitive. The maximum variable name length is currently 256 characters. Variables reference arrays of multi-dimensional data. These data can be described by variable attributes, named dimensions, and coordinate variables. Variables can also reference files and graphical objects.
The following are examples of unique variable names:
a A forecast_time s092389 __t__Variables, like in other programming languages, are textual names that reference data. In NCL, somewhat like Fortran, variables can be created without previously defining them. This is call-implicit instantiation. Unlike Fortran though, the type of a variable is based on what type of value is assigned to it, not the name. Unlike other languages, variables in NCL can be deleted, or changed from defined to undefined.
NCL has been designed with special features that allow ancillary information to be "attached" to a variable programmatically. NCL provides a unique syntax for storing and retrieving these ancillary data values. These ancillary data are divided up into three categories: variable attributes, dimensions, and coordinates. Variables can have an unlimited number of attributes assigned to them. Each dimension of a variable can have a name associated with it and optionally a coordinate variable. Variables become defined when an undefined name appears on the left side of an assignment statement.
There are three types of variables referenced in this document. The first and most obvious is the term variable which is defined as a textual reference to a multi-dimensional or scalar value. Second, there is the term variable that references a file, which is defined as a variable that is assigned the return value of the addfile function. These variables provide references to open files. Finally, the term file variable is defined to be a variable in a file that references a multi-dimensional data value. These terms will be used throughout this section of the reference guide to distinguish between different kinds of variables.
temperature@units = "Degrees C" temperature@long_name = "Temperature at Tropopause" temperature@_FillValue = -9999.0
Attributes can be used in expressions and subscripted in the same fashion as variables. Common uses of attributes are to store the units that data are stored in, and to store names and text that could be useful.
The _FillValue attribute has many important uses in NCL. First and most important is how missing values are handled in expressions. When missing values appear in terms of an NCL expression, they are ignored for the specific element that contains the missing value. Consider the following example:
a = (/27.2, -10.0/) a@_FillValue = -10.0 b = a * 9.0/5.0 + 32.0 print(b) Variable: b Type: float Total Size: 8 bytes 2 values Number of Dimensions: 1 Dimensions and sizes: [2] Coordinates: Number Of Attributes: 1 _FillValue : -10 (0) 80.96 (1) -10In this example, the constant array (/ 27.2, -10.0/) is assigned to the variable a. Next the value of -10.0 is assigned as the _FillValue attribute. When the expression is evaluated, the element equal to -10.0 in the array is ignored, and the result is the array referenced by b has -10.0 as its _FillValue. See Expressions and missing values for more discussion.
The default missing values for the various types are:
logical : -1 byte : 0 short : -99 integer : -999 long : -9999 float : -999 double : -9999 graphic : -9999 file : -9999 character : 0 or '\0' for those who know C string : "missing"
temperature!0 = "frtime" temperature!1 = "lat" temperature!2 = "lon"The previous example is valid only if temperature has three or more dimensions.
temperature&frtime = forecast_times temperature&lat = lat_points temperature&lon = lon_points
dimnames = (/"frtime","lat","lon"/) attnames = (/"_FillValue", "long_name"/) ; ; access to attribute ; att0 = temperature@$attnames(0)$ ; ; Example of referencing a coordinate variable ; without knowing the dimension name ; if(iscoord(dimnames(0)) coord0 = temperature&$temperature!0$ end if
In the following example the variable a is subscripted note how the assignments in the procedure set are propagated back to the calling environment:
procedure set(x) begin x = 1 x!0 = "dim1" x@_FillValue = 1 end a = (/(/1,2,3/),(/4,5,6/),(/7,8,9/)/) set(a(1,:)) print(a)It is important to consider this functionality whenever writing an NCL function or procedure that makes any kind of assignments to the input parameters.
Note: Individual subscripts are separated by commas ',' and the entire subscript list is enclosed in parentheses.
temperature(0,5,6)A range subscript selection accepts a beginning and ending index separated by a colon ':'. Both the beginning index and the ending index are included in the selection, therefore the range is inclusive. Furthermore, if the start is greater than the end, then the selection reverses the ordering of the array. Some examples are:
temperature(1:3,5,6) temperature(1:3,4:5,5:6)The first selection selects a 3x1x1 subsection of the array temperature, and the second selection selects a 3x2x2 subsection. In addition to the above style of selection, a stride can also be specified that causes the selection to skip over a given number of elements. For example, a value of 1 means that every element from the beginning of the range and the end of the range will be selected. With values greater than 1, the first index of the subscript is followed by the stride plus the current index. Therefore a value of 3 selects the first, fourth, seventh, and so on.
temperature(0:4:2,0:5:3,0:6:4)The above selection uses strides to produce a 3x2x2 array.
There is no restriction on having the start of a subscript range be less than the end of the subscript range. When the start is greater than the end, a reverse selection is done, meaning the order output selection is reversed from the original variable. For example:
temperature(3:1,5,6) temperature(3:1,4:5,5:6)
Another option for selection is to leave out the start, end, or both. This means that the start or end will default to the beginning or end respectively.
temperature(:2,:1,5:) temperature(:,:,:)The first selection selects from the beginning to index 2 for the first dimension, the beginning to index 1 for the second dimension, and the final subscript selects from index 5 to the end for the 3rd dimension. The second example shows how the entire array can be selected.
The following uses the default range to reverse the ordering of each dimension using a negative stride:
temperature(:2:-1,:1:-1,5::-1) temperature(::-1,::-1,::-1)
Finally, a vector of integer indexes can be used as a subscript. As long as all of the entries in the vector are within the bounds of the given dimension, the vector could be any size. Vector subscripting allows a single index to be selected more than once. For example, consider the following array and its use of vector subscripting on the variable temperature:
(/1,1,1,2,2,2/) temperature((/1,1,1,2,2,2,/),:,:)This selection creates an array 6x6x7 which is actually bigger than the original. The first, second, and third indexes of the first dimension contain identical arrays. The vector must always be a single-dimensioned array of integers.
temperature(0,{20:60},{-95:-120}) temperature(0,{20},{-95}) temperature(0,{:20:2},{:-95:2})
Coordinate subscripting only works when the coordinate variables assigned to the variables are monotonically increasing or decreasing. If an attempt is made to subscript a coordinate variable that is not monotonic, an error message is generated.
temperature( time | 0, lon | :, lat | :) temperature( time | :, {lon | 20 : 60}, {lat | -95 : -120})
The first example "swaps" the lat and lon dimensions. The second example shows a similar dimension reordering but utilizes coordinate subscripting.
dims = getfilevardims(file1,"T") T = file1->T( $dims(1)$ | :, $dims(0)$ | :, $dims(2)$ | :)
When a variable appearing on the left side of an assignment has not be defined or was previously deleted, the assignment statement causes the variable to become defined and the data type and dimensionality of the variable is determined by the right side.
When a variable appearing on the left side is already defined, then the right side must have the same type, or be coercible to the type on the left, and the right side must have the same dimensionality.
If the left side variable was defined prior to the assignment statement, then the value on the left side is assigned the value of the right side. If the left side is a subscripted reference to a variable, then the right side elements are mapped to the appropriate location in the left side variable. If the left side has any attributes, dimension names, or coordinate variables, they are left unchanged since only a value is being assigned to the left side variable. When the left side is defined, then the type of the right side and the dimensionality must match. However, there is one exception to the requirement that the dimension sizes of the left side and the right side match, a single scalar value can be assigned to more than one location. Consider the following example:
a = (/1,2,3,4,5,6,7,8,9,10/) a(0:3) = -1 print(a) Variable: a Type: integer Total Size: 40 bytes 10 values Number of Dimensions: 1 Dimensions and sizes: [10] Coordinates: (0) -1 (1) -1 (2) -1 (3) -1 (4) 5 (5) 6 (6) 7 (7) 8 (8) 9 (9) 10This example demonstrates the value of -1 being assigned to the first four elements of the variable a.
; ; Example of array designator use to force "Value Only" assignment ; variable1 = (/ variable2 /)
Variable-to-variable assignment occurs when both the left side and the right side are variables. In this situation, the assignment statement also tries to assign attributes, dimension names, and coordinates of the right side to the left side.
The two simplest cases are:
In both these situations, all of the right side's attributes, coordinates, and dimension names are assigned to the left side. If the left side has the same dimension and coordinate names, then only the coordinate variable is overwritten with the value and attributes of the right side's coordinate variables. However, if the names of the dimension names do not match, a warning message is generated and the names and coordinate variables of the left side are overwritten. As far as attributes go, if the left side has attributes, then the left side's attribute list is merged with that of the right side. If the same attribute name appears on both the left and right sides, the right side's attribute overwrites the left side's. If the types of the attribute values do not match, you could have a type mismatch error.
The following are examples of some variable-to-variable assignment situations:
This first example shows assignment to an undefined variable and then shows the use of the array designator characters '(/' and '/)' to perform a value-only assignment.
; ; Create variable be with values, dimension names, coordinate variables ; and attributes ; b = (/ (/1.0,2.0,3.0/), (/4.0,5.0,6.0/), (/7.0,8.0,9.0/) /) b!0 = "dim0" b!1 = "dim1" b@units = "none" b&dim0 = (/.1,.2,.3/) b&dim1 = (/10,100,1000/) ; ; Variable-to-variable assignment with left side undefined ; a = b ; ; Use of array designator characters to assign "Value Only" to undefined ; left side ; c = (/b/) ; ; This print shows that all of the dimension names, attributes, and coordinate ; variables have been assigned to a. ; print(a) Variable: a Type: float Total Size: 36 bytes 9 values Number of Dimensions: 2 Dimensions and sizes: [dim0 | 3] x [dim1 | 3] Coordinates: dim0: [0.1..0.3] dim1: [10..1000] Number Of Attributes: 1 units : none (0,0) 1 (0,1) 2 (0,2) 3 (1,0) 4 (1,1) 5 (1,2) 6 (2,0) 7 (2,1) 8 (2,2) 9 ; ; This print shows that only the values of b were assigned to c. ; print(c) Variable: c Type: float Total Size: 36 bytes 9 values Number of Dimensions: 2 Dimensions and sizes: [3] x [3] Coordinates: (0,0) 1 (0,1) 2 (0,2) 3 (1,0) 4 (1,1) 5 (1,2) 6 (2,0) 7 (2,1) 8 (2,2) 9
This second example demonstrates a defined variable being assigned to a defined variable. Note the changes resulting from assignment to the dimension names, attribute values, and coordinate variables in variable a. These assignments that change the left side's coordinates and dimension names generate errors. When left and right dimension names are different, NCL considers this an error that the user should be warned about. To avoid these errors you can either make sure before assignment that the left and right sides have the same dimension names, or if you only want to assign a value and don't care about attributes, dimensions, and coordinate variables, you can enclose the right side using '(/' and '/)', which forces NCL to use only the value of the right side.
; ; Define variable a with value, dimension names and attributes. ; No coordinate variables assigned. ; a = (/ (/1.1,1.2,1.3/), (/2.1,2.2,2.3/), (/3.1,3.2,3.3/) /) a!0 = "test0" a!1 = "test1" a@units = "Degrees" a@long_name = "A" ; ; Define variable b with value, dimension names, attributes, and : coordinate variables. ; b = (/ (/1.0,2.0,3.0/), (/4.0,5.0,6.0/), (/7.0,8.0,9.0/) /) b!0 = "dim0" b!1 = "dim1" b@units = "none" b&dim0 = (/.1,.2,.3/) b&dim1 = (/10,100,1000/) ; ; Here is the "Variable-to-variable" assignment. The dimension names of a ; change, and the coordinate variables of b are assigned to a. In addition, ; the attribute lists are merged. ; a = b print(a) Variable: a Type: float Total Size: 36 bytes 9 values Number of Dimensions: 2 Dimensions and sizes: [dim0 | 3] x [dim1 | 3] Coordinates: dim0: [0.1..0.3] dim1: [10..1000] Number Of Attributes: 2 units : none long_name : A (0,0) 1 (0,1) 2 (0,2) 3 (1,0) 4 (1,1) 5 (1,2) 6 (2,0) 7 (2,1) 8 (2,2) 9
The remaining case is that when the left side is subscripted, only a portion of the target variable is being assigned to. The simplest case here is when the left-side dimension names are the same and both the left side and right side have coordinate variables for the same dimensions. In this case, assignment occurs for each coordinate variable. The subscripted left-side coordinate variable is assigned the subscripted right side coordinate. The attributes lists for the right side is merged with that of the left side and assigned to the left side variable. The following demonstrates this kind of variable-to-variable assignment.
; ; Define variable a with values, dimension names, attributes and ; coordinate variables. ; a = (/ (/1.1,1.2,1.3/), (/2.1,2.2,2.3/), (/3.1,3.2,3.3/) /) a!0 = "dim0" a!1 = "dim1" a&dim0 = (/.1,.2,.3/) a&dim1 = (/.1,.01,.001/) a@units = "Degrees" a@long_name = "A" ; ; Define b with same dimension names, and assign different coordinate ; variables for dim1. ; b = (/ (/1.0,2.0,3.0/), (/4.0,5.0,6.0/), (/7.0,8.0,9.0/) /) b!0 = "dim0" b!1 = "dim1" b@units = "none" b&dim0 = (/.1,.2,.3/) b&dim1 = (/10.0,100.0,1000.0/) ; ; Here is the example of "Variable to Variable" assignment where the left ; side is already defined. The coordinate variable for "dim1" is overwritten. ; b(0,:) = a(0,:) print(b) Variable: b Type: float Total Size: 36 bytes 9 values Number of Dimensions: 2 Dimensions and sizes: [dim0 | 3] x [dim1 | 3] Coordinates: dim0: [0.1..0.3] dim1: [0.1..0.001] Number Of Attributes: 2 units : Degrees long_name : A (0,0) 1.1 (0,1) 1.2 (0,2) 1.3 (1,0) 4 (1,1) 5 (1,2) 6 (2,0) 7 (2,1) 8 (2,2) 9If the left side variable does not have a coordinate variable and the right side does, a coordinate variable is created and assigned. If the left side is subscripted, then the created coordinate variable only has values assigned for the subscripted range, and the rest of the coordinate variable is filled with missing values. The following example illustrates this feature:
; ; Define b with no coordinate variables. ; b = (/ 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0/) b!0 = "dim0" ; ; Define a with coordinate variables. ; a = (/ 1.1,1.2,1.3,2.1,2.2/) a!0 = "dim0" a&dim0 = (/.1,.2,.3,.4,.5/) ; ; Assignment of a to b. Selection of dim0 selects only every other element. ; b(::2) = a(:) ; ; Print of the coordinate variable "dim0" demonstrates filling of missing ; value for non-selected element. ; print(b&dim0) Variable: dim0 (coordinate) Type: float Total Size: 36 bytes 9 values Number of Dimensions: 1 Dimensions and sizes: [dim0 | 9] Coordinates: Number Of Attributes: 1 _FillValue : -999 (0) 0.1 (1) -999 (2) 0.2 (3) -999 (4) 0.3 (5) -999 (6) 0.4 (7) -999 (8) 0.5The final situation that must be considered when assigning one variable to another is when the dimension names of the left side and the right side do not match. In this case, the assignment overrides the left side's dimension names and coordinate variables, and a warning message is generated. If this is not the desired effect, then the array designator characters '(/' and '/)' can be used to make the assignment a "value-only" assignment.
HLU object variables support assignment and all of the other properties of NCL variables. Also, HLU object variables can be compared with the .ne. and .eq. operators.
The addfile function uses the file extension (i.e. ".nc" or ".cdf" for netCDF, ".hdf" for HDF, ".ccm" for CCM history files, and ".grb" for GRIB) to determine what type of file to open. Once open, all files and file variables regardless of type are referenced using the same NCL file reference syntax. For more information on what types of file formats are currently supported and special conventions of a specific file format, see the Supported data format information section of the reference guide.
a = file1->temperature(0,:,:,:) att = file1->temperature@units lon = file1->temperature&lonUsing the '->' operator requires the variable name to appear immediately after the '->'; parentheses and expressions are not allowed immediately after the '->'. A different kind of file variable access is available to reference variables by a string expression. This is covered later.
File variables function just like regular NCL variables with respect to what is outlined in the NCL properties of variables section. It is important to understand that only the section defined by the variable reference is read or written. This means that NCL allows direct access to file variables, the entire variable does not have to be read in to NCL at one time. For instance, if file1 contains a variable "elev" that is dimensioned [lat | 2159] x [lon | 4320], the selection file1->elev({20:60},{-135:-65}) will read in only the [lat | 480] x [lon | 840] subsection defined by the reference leaving the remaining 8923680 data points in the file.
The following is an example of how to copy a file from one format to another without knowing the names of the variables in the file.
gribfile = addfile(ncargpath("data") + "/grb/ced1.lf00.t00z.eta.grb","r") ncfile = addfile("./ced1.lf00.t00z.eta.nc","c") names = getfilevarnames( gribfile ) do i = 0, dimsizes( names ) - 1 ncfile->$names(i)$ = gribfile->$names(i)$ end ifThe following are examples of referencing attributes and dimensions using string references:
ncl < fileinfo.ncl > file.output
begin ; ; Open a file. ; gribfile = addfile(ncargpath("data") + "/grb/ced1.lf00.t00z.eta.grb","r") ; ; Get the names of the variables. ; names = getfilevarnames( gribfile ) ; ; Loop on all the variables. ; do i = 0, dimsizes( names ) - 1 print("Variable Name: " + names(i)) ; ; Retrieve variable information. ; dims = getfilevardims(gribfile,names(i)) sizes = filevardimsizes(gribfile,names(i)) ; ; Print variable information. ; print(dimsizes(sizes) + " Dimensions:") if(.not.any(ismissing(dims))) then do j = 0, dimsizes(dims) -1 print( j + ") " + dims(j) + ": " + sizes(j)) end do end if atts = getfilevaratts(gribfile,names(i)) if(.not.any(ismissing(atts))) then do k = 0, dimsizes(atts) -1 ; ; Example of accessing attributes and variable using the string ; reference technique. ; print(atts(k) + ": " +gribfile->$names(i)$@$atts(k)$) end do end if delete(atts) delete(dims) delete(sizes) print("") end do end
NG4.1 Home, Index, Examples, Glossary, Feedback, Ref Contents, Ref WhereAmI?