Introduction

Overview

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

  • How to invoke NCL from the command line?

Objectives
  • Learn what is NCL

  • Learn how to start NCL

  • Learn about the netCDF data model

What is NCL?

NCAR Command Language is an Integrated Processing Environment. NCL syntax is close to python or matlab.

;================================================;
;  maponly_1.ncl
;================================================;
;
; Concepts illustrated:
;   - Drawing a default cylindrical equidistant map
;
;================================================;
;
; These files are loaded by default in NCL V6.2.0 and newer
; load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"   
; load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl"   
; ================================================;
begin

  wks  = gsn_open_wks("png","maponly")    ; send graphics to PNG file
  plot = gsn_csm_map(wks,False)        ; draw global map

  end

Ncl is an interpreted language (not compiled)

How to run it?

$ ncl
 Copyright (C) 1995-2015 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.3.0
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.
ncl 0>

Pros

Cons

What’s required to run it

Running NCL interactively

Like for python or R, we can start ncl and enter ncl commands one after the other:

pi = 4.0 * atan(1.0)
print(pi)
$ ncl
 Copyright (C) 1995-2015 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.3.0
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.
ncl 0> pi=4.0*atan(1.0)
ncl 1> print(pi)


Variable: pi
Type: float
Total Size: 4 bytes
            1 values
Number of Dimensions: 1
Dimensions and sizes:   [1]
Coordinates:
(0)     3.141593
ncl 2>

It is useful for testing your NCL installation but not recommended. We usually create a text file where we write our program and then execute it.

For instance, let’s create a new file called test.ncl with your favourite editor:

nano test.ncl

Then store these two lines in test.ncl:

pi = 4.0 * atan(1.0)
print(pi)

Save your file. With nano, use CTRL (Control key on your keyboard) and x (key x) and enter (key Return on your keyboard).

To execute your ncl script:

ncl test.ncl
 Copyright (C) 1995-2015 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.3.0
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.


Variable: pi
Type: float
Total Size: 4 bytes
            1 values
Number of Dimensions: 1
Dimensions and sizes:   [1]
Coordinates:
(0)     3.141593

Your ncl script may take a few seconds or a few hours depending on its complexity and how much data you are processing. It is therefore recommended to start your NCL script in background so you can logout from your computer and still run your script:

nohup ncl test.ncl > log_ncl.txt &

The output of your NCL script will then be stored in log_ncl.txt (you can use nano or any other editor to inspect its content).

NCL command line structure

To get the list of available options, you can use:

ncl -h
Usage: ncl -fhnopxQV <args> <file.ncl>
         -f: use new file structure and NetCDF4 features when possible
         -h: print this message and exit
         -n: don't enumerate values in print()
         -o: retain former behavior for certain backwards-incompatible changes
         -p: don't page output from the system() command
         -x: echo NCL commands
         -Q: turn off echo of NCL version and copyright info
         -V: print NCL version and exit
ncl –np test.ncl

The NetCDF data model à NCL’s data model

Why is this important?

Implication of using NetCDF structured, binary file format

NetCDF array-like data

A bit more on netCDF with ncdump

Using the online command ncdump -h allows to get metadata information on your netCDF file. Let’s take a history file of CESM CAM model:

