c HDF_F_read.f c c DISCLAIMER: This software is provided for users of TRMM data. c TSDIS DOES NOT PROVIDE SUPPORT FOR THIS SOFTWARE. c c The following program demonstrates how TSDIS 1B11 data c can be read via HDF (Heirarchical Data Format) routines. c c Hence we can see the SDS(multi-dimentional array) and Vdata(table) c formats of HDF in the TSDIS data. c c Sample execution: c c HDF_F_read c c It is assumed that a good 1B11 TSDIS data file is being read. program readTMI_01 integer i, retn integer*1 miss_valid(2) integer*2 lowresch(7,104,3000) integer*4 sd_id, sds_id, start(3), stride(3), count(3) integer*4 file_id, vdata_id, n_rec, interlace integer*4 vdata_size character fields * 30 character granule_name * 80 parameter (granule_name = 1 '1B11_CSI.000901.15900.KWAJ.5.HDF') c Function declarations c --------------------- integer hopen, vsfatch, vsfinq, vsfdtch, hclose integer vsfread, vsfsfld, vsffnd integer sfstart, sfselect, sfn2index, sfrdata, sfendacc, sfend integer DFACC_RDONLY parameter (DFACC_RDONLY = 1) c Read Vdata c ---------- c A Vdata can be thought of as a table with each record consisting c of a number of fields which can be of mixed data type including c strings. For TRMM granules, Vdatas typically contain auxillary c information such as data quality rather than the actual algorithm c output which typically is stored in SDSs. Please refer to the c "Interface Control Specification (ICS) Volume 3 document entitled c "File Specifications for TRMM Products - Level 1" (TSDIS-P907) c for information about the TRMM products file structure. c The general technique for accessing data from a Vdata is as c follows: c 1) Open the granule: "hopen". c 2) Start the Vgroup access: "vfstart". c 3) Attach to the desired Vdata: "vsfatch". c 4) Define the particular fields to access: "vsfsfld". c 5) Read the data: "vsfread". c 6) Release the Vdata: "vsfdtch". c 7) End the Vgroup access: "vfend". c 8) Close the granule: "hclose". c To read different fields in the same Vdata simply cycle steps c (4)-(5). c To read data from a different Vdata in the same granule simply c cycle steps (3)-(6). c In this example we read the "missing" and "validity" fields from c the "scan_status_tmi" Vdata in a 1B11 TMI granule. c Step 1: Open granule c --------------------- c The first parameter is the granule name including the directory c path. The "DFACC_RDONLY" parameter (defined in hdf.h) specifies c that the file to be opened is for read-access only. This will c protect the file from being accidently written to. The third c parameter should be set to 0 (trust me). This function returns c the file ID, "file_id". file_id=hopen(granule_name, DFACC_RDONLY , 0) c Step 2: Start Vgroup access c ---------------------------- c Note: Uses "file_id" from hopen. call vfstart(file_id) c Step 3: Attach to Vdata c ------------------------ c The first parameter is simply the "file_id" from hopen. The c "vsffnd" function in the second parameter translates from the Vdata c name: "scan_status_tmi" to a reference number used by the "vsfatch" c function. The third parameter specifies that the Vdata is to be c accessed for reading only. This function returns the vdata ID, c "vdata_id". vdata_id = vsfatch(file_id, vsffnd(file_id,'scan_status_tmi'), 'r') c The "vsfinq" function can be used to get the number of records c in the Vdata table as well as the interlace. An interlace value c of 0 (FULL_INTERLACE default) means that the Vdata is filled c record by record. A value of 1 (NO_INTERLACE) means that the c Vdata is filled field by field. This would proclude further c records being added to an existing Vdata. Vdatas in TRMM HDF c granules typically have the default FULL_INTERLACE. retn = vsfinq(vdata_id, n_rec, interlace, 1 fields, vdata_size, vdata_name) print*, 'Interlace: ', interlace print*, 'Number of records: ', n_rec c Step 4: Define fields to read c ------------------------------ c The first parameter is simply the Vdata ID. The second parameter c is a string of comma-separated field names that are to be read" retn = vsfsfld(vdata_id, 'missing,validity') c Step 5: Read data c ------------------ do i=1,n_rec retn = vsfread(vdata_id, miss_valid, 1, interlace) print*, i, miss_valid(1), miss_valid(2) enddo c Step 6: Detach from Vdata c -------------------------- retn = vsfdtch(vdata_id) c Step 7: End Vgroup access c -------------------------- call vfend(file_id) c Step 8: Close granule c ---------------------- retn = hclose(file_id) c Read SDS c -------- c SDSs typically contain the "large" volume datasets within a c granule. In this example for a 1B11 (TMI) granule this includes c the channel temperatures (scaled), calibration counts and pixel c geolocation. Every element in a given SDS is of the same data c type. HDF provides very flexible access to various elements in c an SDS through the "start", "stride", and "edge" parameters. For c each of the dimensions of an SDS, the user chooses (1) the c element at which to begin ("start"), (2) the number of entries to c increment for the next element ("stride"), and (3) the number of c elements to read along that dimension ("edge"). (Perhaps a c better name for this third choice would be "count".) c The general technique for accessing data from an SDS is as c follows: c 1) Open graunule for SDS access: "sfstart". c 2) Select the desired SDS: "sfselect". c 3) Read the data: "sfrdata". c 4) End access to the SDS: "sfendacc". c 5) Close granule to the SDS access: "sfend". c To read data from a different SDSs in the same granule simply c cycle steps (2)-(4). c Step 1: Open granule for SDS access c ------------------------------------ c The first parameter is the granule name including the directory c path. The "DFACC_RDONLY" parameter (defined in hdf.h) specifies c that the file to be opened is for read-access only. This c function returns the SDS interface ID, "sd_id". Even though SDSs c are part of an HDF file, for historical reasons they require c their own file opening routine, "sfstart". sd_id = sfstart(granule_name, DFACC_RDONLY) c Step 2: Select the desired SDS c ------------------------------- c The first parameter is the SDS interface ID from Step 1. The c second parameter uses the "sfn2index" routine to return the c reference number to the desired SDS, in this case, the (scaled) c low resolution channel temperatures. The "sfselect" function c returns the SDS id. sds_id = sfselect(sd_id, sfn2index(sd_id,'lowResCh')) c Step 3: Read the data c ---------------------- c The first parameter is the SDS id returned from Step 2. The next c three parameters are the "start", "stride", and "edge" (count) c arrays. We will read the entire SDS in this call, therefore, all c elements in the "start" array are set to 0. (Note: SDSs are c 0-based, that is, the first element is designated with a 0.) c Typically, the "stride" elements are set to 1, that is, no c elements along a given dimension are skipped. Finally, we wish to c read all elements for each dimension so we set the "counts" array c to the size of each dimension. The last parameter is the data buffer c into which we read the data. We have dimensioned it to hold up c to 3000 scans, however this function will only fillup the first c "n_rec" scans. start(1) = 0 start(2) = 0 start(3) = 0 stride(1) = 1 stride(2) = 1 stride(3) = 1 count(1) = 7 count(2) = 104 count(3) = n_rec retn = sfrdata(sds_id, start, stride, count, lowresch) c Print channel temperatures for first pixel in the 10th scan c ----------------------------------------------------------- do i=1,7 print*, 'Channel:', i, ' Temperature:', 1 lowresch(i,1,10)/100.0 + 100 enddo c Step 4: End access to SDS c -------------------------- c This ends access to the particular SDS selected in Step 2. retn = sfendacc(sds_id) c Step 4: Close granule to SDS access c ------------------------------------ c This closes the HDF to SDS access for all SDSs in the granule. retn = sfend(sd_id) end