function read_vdata,filename,vdname,vdata_struc ; This function reads the named vdata table from the specified file which is written ; in the HDF format. ; ; INPUT PARAMETERS: ; filename - the full path and file name of the data file containing the vdata to ; be read ; vdname - the name of the vdata table to be read ; ; OUTPUT PARAMETERS ; vdata_struc - the variable in which the vdata records are returned; it is an IDL ; structure variable ; ; KEYWORD PARAMETERS ; none ; ; FUNCTION RETURN VALUE ; A value of 0 is returned if the read operation was successsful; -1 is returned ; in the case of failure. A message dialog box is also displayed to indicate the ; source of the failure. ; ; USAGE EXAMPLES ; ; filename = DIALOG_PICKFILE(TITLE="Select MISR Level 2 Aerosol File") ; read the Time of Observation information ; vdname = "Time of Observations AerosolParameterAverage" ; status = read_vdata(filename,vdname,vdrec_struc) ; ; MODIFICATION HISTORY: ; 5/2006 - updated to handle vector vdata fields ; fid = HDF_OPEN(filename,/READ) if (fid eq -1) then begin msg_text = "Problem opening file " + filename goto, error endif vdref = HDF_VD_FIND(fid,vdname) if (vdref eq 0) then begin msg_text = "Can't find vdata " + vdname + " in file " + filename goto, error endif vdid = HDF_VD_ATTACH(fid,vdref,/READ) if (vdref eq 0) then begin msg_text = "Problem attaching vdata " + vdname goto, error endif HDF_VD_GET,vdid,COUNT=vdnumrec,FIELDS=vdfields,NAME=vdname,NFIELDS=vdnfields vdfieldnames = STRSPLIT(vdfields,',',/EXTRACT) ;print,vdname,vdnumrec,vdnfields ;print,vdfieldnames ; Get information for each field and read the field data. ; Set up a temporary IDL structure using individual structure elements ; to contain the data for each field. This will be built iteratively, adding ; one vdata column at a time, so we can dynamically discover and access the ; contents of the vdata. ; NOTE: by reading the vdata one field at a time, putting each field into a separate ; element of the structure, we don't have to worry about the field data type and the ; the issue of packing and unpacking data that would need to be done when reading ; records from a vdata whose columns are different data types (see the HDF User's ; Guide if you really want to know more about this!) for i=0,vdnfields-1 do begin HDF_VD_GETINFO,vdid,i,NAME=fieldname,ORDER=fieldorder,SIZE=fieldsize,TYPE=fieldtype ;print,"Field Name:",fieldname," Order: ",fieldorder," Type: ",fieldtype," Size: ",fieldsize status = HDF_VD_READ(vdid,fielddata,FIELDS=fieldname) ; there is an issue with character strings being returned with a type of BYTE rather ; than string--HDF_VD_GETINFO returns BYTE even when the field is defined with an HDF ; type of DFNT_CHAR8 ; since this routine is being written to work with MISR data at this point, and in ; all of the MISR vdatas, the UINT8 or true byte fields are scalars and fields whose ; type is returned as BYTE with a length greater than 1 are strings (CHAR8 fields), ; so we'll use that information as a workaround until RSI fixes the returned type for ; CHAR8 data if ((fieldtype eq "BYTE") and (fieldsize gt 1)) then fielddata = string(fielddata) ;print,fielddata ; structure tag names can't contain the period (".") character so substitute an ; underscore ("_") if the fieldname contains a period WHILE (STRPOS(fieldname,'.') ge 0) do STRPUT,fieldname,'_',STRPOS(fieldname,'.') if (i eq 0) then begin vdstruc = CREATE_STRUCT(fieldname,fielddata) ; create the initial structure endif else begin vdstruc = CREATE_STRUCT(fieldname,fielddata,vdstruc) ; create structure, appending previous endelse ; structure endfor numtags = N_TAGS(vdstruc) tags =TAG_NAMES(vdstruc) ; Ok, the temporary structure has components which are arrays, but accessing a record ; or row of the vdata is not convenient in this format. So the structure will be recreated ; so the vdata will become an array of structures, where each structure is one record of ; the vdata. Initally we'll build one record, doing it iteratively so we can dynamically ; create the structure elements to match the vdata. We'll give the structure a name (the ; name of the vdata) when the last component is added. ; create the first record as a new named structure for i=0,numtags-1 do begin sz = size(vdstruc.(i)) case i of 0 : begin if (numtags eq 1) then begin ; only one field in the vdata, so create structure and name it case sz[0] of 0 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i),NAME=vdname) end 1 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[0],NAME=vdname) end 2 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[*,0],NAME=vdname) end else : begin print,"Not handling multi-dimensional vdata elements" end endcase break ; make sure no other case element is matched endif else begin ; just create the structure (name at the end) case sz[0] of 0 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)) end 1 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[0]) end 2 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[*,0]) end else : begin print,"Not handling multi-dimensional vdata elements" end endcase endelse end ; add last tag to structure and name it numtags-1 : begin case sz[0] of 0 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i),vdrecstruc,NAME=vdname) end 1 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[0],vdrecstruc,NAME=vdname) end 2 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[*,0],vdrecstruc,NAME=vdname) end else : begin print,"Not handling multi-dimensional vdata elements" end endcase end ; continue building structure else : begin case sz[0] of 0 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i),vdrecstruc) end 1 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[0],vdrecstruc) end 2 : begin vdrecstruc = CREATE_STRUCT(tags[i],vdstruc.(i)[*,0],vdrecstruc) end else : begin print,"Not handling multi-dimensional vdata elements" end endcase end endcase endfor ; now make an array of those structures, one for each record in the vdata vdata_struc = REPLICATE(vdrecstruc,vdnumrec) ; and populate the records with the data fields read from the vdata and saved in the ; preliminary structure for j=0,numtags-1 do begin vdata_struc.(j) = vdstruc.((numtags-1)-j) endfor HDF_VD_DETACH,vdid HDF_CLOSE,fid return,0 ; error handler error: status = DIALOG_MESSAGE(msg_text,/INFORMATION,TITLE='read_vdata message') vdata_struc = 0 return,-1 end