ncdump -h
netcdf f2000.T31T31.control.cam.h0.0007-08-29-00000 {
dimensions:
	lat = 48 ;
	lon = 96 ;
	time = UNLIMITED ; // (30 currently)
	nbnd = 2 ;
	chars = 8 ;
	lev = 30 ;
	ilev = 31 ;
variables:
	double lev(lev) ;
		lev:long_name = "hybrid level at midpoints (1000*(A+B))" ;
		lev:units = "level" ;
		lev:positive = "down" ;
		lev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ;
		lev:formula_terms = "a: hyam b: hybm p0: P0 ps: PS" ;
	double hyam(lev) ;
		hyam:long_name = "hybrid A coefficient at layer midpoints" ;
	double hybm(lev) ;
		hybm:long_name = "hybrid B coefficient at layer midpoints" ;
	double ilev(ilev) ;
		ilev:long_name = "hybrid level at interfaces (1000*(A+B))" ;
		ilev:units = "level" ;
		ilev:positive = "down" ;
		ilev:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ;
		ilev:formula_terms = "a: hyai b: hybi p0: P0 ps: PS" ;
	double hyai(ilev) ;
		hyai:long_name = "hybrid A coefficient at layer interfaces" ;
	double hybi(ilev) ;
		hybi:long_name = "hybrid B coefficient at layer interfaces" ;
	double P0 ;
		P0:long_name = "reference pressure" ;
		P0:units = "Pa" ;
	double time(time) ;
		time:long_name = "time" ;
		time:units = "days since 0001-01-01 00:00:00" ;
		time:calendar = "noleap" ;
		time:bounds = "time_bnds" ;
	int date(time) ;
		date:long_name = "current date (YYYYMMDD)" ;
	int datesec(time) ;
		datesec:long_name = "current seconds of current date" ;
	double lat(lat) ;
		lat:long_name = "latitude" ;
		lat:units = "degrees_north" ;
	double lon(lon) ;
		lon:long_name = "longitude" ;
		lon:units = "degrees_east" ;
	double time_bnds(time, nbnd) ;
		time_bnds:long_name = "time interval endpoints" ;
	char date_written(time, chars) ;
	char time_written(time, chars) ;
	int ntrm ;
		ntrm:long_name = "spectral truncation parameter M" ;
	int ntrn ;
		ntrn:long_name = "spectral truncation parameter N" ;
	int ntrk ;
		ntrk:long_name = "spectral truncation parameter K" ;
	int ndbase ;
		ndbase:long_name = "base day" ;
	int nsbase ;
		nsbase:long_name = "seconds of base day" ;
	int nbdate ;
		nbdate:long_name = "base date (YYYYMMDD)" ;
	int nbsec ;
		nbsec:long_name = "seconds of base date" ;
	int mdt ;
		mdt:long_name = "timestep" ;
		mdt:units = "s" ;
	int nlon(lat) ;
		nlon:long_name = "number of longitudes" ;
	int wnummax(lat) ;
		wnummax:long_name = "cutoff Fourier wavenumber" ;
	double gw(lat) ;
		gw:long_name = "gauss weights" ;
	int ndcur(time) ;
		ndcur:long_name = "current day (from base day)" ;
	int nscur(time) ;
		nscur:long_name = "current seconds of current day" ;
	double co2vmr(time) ;
		co2vmr:long_name = "co2 volume mixing ratio" ;
	double ch4vmr(time) ;
		ch4vmr:long_name = "ch4 volume mixing ratio" ;
	double n2ovmr(time) ;
		n2ovmr:long_name = "n2o volume mixing ratio" ;
	double f11vmr(time) ;
		f11vmr:long_name = "f11 volume mixing ratio" ;
	double f12vmr(time) ;
		f12vmr:long_name = "f12 volume mixing ratio" ;
	double sol_tsi(time) ;
		sol_tsi:long_name = "total solar irradiance" ;
		sol_tsi:units = "W/m2" ;
	int nsteph(time) ;
		nsteph:long_name = "current timestep" ;
	float AEROD_v(time, lat, lon) ;
		AEROD_v:_FillValue = 1.e+36f ;
		AEROD_v:missing_value = 1.e+36f ;
		AEROD_v:units = "1" ;
		AEROD_v:long_name = "Total Aerosol Optical Depth in visible band" ;
		AEROD_v:cell_methods = "time: mean" ;
	float ANRAIN(time, lev, lat, lon) ;
		ANRAIN:mdims = 1 ;
		ANRAIN:units = "m-3" ;
		ANRAIN:long_name = "Average rain number conc" ;
		ANRAIN:cell_methods = "time: mean" ;
	float ANSNOW(time, lev, lat, lon) ;
		ANSNOW:mdims = 1 ;
		ANSNOW:units = "m-3" ;
		ANSNOW:long_name = "Average snow number conc" ;
		ANSNOW:cell_methods = "time: mean" ;
	float AODDUST1(time, lat, lon) ;
		AODDUST1:_FillValue = 1.e+36f ;
		AODDUST1:missing_value = 1.e+36f ;
		AODDUST1:units = "" ;
		AODDUST1:long_name = "Aerosol optical depth 550 nm model 1 from dust" ;
		AODDUST1:cell_methods = "time: mean" ;
	float AODDUST3(time, lat, lon) ;
		AODDUST3:_FillValue = 1.e+36f ;
		AODDUST3:missing_value = 1.e+36f ;
		AODDUST3:units = "" ;
		AODDUST3:long_name = "Aerosol optical depth 550 nm model 3 from dust" ;
		AODDUST3:cell_methods = "time: mean" ;
	float AODVIS(time, lat, lon) ;
		AODVIS:_FillValue = 1.e+36f ;
		AODVIS:missing_value = 1.e+36f ;
		AODVIS:units = "" ;
		AODVIS:long_name = "Aerosol optical depth 550 nm" ;
		AODVIS:cell_methods = "time: mean" ;
	float AQRAIN(time, lev, lat, lon) ;
		AQRAIN:mdims = 1 ;
		AQRAIN:units = "kg/kg" ;
		AQRAIN:long_name = "Average rain mixing ratio" ;
		AQRAIN:cell_methods = "time: mean" ;
	float AQSNOW(time, lev, lat, lon) ;
		AQSNOW:mdims = 1 ;
		AQSNOW:units = "kg/kg" ;
		AQSNOW:long_name = "Average snow mixing ratio" ;
		AQSNOW:cell_methods = "time: mean" ;
	float AREI(time, lev, lat, lon) ;
		AREI:mdims = 1 ;
		AREI:units = "Micron" ;
		AREI:long_name = "Average ice effective radius" ;
		AREI:cell_methods = "time: mean" ;
	float AREL(time, lev, lat, lon) ;
		AREL:mdims = 1 ;
		AREL:units = "Micron" ;
		AREL:long_name = "Average droplet effective radius" ;
		AREL:cell_methods = "time: mean" ;
	float AWNC(time, lev, lat, lon) ;
		AWNC:mdims = 1 ;
		AWNC:units = "m-3" ;
		AWNC:long_name = "Average cloud water number conc" ;
		AWNC:cell_methods = "time: mean" ;
	float AWNI(time, lev, lat, lon) ;
		AWNI:mdims = 1 ;
		AWNI:units = "m-3" ;
		AWNI:long_name = "Average cloud ice number conc" ;
		AWNI:cell_methods = "time: mean" ;
	float BURDEN1(time, lat, lon) ;
		BURDEN1:_FillValue = 1.e+36f ;
		BURDEN1:missing_value = 1.e+36f ;
		BURDEN1:units = "kg/m2" ;
		BURDEN1:long_name = "Aerosol burden mode 1" ;
		BURDEN1:cell_methods = "time: mean" ;
	float BURDEN2(time, lat, lon) ;
		BURDEN2:_FillValue = 1.e+36f ;
		BURDEN2:missing_value = 1.e+36f ;
		BURDEN2:units = "kg/m2" ;
		BURDEN2:long_name = "Aerosol burden mode 2" ;
		BURDEN2:cell_methods = "time: mean" ;
	float BURDEN3(time, lat, lon) ;
		BURDEN3:_FillValue = 1.e+36f ;
		BURDEN3:missing_value = 1.e+36f ;
		BURDEN3:units = "kg/m2" ;
		BURDEN3:long_name = "Aerosol burden mode 3" ;
		BURDEN3:cell_methods = "time: mean" ;
	float BURDENBC(time, lat, lon) ;
		BURDENBC:_FillValue = 1.e+36f ;
		BURDENBC:missing_value = 1.e+36f ;
		BURDENBC:units = "kg/m2" ;
		BURDENBC:long_name = "Black carbon aerosol burden" ;
		BURDENBC:cell_methods = "time: mean" ;
	float BURDENDUST(time, lat, lon) ;
		BURDENDUST:_FillValue = 1.e+36f ;
		BURDENDUST:missing_value = 1.e+36f ;
		BURDENDUST:units = "kg/m2" ;
		BURDENDUST:long_name = "Dust aerosol burden" ;
		BURDENDUST:cell_methods = "time: mean" ;
	float BURDENPOM(time, lat, lon) ;
		BURDENPOM:_FillValue = 1.e+36f ;
		BURDENPOM:missing_value = 1.e+36f ;
		BURDENPOM:units = "kg/m2" ;
		BURDENPOM:long_name = "POM aerosol burden" ;
		BURDENPOM:cell_methods = "time: mean" ;
	float BURDENSEASALT(time, lat, lon) ;
		BURDENSEASALT:_FillValue = 1.e+36f ;
		BURDENSEASALT:missing_value = 1.e+36f ;
		BURDENSEASALT:units = "kg/m2" ;
		BURDENSEASALT:long_name = "Seasalt aerosol burden" ;
		BURDENSEASALT:cell_methods = "time: mean" ;
	float BURDENSO4(time, lat, lon) ;
		BURDENSO4:_FillValue = 1.e+36f ;
		BURDENSO4:missing_value = 1.e+36f ;
		BURDENSO4:units = "kg/m2" ;
		BURDENSO4:long_name = "Sulfate aerosol burden" ;
		BURDENSO4:cell_methods = "time: mean" ;
	float BURDENSOA(time, lat, lon) ;
		BURDENSOA:_FillValue = 1.e+36f ;
		BURDENSOA:missing_value = 1.e+36f ;
		BURDENSOA:units = "kg/m2" ;
		BURDENSOA:long_name = "SOA aerosol burden" ;
		BURDENSOA:cell_methods = "time: mean" ;
	float CCN3(time, lev, lat, lon) ;
		CCN3:mdims = 1 ;
		CCN3:units = "#/cm3" ;
		CCN3:long_name = "CCN concentration at S=0.1%" ;
		CCN3:cell_methods = "time: mean" ;
	float CDNUMC(time, lat, lon) ;
		CDNUMC:units = "1/m2" ;
		CDNUMC:long_name = "Vertically-integrated droplet concentration" ;
		CDNUMC:cell_methods = "time: mean" ;
	float CLDHGH(time, lat, lon) ;
		CLDHGH:units = "fraction" ;
		CLDHGH:long_name = "Vertically-integrated high cloud" ;
		CLDHGH:cell_methods = "time: mean" ;
	float CLDICE(time, lev, lat, lon) ;
		CLDICE:mdims = 1 ;
		CLDICE:units = "kg/kg" ;
		CLDICE:long_name = "Grid box averaged cloud ice amount" ;
		CLDICE:cell_methods = "time: mean" ;
	float CLDLIQ(time, lev, lat, lon) ;
		CLDLIQ:mdims = 1 ;
		CLDLIQ:units = "kg/kg" ;
		CLDLIQ:long_name = "Grid box averaged cloud liquid amount" ;
		CLDLIQ:cell_methods = "time: mean" ;
	float CLDLOW(time, lat, lon) ;
		CLDLOW:units = "fraction" ;
		CLDLOW:long_name = "Vertically-integrated low cloud" ;
		CLDLOW:cell_methods = "time: mean" ;
	float CLDMED(time, lat, lon) ;
		CLDMED:units = "fraction" ;
		CLDMED:long_name = "Vertically-integrated mid-level cloud" ;
		CLDMED:cell_methods = "time: mean" ;
	float CLDTOT(time, lat, lon) ;
		CLDTOT:units = "fraction" ;
		CLDTOT:long_name = "Vertically-integrated total cloud" ;
		CLDTOT:cell_methods = "time: mean" ;
	float CLOUD(time, lev, lat, lon) ;
		CLOUD:mdims = 1 ;
		CLOUD:units = "fraction" ;
		CLOUD:long_name = "Cloud fraction" ;
		CLOUD:cell_methods = "time: mean" ;
	float DCQ(time, lev, lat, lon) ;
		DCQ:mdims = 1 ;
		DCQ:units = "kg/kg/s" ;
		DCQ:long_name = "Q tendency due to moist processes" ;
		DCQ:cell_methods = "time: mean" ;
	float DMS_SRF(time, lat, lon) ;
		DMS_SRF:units = "kg/kg" ;
		DMS_SRF:long_name = "DMS in bottom layer" ;
		DMS_SRF:cell_methods = "time: mean" ;
	float DTCOND(time, lev, lat, lon) ;
		DTCOND:mdims = 1 ;
		DTCOND:units = "K/s" ;
		DTCOND:long_name = "T tendency - moist processes" ;
		DTCOND:cell_methods = "time: mean" ;
	float DTH(time, lev, lat, lon) ;
		DTH:mdims = 1 ;
		DTH:units = "K/s" ;
		DTH:long_name = "T horizontal diffusive heating" ;
		DTH:cell_methods = "time: mean" ;
	float DTV(time, lev, lat, lon) ;
		DTV:mdims = 1 ;
		DTV:units = "K/s" ;
		DTV:long_name = "T vertical diffusion" ;
		DTV:cell_methods = "time: mean" ;
	float EMISCLD(time, lev, lat, lon) ;
		EMISCLD:mdims = 1 ;
		EMISCLD:units = "1" ;
		EMISCLD:long_name = "cloud emissivity" ;
		EMISCLD:cell_methods = "time: mean" ;
	float FICE(time, lev, lat, lon) ;
		FICE:mdims = 1 ;
		FICE:units = "fraction" ;
		FICE:long_name = "Fractional ice content within cloud" ;
		FICE:cell_methods = "time: mean" ;
	float FLDS(time, lat, lon) ;
		FLDS:Sampling_Sequence = "rad_lwsw" ;
		FLDS:units = "W/m2" ;
		FLDS:long_name = "Downwelling longwave flux at surface" ;
		FLDS:cell_methods = "time: mean" ;
	float FLNS(time, lat, lon) ;
		FLNS:Sampling_Sequence = "rad_lwsw" ;
		FLNS:units = "W/m2" ;
		FLNS:long_name = "Net longwave flux at surface" ;
		FLNS:cell_methods = "time: mean" ;
	float FLNSC(time, lat, lon) ;
		FLNSC:Sampling_Sequence = "rad_lwsw" ;
		FLNSC:units = "W/m2" ;
		FLNSC:long_name = "Clearsky net longwave flux at surface" ;
		FLNSC:cell_methods = "time: mean" ;
	float FLNT(time, lat, lon) ;
		FLNT:Sampling_Sequence = "rad_lwsw" ;
		FLNT:units = "W/m2" ;
		FLNT:long_name = "Net longwave flux at top of model" ;
		FLNT:cell_methods = "time: mean" ;
	float FLNTC(time, lat, lon) ;
		FLNTC:Sampling_Sequence = "rad_lwsw" ;
		FLNTC:units = "W/m2" ;
		FLNTC:long_name = "Clearsky net longwave flux at top of model" ;
		FLNTC:cell_methods = "time: mean" ;
	float FLUT(time, lat, lon) ;
		FLUT:Sampling_Sequence = "rad_lwsw" ;
		FLUT:units = "W/m2" ;
		FLUT:long_name = "Upwelling longwave flux at top of model" ;
		FLUT:cell_methods = "time: mean" ;
	float FLUTC(time, lat, lon) ;
		FLUTC:Sampling_Sequence = "rad_lwsw" ;
		FLUTC:units = "W/m2" ;
		FLUTC:long_name = "Clearsky upwelling longwave flux at top of model" ;
		FLUTC:cell_methods = "time: mean" ;
	float FREQI(time, lev, lat, lon) ;
		FREQI:mdims = 1 ;
		FREQI:units = "fraction" ;
		FREQI:long_name = "Fractional occurrence of ice" ;
		FREQI:cell_methods = "time: mean" ;
	float FREQL(time, lev, lat, lon) ;
		FREQL:mdims = 1 ;
		FREQL:units = "fraction" ;
		FREQL:long_name = "Fractional occurrence of liquid" ;
		FREQL:cell_methods = "time: mean" ;
	float FREQR(time, lev, lat, lon) ;
		FREQR:mdims = 1 ;
		FREQR:units = "fraction" ;
		FREQR:long_name = "Fractional occurrence of rain" ;
		FREQR:cell_methods = "time: mean" ;
	float FREQS(time, lev, lat, lon) ;
		FREQS:mdims = 1 ;
		FREQS:units = "fraction" ;
		FREQS:long_name = "Fractional occurrence of snow" ;
		FREQS:cell_methods = "time: mean" ;
	float FSDS(time, lat, lon) ;
		FSDS:Sampling_Sequence = "rad_lwsw" ;
		FSDS:units = "W/m2" ;
		FSDS:long_name = "Downwelling solar flux at surface" ;
		FSDS:cell_methods = "time: mean" ;
	float FSDSC(time, lat, lon) ;
		FSDSC:Sampling_Sequence = "rad_lwsw" ;
		FSDSC:units = "W/m2" ;
		FSDSC:long_name = "Clearsky downwelling solar flux at surface" ;
		FSDSC:cell_methods = "time: mean" ;
	float FSNS(time, lat, lon) ;
		FSNS:Sampling_Sequence = "rad_lwsw" ;
		FSNS:units = "W/m2" ;
		FSNS:long_name = "Net solar flux at surface" ;
		FSNS:cell_methods = "time: mean" ;
	float FSNSC(time, lat, lon) ;
		FSNSC:Sampling_Sequence = "rad_lwsw" ;
		FSNSC:units = "W/m2" ;
		FSNSC:long_name = "Clearsky net solar flux at surface" ;
		FSNSC:cell_methods = "time: mean" ;
	float FSNT(time, lat, lon) ;
		FSNT:Sampling_Sequence = "rad_lwsw" ;
		FSNT:units = "W/m2" ;
		FSNT:long_name = "Net solar flux at top of model" ;
		FSNT:cell_methods = "time: mean" ;
	float FSNTC(time, lat, lon) ;
		FSNTC:Sampling_Sequence = "rad_lwsw" ;
		FSNTC:units = "W/m2" ;
		FSNTC:long_name = "Clearsky net solar flux at top of model" ;
		FSNTC:cell_methods = "time: mean" ;
	float FSNTOA(time, lat, lon) ;
		FSNTOA:Sampling_Sequence = "rad_lwsw" ;
		FSNTOA:units = "W/m2" ;
		FSNTOA:long_name = "Net solar flux at top of atmosphere" ;
		FSNTOA:cell_methods = "time: mean" ;
	float FSNTOAC(time, lat, lon) ;
		FSNTOAC:Sampling_Sequence = "rad_lwsw" ;
		FSNTOAC:units = "W/m2" ;
		FSNTOAC:long_name = "Clearsky net solar flux at top of atmosphere" ;
		FSNTOAC:cell_methods = "time: mean" ;
	float FSUTOA(time, lat, lon) ;
		FSUTOA:Sampling_Sequence = "rad_lwsw" ;
		FSUTOA:units = "W/m2" ;
		FSUTOA:long_name = "Upwelling solar flux at top of atmosphere" ;
		FSUTOA:cell_methods = "time: mean" ;
	float H2O2_SRF(time, lat, lon) ;
		H2O2_SRF:units = "kg/kg" ;
		H2O2_SRF:long_name = "H2O2 in bottom layer" ;
		H2O2_SRF:cell_methods = "time: mean" ;
	float H2SO4_SRF(time, lat, lon) ;
		H2SO4_SRF:units = "kg/kg" ;
		H2SO4_SRF:long_name = "H2SO4 in bottom layer" ;
		H2SO4_SRF:cell_methods = "time: mean" ;
	float ICEFRAC(time, lat, lon) ;
		ICEFRAC:units = "fraction" ;
		ICEFRAC:long_name = "Fraction of sfc area covered by sea-ice" ;
		ICEFRAC:cell_methods = "time: mean" ;
	float ICIMR(time, lev, lat, lon) ;
		ICIMR:mdims = 1 ;
		ICIMR:units = "kg/kg" ;
		ICIMR:long_name = "Prognostic in-cloud ice mixing ratio" ;
		ICIMR:cell_methods = "time: mean" ;
	float ICWMR(time, lev, lat, lon) ;
		ICWMR:mdims = 1 ;
		ICWMR:units = "kg/kg" ;
		ICWMR:long_name = "Prognostic in-cloud water mixing ratio" ;
		ICWMR:cell_methods = "time: mean" ;
	float IWC(time, lev, lat, lon) ;
		IWC:mdims = 1 ;
		IWC:units = "kg/m3" ;
		IWC:long_name = "Grid box average ice water content" ;
		IWC:cell_methods = "time: mean" ;
	float LANDFRAC(time, lat, lon) ;
		LANDFRAC:units = "fraction" ;
		LANDFRAC:long_name = "Fraction of sfc area covered by land" ;
		LANDFRAC:cell_methods = "time: mean" ;
	float LHFLX(time, lat, lon) ;
		LHFLX:units = "W/m2" ;
		LHFLX:long_name = "Surface latent heat flux" ;
		LHFLX:cell_methods = "time: mean" ;
	float LWCF(time, lat, lon) ;
		LWCF:Sampling_Sequence = "rad_lwsw" ;
		LWCF:units = "W/m2" ;
		LWCF:long_name = "Longwave cloud forcing" ;
		LWCF:cell_methods = "time: mean" ;
	float NUMICE(time, lev, lat, lon) ;
		NUMICE:mdims = 1 ;
		NUMICE:units = "1/kg" ;
		NUMICE:long_name = "Grid box averaged cloud ice number" ;
		NUMICE:cell_methods = "time: mean" ;
	float NUMLIQ(time, lev, lat, lon) ;
		NUMLIQ:mdims = 1 ;
		NUMLIQ:units = "1/kg" ;
		NUMLIQ:long_name = "Grid box averaged cloud liquid number" ;
		NUMLIQ:cell_methods = "time: mean" ;
	float OCNFRAC(time, lat, lon) ;
		OCNFRAC:units = "fraction" ;
		OCNFRAC:long_name = "Fraction of sfc area covered by ocean" ;
		OCNFRAC:cell_methods = "time: mean" ;
	float OMEGA(time, lev, lat, lon) ;
		OMEGA:mdims = 1 ;
		OMEGA:units = "Pa/s" ;
		OMEGA:long_name = "Vertical velocity (pressure)" ;
		OMEGA:cell_methods = "time: mean" ;
	float OMEGAT(time, lev, lat, lon) ;
		OMEGAT:mdims = 1 ;
		OMEGAT:units = "K Pa/s" ;
		OMEGAT:long_name = "Vertical heat flux" ;
		OMEGAT:cell_methods = "time: mean" ;
	float ORO(time, lat, lon) ;
		ORO:units = "frac" ;
		ORO:long_name = "ORO" ;
		ORO:cell_methods = "time: mean" ;
	float PBLH(time, lat, lon) ;
		PBLH:units = "m" ;
		PBLH:long_name = "PBL height" ;
		PBLH:cell_methods = "time: mean" ;
	float PHIS(time, lat, lon) ;
		PHIS:units = "m2/s2" ;
		PHIS:long_name = "Surface geopotential" ;
	float PRECC(time, lat, lon) ;
		PRECC:units = "m/s" ;
		PRECC:long_name = "Convective precipitation rate (liq + ice)" ;
		PRECC:cell_methods = "time: mean" ;
	float PRECL(time, lat, lon) ;
		PRECL:units = "m/s" ;
		PRECL:long_name = "Large-scale (stable) precipitation rate (liq + ice)" ;
		PRECL:cell_methods = "time: mean" ;
	float PRECSC(time, lat, lon) ;
		PRECSC:units = "m/s" ;
		PRECSC:long_name = "Convective snow rate (water equivalent)" ;
		PRECSC:cell_methods = "time: mean" ;
	float PRECSL(time, lat, lon) ;
		PRECSL:units = "m/s" ;
		PRECSL:long_name = "Large-scale (stable) snow rate (water equivalent)" ;
		PRECSL:cell_methods = "time: mean" ;
	float PS(time, lat, lon) ;
		PS:units = "Pa" ;
		PS:long_name = "Surface pressure" ;
		PS:cell_methods = "time: mean" ;
	float PSL(time, lat, lon) ;
		PSL:units = "Pa" ;
		PSL:long_name = "Sea level pressure" ;
		PSL:cell_methods = "time: mean" ;
	float Q(time, lev, lat, lon) ;
		Q:mdims = 1 ;
		Q:units = "kg/kg" ;
		Q:long_name = "Specific humidity" ;
		Q:cell_methods = "time: mean" ;
	float QFLX(time, lat, lon) ;
		QFLX:units = "kg/m2/s" ;
		QFLX:long_name = "Surface water flux" ;
		QFLX:cell_methods = "time: mean" ;
	float QREFHT(time, lat, lon) ;
		QREFHT:units = "kg/kg" ;
		QREFHT:long_name = "Reference height humidity" ;
		QREFHT:cell_methods = "time: mean" ;
	float QRL(time, lev, lat, lon) ;
		QRL:mdims = 1 ;
		QRL:Sampling_Sequence = "rad_lwsw" ;
		QRL:units = "K/s" ;
		QRL:long_name = "Longwave heating rate" ;
		QRL:cell_methods = "time: mean" ;
	float QRS(time, lev, lat, lon) ;
		QRS:mdims = 1 ;
		QRS:Sampling_Sequence = "rad_lwsw" ;
		QRS:units = "K/s" ;
		QRS:long_name = "Solar heating rate" ;
		QRS:cell_methods = "time: mean" ;
	float RELHUM(time, lev, lat, lon) ;
		RELHUM:mdims = 1 ;
		RELHUM:units = "percent" ;
		RELHUM:long_name = "Relative humidity" ;
		RELHUM:cell_methods = "time: mean" ;
	float SHFLX(time, lat, lon) ;
		SHFLX:units = "W/m2" ;
		SHFLX:long_name = "Surface sensible heat flux" ;
		SHFLX:cell_methods = "time: mean" ;
	float SNOWHICE(time, lat, lon) ;
		SNOWHICE:units = "m" ;
		SNOWHICE:long_name = "Snow depth over ice" ;
		SNOWHICE:cell_methods = "time: mean" ;
	float SNOWHLND(time, lat, lon) ;
		SNOWHLND:units = "m" ;
		SNOWHLND:long_name = "Water equivalent snow depth" ;
		SNOWHLND:cell_methods = "time: mean" ;
	float SO2_SRF(time, lat, lon) ;
		SO2_SRF:units = "kg/kg" ;
		SO2_SRF:long_name = "SO2 in bottom layer" ;
		SO2_SRF:cell_methods = "time: mean" ;
	float SOAG_SRF(time, lat, lon) ;
		SOAG_SRF:units = "kg/kg" ;
		SOAG_SRF:long_name = "SOAG in bottom layer" ;
		SOAG_SRF:cell_methods = "time: mean" ;
	float SOLIN(time, lat, lon) ;
		SOLIN:Sampling_Sequence = "rad_lwsw" ;
		SOLIN:units = "W/m2" ;
		SOLIN:long_name = "Solar insolation" ;
		SOLIN:cell_methods = "time: mean" ;
	float SWCF(time, lat, lon) ;
		SWCF:Sampling_Sequence = "rad_lwsw" ;
		SWCF:units = "W/m2" ;
		SWCF:long_name = "Shortwave cloud forcing" ;
		SWCF:cell_methods = "time: mean" ;
	float T(time, lev, lat, lon) ;
		T:mdims = 1 ;
		T:units = "K" ;
		T:long_name = "Temperature" ;
		T:cell_methods = "time: mean" ;
	float TAUX(time, lat, lon) ;
		TAUX:units = "N/m2" ;
		TAUX:long_name = "Zonal surface stress" ;
		TAUX:cell_methods = "time: mean" ;
	float TAUY(time, lat, lon) ;
		TAUY:units = "N/m2" ;
		TAUY:long_name = "Meridional surface stress" ;
		TAUY:cell_methods = "time: mean" ;
	float TGCLDCWP(time, lat, lon) ;
		TGCLDCWP:units = "kg/m2" ;
		TGCLDCWP:long_name = "Total grid-box cloud water path (liquid and ice)" ;
		TGCLDCWP:cell_methods = "time: mean" ;
	float TGCLDIWP(time, lat, lon) ;
		TGCLDIWP:units = "kg/m2" ;
		TGCLDIWP:long_name = "Total grid-box cloud ice water path" ;
		TGCLDIWP:cell_methods = "time: mean" ;
	float TGCLDLWP(time, lat, lon) ;
		TGCLDLWP:units = "kg/m2" ;
		TGCLDLWP:long_name = "Total grid-box cloud liquid water path" ;
		TGCLDLWP:cell_methods = "time: mean" ;
	float TMQ(time, lat, lon) ;
		TMQ:units = "kg/m2" ;
		TMQ:long_name = "Total (vertically integrated) precipitable water" ;
		TMQ:cell_methods = "time: mean" ;
	float TREFHT(time, lat, lon) ;
		TREFHT:units = "K" ;
		TREFHT:long_name = "Reference height temperature" ;
		TREFHT:cell_methods = "time: mean" ;
	float TS(time, lat, lon) ;
		TS:units = "K" ;
		TS:long_name = "Surface temperature (radiative)" ;
		TS:cell_methods = "time: mean" ;
	float TSMN(time, lat, lon) ;
		TSMN:units = "K" ;
		TSMN:long_name = "Minimum surface temperature over output period" ;
		TSMN:cell_methods = "time: minimum" ;
	float TSMX(time, lat, lon) ;
		TSMX:units = "K" ;
		TSMX:long_name = "Maximum surface temperature over output period" ;
		TSMX:cell_methods = "time: maximum" ;
	float U(time, lev, lat, lon) ;
		U:mdims = 1 ;
		U:units = "m/s" ;
		U:long_name = "Zonal wind" ;
		U:cell_methods = "time: mean" ;
	float U10(time, lat, lon) ;
		U10:units = "m/s" ;
		U10:long_name = "10m wind speed" ;
		U10:cell_methods = "time: mean" ;
	float UU(time, lev, lat, lon) ;
		UU:mdims = 1 ;
		UU:units = "m2/s2" ;
		UU:long_name = "Zonal velocity squared" ;
		UU:cell_methods = "time: mean" ;
	float V(time, lev, lat, lon) ;
		V:mdims = 1 ;
		V:units = "m/s" ;
		V:long_name = "Meridional wind" ;
		V:cell_methods = "time: mean" ;
	float VD01(time, lev, lat, lon) ;
		VD01:mdims = 1 ;
		VD01:units = "kg/kg/s" ;
		VD01:long_name = "Vertical diffusion of Q" ;
		VD01:cell_methods = "time: mean" ;
	float VQ(time, lev, lat, lon) ;
		VQ:mdims = 1 ;
		VQ:units = "m/skg/kg" ;
		VQ:long_name = "Meridional water transport" ;
		VQ:cell_methods = "time: mean" ;
	float VT(time, lev, lat, lon) ;
		VT:mdims = 1 ;
		VT:units = "K m/s" ;
		VT:long_name = "Meridional heat transport" ;
		VT:cell_methods = "time: mean" ;
	float VU(time, lev, lat, lon) ;
		VU:mdims = 1 ;
		VU:units = "m2/s2" ;
		VU:long_name = "Meridional flux of zonal momentum" ;
		VU:cell_methods = "time: mean" ;
	float VV(time, lev, lat, lon) ;
		VV:mdims = 1 ;
		VV:units = "m2/s2" ;
		VV:long_name = "Meridional velocity squared" ;
		VV:cell_methods = "time: mean" ;
	float WGUSTD(time, lat, lon) ;
		WGUSTD:units = "m/s" ;
		WGUSTD:long_name = "wind gusts from turbulence" ;
		WGUSTD:cell_methods = "time: mean" ;
	float WSUB(time, lev, lat, lon) ;
		WSUB:mdims = 1 ;
		WSUB:units = "m/s" ;
		WSUB:long_name = "Diagnostic sub-grid vertical velocity" ;
		WSUB:cell_methods = "time: mean" ;
	float Z3(time, lev, lat, lon) ;
		Z3:mdims = 1 ;
		Z3:units = "m" ;
		Z3:long_name = "Geopotential Height (above sea level)" ;
		Z3:cell_methods = "time: mean" ;
	float bc_a1_SRF(time, lat, lon) ;
		bc_a1_SRF:units = "kg/kg" ;
		bc_a1_SRF:long_name = "bc_a1 in bottom layer" ;
		bc_a1_SRF:cell_methods = "time: mean" ;
	float dst_a1SF(time, lat, lon) ;
		dst_a1SF:units = "kg/m2/s" ;
		dst_a1SF:long_name = "dst_a1 dust surface emission" ;
		dst_a1SF:cell_methods = "time: mean" ;
	float dst_a1_SRF(time, lat, lon) ;
		dst_a1_SRF:units = "kg/kg" ;
		dst_a1_SRF:long_name = "dst_a1 in bottom layer" ;
		dst_a1_SRF:cell_methods = "time: mean" ;
	float dst_a3SF(time, lat, lon) ;
		dst_a3SF:units = "kg/m2/s" ;
		dst_a3SF:long_name = "dst_a3 dust surface emission" ;
		dst_a3SF:cell_methods = "time: mean" ;
	float dst_a3_SRF(time, lat, lon) ;
		dst_a3_SRF:units = "kg/kg" ;
		dst_a3_SRF:long_name = "dst_a3 in bottom layer" ;
		dst_a3_SRF:cell_methods = "time: mean" ;
	float ncl_a1_SRF(time, lat, lon) ;
		ncl_a1_SRF:units = "kg/kg" ;
		ncl_a1_SRF:long_name = "ncl_a1 in bottom layer" ;
		ncl_a1_SRF:cell_methods = "time: mean" ;
	float ncl_a2_SRF(time, lat, lon) ;
		ncl_a2_SRF:units = "kg/kg" ;
		ncl_a2_SRF:long_name = "ncl_a2 in bottom layer" ;
		ncl_a2_SRF:cell_methods = "time: mean" ;
	float ncl_a3_SRF(time, lat, lon) ;
		ncl_a3_SRF:units = "kg/kg" ;
		ncl_a3_SRF:long_name = "ncl_a3 in bottom layer" ;
		ncl_a3_SRF:cell_methods = "time: mean" ;
	float num_a1_SRF(time, lat, lon) ;
		num_a1_SRF:units = " 1/kg" ;
		num_a1_SRF:long_name = "num_a1 in bottom layer" ;
		num_a1_SRF:cell_methods = "time: mean" ;
	float num_a2_SRF(time, lat, lon) ;
		num_a2_SRF:units = " 1/kg" ;
		num_a2_SRF:long_name = "num_a2 in bottom layer" ;
		num_a2_SRF:cell_methods = "time: mean" ;
	float num_a3_SRF(time, lat, lon) ;
		num_a3_SRF:units = " 1/kg" ;
		num_a3_SRF:long_name = "num_a3 in bottom layer" ;
		num_a3_SRF:cell_methods = "time: mean" ;
	float pom_a1_SRF(time, lat, lon) ;
		pom_a1_SRF:units = "kg/kg" ;
		pom_a1_SRF:long_name = "pom_a1 in bottom layer" ;
		pom_a1_SRF:cell_methods = "time: mean" ;
	float so4_a1_SRF(time, lat, lon) ;
		so4_a1_SRF:units = "kg/kg" ;
		so4_a1_SRF:long_name = "so4_a1 in bottom layer" ;
		so4_a1_SRF:cell_methods = "time: mean" ;
	float so4_a2_SRF(time, lat, lon) ;
		so4_a2_SRF:units = "kg/kg" ;
		so4_a2_SRF:long_name = "so4_a2 in bottom layer" ;
		so4_a2_SRF:cell_methods = "time: mean" ;
	float so4_a3_SRF(time, lat, lon) ;
		so4_a3_SRF:units = "kg/kg" ;
		so4_a3_SRF:long_name = "so4_a3 in bottom layer" ;
		so4_a3_SRF:cell_methods = "time: mean" ;
	float soa_a1_SRF(time, lat, lon) ;
		soa_a1_SRF:units = "kg/kg" ;
		soa_a1_SRF:long_name = "soa_a1 in bottom layer" ;
		soa_a1_SRF:cell_methods = "time: mean" ;
	float soa_a2_SRF(time, lat, lon) ;
		soa_a2_SRF:units = "kg/kg" ;
		soa_a2_SRF:long_name = "soa_a2 in bottom layer" ;
		soa_a2_SRF:cell_methods = "time: mean" ;

// global attributes:
		:Conventions = "CF-1.0" ;
		:source = "CAM" ;
		:case = "f2000.T31T31.control" ;
		:title = "UNSET" ;
		:logname = "hanbre" ;
		:host = "hexagon-5" ;
		:Version = "$Name$" ;
		:revision_Id = "$Id$" ;
		:initial_file = "/work/hanbre/inputdata/atm/cam/inic/gaus/cami_0000-01-01_48x96_L30_c100426.nc" ;
		:topography_file = "/work/hanbre/inputdata/atm/cam/topo/USGS-gtopo30_48x96_c050520.nc" ;
}

