; $Header: /science/nmc/met_fields/programs/dfread_grids.pro,v 1.9 2002/04/17 19:04:49 nash Exp $ function dfread_grids,path,file,dat,badval,length,partial=partial, $ audit=audit,comment=comment,dimavg=dimavg,diminfo=diminfo, $ fstruct=fstruct,fname=fname,info=info,pakinfo=pakinfo, $ procinfo=procinfo,unit=unit,vartype=vartype ;+ ; NAME: ; dfread_grids ; PURPOSE: ; Reads in data from gridded df files. This is a midlevel routine: ; The data is returned in an array and information about the array is ; returned in coded form. This routine cannot handle information that ; applies to only parts of dimensions. ; CATEGORY: ; df ; CALLING SEQUENCE: ; err = dfread_grids(path,file,dat,badval) ; err = dfread_grids(path,file,dat,badval,length) ; FUNCTION RETURN VALUE: ; long: scalar ; Returns 0 if the file was read with no errors, otherwise returns non-zero. ; INPUT PARAMETERS: ; path = (string) pathname where data file resides ; file = (string) completely specified file name ; OR ; ({df_file_struct} structure) standard df file structure: ; quantity = (string) 4-character quantity code. This must be specified ; avespec = (string) Character code in the file name representing the time ; averaging code of data in the file. Default is "I" for ; instantaneous. ; date = (string) date in the format "yymmddhh". This must be ; specified ; grid = (string) grid code. Default is no gridding ; forecast = (string) forecast time string. Default is no forecast ; sequence = (string) sequence code string. Default is no sequence field ; format = (string) format code string. Default is 'X' for xdr format ; special = (string) special code string. Default is no special field ; time = (string) time string. Default is no time field. ; source = (string) 3-character source code. This must be specified ; OPTIONAL INPUT PARAMETERS: ; INPUT/OUTPUT PARAMETERS: ; OPTIONAL INPUT/OUTPUT PARAMETERS: ; OUTPUT PARAMETERS: ; dat = (float array) the data. Will be dimensioned as in length ; badval = (float) missing data value ; OPTIONAL OUTPUT PARAMETERS: ; length = (long array) number of grid points along each dimension of dat ; INPUT KEYWORDS: ; partial = CURRENTLY IS NOT IMPLEMENTED ; (structure) returns parts of the data array. Each entry in the ; structure should be an array where the first value indicates ; which dimension is being referenced, and the rest of the values ; are indices into the elements of the indicated dimension. ; For example, if you want the 2nd, 10th through 20th, and the ; 25th elements of the 2nd dimension and the 4th and 5th elements ; of the 3rd dimension, then set (remembering that indexing IDL ; starts at 0) ; partial = {p1:[1,9,10,11,12,13,14,15,16,17,18,19,24], $ ; p2:[2,3,4]} ; INPUT/OUTPUT KEYWORDS: ; OUTPUT KEYWORDS: ; audit = ({audit_type} structure array) audit trail ; site = (long) numeric site identifier ; task = (long) numeric task identifier ; date = (long) date of generation ; pointer = (long) relative pointer to the next lowest node in the tree ; comment = (string array) string array of comments from the COMMENT record ; dimavg = (structure) Level 3 (averaging) data dimensions. These are ; "virtual" dimensions that have been averaged over. There will be ; one entry for each dimension in the data array and will have the ; names: dim0, dim1, dim2, ... ; dim{n} = (structure) dimension description containing the following ; fields: ; avgcod = (long) averaging method code ; gptnum = (long) number of grid points along this dimension ; dupnum = (long) number of duplicate descriptors for this dimension ; dessup = (long) number of elements in svals ; desfmt = (long) format code for the values in avals ; destype = (long) dimension quantity numerical code ; units = (long) dimension unit numerical code ; storg = (long) storage index of the descriptor: ; 0 = an explicit array of descriptor values ; 1 = an implicit specification consisting of a ; (low-value, interval-value) pair ; 2 = an implicit specification consisting of a ; (low-value, high-value) pair ; avals = ([gptnum] destype array) contains values of the ; dimension descriptor ; supcode = (optional long) the supplemental code ; svals = (optional [dessup] float array) supplementary information ; dup{n} = (optional structure) there will be one entry for each ; duplicate dimension descriptor and will have the names: ; dup0, dup1, dup2, ... ; Each dup{n} will be a structure with the following fields: ; dindex = (long) a relative index for sorting the duplicate ; descriptors ; dessup = (long) number of elements in svals ; desfmt = (long) format code for the values in avals ; destype = (long) dimension quantity numerical code ; units = (long) dimension unit numerical code ; storg = (long) storage index of the descriptor: ; 0 = an explicit array of descriptor values ; 1 = an implicit specification consisting of a ; (low-value, interval-value) pair. ; 2 = an implicit specification consisting of a ; (low-value, high-value) pair. ; avals = ([gptnum] destype array) contains values of the ; dimension descriptor ; supcode = (optional long) the supplemental code ; svals = (optional [dessup] float array) supplementary ; information ; diminfo = (structure) the dimensions in the data array. There will be one ; entry for each dimension in the data array and will have the ; names: dim0, dim1, dim2, ... ; dim{n} = (structure) dimension description containing the following ; fields: ; level = (long) the dimension level (1 or 2) ; gptnum = (long) number of grid points along this dimension ; dupnum = (long) number of duplicate descriptors for this dimension ; dessup = (long) number of elements in svals ; desfmt = (long) format code for the values in avals ; destype = (long) dimension quantity numerical code ; units = (long) dimension unit numerical code ; storg = (long) storage index of the descriptor: ; 0 = an explicit array of descriptor values ; 1 = an implicit specification consisting of a ; (low-value, interval-value) pair ; 2 = an implicit specification consisting of a ; (low-value, high-value) pair ; avals = ([gptnum] destype array) contains values of the ; dimension descriptor ; supcode = (optional long) the supplemental code ; svals = (optional [dessup] float array) supplementary information ; dup{n} = (optional structure) there will be one entry for each ; duplicate dimension descriptor and will have the names: ; dup0, dup1, dup2, ... ; Each dup{n} will be a structure with the following fields: ; dindex = (long) a relative index for sorting the duplicate ; descriptors ; dessup = (long) number of elements in svals ; desfmt = (long) format code for the values in avals ; destype = (long) dimension quantity numerical code ; units = (long) dimension unit numerical code ; storg = (long) storage index of the descriptor: ; 0 = an explicit array of descriptor values ; 1 = an implicit specification consisting of a ; (low-value, interval-value) pair ; 2 = an implicit specification consisting of a ; (low-value, high-value) pair ; avals = ([gptnum] destype array) contains values of the ; dimension descriptor ; supcode = (optional long) the supplemental code ; svals = (optional [dessup] float array) supplementary ; information ; fstruct = (structure: df_file_struct) standard df file structure for file ; used. Fields are defined in the file parameter, above ; fname = (string) file name used ; info = (bytarr) array of bytes from the INFO record ; pakinfo = (structure) packing information. There will be one entry for ; each packing code with the names pak0, pak1, pak2, ... ; pak{n} = (structure) packing information with the following fields: ; recsort = (long) specifies the ordering index which indicates what ; sort of priority this packing code has over other codes. ; Higher numbers imply higher priorities ; starts = ([ndim0+ndim1+ndim2] long array) array indices ; at which this packing code starts to take effect ; stops = ([ndim0+ndim1+ndim2] long array) array-indices ; at which this packing code ceases being in effect ; code = (long) packing code ; dpakfmt = (long) the format of the packed data in PAKDAT.VALS ; paknum = (long) number of info field values ; pakbad = (dpakfmt) bad-value flag of the data in PAKDAT.VALS ; pakfmt = (optional paknum long array) the format of the info field ; values. Will only be present if paknum > 0 ; info = (optional paknum double precision array) packing ; information. The data are stored in a double prescision ; array to allow for the mixing of all types of data. Will ; only be present if paknum > 0 ; procinfo = (structure) processing information. There will be one entry for ; each processing code with the names proc0, proc1, proc2, ... ; proc{n} = (structure) processing information with the following fields: ; recsort = (long) specifies the ordering index which indicates what ; sort of priority this processing code has over other ; codes. Higher numbers imply higher priorities ; starts = ([ndim0+ndim1+ndim2] long array) array indices ; at which this processing code starts to take effect ; stops = ([ndim0+ndim1+ndim2] long array) array-indices ; at which this processing code ceases being in effect ; code = (long) processing code ; prcnum = (long) number of info field values ; ndups = (long) the number of duplicate records ; prcfmt = (optional prcnum long array) the format of the info field ; values. Will only be present if prcnum > 0 ; info = (optional prcnum string array) processing information. ; The data are stored in a string array to allow for the ; mixing of all types of data. Will only be present if ; prcnum > 0 ; dup{n} = there will be one entry for each duplicate processing code ; and will have the names: dup0, dup1, dup2, ... ; Each dup{n} will be a structure with the following fields: ; pindex = (long) specifies the ordering index which indicates ; what sort of priority this duplicate has over other ; duplicates. Higher numbers imply higher priorities ; starts = ([ndim0+ndim1+ndim2] long array) array indices ; at which this processing code starts to take effect ; stops = ([ndim0+ndim1+ndim2] long array) array-indices ; at which this processing code ceases being in effect ; unit = (long) unit code of the quantity read in ; vartype = (long) quantity code ; COMMON BLOCKS: ; REQUIRED ROUTINES: ; df_conv_fmt, df_make_name, df_make_var, df_openr, df_parse_name, ; df_trans_source, df_trans_var, df_unpkdata_s, dfget_audit, dfget_badval, ; dfget_comment, dfget_gdimens, dfget_info, dfget_objdesc, dfget_pack_s, ; dfget_proc_s, dfhead, in, str_parse ; @ FILES: ; RESTRICTIONS: ; SIDE EFFECTS: ; DIAGNOSTIC INFORMATION: ; PROCEDURE: ; EXAMPLES: ; REFERENCE: ; Lait, L. R., E. R. Nash, and P. A. Newman, df:A Proposed Data Format ; Standard, NASA Technical Memorandum 4467, 175 pp., 1993. ; FURTHER INFORMATION: ; RELATED FUNCTIONS AND PROCEDURES: ; MODIFICATION HISTORY: ; 1995-12-20:nash:written ; 1996-03-05:nash:revised documentation of dimavg and diminfo ; 1996-03-05:nash:fixed so that file and fstruct work properly ; 1997-04-04:nash:bug in processing codes...use of k index no longer needed ; 2000-01-10:nash:updated documentation ; 2002-04-02:nash:removed all of the date and forecast stuff ; 2002-04-17:nash:fixed improper handling of structure file input ;- ; *****initialize dfhead,/xdr,consts=const fdesc = {fdesc} ; *****open file for reading if (size(file,/type) eq 7) then s = df_parse_name(file,fout=fstruct) $ else fstruct = file fname = df_make_name(fin=temporary(fstruct),fout=fstruct) fdesc = df_openr(path+'/',fname,res,/xdr) if (res ne 0) then return,res ; *****read in OBJDESC record if (dfget_objdesc(fdesc,vchk,schk) ne 0) then goto,bad_file ; *****check quantity code df_trans_var,num=quantity,short=fstruct.quantity if (quantity ne vchk) then begin message,/continue,'Quantity code ('+strcompress(temporary(vchk),/rem)+ $ ') is inconsistent with file name ('+strcompress(quantity,/rem)+')' goto,bad_file endif ; *****read in AUDIT record if (fdesc.naudit gt 0) then $ if (dfget_audit(fdesc,audit) ne 0) then goto,bad_file ; *****check source code isourc = 0 df_trans_source,num=isourc,short=fstruct.source,err=res,/dir, $ site=audit[fdesc.naudit-1].site if (temporary(res) eq 1) then begin message,'Unknown source: '+strcompress(isourc,/rem),/continue return,1 endif if (isourc ne schk) then begin message,/continue,'Data source ('+strcompress(temporary(schk),/rem)+ $ ') is not the same as requested ('+strcompress(temporary(isourc),/rem)+')' goto,bad_file endif ; *****read the INFOSPEC record if (dfget_info(fdesc,info) ne 0) then goto,bad_file ; *****read the COMMENT records if (dfget_comment(fdesc,comment) ne 0) then goto,bad_file ; *****read in dimensional stuff if (dfget_gdimens(fdesc,length,dimavg=dimavg,diminfo=diminfo, $ units=unit,vartype=vartype) ne 0) then goto,bad_file ; *****check quantity if (quantity ne vartype) then begin message,/continue,'DESCRIP0.VARTYPE ('+strcompress(vartype,/tmp)+ $ ') is not the same as OBJDESC.VARTYPE ('+ $ strcompress(temporary(quantity),/tmp)+')' goto,bad_file endif ndims = fdesc.ndim1+fdesc.ndim2 ; *****read in BADVAL record if (dfget_badval(fdesc,dum,badval) ne 0) then goto,bad_file badval = badval[0] ; *****read in PROC stuff if (dfget_proc_s(fdesc,procinfo) ne 0) then goto,bad_file ; *****get packing stuff if (dfget_pack_s(fdesc,pakinfo) ne 0) then goto,bad_file ; *****get index of values wanted datfmt = (long(str_parse(fdesc.datfmt,':')))[0] dat = reform(df_make_var(data_typ=datfmt,num=fdesc.dinrec*fdesc.rinfil), $ length[1:fdesc.ndim1+fdesc.ndim2]) ; *****read in data irec = 0L rectype = 0L ; *****read in data from REGDAT records if (fdesc.npacks eq 0) then begin tdat = df_make_var(data_typ=datfmt,num=fdesc.dinrec) while (not(eof(fdesc.lun))) do begin readu,fdesc.lun,rectype,tdat dat[fdesc.dinrec*irec] = tdat[*] irec = temporary(irec)+1L endwhile ; *****read in data from PAKDAT records endif else begin tdat = df_make_var(data_typ=pakinfo.(0).dpakfmt,num=fdesc.dinrec) while (not(eof(fdesc.lun))) do begin readu,fdesc.lun,rectype,tdat dat[fdesc.dinrec*irec] = df_unpkdata_s(fdesc,tdat,length,pakinfo,badval) irec = temporary(irec)+1L endwhile endelse length = length[1:fdesc.ndim1+fdesc.ndim2] ; *****no errors free_lun,fdesc.lun return,0 ; *****errors found bad_file: if (n_elements(lun) gt 0) then free_lun,fdesc.lun return,1 end