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)