FUNCTION MOD08_Reader, MOD08Filename, variableName, start=start, count=count, $ stride=stride, Data=Data, FillValue=FillValue, unit=unit ;............................................................................... ; $Id$ ;............................................................................... ; ; PURPOSE: ; read a data from MOD08 file. The data values are returned via ; keyword Data. ; ; CATEGORY: ; general purpose MOD08 HDF reader ; ; CALLING SEQUENCE: ; iret = MOD08_Reader(MOD08Filename, variableName) ; ; INPUTS: ; MOD08Filename = input filename ; variableName = exact name of a SDS of interest ; ; Optional: ; start = starting position (0 based) for the read. If not set, ; the default starting positions are [0, 0, ....]. ; ; count = number of items or counts to be read. If not set, ; the default count encompass the entire SDS. ; ; stride = sampling intervals, between accessed values of the SDS. ; if not set, the default is set to continous mode. ; ; OUTPUTS: ; Returns an error code, 0 is ok or 1 means failed ; ; Optional: ; Data = calibrated data values ; FillValue = fill/missing value of this SDS ; ; ; ; EXAMPLES: ; 1. read entire Cirrus_Reflectance_Mean data (2-dimensional): ; ; iret = MOD08_Reader("sample.hdf", "Cirrus_Reflectance_Mean", $ ; data=reflectanceMean, FillValue=FillValue) ; ; ; 2. read every other data point: ; ; iret = MOD08_Reader("sample.hdf", "Cirrus_Reflectance_Mean", stride=[1,1], $ ; data=reflectanceMean, FillValue=FillValue) ; ; ; RESTRICTIONS: ; Does not calibrate character or byte type data. In HDF's lingo, ; this includes DFNT_CHAR, DFNT_INT8 and DFNT_UINT8 data types. The ; reason for this is that BYTE type data are flags or masks of some ; sort and should not be calibrated. ; ;............................................................................... ; REVISION HISTORY: ; $Log$ ;............................................................................... ; PROGRAMMER: ; Jason Li (SM&A) ; Climate and Radiation Branch ; NASA Goddard Space Flight Center ; Greenbelt, Maryland 20771 ;............................................................................... errorLevel = 0 ;... Open HDF file and lock on requested SDS: fileHandle = HDF_OPEN(MOD08Filename, /READ ) IF fileHandle LT 1 THEN BEGIN errorLevel = 1 Return, errorLevel ENDIF HDF_CLOSE, fileHandle hdfid = HDF_SD_START(MOD08Filename, /READ) index = HDF_SD_NAMETOINDEX(hdfid,variableName) sdsId = HDF_SD_SELECT(hdfid, index) ;... Gather information about requested SDS: HDF_SD_GETINFO, sdsId, HDF_TYPE = dataType, $ ndims = numberOfDimensions, $ natts = numberOfAttributes, $ dims = dimensionSizes ;... Define the shape of a SDS slab to read: ; starting position (0 based) for the read: rank = N_Elements(start) CASE 1 OF (rank EQ 0): start = Make_Array(numberOfDimensions, value = 0L, /LONG) (rank EQ numberOfDimensions): start = start ELSE: BEGIN errorLevel = 1 print, "[Quit]: wrong number of elements in START" goto, Done END ENDCASE ; number of items or counts to be read: rank = N_Elements(count) CASE 1 OF (rank EQ 0): count = dimensionSizes (rank EQ numberOfDimensions): count = count ELSE: BEGIN errorLevel = 1 print, "[Quit]: wrong number of elements in COUNT" goto, Done END ENDCASE ; sampling intervals, between accessed values of the HDF variable: rank = N_Elements(stride) CASE 1 OF (rank EQ 0): stride = Make_Array(numberOfDimensions, value = 0L, /LONG) (rank EQ numberOfDimensions): stride = stride ELSE: BEGIN errorLevel = 1 print, "[Quit]: wrong number of elements in STRIDE" goto, Done END ENDCASE ;... Read data and its attributes: HDF_SD_GETDATA, sdsId, sdsData, start = start, count = count, stride = stride fillId = -1 scaleId = -1 offsetId = -1 fillValue = -1234567890.0 IF(numberOfAttributes GT 0) THEN BEGIN FOR i = 0, numberOfAttributes - 1 DO BEGIN HDF_SD_ATTRINFO, sdsId, i, name = name CASE name OF 'scale_factor': BEGIN scaleId = HDF_SD_ATTRFIND(sdsId,"scale_factor") HDF_SD_ATTRINFO, sdsid, scaleId, DATA = scale_factor scaleFactor = scale_factor[0] END 'add_offset': BEGIN offsetId = HDF_SD_ATTRFIND(sdsId,"add_offset") HDF_SD_ATTRINFO, sdsid, offsetId, DATA = add_offset addOffset = add_offset[0] END 'units': BEGIN unitsId = HDF_SD_ATTRFIND(sdsId,"units") HDF_SD_ATTRINFO, sdsid, unitsId, DATA = units unit = units[0] END '_FillValue': BEGIN fillId = HDF_SD_ATTRFIND(sdsId,"_FillValue") HDF_SD_ATTRINFO, sdsid, fillId, DATA = fill_value fillValue = fill_value[0] END ELSE: ; null ENDCASE ENDFOR ENDIF ;... calibrate data by applying scale factor and offset if necessary: IF(dataType EQ 'DFNT_CHAR' OR dataType EQ 'DFNT_INT8' OR $ dataType EQ 'DFNT_UINT8') THEN BEGIN data = sdsData ENDIF ELSE BEGIN data = sdsData * 1.0 ; ensure it is floating data type IF fillId NE -1 THEN index = Where(sdsData NE fillValue, ncount) IF ncount gt 0 THEN BEGIN CASE 1 OF (offsetId NE -1 AND scaleId NE -1): $ data[index] = (sdsData[index] - addOffset) * scaleFactor (offsetId NE -1 AND scaleId EQ -1): $ data[index] = sdsData[index] - addOffset (offsetId EQ -1 AND scaleId NE -1): $ data[index] = sdsData[index] * scaleFactor ENDCASE ENDIF ENDELSE HDF_SD_ENDACCESS, sdsid Done: HDF_SD_END, hdfid Return, errorLevel END