Project

General

Profile

CDI  Fortran Manual

PICT

Climate Data Interface
Version 1.9.9
October 2020

Uwe Schulzweida

Max-Planck-Institute for Meteorology

PICT

Contents

1  Introduction
 1.1  Building from sources
  1.1.1  Compilation
  1.1.2  Installation
2  File Formats
 2.1  GRIB
  2.1.1  GRIB edition 1
  2.1.2  GRIB edition 2
 2.2  NetCDF
 2.3  SERVICE
 2.4  EXTRA
 2.5  IEG
3  Use of the CDI Library
 3.1  Creating a dataset
 3.2  Reading a dataset
 3.3  Compiling and Linking with the CDI library
4  CDI modules
 4.1  Dataset functions
  4.1.1  Create a new dataset: streamOpenWrite
  4.1.2  Open a dataset for reading: streamOpenRead
  4.1.3  Close an open dataset: streamClose
  4.1.4  Get the filetype: streamInqFiletype
  4.1.5  Define the byte order: streamDefByteorder
  4.1.6  Get the byte order: streamInqByteorder
  4.1.7  Define the variable list: streamDefVlist
  4.1.8  Get the variable list: streamInqVlist
  4.1.9  Define a timestep: streamDefTimestep
  4.1.10  Get timestep information: streamInqTimestep
  4.1.11  Write a variable: streamWriteVar
  4.1.12  Write a variable: streamWriteVarF
  4.1.13  Write a horizontal slice of a variable: streamWriteVarSlice
  4.1.14  Write a horizontal slice of a variable: streamWriteVarSliceF
  4.1.15  Read a variable: streamReadVar
  4.1.16  Read a variable: streamReadVarF
  4.1.17  Read a horizontal slice of a variable: streamReadVarSlice
  4.1.18  Read a horizontal slice of a variable: streamReadVarSliceF
 4.2  Variable list functions
  4.2.1  Create a variable list: vlistCreate
  4.2.2  Destroy a variable list: vlistDestroy
  4.2.3  Copy a variable list: vlistCopy
  4.2.4  Duplicate a variable list: vlistDuplicate
  4.2.5  Concatenate two variable lists: vlistCat
  4.2.6  Copy some entries of a variable list: vlistCopyFlag
  4.2.7  Number of variables in a variable list: vlistNvars
  4.2.8  Number of grids in a variable list: vlistNgrids
  4.2.9  Number of zaxis in a variable list: vlistNzaxis
  4.2.10  Define the time axis: vlistDefTaxis
  4.2.11  Get the time axis: vlistInqTaxis
 4.3  Variable functions
  4.3.1  Define a Variable: vlistDefVar
  4.3.2  Get the Grid ID of a Variable: vlistInqVarGrid
  4.3.3  Get the Zaxis ID of a Variable: vlistInqVarZaxis
  4.3.4  Get the timestep type of a Variable: vlistInqVarTsteptype
  4.3.5  Define the code number of a Variable: vlistDefVarCode
  4.3.6  Get the Code number of a Variable: vlistInqVarCode
  4.3.7  Define the data type of a Variable: vlistDefVarDatatype
  4.3.8  Get the data type of a Variable: vlistInqVarDatatype
  4.3.9  Define the missing value of a Variable: vlistDefVarMissval
  4.3.10  Get the missing value of a Variable: vlistInqVarMissval
 4.4  Key attributes
  4.4.1  Define a string from a key: cdiDefKeyString
  4.4.2  Get a string from a key: cdiInqKeyString
  4.4.3  Define an integer value from a key: cdiDefKeyInt
  4.4.4  Get an integer value from a key: cdiInqKeyInt
  4.4.5  Define a floating point value from a key: cdiDefKeyFloat
  4.4.6  Get a floating point value from a key: cdiInqKeyFloat
  4.4.7  Define a byte array from a key: cdiDefKeyBytes
  4.4.8  Get a byte array from a key: cdiInqKeyBytes
 4.5  User attributes
  4.5.1  Get number of attributes: cdiInqNatts
  4.5.2  Get information about an attribute: cdiInqAtt
  4.5.3  Define a text attribute: cdiDefAttTxt
  4.5.4  Get the value(s) of a text attribute: cdiInqAttTxt
  4.5.5  Define an integer attribute: cdiDefAttInt
  4.5.6  Get the value(s) of an integer attribute: cdiInqAttInt
  4.5.7  Define a floating point attribute: cdiDefAttFlt
  4.5.8  Get the value(s) of a floating point attribute: cdiInqAttFlt
 4.6  Grid functions
  4.6.1  Create a horizontal Grid: gridCreate
  4.6.2  Destroy a horizontal Grid: gridDestroy
  4.6.3  Duplicate a horizontal Grid: gridDuplicate
  4.6.4  Get the type of a Grid: gridInqType
  4.6.5  Get the size of a Grid: gridInqSize
  4.6.6  Define the number of values of a X-axis: gridDefXsize
  4.6.7  Get the number of values of a X-axis: gridInqXsize
  4.6.8  Define the number of values of a Y-axis: gridDefYsize
  4.6.9  Get the number of values of a Y-axis: gridInqYsize
  4.6.10  Define the number of parallels between a pole and the equator: gridDefNP
  4.6.11  Get the number of parallels between a pole and the equator: gridInqNP
  4.6.12  Define the values of a X-axis: gridDefXvals
  4.6.13  Get all values of a X-axis: gridInqXvals
  4.6.14  Define the values of a Y-axis: gridDefYvals
  4.6.15  Get all values of a Y-axis: gridInqYvals
  4.6.16  Define the bounds of a X-axis: gridDefXbounds
  4.6.17  Get the bounds of a X-axis: gridInqXbounds
  4.6.18  Define the bounds of a Y-axis: gridDefYbounds
  4.6.19  Get the bounds of a Y-axis: gridInqYbounds
 4.7  Z-axis functions
  4.7.1  Create a vertical Z-axis: zaxisCreate
  4.7.2  Destroy a vertical Z-axis: zaxisDestroy
  4.7.3  Get the type of a Z-axis: zaxisInqType
  4.7.4  Get the size of a Z-axis: zaxisInqSize
  4.7.5  Define the levels of a Z-axis: zaxisDefLevels
  4.7.6  Get all levels of a Z-axis: zaxisInqLevels
  4.7.7  Get one level of a Z-axis: zaxisInqLevel
 4.8  T-axis functions
  4.8.1  Create a Time axis: taxisCreate
  4.8.2  Destroy a Time axis: taxisDestroy
  4.8.3  Define the reference date: taxisDefRdate
  4.8.4  Get the reference date: taxisInqRdate
  4.8.5  Define the reference time: taxisDefRtime
  4.8.6  Get the reference time: taxisInqRtime
  4.8.7  Define the verification date: taxisDefVdate
  4.8.8  Get the verification date: taxisInqVdate
  4.8.9  Define the verification time: taxisDefVtime
  4.8.10  Get the verification time: taxisInqVtime
  4.8.11  Define the calendar: taxisDefCalendar
  4.8.12  Get the calendar: taxisInqCalendar
A  Quick Reference
B  Examples
 B.1  Write a dataset
  B.1.1  Result
 B.2  Read a dataset
 B.3  Copy a dataset
 B.4  Fortran 2003: mo_cdi and iso_c_binding
C  Environment Variables
  Function index

1  Introduction

CDI is an Interface to access Climate and forecast model Data. The interface is independent from a specific data format and has a C and Fortran API. CDI was developed for a fast and machine independent access to GRIB and NetCDF datasets with the same interface. The local MPI-MET data formats SERVICE, EXTRA and IEG are also supported.

1.1  Building from sources

This section describes how to build the CDI library from the sources on a UNIX system. CDI is using the GNU configure and build system to compile the source code. The only requirement is a working ANSI C99 compiler.