It contains information about variables (names, dimensions, units) and also global attributes (conventions, source, etc.).

Dimensions

dimensions:
	lat = 48 ;
	lon = 96 ;
	time = UNLIMITED ; // (30 currently)
	nbnd = 2 ;
	chars = 8 ;
	lev = 30 ;
	ilev = 31 ;

Variables


	float T(time, lev, lat, lon) ;
		T:mdims = 1 ;
		T:units = "K" ;
		T:long_name = "Temperature" ;
		T:cell_methods = "time: mean" ;

Coordinate variable definition

	double time(time) ;
		time:long_name = "time" ;
		time:units = "days since 0001-01-01 00:00:00" ;
		time:calendar = "noleap" ;
		time:bounds = "time_bnds" ;
	int date(time) ;
		date:long_name = "current date (YYYYMMDD)" ;
	int datesec(time) ;
		datesec:long_name = "current seconds of current date" ;
	double lat(lat) ;
		lat:long_name = "latitude" ;
		lat:units = "degrees_north" ;
	double lon(lon) ;
		lon:long_name = "longitude" ;
		lon:units = "degrees_east" ;

NetCDF conventions

netCDF is a very flexible data format; so flexible that we usually follow some conventions:

COARDS (1995; frozen) convention

CF (2005/2006; continues to evolve) convention

