Consider a data object consisting of temperatures measured over a longitude-latitude grid and a set of standard atmospheric pressure levels. There may be one or more observations in time; we will suppose that we have only one set of data, valid for 22 July 1991. The longitudes will run every 5 degrees starting from 0, and the latitudes will run every 2 degrees starting from -90. We further suppose that the data will lie on 6 pressure surfaces: 1000, 850, 700, 500, 250, and 100 mb.
Temperature is a scalar, and so the data object will have a single Level 0 dimension having one element. A natural way to think of the data is as a set of six two-dimensional arrays. That is, we will have two Level 1 dimensions, longitude and latitude, and at least one Level 2 dimension: pressure. Because we have data for only one time, there are several ways we could indicate this in the file: putting a time stamp in an INFOSPEC or COMMENT record, adding it in as a Level 1 or Level 2 dimension, or making time a Level 3 dimension whose average type is the oxymoronic ``instantaneous.'' We choose to have time as a second Level 2 dimension with one grid point.
We choose to write the data as a
(i.e,
longitude, latitude, pressure) array.
If our indices start numbering at 0, then we have the following record fields:
In IDL, then, code to define the dimensions of this data object would look like this:
; set up the relevant elements in the OBJDESC record
RECTYPE = long(1)
NDIM0 = long(1)
NDIM1 = long(2)
NDIM2 = long(2)
NDIM3 = long(0)
.
.
.
writeu,log_file_unit, RECTYPE, vartype, reserved $
, NDIM0, NDIM1, NDIM2, NDIM3, reserved, isource $
, reserved, reserved, naudit, ninfo, ncomms, comcod $
, reserved, nbads, reserved, nprocs, reserved, npacks $
, reserved, reserved, cmpnum, reserved, reserved $
, reserved
.
.
.
; set up the DIMSPEC0 record
RECTYPE = long(20)
; Since Temperature is a scalar, there is no array index
, for this to point to.
INDEX = long(-1)
; Since temperature is a scalar, there is only one grid
; point.
GPTNUM = long(1)
writeu,log_file_unit, RECTYPE, reserved, reserved $
, INDEX, GPTNUM
; set up the DIMSPEC1 record
RECTYPE = long(21)
; longitude and latitude will be the first and second
; dimensions of the data array read in.
INDEX = long( [ 0, 1 ] )
; we will specify only one DESCRIP1 record for each
; dimension
DESNUM = long( [ 1, 1 ] )
writeu,log_file_unit, RECTYPE, reserved, reserved $
, INDEX, DESNUM
; set up the DIMSPEC2 record
RECTYPE = long(22)
; pressure and time will be the third and fourth
; dimensions of the data array read in.
INDEX = long( [ 2, 3 ] )
; There will be five pressure levels and one time
GPTNUM = long( [ 6, 1 ] )
writeu,log_file_unit, RECTYPE, reserved, reserved $
, INDEX, GPTNUM
; (There is no DIMSPEC3 record.)
; set up the DESCRIP0 record
RECTYPE = long(30)
; data are floating-point single precision numbers
DATFMT = long(67108864)
; data are temperatures
; Note: in actual working code, one would call here a
; function which would convert the string "Temperature"
; to its quantity ID code 16777216:
; vartype = name_to_number("temperature")
VARTYPE = long(16777216)
; the temperatures are in Kelvin
UNITS = long(681050112)
writeu,log_file_unit, RECTYPE, reserved, reserved $
, DATFMT, VARTYPE, UNITS
; set up the longitude DESCRIP1 record
RECTYPE = long(31)
; This describes the first Level 1 dimension
NDEX = long(0)
; This covers the entire range of both Level 2 dimensions
START = long( [ 0, 0 ] )
; (Note: END is a reserved word in IDL, so we use ENDIT
; here)
ENDIT = long( [ -1, -1 ] )
; There are 72 longitudes
GPTNUM = long(72)
; No duplicate records
DUPNUM = long(0)
; No supplemental information
DESSUP = long(0)
; longitudes are long integers
DESFMT = long(51445760)
; the quantity id for longitude is 17838080
DESTYPE = long(17838080)
; The units code for degrees is 1745355010
UNITS = long(1745355010)
; We will store this as a an implicit
; (low-value, interval) pair
STORG = long(1)
writeu,log_file_unit, RECTYPE, NDEX, START, ENDIT $
, GPTNUM, DUPNUM, DESSUP, DESFMT, DESTYPE, UNITS $
, STORG, reserved, reserved
; set up the longitude DESCVAL record
RECTYPE = long(35)
; This belongs to Level 1, dimension number 1
LEVEL = long(1)
NDEX = long(0)
; We start at 0 longitude and increase by 5 degrees
; thereafter
AVALS = long([ 0, 5 ] )
writeu,log_file_unit, RECTYPE, LEVEL, NDEX, AVALS
; Now do the latitude DESCRIP1 and DESCVAL records
; (This is more terse, to show that you do not really
; need a lot of code to write these records; as an
; exercise, the reader may wish to interpret the
; following). The quantity code for latitude is
; 17838096
writeu,log_file_unit, long(31), long(1), long([0,0]) $
, long([-1,-1]), long(91), long(0), long(0) $
, long(51445760), long(17838096), long(1745355010) $
, long(2), reserved, reserved
writeu,log_file_unit, long(35), long(1), long(1) $
, long([ -90, 90 ])
; Do the pressure DESCRIP2 record
RECTYPE = long(32)
; This describes the first Level 2 dimension
NDEX = long(0)
; No duplicate records
DUPNUM = long(0)
; No supplemental information
DESSUP = long(0)
; pressures are floating-point numbers
DESFMT = long(67108864)
; the quantity id for pressure is 16781312
DESTYPE = long(16781312)
; The units code for millibars is 1081593921
UNITS = long(1081593921)
; We will store this as a an explicit array
STORG = long(0)
writeu,log_file_unit, RECTYPE, NDEX, DUPNUM, DESSUP $
, DESFMT, DESTYPE, UNITS, STORG, reserved, reserved
; set up the pressure DESCVAL record
RECTYPE = long(35)
; This belongs to Level 2, dimension number 1
LEVEL = long(2)
NDEX = long(0)
; We list the pressure levels
AVALS = float([1000., 850., 700., 500., 250., 100.] )
writeu,log_file_unit, RECTYPE, LEVEL, NDEX, AVALS
; do the time dimension spec (tersely: another exercise
; for the reader. The format code for long unsigned
; integers is 50397184, the quantity code for time is
; 131072, and the units code for day number (from
; January 1) is 1615331845. July 22 was the 203rd
; day of 1991.
writeu,log_file_unit, long(32), long(1), long(0) $
, long(0), long(50397184), long(131072) $
, long(1615331845), long(0), reserved, reserved
writeu,log_file_unit, long(35), long(2), long(1) $
, long(203)