First go to the download page (https://code.mpimet.mpg.de/projects/cdi/files) to get the latest distribution, if you do not already have it.

To take full advantage of CDI’s features the following additional libraries should be installed:

  • Unidata NetCDF library (http://www.unidata.ucar.edu/packages/netcdf) version 3 or higher. This is needed to read/write NetCDF files with CDI.
  • ECMWF ecCodes library (https://software.ecmwf.int/wiki/display/ECC/ecCodes+Home) version 2.3.0 or higher. This library is needed to encode/decode GRIB2 records with CDI.

1.1.1  Compilation

Compilation is now done by performing the following steps:

  1. Unpack the archive, if you haven’t already done that:
        
             gunzip cdi-$VERSION.tar.gz    # uncompress the archive
             tar xf cdi-$VERSION.tar       # unpack it
             cd cdi-$VERSION
    

  2. Run the configure script:
        
             ./configure
    

    Or optionally with NetCDF support:

        
             ./configure --with-netcdf=<NetCDF root directory>
    

    For an overview of other configuration options use

        
             ./configure --help
    

  3. Compile the program by running make:
        
             make
    

The software should compile without problems and the CDI library (libcdi.a) should be available in the src directory of the distribution.

1.1.2  Installation

After the compilation of the source code do a make install, possibly as root if the destination permissions require that.


    make install

The library is installed into the directory <prefix>/lib. The C and Fortran include files are installed into the directory <prefix>/include. <prefix> defaults to /usr/local but can be changed with the --prefix option of the configure script.

2  File Formats

2.1  GRIB

GRIB [GRIB] (GRIdded Binary) is a standard format designed by the World Meteorological Organization (WMO) to support the efficient transmission and storage of gridded meteorological data.

A GRIB record consists of a series of header sections, followed by a bitstream of packed data representing one horizontal grid of data values. The header sections are intended to fully describe the data included in the bitstream, specifying information such as the parameter, units, and precision of the data, the grid system and level type on which the data is provided, and the date and time for which the data are valid.

Non-numeric descriptors are enumerated in tables, such that a 1-byte code in a header section refers to a unique description. The WMO provides a standard set of enumerated parameter names and level types, but the standard also allows for the definition of locally used parameters and geometries. Any activity that generates and distributes GRIB records must also make their locally defined GRIB tables available to users.

The GRIB records must be sorted by time to be able to read them correctly with CDI.

CDI does not support the full GRIB standard. The following data representation and level types are implemented:





GRIB1 GRIB2
grid type template GRIB_API name description
0 3.0 regular_ll Regular longitude/latitude grid
3 lambert Lambert conformal grid
4 3.40 regular_gg Regular Gaussian longitude/latitude grid
4 3.40 reduced_gg Reduced Gaussian longitude/latitude grid
10 3.1 rotated_ll Rotated longitude/latitude grid
50 3.50 sh Spherical harmonic coefficients
192 3.100 Icosahedral-hexagonal GME grid
3.101 General unstructured grid








GRIB1 GRIB2
level type level type GRIB_API name description
1 1 surface Surface level
2 2 cloudBase Cloud base level
3 3 cloudTop Level of cloud tops
4 4 isothermZero Level of 0 C isotherm
8 8 nominalTop Norminal top of atmosphere
9 9 seaBottom Sea bottom
10 10 entireAtmosphere Entire atmosphere
100 100 isobaricInhPa Isobaric level in hPa
102 101 meanSea Mean sea level
103 102 heightAboveSea Altitude above mean sea level
105 103 heightAboveGround Height level above ground
107 104 sigma Sigma level
109 105 hybrid Hybrid level
110 105 hybridLayer Layer between two hybrid levels
111 106 depthBelowLand Depth below land surface
112 106 depthBelowLandLayer Layer between two depths below land surface
113 107 theta Isentropic (theta) level
114 Snow level
160 160 depthBelowSea Depth below sea level
162 162 Lake or River Bottom
163 163 Bottom Of Sediment Layer
164 164 Bottom Of Thermally Active Sediment Layer
165 165 Bottom Of Sediment Layer Penetrated By
Thermal Wave
166 166 Mixing Layer
210 isobaricInPa Isobaric level in Pa




2.1.1  GRIB edition 1

GRIB1 is implemented in CDI as an internal library and enabled per default. The internal GRIB1 library is called CGRIBEX. This is a lightweight version of the ECMWF GRIBEX library. CGRIBEX is written in ANSI C with a portable Fortran interface. The configure option --disable-cgribex will disable the encoding/decoding of GRIB1 records with CGRIBEX.

2.1.2  GRIB edition 2

GRIB2 is available in CDI via the ECMWF ecCodes [ecCodes] library. ecCodes is an external library and not part of CDI. To use GRIB2 with CDI the ecCodes library must be installed before the configuration of the CDI library. Use the configure option --with-eccodes to enable GRIB2 support.

The ecCodes library is also used to encode/decode GRIB1 records if the support for the CGRIBEX library is disabled. This feature is not tested regulary and the status is experimental!

A single GRIB2 message can contain multiple fields. This feature is not supported in CDI!

2.2  NetCDF

NetCDF [NetCDF] (Network Common Data Form) is an interface for array-oriented data access and a library that provides an implementation of the interface. The NetCDF library also defines a machine-independent format for representing scientific data. Together, the interface, library, and format support the creation, access, and sharing of scientific data.

CDI only supports the classic data model of NetCDF and arrays up to 4 dimensions. These dimensions should only be used by the horizontal and vertical grid and the time. The NetCDF attributes should follow the GDT, COARDS or CF Conventions.

NetCDF is an external library and not part of CDI. To use NetCDF with CDI the NetCDF library must be installed before the configuration of the CDI library. Use the configure option --with-netcdf to enable NetCDF support (see Build).

2.3  SERVICE

SERVICE is the binary exchange format of the atmospheric general circulation model ECHAM [ECHAM]. It has a header section with 8 integer values followed by the data section. The header and the data section have the standard Fortran blocking for binary data records. A SERVICE record can have an accuracy of 4 or 8 bytes and the byteorder can be little or big endian. In CDI the accuracy of the header and data section must be the same. The following Fortran code example can be used to read a SERVICE record with an accuracy of 4 bytes:

  INTEGER*4 icode,ilevel,idate,itime,nlon,nlat,idispo1,idispo2 
  REAL*4 field(mlon,mlat) 
    ... 
  READ(unit) icode,ilevel,idate,itime,nlon,nlat,idispo1,idispo2 
  READ(unit) ((field(ilon,ilat), ilon=1,nlon), ilat=1,nlat)

The constants mlon and mlat must be greater or equal than nlon and nlat. The meaning of the variables are:

  

icode

The code number

ilevel

The level

idate

The date as YYYYMMDD

itime

The time as hhmmss

nlon

The number of longitudes

nlat

The number of latitides

idispo1

For the users disposal (Not used in CDI)

idispo2

For the users disposal (Not used in CDI)

SERVICE is implemented in CDI as an internal library and enabled per default. The configure option --disable-service will disable the support for the SERVICE format.

2.4  EXTRA

EXTRA is the standard binary output format of the ocean model MPIOM [MPIOM]. It has a header section with 4 integer values followed by the data section. The header and the data section have the standard Fortran blocking for binary data records. An EXTRA record can have an accuracy of 4 or 8 bytes and the byteorder can be little or big endian. In CDI the accuracy of the header and data section must be the same. The following Fortran code example can be used to read an EXTRA record with an accuracy of 4 bytes:

  INTEGER*4 idate,icode,ilevel,nsize 
  REAL*4 field(msize) 
    ... 
  READ(unit) idate,icode,ilevel,nsize 
  READ(unit) (field(isize),isize=1,nsize)

The constant msize must be greater or equal than nsize. The meaning of the variables are:

  

idate

The date as YYYYMMDD

icode

The code number

ilevel

The level

nsize

The size of the field

EXTRA is implemented in CDI as an internal library and enabled per default. The configure option --disable-extra will disable the support for the EXTRA format.

2.5  IEG

IEG is the standard binary output format of the regional model REMO [REMO]. It is simple an unpacked GRIB edition 1 format. The product and grid description sections are coded with 4 byte integer values and the data section can have 4 or 8 byte IEEE floating point values. The header and the data section have the standard Fortran blocking for binary data records. The IEG format has a fixed size of 100 for the vertical coordinate table. That means it is not possible to store more than 50 model levels with this format. CDI supports only data on Gaussian and LonLat grids for the IEG format.

IEG is implemented in CDI as an internal library and enabled per default. The configure option --disable-ieg will disable the support for the IEG format.

3  Use of the CDI Library

This chapter provides templates of common sequences of CDI calls needed for common uses. For clarity only the names of routines are used. Declarations and error checking were omitted. Statements that are typically invoked multiple times were indented and ... is used to represent arbitrary sequences of other statements. Full parameter lists are described in later chapters.

Complete examples for write, read and copy a dataset with CDI can be found in Appendix B.

3.1  Creating a dataset

Here is a typical sequence of CDI calls used to create a new dataset:

   gridCreate          ! create a horizontal Grid: from type and size 
      ... 
   zaxisCreate         ! create a vertical Z-axis: from type and size 
      ... 
   taxisCreate         ! create a Time axis: from type 
      ... 
   vlistCreate         ! create a variable list 
         ... 
      vlistDefVar      ! define variables: from Grid and Z-axis 
         ... 
   streamOpenWrite     ! create a dataset: from name and file type 
      ... 
   streamDefVlist      ! define variable list 
      ... 
   streamDefTimestep    ! define time step 
         ... 
      streamWriteVar    ! write variable 
         ... 
   streamClose         ! close the dataset 
      ... 
   vlistDestroy        ! destroy the variable list 
      ... 
   taxisDestroy        ! destroy the Time axis 
      ... 
   zaxisDestroy        ! destroy the Z-axis 
      ... 
   gridDestroy         ! destroy the Grid

3.2  Reading a dataset

Here is a typical sequence of CDI calls used to read a dataset:

   streamOpenRead      ! open existing dataset 
      ... 
   streamInqVlist      ! find out what is in it 
         ... 
      vlistInqVarGrid   ! get an identifier to the Grid 
         ... 
      vlistInqVarZaxis  ! get an identifier to the Z-axis 
         ... 
      vlistInqTaxis    ! get an identifier to the T-axis 
         ... 
   streamInqTimestep    ! get time step 
         ... 
      streamReadVar    ! read varible 
         ... 
   streamClose         ! close the dataset

3.3  Compiling and Linking with the CDI library

Details of how to compile and link a program that uses the CDI C or FORTRAN interfaces differ, depending on the operating system, the available compilers, and where the CDI library and include files are installed. Here are examples of how to compile and link a program that uses the CDI library on a Unix platform, so that you can adjust these examples to fit your installation. There are two different interfaces for using CDI functions in Fortran: cfortran.h and the instrinsic iso_c_binding module from Fortran 2003 standard. At first, the preparations for compilers without F2003 capabilities are described.

Every FORTRAN file that references CDI functions or constants must contain an appropriate INCLUDE statement before the first such reference:


   INCLUDE "cdi.inc"

Unless the cdi.inc file is installed in a standard directory where FORTRAN compiler always looks, you must use the -I option when invoking the compiler, to specify a directory where cdi.inc is installed, for example:


   f77 -c -I/usr/local/cdi/include myprogram.f

Alternatively, you could specify an absolute path name in the INCLUDE statement, but then your program would not compile on another platform where CDI is installed in a different location.

Unless the CDI library is installed in a standard directory where the linker always looks, you must use the -L and -l options to links an object file that uses the CDI library. For example:


   f77 -o myprogram myprogram.o -L/usr/local/cdi/lib -lcdi

Alternatively, you could specify an absolute path name for the library:


   f77 -o myprogram myprogram.o -L/usr/local/cdi/lib/libcdi

If the CDI library is using other external libraries, you must add this libraries in the same way. For example with the NetCDF library:


   f77 -o myprogram myprogram.o -L/usr/local/cdi/lib -lcdi \
                                -L/usr/local/netcdf/lib -lnetcdf

For using the iso_c_bindings two things are necessary in a program or module


   USE ISO_C_BINDING
   USE mo_cdi

The iso_c_binding module is included in mo_cdi, but without cfortran.h characters and character variables have to be handled separately. Examples are available in section B.4.

After installation mo_cdi.o and mo_cdi.mod are located in the library and header directory respectively. cdilib.o has to be mentioned directly on the command line. It can be found in the library directory, too. Depending on the CDI configuration, a compile command should look like this:


nagf95 -f2003 -g cdi_read_f2003.f90 -L/usr/lib -lnetcdf -o cdi_read_example
                                    -I/usr/local/include
                                    /usr/local/lib/cdilib.o /usr/local/lib/mo_cdi.o

4  CDI modules

4.1  Dataset functions

This module contains functions to read and write the data. To create a new dataset the output format must be specified with one of the following predefined file format types:

  

CDI_FILETYPE_GRB

File type GRIB version 1

CDI_FILETYPE_GRB2

File type GRIB version 2

CDI_FILETYPE_NC

File type NetCDF

CDI_FILETYPE_NC2

File type NetCDF version 2 (64-bit offset)

CDI_FILETYPE_NC4

File type NetCDF-4 (HDF5)

CDI_FILETYPE_NC4C

File type NetCDF-4 classic

CDI_FILETYPE_NC5

File type NetCDF version 5 (64-bit data)

CDI_FILETYPE_SRV

File type SERVICE

CDI_FILETYPE_EXT

File type EXTRA

CDI_FILETYPE_IEG

File type IEG

CDI_FILETYPE_GRB2 is only available if the CDI library was compiled with ecCodes support and all NetCDF file types are only available if the CDI library was compiled with NetCDF support!

To set the byte order of a binary dataset with the file format type CDI_FILETYPE_SRV, CDI_FILETYPE_EXT or CDI_FILETYPE_IEG use one of the following predefined constants in the call to streamDefByteorder:

  

CDI_BIGENDIAN

Byte order big endian

CDI_LITTLEENDIAN

Byte order little endian

4.1.1  Create a new dataset: streamOpenWrite

The function streamOpenWrite creates a new datset.

Usage

    INTEGER FUNCTION streamOpenWrite(CHARACTER*(*) path, INTEGER filetype)

 

path

The name of the new dataset.

filetype

The type of the file format, one of the set of predefined CDI file format types. The valid CDI file format types are CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C, CDI_FILETYPE_NC5, CDI_FILETYPE_SRV, CDI_FILETYPE_EXT and CDI_FILETYPE_IEG.

Result

Upon successful completion streamOpenWrite returns an identifier to the open stream. Otherwise, a negative number with the error status is returned.

Errors

 

CDI_ESYSTEM

Operating system error.

CDI_EINVAL

Invalid argument.

CDI_EUFILETYPE

Unsupported file type.

CDI_ELIBNAVAIL

Library support not compiled in.

Example

Here is an example using streamOpenWrite to create a new NetCDF file named foo.nc for writing:

 
   INCLUDE cdi.inc 
     ... 
   INTEGER streamID 
     ... 
   streamID = streamOpenWrite("foo.nc", CDI_FILETYPE_NC) 
   IF ( streamID .LT. 0 ) CALL handle_error(streamID) 
     ...

4.1.2  Open a dataset for reading: streamOpenRead

The function streamOpenRead opens an existing dataset for reading.

Usage

    INTEGER FUNCTION streamOpenRead(CHARACTER*(*) path)

 

path

The name of the dataset to be read.

Result

Upon successful completion streamOpenRead returns an identifier to the open stream. Otherwise, a negative number with the error status is returned.

Errors

 

CDI_ESYSTEM

Operating system error.

CDI_EINVAL

Invalid argument.

CDI_EUFILETYPE

Unsupported file type.

CDI_ELIBNAVAIL

Library support not compiled in.

Example

Here is an example using streamOpenRead to open an existing NetCDF file named foo.nc for reading:

 
   INCLUDE cdi.inc 
     ... 
   INTEGER streamID 
     ... 
   streamID = streamOpenRead("foo.nc") 
   IF ( streamID .LT. 0 ) CALL handle_error(streamID) 
     ...

4.1.3  Close an open dataset: streamClose

The function streamClose closes an open dataset.

Usage

    SUBROUTINE streamClose(INTEGER streamID)

 

streamID

Stream ID, from a previous call to streamOpenRead or streamOpenWrite.

4.1.4  Get the filetype: streamInqFiletype

The function streamInqFiletype returns the filetype of a stream.

Usage

    INTEGER FUNCTION streamInqFiletype(INTEGER streamID)

 

streamID

Stream ID, from a previous call to streamOpenRead or streamOpenWrite.

Result

streamInqFiletype returns the type of the file format, one of the set of predefined CDI file format types. The valid CDI file format types are CDI_FILETYPE_GRB, CDI_FILETYPE_GRB2, CDI_FILETYPE_NC, CDI_FILETYPE_NC2, CDI_FILETYPE_NC4, CDI_FILETYPE_NC4C, CDI_FILETYPE_NC5, CDI_FILETYPE_SRV, CDI_FILETYPE_EXT and CDI_FILETYPE_IEG.

4.1.5  Define the byte order: streamDefByteorder

The function streamDefByteorder defines the byte order of a binary dataset with the file format type CDI_FILETYPE_SRV, CDI_FILETYPE_EXT or CDI_FILETYPE_IEG.

Usage

    SUBROUTINE streamDefByteorder(INTEGER streamID, INTEGER byteorder)

 

streamID

Stream ID, from a previous call to streamOpenWrite.

byteorder

The byte order of a dataset, one of the CDI constants CDI_BIGENDIAN and CDI_LITTLEENDIAN.

4.1.6  Get the byte order: streamInqByteorder

The function streamInqByteorder returns the byte order of a binary dataset with the file format type CDI_FILETYPE_SRV, CDI_FILETYPE_EXT or CDI_FILETYPE_IEG.

Usage

    INTEGER FUNCTION streamInqByteorder(INTEGER streamID)

 

streamID

Stream ID, from a previous call to streamOpenRead or streamOpenWrite.

Result

streamInqByteorder returns the type of the byte order. The valid CDI byte order types are CDI_BIGENDIAN and CDI_LITTLEENDIAN

4.1.7  Define the variable list: streamDefVlist

The function streamDefVlist defines the variable list of a stream.

To safeguard against errors by modifying the wrong vlist object, this function makes the passed vlist object immutable. All further vlist changes have to use the vlist object returned by streamInqVlist().

Usage

    SUBROUTINE streamDefVlist(INTEGER streamID, INTEGER vlistID)

 

streamID

Stream ID, from a previous call to streamOpenWrite.

vlistID

Variable list ID, from a previous call to vlistCreate.

4.1.8  Get the variable list: streamInqVlist

The function streamInqVlist returns the variable list of a stream.

Usage

    INTEGER FUNCTION streamInqVlist(INTEGER streamID)

 

streamID

Stream ID, from a previous call to streamOpenRead or streamOpenWrite.

Result

streamInqVlist returns an identifier to the variable list.

4.1.9  Define a timestep: streamDefTimestep

The function streamDefTimestep defines a timestep of a stream by the identifier tsID. The identifier tsID is the timestep index starting at 0 for the first timestep. Before calling this function the functions taxisDefVdate and taxisDefVtime should be used to define the timestamp for this timestep. All calls to write the data refer to this timestep.

Usage

    INTEGER FUNCTION streamDefTimestep(INTEGER streamID, INTEGER tsID)

 

streamID

Stream ID, from a previous call to streamOpenWrite.

tsID

Timestep identifier.

Result

streamDefTimestep returns the number of expected records of the timestep.

4.1.10  Get timestep information: streamInqTimestep

The function streamInqTimestep sets the next timestep to the identifier tsID. The identifier tsID is the timestep index starting at 0 for the first timestep. After a call to this function the functions taxisInqVdate and taxisInqVtime can be used to read the timestamp for this timestep. All calls to read the data refer to this timestep.

Usage

    INTEGER FUNCTION streamInqTimestep(INTEGER streamID, INTEGER tsID)

 

streamID

Stream ID, from a previous call to streamOpenRead or streamOpenWrite.

tsID

Timestep identifier.

Result

streamInqTimestep returns the number of records of the timestep or 0, if the end of the file is reached.

4.1.11  Write a variable: streamWriteVar

The function streamWriteVar writes the values of one time step of a variable to an open dataset. The values are converted to the external data type of the variable, if necessary.

Usage

    SUBROUTINE streamWriteVar(INTEGER streamID, INTEGER varID, REAL*8 data,
                              INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenWrite.

varID

Variable identifier.

data

Pointer to a block of double precision floating point data values to be written.

nmiss

Number of missing values.

4.1.12  Write a variable: streamWriteVarF

The function streamWriteVarF writes the values of one time step of a variable to an open dataset. The values are converted to the external data type of the variable, if necessary.

Usage

    SUBROUTINE streamWriteVarF(INTEGER streamID, INTEGER varID, REAL*4 data,
                               INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenWrite.

varID

Variable identifier.

data

Pointer to a block of single precision floating point data values to be written.

nmiss

Number of missing values.

4.1.13  Write a horizontal slice of a variable: streamWriteVarSlice

The function streamWriteVarSlice writes the values of a horizontal slice of a variable to an open dataset. The values are converted to the external data type of the variable, if necessary.

Usage

    SUBROUTINE streamWriteVarSlice(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                   REAL*8 data, INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenWrite.

varID

Variable identifier.

levelID

Level identifier.

data

Pointer to a block of double precision floating point data values to be written.

nmiss

Number of missing values.

4.1.14  Write a horizontal slice of a variable: streamWriteVarSliceF

The function streamWriteVarSliceF writes the values of a horizontal slice of a variable to an open dataset. The values are converted to the external data type of the variable, if necessary.

Usage

    SUBROUTINE streamWriteVarSliceF(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                    REAL*4 data, INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenWrite.

varID

Variable identifier.

levelID

Level identifier.

data

Pointer to a block of single precision floating point data values to be written.

nmiss

Number of missing values.

4.1.15  Read a variable: streamReadVar

The function streamReadVar reads all the values of one time step of a variable from an open dataset.

Usage

    SUBROUTINE streamReadVar(INTEGER streamID, INTEGER varID, REAL*8 data,
                             INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenRead.

varID

Variable identifier.

data

Pointer to the location into which the data values are read. The caller must allocate space for the returned values.

nmiss

Number of missing values.

4.1.16  Read a variable: streamReadVarF

The function streamReadVar reads all the values of one time step of a variable from an open dataset.

Usage

    SUBROUTINE streamReadVar(INTEGER streamID, INTEGER varID, REAL*4 data,
                             INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenRead.

varID

Variable identifier.

data

Pointer to the location into which the data values are read. The caller must allocate space for the returned values.

nmiss

Number of missing values.

4.1.17  Read a horizontal slice of a variable: streamReadVarSlice

The function streamReadVarSlice reads all the values of a horizontal slice of a variable from an open dataset.

Usage

    SUBROUTINE streamReadVarSlice(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                  REAL*8 data, INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenRead.

varID

Variable identifier.

levelID

Level identifier.

data

Pointer to the location into which the data values are read. The caller must allocate space for the returned values.

nmiss

Number of missing values.

4.1.18  Read a horizontal slice of a variable: streamReadVarSliceF

The function streamReadVarSliceF reads all the values of a horizontal slice of a variable from an open dataset.

Usage

    SUBROUTINE streamReadVarSliceF(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                   REAL*4 data, INTEGER nmiss)

 

streamID

Stream ID, from a previous call to streamOpenRead.

varID

Variable identifier.

levelID

Level identifier.

data

Pointer to the location into which the data values are read. The caller must allocate space for the returned values.

nmiss

Number of missing values.

4.2  Variable list functions

This module contains functions to handle a list of variables. A variable list is a collection of all variables of a dataset.

4.2.1  Create a variable list: vlistCreate

Usage

    INTEGER FUNCTION vlistCreate()

Example

Here is an example using vlistCreate to create a variable list and add a variable with vlistDefVar.

 
   INCLUDE cdi.inc 
     ... 
   INTEGER vlistID, varID 
     ... 
   vlistID = vlistCreate() 
   varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING) 
     ... 
   streamDefVlist(streamID, vlistID) 
     ... 
   vlistDestroy(vlistID) 
     ...

4.2.2  Destroy a variable list: vlistDestroy

Usage

    SUBROUTINE vlistDestroy(INTEGER vlistID)

 

vlistID

Variable list ID, from a previous call to vlistCreate.

4.2.3  Copy a variable list: vlistCopy

The function vlistCopy copies all entries from vlistID1 to vlistID2.

Usage

    SUBROUTINE vlistCopy(INTEGER vlistID2, INTEGER vlistID1)

 

vlistID2

Target variable list ID.

vlistID1

Source variable list ID.

4.2.4  Duplicate a variable list: vlistDuplicate

The function vlistDuplicate duplicates the variable list from vlistID1.

Usage

    INTEGER FUNCTION vlistDuplicate(INTEGER vlistID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

Result

vlistDuplicate returns an identifier to the duplicated variable list.

4.2.5  Concatenate two variable lists: vlistCat

Concatenate the variable list vlistID1 at the end of vlistID2.

Usage

    SUBROUTINE vlistCat(INTEGER vlistID2, INTEGER vlistID1)

 

vlistID2

Target variable list ID.

vlistID1

Source variable list ID.

4.2.6  Copy some entries of a variable list: vlistCopyFlag

The function vlistCopyFlag copies all entries with a flag from vlistID1 to vlistID2.

Usage

    SUBROUTINE vlistCopyFlag(INTEGER vlistID2, INTEGER vlistID1)

 

vlistID2

Target variable list ID.

vlistID1

Source variable list ID.

4.2.7  Number of variables in a variable list: vlistNvars

The function vlistNvars returns the number of variables in the variable list vlistID.

Usage

    INTEGER FUNCTION vlistNvars(INTEGER vlistID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

Result

vlistNvars returns the number of variables in a variable list.

4.2.8  Number of grids in a variable list: vlistNgrids

The function vlistNgrids returns the number of grids in the variable list vlistID.

Usage

    INTEGER FUNCTION vlistNgrids(INTEGER vlistID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

Result

vlistNgrids returns the number of grids in a variable list.

4.2.9  Number of zaxis in a variable list: vlistNzaxis

The function vlistNzaxis returns the number of zaxis in the variable list vlistID.

Usage

    INTEGER FUNCTION vlistNzaxis(INTEGER vlistID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

Result

vlistNzaxis returns the number of zaxis in a variable list.

4.2.10  Define the time axis: vlistDefTaxis

The function vlistDefTaxis defines the time axis of a variable list.

Usage

    SUBROUTINE vlistDefTaxis(INTEGER vlistID, INTEGER taxisID)

 

vlistID

Variable list ID, from a previous call to vlistCreate.

taxisID

Time axis ID, from a previous call to taxisCreate.

4.2.11  Get the time axis: vlistInqTaxis

The function vlistInqTaxis returns the time axis of a variable list.

Usage

    INTEGER FUNCTION vlistInqTaxis(INTEGER vlistID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

Result

vlistInqTaxis returns an identifier to the time axis.

4.3  Variable functions

This module contains functions to add new variables to a variable list and to get information about variables from a variable list. To add new variables to a variables list one of the following timestep types must be specified:

  

TSTEP_CONSTANT

The data values have no time dimension.

TSTEP_INSTANT

The data values are representative of points in space or time (instantaneous).

TSTEP_ACCUM

The data values are representative of a sum or accumulation over the cell.

TSTEP_AVG

Mean (average value)

TSTEP_MAX

Maximum

TSTEP_MIN

Minimum

TSTEP_SD

Standard deviation

The default data type is 16 bit for GRIB and 32 bit for all other file format types. To change the data type use one of the following predefined constants:

  

CDI_DATATYPE_PACK8

8 packed bit (only for GRIB)

CDI_DATATYPE_PACK16

16 packed bit (only for GRIB)

CDI_DATATYPE_PACK24

24 packed bit (only for GRIB)

CDI_DATATYPE_FLT32

32 bit floating point

CDI_DATATYPE_FLT64

64 bit floating point

CDI_DATATYPE_INT8

8 bit integer

CDI_DATATYPE_INT16

16 bit integer

CDI_DATATYPE_INT32

32 bit integer

4.3.1  Define a Variable: vlistDefVar

The function vlistDefVar adds a new variable to vlistID.

Usage

    INTEGER FUNCTION vlistDefVar(INTEGER vlistID, INTEGER gridID, INTEGER zaxisID,
                                 INTEGER timetype)

 

vlistID

Variable list ID, from a previous call to vlistCreate.

gridID

Grid ID, from a previous call to gridCreate.

zaxisID

Z-axis ID, from a previous call to zaxisCreate.

timetype

One of the set of predefined CDI timestep types. The valid CDI timestep types are TIME_CONSTANT and TIME_VARYING.

Result

vlistDefVar returns an identifier to the new variable.

Example

Here is an example using vlistCreate to create a variable list and add a variable with vlistDefVar.

 
   INCLUDE cdi.inc 
     ... 
   INTEGER vlistID, varID 
     ... 
   vlistID = vlistCreate() 
   varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING) 
     ... 
   streamDefVlist(streamID, vlistID) 
     ... 
   vlistDestroy(vlistID) 
     ...

4.3.2  Get the Grid ID of a Variable: vlistInqVarGrid

The function vlistInqVarGrid returns the grid ID of a Variable.

Usage

    INTEGER FUNCTION vlistInqVarGrid(INTEGER vlistID, INTEGER varID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

varID

Variable identifier.

Result

vlistInqVarGrid returns the grid ID of the Variable.

4.3.3  Get the Zaxis ID of a Variable: vlistInqVarZaxis

The function vlistInqVarZaxis returns the zaxis ID of a variable.

Usage

    INTEGER FUNCTION vlistInqVarZaxis(INTEGER vlistID, INTEGER varID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

varID

Variable identifier.

Result

vlistInqVarZaxis returns the zaxis ID of the variable.

4.3.4  Get the timestep type of a Variable: vlistInqVarTsteptype

The function vlistInqVarTsteptype returns the timestep type of a Variable.

Usage

    INTEGER FUNCTION vlistInqVarTsteptype(INTEGER vlistID, INTEGER varID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

varID

Variable identifier.

Result

vlistInqVarTsteptype returns the timestep type of the Variable, one of the set of predefined CDI timestep types. The valid CDI timestep types are TSTEP_INSTANT, TSTEP_ACCUM, TSTEP_AVG, TSTEP_MAX, TSTEP_MIN and TSTEP_SD.

4.3.5  Define the code number of a Variable: vlistDefVarCode

The function vlistDefVarCode defines the code number of a variable.

Usage

    SUBROUTINE vlistDefVarCode(INTEGER vlistID, INTEGER varID, INTEGER code)

 

vlistID

Variable list ID, from a previous call to vlistCreate.

varID

Variable identifier.

code

Code number.

4.3.6  Get the Code number of a Variable: vlistInqVarCode

The function vlistInqVarCode returns the code number of a variable.

Usage

    INTEGER FUNCTION vlistInqVarCode(INTEGER vlistID, INTEGER varID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

varID

Variable identifier.

Result

vlistInqVarCode returns the code number of the variable.

4.3.7  Define the data type of a Variable: vlistDefVarDatatype

The function vlistDefVarDatatype defines the data type of a variable.

Usage

    SUBROUTINE vlistDefVarDatatype(INTEGER vlistID, INTEGER varID, INTEGER datatype)

 

vlistID

Variable list ID, from a previous call to vlistCreate.

varID

Variable identifier.

datatype

The data type identifier. The valid CDI data types are CDI_DATATYPE_PACK8, CDI_DATATYPE_PACK16, CDI_DATATYPE_PACK24, CDI_DATATYPE_FLT32, CDI_DATATYPE_FLT64, CDI_DATATYPE_INT8, CDI_DATATYPE_INT16 and CDI_DATATYPE_INT32.

4.3.8  Get the data type of a Variable: vlistInqVarDatatype

The function vlistInqVarDatatype returns the data type of a variable.

Usage

    INTEGER FUNCTION vlistInqVarDatatype(INTEGER vlistID, INTEGER varID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

varID

Variable identifier.

Result

vlistInqVarDatatype returns an identifier to the data type of the variable. The valid CDI data types are CDI_DATATYPE_PACK8, CDI_DATATYPE_PACK16, CDI_DATATYPE_PACK24, CDI_DATATYPE_FLT32, CDI_DATATYPE_FLT64, CDI_DATATYPE_INT8, CDI_DATATYPE_INT16 and CDI_DATATYPE_INT32.

4.3.9  Define the missing value of a Variable: vlistDefVarMissval

The function vlistDefVarMissval defines the missing value of a variable.

Usage

    SUBROUTINE vlistDefVarMissval(INTEGER vlistID, INTEGER varID, REAL*8 missval)

 

vlistID

Variable list ID, from a previous call to vlistCreate.

varID

Variable identifier.

missval

Missing value.

4.3.10  Get the missing value of a Variable: vlistInqVarMissval

The function vlistInqVarMissval returns the missing value of a variable.

Usage

    REAL*8 FUNCTION vlistInqVarMissval(INTEGER vlistID, INTEGER varID)

 

vlistID

Variable list ID, from a previous call to vlistCreate or streamInqVlist.

varID

Variable identifier.

Result

vlistInqVarMissval returns the missing value of the variable.

4.4  Key attributes

Attributes are metadata used to describe variables or a data set. CDI distinguishes between key attributes and user attributes. User defined attributes are described in the next chapter.

Key attributes are attributes that are interpreted by CDI. An example is the name or the units of a variable.

Key attributes can be defined for data variables and coordinate variables Use the variable ID or one of the following identifiers for the coordinates:

  

CDI_KEY_XAXIS

X-axis ID

CDI_KEY_YAXIS

Y-axis ID

CDI_KEY_GLOBAL

Global Z-axis

Some keys like name and units can be used for all variables. Other keys are very special and should only be used for certain variables. The user is also responsible for the data type of the key.

CDI supports string, integer, floating point and byte array key attributes. The following key attributes are available:

String keys

  

CDI_KEY_NAME

Variable name

CDI_KEY_LONGNAME

Long name of the variable

CDI_KEY_STDNAME

CF Standard name of the variable

CDI_KEY_UNITS

Units of the variable

CDI_KEY_REFERENCEURI

Reference URI to grid file

Integer keys

  

CDI_KEY_NUMBEROFGRIDUSED

GRIB2 numberOfGridUsed

CDI_KEY_NUMBEROFGRIDINREFERENCE

GRIB2 numberOfGridInReference

CDI_KEY_NUMBEROFVGRIDUSED

GRIB2 numberOfVGridUsed

CDI_KEY_NLEV

GRIB2 nlev

Floating point keys

Byte array keys

  

CDI_KEY_UUID

UUID for grid/Z-axis reference [size: CDI_UUID_SIZE]

4.4.1  Define a string from a key: cdiDefKeyString

The function cdiDefKeyString defines a text string from a key.

Usage

    INTEGER FUNCTION cdiDefKeyString(INTEGER cdiID, INTEGER varID, INTEGER key,
                                     CHARACTER*(*) string)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched.

string

The address of a string where the data will be read.

Result

cdiDefKeyString returns CDI_NOERR if OK.

Example

Here is an example using cdiDefKeyString to define the name of a variable:

 
   INCLUDE cdi.inc 
     ... 
   INTEGER vlistID, varID, status 
     ... 
   vlistID = vlistCreate() 
   varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING) 
     ... 
   status = cdiDefKeyString(vlistID, varID, CDI_KEY_NAME, "temperature") 
     ...

4.4.2  Get a string from a key: cdiInqKeyString

The function cdiInqKeyString gets a text string from a key.

Usage

    INTEGER FUNCTION cdiInqKeyString(INTEGER cdiID, INTEGER varID, INTEGER key,
                                     CHARACTER*(*) string, INTEGER length)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched.

string

The address of a string where the data will be retrieved. The caller must allocate space for the returned string.

length

The allocated length of the string on input.

Result

cdiInqKeyString returns CDI_NOERR if key is available.

Example

Here is an example using cdiInqKeyString to get the name of the first variable:

 
   INCLUDE cdi.inc 
     ... 
   #define STRLEN 256 
     ... 
   INTEGER streamID, vlistID, varID, status 
   INTEGER length = STRLEN 
   CHARACTER name[STRLEN] 
     ... 
   streamID = streamOpenRead(...) 
   vlistID = streamInqVlist(streamID) 
     ... 
   varID = 0 
   status = cdiInqKeyString(vlistID, varID, CDI_KEY_NAME, name, length) 
     ...

4.4.3  Define an integer value from a key: cdiDefKeyInt

The function cdiDefKeyInt defines an integer value from a key.

Usage

    INTEGER FUNCTION cdiDefKeyInt(INTEGER cdiID, INTEGER varID, INTEGER key,
                                  INTEGER value)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched.

value

An integer where the data will be read.

Result

cdiDefKeyInt returns CDI_NOERR if OK.

4.4.4  Get an integer value from a key: cdiInqKeyInt

The function cdiInqKeyInt gets an integer value from a key.

Usage

    INTEGER FUNCTION cdiInqKeyInt(INTEGER cdiID, INTEGER varID, INTEGER key,
                                  INTEGER value)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched..

value

The address of an integer where the data will be retrieved.

Result

cdiInqKeyInt returns CDI_NOERR if key is available.

4.4.5  Define a floating point value from a key: cdiDefKeyFloat

The function cdiDefKeyFloat defines a CDI floating point value from a key.

Usage

    INTEGER FUNCTION cdiDefKeyFloat(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    REAL*8 value)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched

value

A double where the data will be read

Result

cdiDefKeyFloat returns CDI_NOERR if OK.

4.4.6  Get a floating point value from a key: cdiInqKeyFloat

The function cdiInqKeyFloat gets a floating point value from a key.

Usage

    INTEGER FUNCTION cdiInqKeyFloat(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    REAL*8 value)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched.

value

The address of a double where the data will be retrieved.

Result

cdiInqKeyFloat returns CDI_NOERR if key is available.

4.4.7  Define a byte array from a key: cdiDefKeyBytes

The function cdiDefKeyBytes defines a byte array from a key.

Usage

    INTEGER FUNCTION cdiDefKeyBytes(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    unsigned CHARACTER*(*) bytes, INTEGER length)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched.

bytes

The address of a byte array where the data will be read.

length

Length of the byte array

Result

cdiDefKeyBytes returns CDI_NOERR if OK.

4.4.8  Get a byte array from a key: cdiInqKeyBytes

The function cdiInqKeyBytes gets a byte array from a key.

Usage

    INTEGER FUNCTION cdiInqKeyBytes(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    unsigned CHARACTER*(*) bytes, INTEGER length)

 

cdiID

CDI object ID (vlistID, gridID, zaxisID).

varID

Variable identifier or CDI_GLOBAL.

key

The key to be searched.

bytes

The address of a byte array where the data will be retrieved. The caller must allocate space for the returned byte array.

length

The allocated length of the byte array on input.

Result

cdiInqKeyBytes returns CDI_NOERR if key is available.

4.5  User attributes

Attributes are metadata used to describe variables or a data set. CDI distinguishes between key attributes and user attributes. Key attributes are described in the last chapter.

User defined attributes are additional attributes that are not interpreted by CDI. These attributes are only available for NetCDF datasets. Here they correspond to all attributes that are not used by CDI as key attributes.

A user defined attribute has a variable to which it is assigned, a name, a type, a length, and a sequence of one or more values. The attributes have to be defined after the variable is created and before the variables list is associated with a stream.

It is also possible to have attributes that are not associated with any variable. These are called global attributes and are identified by using CDI_GLOBAL as a variable pseudo-ID. Global attributes are usually related to the dataset as a whole.

CDI supports integer, floating point and text attributes. The data types are defined by the following predefined constants:

  

CDI_DATATYPE_INT16

16-bit integer attribute

CDI_DATATYPE_INT32

32-bit integer attribute

CDI_DATATYPE_FLT32

32-bit floating point attribute

CDI_DATATYPE_FLT64

64-bit floating point attribute

CDI_DATATYPE_TXT

Text attribute

4.5.1  Get number of attributes: cdiInqNatts

The function cdiInqNatts gets the number of attributes assigned to this variable.

Usage

    INTEGER FUNCTION cdiInqNatts(INTEGER cdiID, INTEGER varID, INTEGER nattsp)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or streamInqVlist.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

nattsp

Pointer to location for returned number of attributes.

4.5.2  Get information about an attribute: cdiInqAtt

The function cdiInqAtt gets information about an attribute.

Usage

    INTEGER FUNCTION cdiInqAtt(INTEGER cdiID, INTEGER varID, INTEGER attnum,
                               CHARACTER*(*) name, INTEGER typep, INTEGER lenp)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or streamInqVlist.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

attnum

Attribute number (from 0 to natts-1).

name

Pointer to the location for the returned attribute name. The caller must allocate space for the returned string. The maximum possible length, in characters, of the string is given by the predefined constant CDI_MAX_NAME.

typep

Pointer to location for returned attribute type.

lenp

Pointer to location for returned attribute number.

4.5.3  Define a text attribute: cdiDefAttTxt

The function cdiDefAttTxt defines a text attribute.

Usage

    INTEGER FUNCTION cdiDefAttTxt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER len, CHARACTER*(*) tp)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or zaxisCreate.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

name

Attribute name.

len

Number of values provided for the attribute.

tp

Pointer to one or more character values.

Example

Here is an example using cdiDefAttTxt to define the attribute ”description”:

 
   INCLUDE cdi.inc 
     ... 
   INTEGER vlistID, varID, status 
   CHARACTER text[] = "descriptionofthevariable" 
     ... 
   vlistID = vlistCreate() 
   varID = vlistDefVar(vlistID, gridID, zaxisID, TIME_VARYING) 
     ... 
   status = cdiDefAttTxt(vlistID, varID, "description", LEN(text), text) 
     ...

4.5.4  Get the value(s) of a text attribute: cdiInqAttTxt

The function cdiInqAttTxt gets the values(s) of a text attribute.

Usage

    INTEGER FUNCTION cdiInqAttTxt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER mlen, CHARACTER*(*) tp)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or zaxisCreate.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

name

Attribute name.

mlen

Number of allocated values provided for the attribute.

tp

Pointer location for returned text attribute value(s).

4.5.5  Define an integer attribute: cdiDefAttInt

The function cdiDefAttInt defines an integer attribute.

Usage

    INTEGER FUNCTION cdiDefAttInt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER type, INTEGER len, INTEGER ip)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or zaxisCreate.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

name

Attribute name.

type

External data type (CDI_DATATYPE_INT16 or CDI_DATATYPE_INT32).

len

Number of values provided for the attribute.

ip

Pointer to one or more integer values.

4.5.6  Get the value(s) of an integer attribute: cdiInqAttInt

The function cdiInqAttInt gets the values(s) of an integer attribute.

Usage

    INTEGER FUNCTION cdiInqAttInt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER mlen, INTEGER ip)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or zaxisCreate.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

name

Attribute name.

mlen

Number of allocated values provided for the attribute.

ip

Pointer location for returned integer attribute value(s).

4.5.7  Define a floating point attribute: cdiDefAttFlt

The function cdiDefAttFlt defines a floating point attribute.

Usage

    INTEGER FUNCTION cdiDefAttFlt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER type, INTEGER len, REAL*8 dp)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or zaxisCreate.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

name

Attribute name.

type

External data type (CDI_DATATYPE_FLT32 or CDI_DATATYPE_FLT64).

len

Number of values provided for the attribute.

dp

Pointer to one or more floating point values.

4.5.8  Get the value(s) of a floating point attribute: cdiInqAttFlt

The function cdiInqAttFlt gets the values(s) of a floating point attribute.

Usage

    INTEGER FUNCTION cdiInqAttFlt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER mlen, REAL*8 dp)

 

cdiID

CDI ID, from a previous call to vlistCreate, gridCreate or zaxisCreate.

varID

Variable identifier, or CDI_GLOBAL for a global attribute.

name

Attribute name.

mlen

Number of allocated values provided for the attribute.

dp

Pointer location for returned floating point attribute value(s).

4.6  Grid functions

This module contains functions to define a new horizontal Grid and to get information from an existing Grid. A Grid object is necessary to define a variable. The following different Grid types are available:

  

GRID_GENERIC

Generic user defined grid

GRID_LONLAT

Regular longitude/latitude grid

GRID_GAUSSIAN

Regular Gaussian lon/lat grid

GRID_PROJECTION

Projected coordinates

GRID_SPECTRAL

Spherical harmonic coefficients

GRID_GME

Icosahedral-hexagonal GME grid

GRID_CURVILINEAR

Curvilinear grid

GRID_UNSTRUCTURED

Unstructured grid

4.6.1  Create a horizontal Grid: gridCreate

The function gridCreate creates a horizontal Grid.

Usage

    INTEGER FUNCTION gridCreate(INTEGER gridtype, INTEGER size)

 

gridtype

The type of the grid, one of the set of predefined CDI grid types. The valid CDI grid types are GRID_GENERIC, GRID_LONLAT, GRID_GAUSSIAN, GRID_PROJECTION, GRID_SPECTRAL, GRID_GME, GRID_CURVILINEAR and GRID_UNSTRUCTURED.

size

Number of gridpoints.

Result

gridCreate returns an identifier to the Grid.

Example

Here is an example using gridCreate to create a regular lon/lat Grid:

 
   INCLUDE cdi.inc 
     ... 
   #define nlon 12 
   #define nlat 6 
     ... 
   REAL*8 lons(nlon) = (/0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330/) 
   REAL*8 lats(nlat) = (/-75, -45, -15, 15, 45, 75/) 
   INTEGER gridID 
     ... 
   gridID = gridCreate(GRID_LONLAT, nlon*nlat) 
   CALL gridDefXsize(gridID, nlon) 
   CALL gridDefYsize(gridID, nlat) 
   CALL gridDefXvals(gridID, lons) 
   CALL gridDefYvals(gridID, lats) 
     ...

4.6.2  Destroy a horizontal Grid: gridDestroy

Usage

    SUBROUTINE gridDestroy(INTEGER gridID)

 

gridID

Grid ID, from a previous call to gridCreate.

4.6.3  Duplicate a horizontal Grid: gridDuplicate

The function gridDuplicate duplicates a horizontal Grid.

Usage

    INTEGER FUNCTION gridDuplicate(INTEGER gridID)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

Result

gridDuplicate returns an identifier to the duplicated Grid.

4.6.4  Get the type of a Grid: gridInqType

The function gridInqType returns the type of a Grid.

Usage

    INTEGER FUNCTION gridInqType(INTEGER gridID)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

Result

gridInqType returns the type of the grid, one of the set of predefined CDI grid types. The valid CDI grid types are GRID_GENERIC, GRID_LONLAT, GRID_GAUSSIAN, GRID_PROJECTION, GRID_SPECTRAL, GRID_GME, GRID_CURVILINEAR and GRID_UNSTRUCTURED.

4.6.5  Get the size of a Grid: gridInqSize

The function gridInqSize returns the size of a Grid.

Usage

    INTEGER FUNCTION gridInqSize(INTEGER gridID)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

Result

gridInqSize returns the number of grid points of a Grid.

4.6.6  Define the number of values of a X-axis: gridDefXsize

The function gridDefXsize defines the number of values of a X-axis.

Usage

    SUBROUTINE gridDefXsize(INTEGER gridID, INTEGER xsize)

 

gridID

Grid ID, from a previous call to gridCreate.

xsize

Number of values of a X-axis.

4.6.7  Get the number of values of a X-axis: gridInqXsize

The function gridInqXsize returns the number of values of a X-axis.

Usage

    INTEGER FUNCTION gridInqXsize(INTEGER gridID)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

Result

gridInqXsize returns the number of values of a X-axis.

4.6.8  Define the number of values of a Y-axis: gridDefYsize

The function gridDefYsize defines the number of values of a Y-axis.

Usage

    SUBROUTINE gridDefYsize(INTEGER gridID, INTEGER ysize)

 

gridID

Grid ID, from a previous call to gridCreate.

ysize

Number of values of a Y-axis.

4.6.9  Get the number of values of a Y-axis: gridInqYsize

The function gridInqYsize returns the number of values of a Y-axis.

Usage

    INTEGER FUNCTION gridInqYsize(INTEGER gridID)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

Result

gridInqYsize returns the number of values of a Y-axis.

4.6.10  Define the number of parallels between a pole and the equator: gridDefNP

The function gridDefNP defines the number of parallels between a pole and the equator of a Gaussian grid.

Usage

    SUBROUTINE gridDefNP(INTEGER gridID, INTEGER np)

 

gridID

Grid ID, from a previous call to gridCreate.

np

Number of parallels between a pole and the equator.

4.6.11  Get the number of parallels between a pole and the equator: gridInqNP

The function gridInqNP returns the number of parallels between a pole and the equator of a Gaussian grid.

Usage

    INTEGER FUNCTION gridInqNP(INTEGER gridID)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

Result

gridInqNP returns the number of parallels between a pole and the equator.

4.6.12  Define the values of a X-axis: gridDefXvals

The function gridDefXvals defines all values of the X-axis.

Usage

    SUBROUTINE gridDefXvals(INTEGER gridID, REAL*8 xvals)

 

gridID

Grid ID, from a previous call to gridCreate.

xvals

X-values of the grid.

4.6.13  Get all values of a X-axis: gridInqXvals

The function gridInqXvals returns all values of the X-axis.

Usage

    INTEGER FUNCTION gridInqXvals(INTEGER gridID, REAL*8 xvals)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

xvals

Pointer to the location into which the X-values are read. The caller must allocate space for the returned values.

Result

Upon successful completion gridInqXvals returns the number of values and the values are stored in xvals. Otherwise, 0 is returned and xvals is empty.

4.6.14  Define the values of a Y-axis: gridDefYvals

The function gridDefYvals defines all values of the Y-axis.

Usage

    SUBROUTINE gridDefYvals(INTEGER gridID, REAL*8 yvals)

 

gridID

Grid ID, from a previous call to gridCreate.

yvals

Y-values of the grid.

4.6.15  Get all values of a Y-axis: gridInqYvals

The function gridInqYvals returns all values of the Y-axis.

Usage

    INTEGER FUNCTION gridInqYvals(INTEGER gridID, REAL*8 yvals)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

yvals

Pointer to the location into which the Y-values are read. The caller must allocate space for the returned values.

Result

Upon successful completion gridInqYvals returns the number of values and the values are stored in yvals. Otherwise, 0 is returned and yvals is empty.

4.6.16  Define the bounds of a X-axis: gridDefXbounds

The function gridDefXbounds defines all bounds of the X-axis.

Usage

    SUBROUTINE gridDefXbounds(INTEGER gridID, REAL*8 xbounds)

 

gridID

Grid ID, from a previous call to gridCreate.

xbounds

X-bounds of the grid.

4.6.17  Get the bounds of a X-axis: gridInqXbounds

The function gridInqXbounds returns the bounds of the X-axis.

Usage

    INTEGER FUNCTION gridInqXbounds(INTEGER gridID, REAL*8 xbounds)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

xbounds

Pointer to the location into which the X-bounds are read. The caller must allocate space for the returned values.

Result

Upon successful completion gridInqXbounds returns the number of bounds and the bounds are stored in xbounds. Otherwise, 0 is returned and xbounds is empty.

4.6.18  Define the bounds of a Y-axis: gridDefYbounds

The function gridDefYbounds defines all bounds of the Y-axis.

Usage

    SUBROUTINE gridDefYbounds(INTEGER gridID, REAL*8 ybounds)

 

gridID

Grid ID, from a previous call to gridCreate.

ybounds

Y-bounds of the grid.

4.6.19  Get the bounds of a Y-axis: gridInqYbounds

The function gridInqYbounds returns the bounds of the Y-axis.

Usage

    INTEGER FUNCTION gridInqYbounds(INTEGER gridID, REAL*8 ybounds)

 

gridID

Grid ID, from a previous call to gridCreate or vlistInqVarGrid.

ybounds

Pointer to the location into which the Y-bounds are read. The caller must allocate space for the returned values.

Result

Upon successful completion gridInqYbounds returns the number of bounds and the bounds are stored in ybounds. Otherwise, 0 is returned and ybounds is empty.

4.7  Z-axis functions

This section contains functions to define a new vertical Z-axis and to get information from an existing Z-axis. A Z-axis object is necessary to define a variable. The following different Z-axis types are available:

  

ZAXIS_GENERIC

Generic user defined zaxis type

ZAXIS_SURFACE

Surface level

ZAXIS_HYBRID

Hybrid level

ZAXIS_SIGMA

Sigma level

ZAXIS_PRESSURE

Isobaric pressure level in Pascal

ZAXIS_HEIGHT

Height above ground in meters

ZAXIS_ISENTROPIC

Isentropic (theta) level

ZAXIS_ALTITUDE

Altitude above mean sea level in meters

ZAXIS_MEANSEA

Mean sea level

ZAXIS_TOA

Norminal top of atmosphere

ZAXIS_SEA_BOTTOM

Sea bottom

ZAXIS_ATMOSPHERE

Entire atmosphere

ZAXIS_CLOUD_BASE

Cloud base level

ZAXIS_CLOUD_TOP

Level of cloud tops

ZAXIS_ISOTHERM_ZERO

Level of 0 C isotherm

ZAXIS_SNOW

Snow level

ZAXIS_LAKE_BOTTOM

Lake or River Bottom

ZAXIS_SEDIMENT_BOTTOM

Bottom Of Sediment Layer

ZAXIS_SEDIMENT_BOTTOM_TA

Bottom Of Thermally Active Sediment Layer

ZAXIS_SEDIMENT_BOTTOM_TW

Bottom Of Sediment Layer Penetrated By Thermal Wave

ZAXIS_ZAXIS_MIX_LAYER

Mixing Layer

ZAXIS_DEPTH_BELOW_SEA

Depth below sea level in meters

ZAXIS_DEPTH_BELOW_LAND

Depth below land surface in centimeters

4.7.1  Create a vertical Z-axis: zaxisCreate

The function zaxisCreate creates a vertical Z-axis.

Usage

    INTEGER FUNCTION zaxisCreate(INTEGER zaxistype, INTEGER size)

 

zaxistype

The type of the Z-axis, one of the set of predefined CDI Z-axis types. The valid CDI Z-axis types are ZAXIS_GENERIC, ZAXIS_SURFACE, ZAXIS_HYBRID, ZAXIS_SIGMA, ZAXIS_PRESSURE, ZAXIS_HEIGHT, ZAXIS_ISENTROPIC, ZAXIS_ALTITUDE, ZAXIS_MEANSEA, ZAXIS_TOA, ZAXIS_SEA_BOTTOM, ZAXIS_ATMOSPHERE, ZAXIS_CLOUD_BASE, ZAXIS_CLOUD_TOP, ZAXIS_ISOTHERM_ZERO, ZAXIS_SNOW, ZAXIS_LAKE_BOTTOM, ZAXIS_SEDIMENT_BOTTOM, ZAXIS_SEDIMENT_BOTTOM_TA, ZAXIS_SEDIMENT_BOTTOM_TW, ZAXIS_MIX_LAYER, ZAXIS_DEPTH_BELOW_SEA and ZAXIS_DEPTH_BELOW_LAND.

size

Number of levels.

Result

zaxisCreate returns an identifier to the Z-axis.

Example

Here is an example using zaxisCreate to create a pressure level Z-axis:

 
   INCLUDE cdi.inc 
     ... 
   #define nlev  5 
     ... 
   REAL*8 levs(nlev) = (/101300, 92500, 85000, 50000, 20000/) 
   INTEGER zaxisID 
     ... 
   zaxisID = zaxisCreate(ZAXIS_PRESSURE, nlev) 
   CALL zaxisDefLevels(zaxisID, levs) 
     ...

4.7.2  Destroy a vertical Z-axis: zaxisDestroy

Usage

    SUBROUTINE zaxisDestroy(INTEGER zaxisID)

 

zaxisID

Z-axis ID, from a previous call to zaxisCreate.

4.7.3  Get the type of a Z-axis: zaxisInqType

The function zaxisInqType returns the type of a Z-axis.

Usage

    INTEGER FUNCTION zaxisInqType(INTEGER zaxisID)

 

zaxisID

Z-axis ID, from a previous call to zaxisCreate or vlistInqVarZaxis.

Result

zaxisInqType returns the type of the Z-axis, one of the set of predefined CDI Z-axis types. The valid CDI Z-axis types are ZAXIS_GENERIC, ZAXIS_SURFACE, ZAXIS_HYBRID, ZAXIS_SIGMA, ZAXIS_PRESSURE, ZAXIS_HEIGHT, ZAXIS_ISENTROPIC, ZAXIS_ALTITUDE, ZAXIS_MEANSEA, ZAXIS_TOA, ZAXIS_SEA_BOTTOM, ZAXIS_ATMOSPHERE, ZAXIS_CLOUD_BASE, ZAXIS_CLOUD_TOP, ZAXIS_ISOTHERM_ZERO, ZAXIS_SNOW, ZAXIS_LAKE_BOTTOM, ZAXIS_SEDIMENT_BOTTOM, ZAXIS_SEDIMENT_BOTTOM_TA, ZAXIS_SEDIMENT_BOTTOM_TW, ZAXIS_MIX_LAYER, ZAXIS_DEPTH_BELOW_SEA and ZAXIS_DEPTH_BELOW_LAND.

4.7.4  Get the size of a Z-axis: zaxisInqSize

The function zaxisInqSize returns the size of a Z-axis.

Usage

    INTEGER FUNCTION zaxisInqSize(INTEGER zaxisID)

 

zaxisID

Z-axis ID, from a previous call to zaxisCreate or vlistInqVarZaxis.

Result

zaxisInqSize returns the number of levels of a Z-axis.

4.7.5  Define the levels of a Z-axis: zaxisDefLevels

The function zaxisDefLevels defines the levels of a Z-axis.

Usage

    SUBROUTINE zaxisDefLevels(INTEGER zaxisID, REAL*8 levels)

 

zaxisID

Z-axis ID, from a previous call to zaxisCreate.

levels

All levels of the Z-axis.

4.7.6  Get all levels of a Z-axis: zaxisInqLevels

The function zaxisInqLevels returns all levels of a Z-axis.

Usage

    SUBROUTINE zaxisInqLevels(INTEGER zaxisID, REAL*8 levels)

 

zaxisID

Z-axis ID, from a previous call to zaxisCreate or vlistInqVarZaxis.

levels

Pointer to the location into which the levels are read. The caller must allocate space for the returned values.

Result

zaxisInqLevels saves all levels to the parameter levels.

4.7.7  Get one level of a Z-axis: zaxisInqLevel

The function zaxisInqLevel returns one level of a Z-axis.

Usage

    REAL*8 FUNCTION zaxisInqLevel(INTEGER zaxisID, INTEGER levelID)

 

zaxisID

Z-axis ID, from a previous call to zaxisCreate or vlistInqVarZaxis.

levelID

Level index (range: 0 to nlevel-1).

Result

zaxisInqLevel returns the level of a Z-axis.

4.8  T-axis functions

This section contains functions to define a new Time axis and to get information from an existing T-axis. A T-axis object is necessary to define the time axis of a dataset and must be assiged to a variable list using vlistDefTaxis. The following different Time axis types are available:

  

TAXIS_ABSOLUTE

Absolute time axis

TAXIS_RELATIVE

Relative time axis

An absolute time axis has the current time to each time step. It can be used without knowledge of the calendar.

A relative time is the time relative to a fixed reference time. The current time results from the reference time and the elapsed interval. The result depends on the used calendar. CDI supports the following calendar types:

  

CALENDAR_STANDARD

Mixed Gregorian/Julian calendar.

CALENDAR_PROLEPTIC

Proleptic Gregorian calendar. This is the default.

CALENDAR_360DAYS

All years are 360 days divided into 30 day months.

CALENDAR_365DAYS

Gregorian calendar without leap years, i.e., all years are 365 days long.

CALENDAR_366DAYS

Gregorian calendar with every year being a leap year, i.e., all years are 366 days long.

4.8.1  Create a Time axis: taxisCreate

The function taxisCreate creates a Time axis.

Usage

    INTEGER FUNCTION taxisCreate(INTEGER taxistype)

 

taxistype

The type of the Time axis, one of the set of predefined CDI time axis types. The valid CDI time axis types are TAXIS_ABSOLUTE and TAXIS_RELATIVE.

Result

taxisCreate returns an identifier to the Time axis.

Example

Here is an example using taxisCreate to create a relative T-axis with a standard calendar.

 
   INCLUDE cdi.inc 
     ... 
   INTEGER taxisID 
     ... 
   taxisID = taxisCreate(TAXIS_RELATIVE) 
   taxisDefCalendar(taxisID, CALENDAR_STANDARD) 
   taxisDefRdate(taxisID, 19850101) 
   taxisDefRtime(taxisID, 120000) 
     ...

4.8.2  Destroy a Time axis: taxisDestroy

Usage

    SUBROUTINE taxisDestroy(INTEGER taxisID)

 

taxisID

Time axis ID, from a previous call to taxisCreate

4.8.3  Define the reference date: taxisDefRdate

The function taxisDefRdate defines the reference date of a Time axis.

Usage

    SUBROUTINE taxisDefRdate(INTEGER taxisID, INTEGER rdate)

 

taxisID

Time axis ID, from a previous call to taxisCreate

rdate

Reference date (YYYYMMDD)

4.8.4  Get the reference date: taxisInqRdate

The function taxisInqRdate returns the reference date of a Time axis.

Usage

    INTEGER FUNCTION taxisInqRdate(INTEGER taxisID)

 

taxisID

Time axis ID, from a previous call to taxisCreate or vlistInqTaxis

Result

taxisInqRdate returns the reference date.

4.8.5  Define the reference time: taxisDefRtime

The function taxisDefRtime defines the reference time of a Time axis.

Usage

    SUBROUTINE taxisDefRtime(INTEGER taxisID, INTEGER rtime)

 

taxisID

Time axis ID, from a previous call to taxisCreate

rtime

Reference time (hhmmss)

4.8.6  Get the reference time: taxisInqRtime

The function taxisInqRtime returns the reference time of a Time axis.

Usage

    INTEGER FUNCTION taxisInqRtime(INTEGER taxisID)

 

taxisID

Time axis ID, from a previous call to taxisCreate or vlistInqTaxis

Result

taxisInqRtime returns the reference time.

4.8.7  Define the verification date: taxisDefVdate

The function taxisDefVdate defines the verification date of a Time axis.

Usage

    SUBROUTINE taxisDefVdate(INTEGER taxisID, INTEGER vdate)

 

taxisID

Time axis ID, from a previous call to taxisCreate

vdate

Verification date (YYYYMMDD)

4.8.8  Get the verification date: taxisInqVdate

The function taxisInqVdate returns the verification date of a Time axis.

Usage

    INTEGER FUNCTION taxisInqVdate(INTEGER taxisID)

 

taxisID

Time axis ID, from a previous call to taxisCreate or vlistInqTaxis

Result

taxisInqVdate returns the verification date.

4.8.9  Define the verification time: taxisDefVtime

The function taxisDefVtime defines the verification time of a Time axis.

Usage

    SUBROUTINE taxisDefVtime(INTEGER taxisID, INTEGER vtime)

 

taxisID

Time axis ID, from a previous call to taxisCreate

vtime

Verification time (hhmmss)

4.8.10  Get the verification time: taxisInqVtime

The function taxisInqVtime returns the verification time of a Time axis.

Usage

    INTEGER FUNCTION taxisInqVtime(INTEGER taxisID)

 

taxisID

Time axis ID, from a previous call to taxisCreate or vlistInqTaxis

Result

taxisInqVtime returns the verification time.

4.8.11  Define the calendar: taxisDefCalendar

The function taxisDefCalendar defines the calendar of a Time axis.

Usage

    SUBROUTINE taxisDefCalendar(INTEGER taxisID, INTEGER calendar)

 

taxisID

Time axis ID, from a previous call to taxisCreate

calendar

The type of the calendar, one of the set of predefined CDI calendar types. The valid CDI calendar types are CALENDAR_STANDARD, CALENDAR_PROLEPTIC, CALENDAR_360DAYS, CALENDAR_365DAYS and CALENDAR_366DAYS.

4.8.12  Get the calendar: taxisInqCalendar

The function taxisInqCalendar returns the calendar of a Time axis.

Usage

    INTEGER FUNCTION taxisInqCalendar(INTEGER taxisID)

 

taxisID

Time axis ID, from a previous call to taxisCreate or vlistInqTaxis

Result

taxisInqCalendar returns the type of the calendar, one of the set of predefined CDI calendar types. The valid CDI calendar types are CALENDAR_STANDARD, CALENDAR_PROLEPTIC, CALENDAR_360DAYS, CALENDAR_365DAYS and CALENDAR_366DAYS.

Bibliography

[ecCodes]    
API for GRIB decoding/encoding, from the European Centre for Medium-Range Weather Forecasts (ECMWF)

[ECHAM]    
The atmospheric general circulation model ECHAM5, from the Max Planck Institute for Meteorologie

[GRIB]    
GRIB version 1, from the World Meteorological Organisation (WMO)

[HDF5]    
HDF version 5, from the HDF Group

[NetCDF]    
NetCDF Software Package, from the UNIDATA Program Center of the University Corporation for Atmospheric Research

[MPIOM]    
The ocean model MPIOM, from the Max Planck Institute for Meteorologie

[REMO]    
The regional climate model REMO, from the Max Planck Institute for Meteorologie

A.  Quick Reference

This appendix provide a brief listing of the Fortran language bindings of the CDI library routines:

cdiDefAttFlt


    INTEGER FUNCTION cdiDefAttFlt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER type, INTEGER len, REAL*8 dp)

Define a floating point attribute (4.5.7)

cdiDefAttInt


    INTEGER FUNCTION cdiDefAttInt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER type, INTEGER len, INTEGER ip)

Define an integer attribute (4.5.5)

cdiDefAttTxt


    INTEGER FUNCTION cdiDefAttTxt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER len, CHARACTER*(*) tp)

Define a text attribute (4.5.3)

cdiDefKeyBytes


    INTEGER FUNCTION cdiDefKeyBytes(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    unsigned CHARACTER*(*) bytes, INTEGER length)

Define a byte array from a key (4.4.7)

cdiDefKeyFloat


    INTEGER FUNCTION cdiDefKeyFloat(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    REAL*8 value)

Define a floating point value from a key (4.4.5)

cdiDefKeyInt


    INTEGER FUNCTION cdiDefKeyInt(INTEGER cdiID, INTEGER varID, INTEGER key,
                                  INTEGER value)

Define an integer value from a key (4.4.3)

cdiDefKeyString


    INTEGER FUNCTION cdiDefKeyString(INTEGER cdiID, INTEGER varID, INTEGER key,
                                     CHARACTER*(*) string)

Define a string from a key (4.4.1)

cdiInqAtt


    INTEGER FUNCTION cdiInqAtt(INTEGER cdiID, INTEGER varID, INTEGER attnum,
                               CHARACTER*(*) name, INTEGER typep, INTEGER lenp)

Get information about an attribute (4.5.2)

cdiInqAttFlt


    INTEGER FUNCTION cdiInqAttFlt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER mlen, REAL*8 dp)

Get the value(s) of a floating point attribute (4.5.8)

cdiInqAttInt


    INTEGER FUNCTION cdiInqAttInt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER mlen, INTEGER ip)

Get the value(s) of an integer attribute (4.5.6)

cdiInqAttTxt


    INTEGER FUNCTION cdiInqAttTxt(INTEGER cdiID, INTEGER varID, CHARACTER*(*) name,
                                  INTEGER mlen, CHARACTER*(*) tp)

Get the value(s) of a text attribute (4.5.4)

cdiInqKeyBytes


    INTEGER FUNCTION cdiInqKeyBytes(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    unsigned CHARACTER*(*) bytes, INTEGER length)

Get a byte array from a key (4.4.8)

cdiInqKeyFloat


    INTEGER FUNCTION cdiInqKeyFloat(INTEGER cdiID, INTEGER varID, INTEGER key,
                                    REAL*8 value)

Get a floating point value from a key (4.4.6)

cdiInqKeyInt


    INTEGER FUNCTION cdiInqKeyInt(INTEGER cdiID, INTEGER varID, INTEGER key,
                                  INTEGER value)

Get an integer value from a key (4.4.4)

cdiInqKeyString


    INTEGER FUNCTION cdiInqKeyString(INTEGER cdiID, INTEGER varID, INTEGER key,
                                     CHARACTER*(*) string, INTEGER length)

Get a string from a key (4.4.2)

cdiInqNatts


    INTEGER FUNCTION cdiInqNatts(INTEGER cdiID, INTEGER varID, INTEGER nattsp)

Get number of attributes (4.5.1)

gridCreate


    INTEGER FUNCTION gridCreate(INTEGER gridtype, INTEGER size)

Create a horizontal Grid (4.6.1)

gridDefNP


    SUBROUTINE gridDefNP(INTEGER gridID, INTEGER np)

Define the number of parallels between a pole and the equator (4.6.10)

gridDefXbounds


    SUBROUTINE gridDefXbounds(INTEGER gridID, REAL*8 xbounds)

Define the bounds of a X-axis (4.6.16)

gridDefXsize


    SUBROUTINE gridDefXsize(INTEGER gridID, INTEGER xsize)

Define the number of values of a X-axis (4.6.6)

gridDefXvals


    SUBROUTINE gridDefXvals(INTEGER gridID, REAL*8 xvals)

Define the values of a X-axis (4.6.12)

gridDefYbounds


    SUBROUTINE gridDefYbounds(INTEGER gridID, REAL*8 ybounds)

Define the bounds of a Y-axis (4.6.18)

gridDefYsize


    SUBROUTINE gridDefYsize(INTEGER gridID, INTEGER ysize)

Define the number of values of a Y-axis (4.6.8)

gridDefYvals


    SUBROUTINE gridDefYvals(INTEGER gridID, REAL*8 yvals)

Define the values of a Y-axis (4.6.14)

gridDestroy


    SUBROUTINE gridDestroy(INTEGER gridID)

Destroy a horizontal Grid (4.6.2)

gridDuplicate


    INTEGER FUNCTION gridDuplicate(INTEGER gridID)

Duplicate a horizontal Grid (4.6.3)

gridInqNP


    INTEGER FUNCTION gridInqNP(INTEGER gridID)

Get the number of parallels between a pole and the equator (4.6.11)

gridInqSize


    INTEGER FUNCTION gridInqSize(INTEGER gridID)

Get the size of a Grid (4.6.5)

gridInqType


    INTEGER FUNCTION gridInqType(INTEGER gridID)

Get the type of a Grid (4.6.4)

gridInqXbounds


    INTEGER FUNCTION gridInqXbounds(INTEGER gridID, REAL*8 xbounds)

Get the bounds of a X-axis (4.6.17)

gridInqXsize


    INTEGER FUNCTION gridInqXsize(INTEGER gridID)

Get the number of values of a X-axis (4.6.7)

gridInqXvals


    INTEGER FUNCTION gridInqXvals(INTEGER gridID, REAL*8 xvals)

Get all values of a X-axis (4.6.13)

gridInqYbounds


    INTEGER FUNCTION gridInqYbounds(INTEGER gridID, REAL*8 ybounds)

Get the bounds of a Y-axis (4.6.19)

gridInqYsize


    INTEGER FUNCTION gridInqYsize(INTEGER gridID)

Get the number of values of a Y-axis (4.6.9)

gridInqYvals


    INTEGER FUNCTION gridInqYvals(INTEGER gridID, REAL*8 yvals)

Get all values of a Y-axis (4.6.15)

streamClose


    SUBROUTINE streamClose(INTEGER streamID)

Close an open dataset (4.1.3)

streamDefByteorder


    SUBROUTINE streamDefByteorder(INTEGER streamID, INTEGER byteorder)

Define the byte order (4.1.5)

streamDefRecord


    SUBROUTINE streamDefRecord(INTEGER streamID, INTEGER varID, INTEGER levelID)

Define the next record (??)

streamDefTimestep


    INTEGER FUNCTION streamDefTimestep(INTEGER streamID, INTEGER tsID)

Define a timestep (4.1.9)

streamDefVlist


    SUBROUTINE streamDefVlist(INTEGER streamID, INTEGER vlistID)

Define the variable list (4.1.7)

streamInqByteorder


    INTEGER FUNCTION streamInqByteorder(INTEGER streamID)

Get the byte order (4.1.6)

streamInqFiletype


    INTEGER FUNCTION streamInqFiletype(INTEGER streamID)

Get the filetype (4.1.4)

streamInqTimestep


    INTEGER FUNCTION streamInqTimestep(INTEGER streamID, INTEGER tsID)

Get timestep information (4.1.10)

streamInqVlist


    INTEGER FUNCTION streamInqVlist(INTEGER streamID)

Get the variable list (4.1.8)

streamOpenRead


    INTEGER FUNCTION streamOpenRead(CHARACTER*(*) path)

Open a dataset for reading (4.1.2)

streamOpenWrite


    INTEGER FUNCTION streamOpenWrite(CHARACTER*(*) path, INTEGER filetype)

Create a new dataset (4.1.1)

streamReadVar


    SUBROUTINE streamReadVar(INTEGER streamID, INTEGER varID, REAL*8 data,
                             INTEGER nmiss)

Read a variable (4.1.15)

streamReadVarF


    SUBROUTINE streamReadVar(INTEGER streamID, INTEGER varID, REAL*4 data,
                             INTEGER nmiss)

Read a variable (4.1.16)

streamReadVarSlice


    SUBROUTINE streamReadVarSlice(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                  REAL*8 data, INTEGER nmiss)

Read a horizontal slice of a variable (4.1.17)

streamReadVarSliceF


    SUBROUTINE streamReadVarSliceF(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                   REAL*4 data, INTEGER nmiss)

Read a horizontal slice of a variable (4.1.18)

streamWriteVar


    SUBROUTINE streamWriteVar(INTEGER streamID, INTEGER varID, REAL*8 data,
                              INTEGER nmiss)

Write a variable (4.1.11)

streamWriteVarF


    SUBROUTINE streamWriteVarF(INTEGER streamID, INTEGER varID, REAL*4 data,
                               INTEGER nmiss)

Write a variable (4.1.12)

streamWriteVarSlice


    SUBROUTINE streamWriteVarSlice(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                   REAL*8 data, INTEGER nmiss)

Write a horizontal slice of a variable (4.1.13)

streamWriteVarSliceF


    SUBROUTINE streamWriteVarSliceF(INTEGER streamID, INTEGER varID, INTEGER levelID,
                                    REAL*4 data, INTEGER nmiss)

Write a horizontal slice of a variable (4.1.14)

taxisCreate


    INTEGER FUNCTION taxisCreate(INTEGER taxistype)

Create a Time axis (4.8.1)

taxisDefCalendar


    SUBROUTINE taxisDefCalendar(INTEGER taxisID, INTEGER calendar)

Define the calendar (4.8.11)

taxisDefRdate


    SUBROUTINE taxisDefRdate(INTEGER taxisID, INTEGER rdate)

Define the reference date (4.8.3)

taxisDefRtime


    SUBROUTINE taxisDefRtime(INTEGER taxisID, INTEGER rtime)

Define the reference time (4.8.5)

taxisDefVdate


    SUBROUTINE taxisDefVdate(INTEGER taxisID, INTEGER vdate)

Define the verification date (4.8.7)

taxisDefVtime


    SUBROUTINE taxisDefVtime(INTEGER taxisID, INTEGER vtime)

Define the verification time (4.8.9)

taxisDestroy


    SUBROUTINE taxisDestroy(INTEGER taxisID)

Destroy a Time axis (4.8.2)

taxisInqCalendar


    INTEGER FUNCTION taxisInqCalendar(INTEGER taxisID)

Get the calendar (4.8.12)

taxisInqRdate


    INTEGER FUNCTION taxisInqRdate(INTEGER taxisID)

Get the reference date (4.8.4)

taxisInqRtime


    INTEGER FUNCTION taxisInqRtime(INTEGER taxisID)

Get the reference time (4.8.6)

taxisInqVdate


    INTEGER FUNCTION taxisInqVdate(INTEGER taxisID)

Get the verification date (4.8.8)

taxisInqVtime


    INTEGER FUNCTION taxisInqVtime(INTEGER taxisID)

Get the verification time (4.8.10)

vlistCat


    SUBROUTINE vlistCat(INTEGER vlistID2, INTEGER vlistID1)

Concatenate two variable lists (4.2.5)

vlistCopy


    SUBROUTINE vlistCopy(INTEGER vlistID2, INTEGER vlistID1)

Copy a variable list (4.2.3)

vlistCopyFlag


    SUBROUTINE vlistCopyFlag(INTEGER vlistID2, INTEGER vlistID1)

Copy some entries of a variable list (4.2.6)

vlistCreate


    INTEGER FUNCTION vlistCreate()

Create a variable list (4.2.1)

vlistDefTaxis


    SUBROUTINE vlistDefTaxis(INTEGER vlistID, INTEGER taxisID)

Define the time axis (4.2.10)

vlistDefVar


    INTEGER FUNCTION vlistDefVar(INTEGER vlistID, INTEGER gridID, INTEGER zaxisID,
                                 INTEGER timetype)

Define a Variable (4.3.1)

vlistDefVarCode


    SUBROUTINE vlistDefVarCode(INTEGER vlistID, INTEGER varID, INTEGER code)

Define the code number of a Variable (4.3.5)

vlistDefVarDatatype


    SUBROUTINE vlistDefVarDatatype(INTEGER vlistID, INTEGER varID, INTEGER datatype)

Define the data type of a Variable (4.3.7)

vlistDefVarMissval


    SUBROUTINE vlistDefVarMissval(INTEGER vlistID, INTEGER varID, REAL*8 missval)

Define the missing value of a Variable (4.3.9)

vlistDestroy


    SUBROUTINE vlistDestroy(INTEGER vlistID)

Destroy a variable list (4.2.2)

vlistDuplicate


    INTEGER FUNCTION vlistDuplicate(INTEGER vlistID)

Duplicate a variable list (4.2.4)

vlistInqTaxis


    INTEGER FUNCTION vlistInqTaxis(INTEGER vlistID)

Get the time axis (4.2.11)

vlistInqVarCode


    INTEGER FUNCTION vlistInqVarCode(INTEGER vlistID, INTEGER varID)

Get the Code number of a Variable (4.3.6)

vlistInqVarDatatype


    INTEGER FUNCTION vlistInqVarDatatype(INTEGER vlistID, INTEGER varID)

Get the data type of a Variable (4.3.8)

vlistInqVarGrid


    INTEGER FUNCTION vlistInqVarGrid(INTEGER vlistID, INTEGER varID)

Get the Grid ID of a Variable (4.3.2)

vlistInqVarMissval


    REAL*8 FUNCTION vlistInqVarMissval(INTEGER vlistID, INTEGER varID)

Get the missing value of a Variable (4.3.10)

vlistInqVarTsteptype


    INTEGER FUNCTION vlistInqVarTsteptype(INTEGER vlistID, INTEGER varID)

Get the timestep type of a Variable (4.3.4)

vlistInqVarZaxis


    INTEGER FUNCTION vlistInqVarZaxis(INTEGER vlistID, INTEGER varID)

Get the Zaxis ID of a Variable (4.3.3)

vlistNgrids


    INTEGER FUNCTION vlistNgrids(INTEGER vlistID)

Number of grids in a variable list (4.2.8)

vlistNvars


    INTEGER FUNCTION vlistNvars(INTEGER vlistID)

Number of variables in a variable list (4.2.7)

vlistNzaxis


    INTEGER FUNCTION vlistNzaxis(INTEGER vlistID)

Number of zaxis in a variable list (4.2.9)

zaxisCreate


    INTEGER FUNCTION zaxisCreate(INTEGER zaxistype, INTEGER size)

Create a vertical Z-axis (4.7.1)

zaxisDefLevels


    SUBROUTINE zaxisDefLevels(INTEGER zaxisID, REAL*8 levels)

Define the levels of a Z-axis (4.7.5)

zaxisDestroy


    SUBROUTINE zaxisDestroy(INTEGER zaxisID)

Destroy a vertical Z-axis (4.7.2)

zaxisInqLevel


    REAL*8 FUNCTION zaxisInqLevel(INTEGER zaxisID, INTEGER levelID)

Get one level of a Z-axis (4.7.7)

zaxisInqLevels


    SUBROUTINE zaxisInqLevels(INTEGER zaxisID, REAL*8 levels)

Get all levels of a Z-axis (4.7.6)

zaxisInqSize


    INTEGER FUNCTION zaxisInqSize(INTEGER zaxisID)

Get the size of a Z-axis (4.7.4)

zaxisInqType


    INTEGER FUNCTION zaxisInqType(INTEGER zaxisID)

Get the type of a Z-axis (4.7.3)

B.  Examples

This appendix contains complete examples to write, read and copy a dataset with the CDI library.

B.1  Write a dataset

Here is an example using CDI to write a NetCDF dataset with 2 variables on 3 time steps. The first variable is a 2D field on surface level and the second variable is a 3D field on 5 pressure levels. Both variables are on the same lon/lat grid.

 
    PROGRAM CDIWRITE 
 
    IMPLICIT NONE 
 
5    INCLUDE cdi.inc 
 
    INTEGER nlon, nlat 
    INTEGER nlev, nts 
    PARAMETER (nlon = 12) ! Number of longitudes 
10    PARAMETER (nlat = 6) ! Number of latitudes 
    PARAMETER (nlev = 5) ! Number of levels 
    PARAMETER (nts = 3)  ! Number of time steps 
 
    INTEGER gridID, zaxisID1, zaxisID2, taxisID 
15    INTEGER vlistID, varID1, varID2, streamID, tsID, i, status 
    INTEGER nmiss 
    REAL*8 lons(nlon), lats(nlat), levs(nlev) 
    REAL*8 var1(nlon*nlat), var2(nlon*nlat*nlev) 
 
20    DATA lons /0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330/ 
    DATA lats /-75, -45, -15, 15, 45, 75/ 
    DATA levs /101300, 92500, 85000, 50000, 20000/ 
 
    nmiss = 0 
25 
!    Create a regular lon/lat grid 
    gridID = gridCreate(GRID_LONLAT, nlon*nlat) 
    CALL gridDefXsize(gridID, nlon) 
    CALL gridDefYsize(gridID, nlat) 
30    CALL gridDefXvals(gridID, lons) 
    CALL gridDefYvals(gridID, lats) 
 
!    Create a surface level Z-axis 
    zaxisID1 = zaxisCreate(ZAXIS_SURFACE, 1) 
35 
!    Create a pressure level Z-axis 
    zaxisID2 = zaxisCreate(ZAXIS_PRESSURE, nlev) 
    CALL zaxisDefLevels(zaxisID2, levs) 
 
40!    Create a variable list 
    vlistID = vlistCreate() 
 
!    Define the variables 
    varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARYING) 
45    varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARYING) 
 
!    Define the variable names 
    CALL vlistDefVarName(vlistID, varID1, "varname1") 
    CALL vlistDefVarName(vlistID, varID2, "varname2") 
50 
!    Create a Time axis 
    taxisID = taxisCreate(TAXIS_ABSOLUTE) 
 
!    Assign the Time axis to the variable list 
55    CALL vlistDefTaxis(vlistID, taxisID) 
 
!    Create a dataset in netCDF format 
    streamID = streamOpenWrite("example.nc", CDI_FILETYPE_NC) 
    IF ( streamID < 0 ) THEN 
60      WRITE(0,*) cdiStringError(streamID) 
      STOP 
    END IF 
 
!    Assign the variable list to the dataset 
65    CALL streamDefVlist(streamID, vlistID) 
 
!    Loop over the number of time steps 
    DO tsID = 0, nts-1 
!      Set the verification date to 1985-01-01 + tsID 
70      CALL taxisDefVdate(taxisID, 19850101+tsID) 
!      Set the verification time to 12:00:00 
      CALL taxisDefVtime(taxisID, 120000) 
!      Define the time step 
      status = streamDefTimestep(streamID, tsID) 
75 
!      Init var1 and var2 
      DO i = 1, nlon*nlat 
         var1(i) = 1.1 
      END DO 
80      DO i = 1, nlon*nlat*nlev 
         var2(i) = 2.2 
      END DO 
 
!      Write var1 and var2 
85      CALL streamWriteVar(streamID, varID1, var1, nmiss) 
      CALL streamWriteVar(streamID, varID2, var2, nmiss) 
    END DO 
 
!    Close the output stream 
90    CALL streamClose(streamID) 
 
!    Destroy the objects 
    CALL vlistDestroy(vlistID) 
    CALL taxisDestroy(taxisID) 
95    CALL zaxisDestroy(zaxisID1) 
    CALL zaxisDestroy(zaxisID2) 
    CALL gridDestroy(gridID) 
 
    END

B.1.1  Result

This is the ncdump -h output of the resulting NetCDF file example.nc.

1netcdf example { 
dimensions: 
     lon = 12 ; 
     lat = 6 ; 
     lev = 5 ; 
6     time = UNLIMITED ; // (3 currently) 
variables: 
     double lon(lon) ; 
           lon:long_name = "longitude" ; 
           lon:units = "degrees_east" ; 
11           lon:standard_name = "longitude" ; 
     double lat(lat) ; 
           lat:long_name = "latitude" ; 
           lat:units = "degrees_north" ; 
           lat:standard_name = "latitude" ; 
16     double lev(lev) ; 
           lev:long_name = "pressure" ; 
           lev:units = "Pa" ; 
     double time(time) ; 
           time:units = "day as %Y%m%d.%f" ; 
21     float varname1(time, lat, lon) ; 
     float varname2(time, lev, lat, lon) ; 
data: 
 
lon = 0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330 ; 
26 
lat = -75, -45, -15, 15, 45, 75 ; 
 
lev = 101300, 92500, 85000, 50000, 20000 ; 
 
31time = 19850101.5, 19850102.5, 19850103.5 ; 
}

B.2  Read a dataset

This example reads the NetCDF file example.nc from Appendix B.1.

 
    PROGRAM CDIREAD 
 
3    IMPLICIT NONE 
 
    INCLUDE cdi.inc 
 
    INTEGER nlon, nlat 
8    INTEGER nlev, nts 
    PARAMETER (nlon = 12) ! Number of longitudes 
    PARAMETER (nlat = 6) ! Number of latitudes 
    PARAMETER (nlev = 5) ! Number of levels 
    PARAMETER (nts = 3)  ! Number of time steps 
13 
    INTEGER gridID, zaxisID1, zaxisID2, taxisID 
    INTEGER vlistID, varID1, varID2, streamID, tsID 
    INTEGER status, vdate, vtime 
    INTEGER nmiss 
18    REAL*8 var1(nlon*nlat), var2(nlon*nlat*nlev) 
 
!    Open the dataset 
    streamID = streamOpenRead("example.nc") 
    IF ( streamID < 0 ) THEN 
23      WRITE(0,*) cdiStringError(streamID) 
      STOP 
    END IF 
 
!    Get the variable list of the dataset 
28    vlistID = streamInqVlist(streamID) 
 
!    Set the variable IDs 
    varID1 = 0 
    varID2 = 1 
33 
!    Get the Time axis from the variable list 
    taxisID = vlistInqTaxis(vlistID) 
 
!    Loop over the number of time steps 
38    DO tsID = 0, nts-1 
!      Inquire the time step 
      status = streamInqTimestep(streamID, tsID) 
 
!      Get the verification date and time 
43      vdate = taxisInqVdate(taxisID) 
      vtime = taxisInqVtime(taxisID) 
      WRITE(0, *)"readtimestep",tsID+1,"date=",vdate,"time=",vtime 
 
 
48!      Read var1 and var2 
      CALL streamReadVar(streamID, varID1, var1, nmiss) 
      CALL streamReadVar(streamID, varID2, var2, nmiss) 
    END DO 
 
53!    Close the input stream 
    CALL streamClose(streamID) 
 
    END

B.3  Copy a dataset

This example reads the NetCDF file example.nc from Appendix B.1 and writes the result to a GRIB dataset by simple setting the output file type to CDI_FILETYPE_GRB.

 
    PROGRAM CDICOPY 
 
    IMPLICIT NONE 
4 
    INCLUDE cdi.inc 
 
    INTEGER nlon, nlat, nlev, nts 
    PARAMETER (nlon = 12) ! Number of longitudes 
9    PARAMETER (nlat = 6) ! Number of latitudes 
    PARAMETER (nlev = 5) ! Number of levels 
    PARAMETER (nts = 3)  ! Number of time steps 
 
    INTEGER gridID, zaxisID1, zaxisID2, tsID 
14    INTEGER vlistID1, vlistID2, varID1, varID2, streamID1, streamID2 
    INTEGER i, status 
    INTEGER nmiss 
    REAL*8 var1(nlon*nlat), var2(nlon*nlat*nlev) 
 
19!    Open the input dataset 
    streamID1 = streamOpenRead("example.nc") 
    IF ( streamID1 < 0 ) THEN 
      WRITE(0,*) cdiStringError(streamID1) 
      STOP 
24    END IF 
 
!    Get the variable list of the dataset 
    vlistID1 = streamInqVlist(streamID1) 
 
29!    Set the variable IDs 
    varID1 = 0 
    varID2 = 1 
 
!    Open the output dataset (GRIB format) 
34    streamID2 = streamOpenWrite("example.grb", CDI_FILETYPE_GRB) 
    IF ( streamID2 < 0 ) THEN 
      WRITE(0,*) cdiStringError(streamID2) 
      STOP 
    END IF 
39 
    vlistID2 = vlistDuplicate(vlistID1) 
 
    CALL streamDefVlist(streamID2, vlistID2) 
 
44!    Loop over the number of time steps 
    DO tsID = 0, nts-1 
!      Inquire the input time step */ 
      status = streamInqTimestep(streamID1, tsID) 
 
49!      Define the output time step 
      status = streamDefTimestep(streamID2, tsID) 
 
!      Read var1 and var2 
      CALL streamReadVar(streamID1, varID1, var1, nmiss) 
54      CALL streamReadVar(streamID1, varID2, var2, nmiss) 
 
!      Write var1 and var2 
      CALL streamWriteVar(streamID2, varID1, var1, nmiss) 
      CALL streamWriteVar(streamID2, varID2, var2, nmiss) 
59    END DO 
 
!    Close the streams 
    CALL streamClose(streamID1) 
    CALL streamClose(streamID2) 
64 
    END

B.4  Fortran 2003: mo_cdi and iso_c_binding

This is the Fortran 2003 version of the reading and writing examples above. The main differenc to cfortran.h is the character handling. Here CHARACTER(type=c_char) is used instead of CHARACTER. Additionally plain fortran charcters and character variables have to be convertet to C charcters by

  • appending \0’ with //C_NULL_CHAR
  • prepending C_CHAR_ to plain charcters
  • take ctrim from mo_cdi for CHARACTER(type=c_char) variables
 
PROGRAM CDIREADF2003 
 use iso_c_binding 
 use mo_cdi 
 
5 IMPLICIT NONE 
 
 INTEGER(c_size_t) :: gsize, nmiss 
 INTEGER :: nlevel, nvars, code 
 INTEGER :: vdate, vtime, status, ilev 
10 INTEGER :: streamID, varID, gridID, zaxisID 
 INTEGER :: tsID, vlistID, taxisID 
 DOUBLE PRECISION, ALLOCATABLE :: field(:,:) 
 CHARACTER(kind=c_char), POINTER, DIMENSION(:) :: & 
     msg, cdi_version 
15 CHARACTER(kind=c_char, LEN = cdi_max_name + 1) :: & 
     name, longname, units 
 INTEGER :: name_c_len, longname_c_len, units_c_len 
 
 cdi_version => cdiLibraryVersion() 
20 
 WRITE (0, (a,132a)) cdiversion:, cdi_version 
 
 ! Open the dataset 
 streamID = streamOpenRead(C_CHAR_"example.nc"//C_NULL_CHAR) 
25 IF ( streamID < 0 ) THEN 
   PRINT *, CouldnotReadthefile. 
   msg => cdiStringError(streamID) 
   WRITE(0,(132a)) msg 
   STOP 1 
30 END IF 
 
 ! Get the variable list of the dataset 
 vlistID = streamInqVlist(streamID) 
 
35 nvars = vlistNvars(vlistID) 
 
 DO varID = 0, nvars-1 
   code = vlistInqVarCode(vlistID, varID) 
   CALL vlistInqVarName(vlistID, varID, name) 
40   CALL vlistInqVarLongname(vlistID, varID, longname) 
   CALL vlistInqVarUnits(vlistID, varID, units) 
 
   ! CALL ctrim(name) 
   ! CALL ctrim(longname) 
45   ! CALL ctrim(units) 
 
   longname_c_len = c_len(longname) 
   name_c_len = c_len(name) 
   units_c_len = c_len(units) 
50   PRINT (a,2(i0,a),132a), Parameter:, varID+1, , code, , & 
      name(1:name_c_len), , longname(1:longname_c_len), , & 
      units(1:units_c_len), | 
 
 END DO 
55 
 ! Get the Time axis form the variable list 
 taxisID = vlistInqTaxis(vlistID) 
 
 ! Loop over the time steps 
60 DO tsID = 0, 999999 
   ! Read the time step 
   status = streamInqTimestep(streamID, tsID) 
   IF ( status == 0 ) exit 
 
65   ! Get the verification date and time 
   vdate = taxisInqVdate(taxisID) 
   vtime = taxisInqVtime(taxisID) 
 
   PRINT (a,i3,i10,i10), Timestep:, tsID+1, vdate, vtime 
70 
   ! Read the variables at the current timestep 
   DO varID = 0, nvars-1 
    gridID = vlistInqVarGrid(vlistID, varID) 
    gsize = gridInqSize(gridID) 
75    zaxisID = vlistInqVarZaxis(vlistID, varID) 
    nlevel = zaxisInqSize(zaxisID) 
    ALLOCATE(field(gsize, nlevel)) 
    CALL streamReadVar(streamID, varID, field, nmiss) 
    DO ilev = 1, nlevel 
80      PRINT (a,i3,a,i3,a,f10.5,1x,f10.5), var=, varID+1, & 
         level=, ilev, :, & 
         MINVAL(field(:,ilev)), MAXVAL(field(:,ilev)) 
    END DO 
    DEALLOCATE(field) 
85   END DO 
 END DO 
 
 ! Close the input stream 
 CALL streamClose(streamID) 
90 
END PROGRAM CDIREADF2003
 
    PROGRAM CDIWRITEF2003 
 
    USE iso_c_binding 
4    USE mo_cdi 
 
    IMPLICIT NONE 
 
    INTEGER :: nlev, nts 
9    INTEGER(c_size_t) :: nlon, nlat, nmiss 
    PARAMETER (nlon = 12) ! Number of longitudes 
    PARAMETER (nlat = 6) ! Number of latitudes 
    PARAMETER (nlev = 5) ! Number of levels 
    PARAMETER (nts = 3)  ! Number of time steps 
14 
    INTEGER gridID, zaxisID1, zaxisID2, taxisID 
    INTEGER vlistID, varID1, varID2, streamID, tsID 
    INTEGER i, status 
    DOUBLE PRECISION lons(nlon), lats(nlat), levs(nlev) 
19    DOUBLE PRECISION var1(nlon*nlat), var2(nlon*nlat*nlev) 
    CHARACTER(len=256, kind=c_char) :: varname 
    CHARACTER(kind=c_char,len=1), POINTER :: msg(:) 
 
    DATA lons /0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330/ 
24    DATA lats /-75, -45, -15, 15, 45, 75/ 
    DATA levs /101300, 92500, 85000, 50000, 20000/ 
 
    nmiss = 0 
 
29!    Create a regular lon/lat grid 
    gridID = gridCreate(GRID_LONLAT, nlon*nlat) 
    CALL gridDefXsize(gridID, nlon) 
    CALL gridDefYsize(gridID, nlat) 
    CALL gridDefXvals(gridID, lons) 
34    CALL gridDefYvals(gridID, lats) 
 
!    Create a surface level Z-axis 
    zaxisID1 = zaxisCreate(ZAXIS_SURFACE, 1) 
 
39!    Create a pressure level Z-axis 
    zaxisID2 = zaxisCreate(ZAXIS_PRESSURE, nlev) 
    CALL zaxisDefLevels(zaxisID2, levs) 
 
!    Create a variable list 
44    vlistID = vlistCreate() 
 
!    Define the variables 
    varID1 = vlistDefVar(vlistID, gridID, zaxisID1, TIME_VARYING) 
    varID2 = vlistDefVar(vlistID, gridID, zaxisID2, TIME_VARYING) 
49 
!    Define the variable names 
    varname = "varname1" // c_null_char 
    CALL vlistDefVarName(vlistID, varID1, varname) 
    CALL vlistDefVarName(vlistID, varID2, C_CHAR_"varname2"//C_NULL_CHAR) 
54 
!    Create a Time axis 
    taxisID = taxisCreate(TAXIS_ABSOLUTE) 
 
!    Assign the Time axis to the variable list 
59    CALL vlistDefTaxis(vlistID, taxisID) 
 
!    Create a dataset in netCDF format 
    streamID = streamOpenWrite(C_CHAR_"example.nc"//C_NULL_CHAR, CDI_FILETYPE_NC) 
    IF ( streamID < 0 ) THEN 
64      msg => cdiStringError(streamID) 
      WRITE(0,(132a)) msg 
      STOP 1 
    END IF 
 
69!    Assign the variable list to the dataset 
    CALL streamDefVlist(streamID, vlistID) 
 
!    Loop over the number of time steps 
    DO tsID = 0, nts-1 
74!      Set the verification date to 1985-01-01 + tsID 
      CALL taxisDefVdate(taxisID, INT(19850101+tsID,8)) 
!      Set the verification time to 12:00:00 
      CALL taxisDefVtime(taxisID, 120000) 
!      Define the time step 
79      status = streamDefTimestep(streamID, tsID) 
 
!      Init var1 and var2 
      DO i = 1, nlon*nlat 
         var1(i) = 1.1 
84      END DO 
      DO i = 1, nlon*nlat*nlev 
         var2(i) = 2.2 
      END DO 
 
89!      Write var1 and var2 
      CALL streamWriteVar(streamID, varID1, var1, nmiss) 
      CALL streamWriteVar(streamID, varID2, var2, nmiss) 
    END DO 
 
94!    Close the output stream 
    CALL streamClose(streamID) 
 
!    Destroy the objects 
    CALL vlistDestroy(vlistID) 
99    CALL taxisDestroy(taxisID) 
    CALL zaxisDestroy(zaxisID1) 
    CALL zaxisDestroy(zaxisID2) 
    CALL gridDestroy(gridID) 
 
104    END PROGRAM CDIWRITEF2003

C.  Environment Variables

The following table describes the environment variables that affect CDI.




Variable name Default Description



CDI_INVENTORY_MODE None Set to time to skip double variable entries.
CDI_VERSION_INFO 1 Set to 0 to disable NetCDF global attribute CDI.