Most climate related data archives use NetCDF and adhere to these conventions: eg: CMIP5, CMIP3, CESM, IPCC. etc.

CESM CAM 5.3 follows CF conventions.

NCL variables

All NCL variables look like NetCDF variables. They have names, types, shape, size and values. They may also have additional information (metadata) such as a long name, units, names of dimensions, etc.

Let’s define a vector with 3 values:

aInt = (/1,2,3/)
print(aInt)

(/ is used to specify the start of your vector and /) deontes the end of your array. Here we created a vector containing 3 values: 1, 2 and 3. If we print aInt, we will get information on aInt NCL variable:


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

To create a two-dimensional array:

m2D = (/(/1.00,1.00,1.00/),(/0.9,0.80,0.50/)/)
print(m2D)

Variable: m2D
Type: float
Total Size: 24 bytes
            6 values
Number of Dimensions: 2
Dimensions and sizes:   [2] x [3]
Coordinates:
(0,0)    1
(0,1)    1
(0,2)    1
(1,0)   0.9
(1,1)   0.8
(1,2)   0.5

In these two examples, we do not have additional metadata (properties of our variables). Metadata (attributes) can be added using the syntax @:

m2D@units = "degC"
m2D@long_name = "matrix example"
print(m2D)
Variable: m2D
Type: float
Total Size: 24 bytes
            6 values
Number of Dimensions: 2
Dimensions and sizes:   [2] x [3]
Coordinates:
Number Of Attributes: 2
  long_name :   matrix example
  units :       degC
(0,0)    1
(0,1)    1
(0,2)    1
(1,0)   0.9
(1,1)   0.8
(1,2)   0.5

You can see that we now have two attributes when we print m2D.

Detailed Look at an NCL Variable

Let’s take one history file generated by the CAM model. We use addfile to open the netCDF file:

; open netCDF file to read 
f=addfile("f2000.T31T31.control.cam.h0.0008-12-22-00000.nc","r")
; import variable ( STRUCTURE )
T = f->T

print(f)

For the comparison of different simulations or the joint analysis of ensemble simulations, it is very useful to access multiple files at once. The function addfiles can open multiple existing data files or create multiple new data files using one of the supported file formats.

list_of_files = systemfunc("ls *.nc") ; NetCDF file names
f = addfiles(list_of_files, "r") ; data type `list`
; variable overview
printVarSummary (T) 
Variable: T
Type: float
Total Size: 6082560 bytes
            1520640 values
Number of Dimensions: 4
Dimensions and sizes:   [time | 11] x [lev | 30] x [lat | 48] x [lon | 96]
Coordinates:
            time: [2910..2920]
            lev: [3.64346569404006..992.556095123291]
            lat: [-87.15909455586285..87.15909455586285]
            lon: [   0..356.25]
Number Of Attributes: 4
  mdims :       1
  units :       K
  long_name :   Temperature
  cell_methods :        time: mean
(0)     Temperature: min=176.799   max=311.035

The second argument is either True (line feed prior to printing the min/max values) or False (no line feed):

printMinMax (T, True)
(0)
(0)     Temperature: min=176.799   max=311.035

Good to know

  • semi-column (;) is used to comment your code. Everything after ; will be ignored.
  • addfile can read netCDF, grib, hdf and hdfeos data file format.

Detailed look at an NCL variable

For instance, to get the list of times for T:

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

And to get the units:

print(T@units)
(0)     K

Key Points

  • NCL and its netCDF data model