/************************************************************************** * * * HDF Read Program for these SAGEs I & II Profile Data Sets * * * * SAGE I Aerosol Profiles * * SAGE II Aerosol Profiles * * SAGE II Ozone Profiles (O3) * * SAGE II Nitrogen Dioxide Profiles (NO2) * * SAGE II Water Vapor Profiles (H2O) * * * * Version 7.0 January 26, 1999 * * * * HDF Library: Version 4.4r2 * * * * NOTE: When you compile this program, make sure you include the HDF * * library path. The compile program that can also be used to * * build this read program is called compile_read_sage. * * * * * * 08/10/1994 Modifications were made to the code to make the report file * * more readable for the user. The following modifications were * * done: * * (1) Currently, the Langley DAAC has three of the seven exper- * * iments on-line, therefore, this read program has been tested * * for the three experiments. If another option is selected, * * then the program will terminate with an error message. * * (2) Instead of printing out the annotation labels onto the * * screen, now the program is printing out the data labels which * * are more explicit. * * (3) The term Geometric Altitude was replaced with Minimum Alt.* * where event information is printed for every event in the * * report file. The value printed here is actually the first * * value in the Geometric Altitude set of data for each event. * * (4) The code which prints out Dimension information has been * * suppressed. If the user wishes to print this information in * * the report file, just remove the comments. * * (5) In the selection section of the code, it prompts the user * * to enter zero to quit. This option has been changed to say * * enter zero to begin retrieving the data. * * (6) Insert leading zeroes in the EventDate and EventTime so * * that these two data values will always print out six positions* * of data. * * (7) Remove a print statement that was used by the programmer. * * (8) Have the capability to change your selections of which * * parameters to retrieve data. * * (9) This code was compiled with the ANSI C compiler which * * means this this code follows the ANSI C standards. Minor * * modifications were made to make this code ANSI C. * * * * 08/17/1994 Modifications were made in the function, Print_data_info, * * where the data use to only work with 32-bit numbers but now * * the program is capable of working with 16-bit integers and * * 8-bit integers. * * Added the capability to work with the bit flags for ozone * * data. * * 09/02/94 Added the option to quit or if entered an incorrect value, the* * the code would not abort. * * * * 11/28/1994 The program has been modified to read a new data set SAGE II* * Nitrogen Dioxide (NO2) Profiles. * * * * 12/23/1994 Added the option to allow the user to ask to print out all * * of the data parameters without having to enter every parameter* * value. * * * * 05/08/1995 Added options to read SAGE II Water Vapor Profiles to code. * * * * 10/31/1995 Modified dates to more current year dates. * * * * 10/07/1996 Modified code to bring code up to HDF 3.3r4 ANSI standards. * * * * 01/26/1999 Modified the code to be able to compile with the latest * * version of the HDF libraries, Version 4.1r2. * * * * Contact Information: If you have any questions, please contact: * * Langley DAAC User and Data Services * * NASA Langley Research Center * * Mail Stop 157D * * Hampton, VA 23681-2199 * * U.S.A. * * * * Telephone: (757)864-8656 FAX: (757)864-8807 * * E-mail: larc@eos.nasa.gov * * * ***************************************************************************/ /* Must include for C calls in program */ #include /* C library */ #include /* C library */ #include /* C library */ /* HDF requires this include file to be written into the C code */ #include "hdf.h" /* Define global variables used in code */ #define DFACC_read 1 /* HDF position */ #define LISTSIZE 175 #define MAXCHAR 132 /* Maximum number of characters in a string */ #define MAXDATA 65100 /* Max # of events (930) times Max # of data */ /* values per parameter (70) */ #define MAXLABLEN 256 /* Max string label length */ #define MAXLEN 10000 /* Maximum length of file description */ #define MAXLNG 55 /* Max number of labels */ #define MAXRANK 2 /* Max number of dimensions */ #define NumEventPar 6 /* Number of parameter values printed at each event */ main () { /* Begin main function */ void Greetings(); /* Declare function */ void Assign_rpt_name(); /* Declare function */ void Read_data_descript(); /* Declare function */ void Test_exp(); /* Declare function */ void Get_data_types(); /* Declare function */ int Print_data_info(); /* Declare function */ void Read_data(); /* Declare function */ int exp, /* Store type of experiment */ num_events = 0; /* Stores the number of events */ unsigned short int dataitems[LISTSIZE], /* Store reference number of labels */ ref_num[19]; /* Stores event information */ char yesno[2], /* Stores yes/no number for printing header information */ hdfname[MAXCHAR], /* Stores input data file name */ info[MAXCHAR], /* Used as a temporary string buffer */ outfile[MAXCHAR]; /* Stores output report file name */ FILE *ofp; /* Pointer for output report file */ /**********************************/ /* Main function begins */ /**********************************/ (void) Greetings(); printf("\n\n"); printf("This is a list of all SAGE experiments.\n\n"); printf(" 1. SAGE I Aerosol Profiles\n"); printf(" 2. SAGE II Aerosol Profiles\n"); printf(" 3. SAGE II Ozone Profiles\n"); printf(" 4. SAGE II Nitrogen Dioxide Profiles\n"); printf(" 5. SAGE II Water Vapor Profiles\n"); printf("\n"); printf("Enter type of experiment (1 thru 5) ... "); scanf("%s",info); exp = atoi(info); (void) Test_exp (exp); printf("\n\n"); printf("Enter the full data path as well as the data name.\n"); scanf("%s",info); strcpy(hdfname,info); printf("\n\n"); printf("In your output report file, do you want to include the \n"); printf("file description? Enter 1 for yes and 2 for no .... "); scanf("%s",info); strcpy(yesno,info); /* Create an output report file name. */ (void) Assign_rpt_name (outfile, hdfname); ofp = fopen (outfile, "wt"); if (ofp == NULL) { printf("*********************************************\n"); printf("* ERROR - Not able to open the output file, *\n"); printf("* %s. *\n",outfile); printf("* Program has terminated. *\n"); printf("*********************************************\n"); exit ( -1 ); } /* Reads the data file description from HDF file and writes */ /* it out to the output report file. */ (void) Read_data_descript (hdfname, ofp, yesno); /* Allows the user to select the parameters to be written */ /* out to the output report file. */ (void) Get_data_types (ofp, hdfname, dataitems, ref_num); /* Print selected data information and output to report file */ num_events = Print_data_info (ofp, hdfname, dataitems, ref_num); printf("\n\n"); printf("There are %d records/number of events in the HDF file.\n",num_events); printf("NOTE: This will take some time to write out the report file.\n"); /* Read selected data and output to report file */ (void) Read_data (ofp, hdfname, dataitems, ref_num, num_events, exp); /* Print out End of File message onto the screen. */ printf("\n\n"); printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); printf("@ @\n"); printf("@ This program has completed and has created an output report @\n"); printf("@ file called %s in your current @\n",outfile); printf("@ working directory. @\n"); printf("@ @\n"); printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); printf("\n\n"); } /* End main function */ /**************************************************************************** * * * FUNCTION: Greetings * * * * PURPOSE: To print a banner at the beginning of the execution to inform * * the users what version of this read program he or she is * * working with. * * * ****************************************************************************/ void Greetings() { /* Begin Greetings function */ printf("\n\n\n"); printf(" *****************************************************\n"); printf(" * *\n"); printf(" * SAGEs I & II HDF Read Program Version 7.0 *\n"); printf(" * *\n"); printf(" * *\n"); printf(" * This sample read program currently reads the *\n"); printf(" * following data sets: *\n"); printf(" * *\n"); printf(" * SAGE I Aerosol Profiles *\n"); printf(" * SAGE II Aerosol Profiles *\n"); printf(" * SAGE II Ozone Profiles *\n"); printf(" * SAGE II Nitrogen Dioxide Profiles *\n"); printf(" * SAGE II Water Vapor Profiles *\n"); printf(" * *\n"); printf(" * *\n"); printf(" * January 26, 1999 *\n"); printf(" *****************************************************\n"); printf("\n\n\n"); } /* End of Greetings function */ /**************************************************************************** * * * FUNCTION: Assign_rpt_name * * * * PURPOSE: Creates a report filename for the appropriate experiment. * * * ****************************************************************************/ void Assign_rpt_name (outfile, hdfname) char *outfile, *hdfname; { strcpy(outfile,hdfname); strcat(outfile,".rpt"); } /* End of function, Assign_rpt_name. */ /**************************************************************************** * * * FUNCTION: Read_data_descript * * * * PURPOSE: Opens input HDF file, reads the file description, and prints * * the file description to the report file if the user desires to * * have it printed. * * * ****************************************************************************/ void Read_data_descript (hdfname, ofp, yesno) char *hdfname; FILE *ofp; char *yesno; { int dfile, iret; char id[MAXLEN], filedesc[MAXLEN]; /* Open HDF input file using HDF user commands. */ dfile = Hopen(hdfname, DFACC_read, 0); if (dfile == NULL) { printf("************************************************\n"); printf("* ERROR - Not able to open the HDF input file. *\n"); printf("* Program has terminated. *\n"); printf("************************************************\n"); exit ( -1 ); } /* Get file id from HDF input file. */ iret = DFANgetfid (dfile, id, MAXLEN, 1); if (iret == -1) { printf("************************************************\n"); printf("* ERROR - Not able to get file id from the HDF *\n"); printf("* input data file. *\n"); printf("* Program has terminated. *\n"); printf("************************************************\n"); exit ( -1 ); } /* Get file description from HDF input file. */ iret = DFANgetfds(dfile, filedesc, MAXLEN, 1); if (iret == -1) { printf("**************************************************\n"); printf("* ERROR - Error in getting file description from *\n"); printf("* the HDF input data file. *\n"); printf("* Program has terminated. *\n"); printf("**************************************************\n"); exit ( -1 ); } else { if (atoi(yesno) == 1) { fprintf(ofp,"%s\n%s\n\n","File ID: ",id); fprintf(ofp,"%s\n\n%s","File description is as follows:",filedesc); fprintf(ofp,"\n\n"); } } } /* End of function, Read_data_descript. */ /***************************************************************************** * * * FUNCTION: Test_exp * * * * PURPOSE: This function checks to see if the experiment the user has * * entered is a valid choice. If it is not, the program exits. * * * *****************************************************************************/ void Test_exp(exp) int exp; { if (exp < 1) { printf("****************************************************\n"); printf("* ERROR - Numbers one thru five are valid input. *\n"); printf("* Program has terminated. *\n"); printf("****************************************************\n\n"); exit ( -1 ); } else if (exp > 5) { printf("****************************************************\n"); printf("* ERROR - Numbers one thru five are valid input. *\n"); printf("* Program has terminated. *\n"); printf("****************************************************\n\n"); exit ( -1 ); } } /* End of function, Test_exp */ /**************************************************************************** * * * FUNCTION: Get_data_types * * * * PURPOSE: This function prints out all of the parameters within the data * * file (HDF) and allows the user to select which parameters he * * or she wishes to see. Only the first six parameters in the * * string called EventStr will automatically be printed to the * * report file. Geometric Altitude will be printed in the event * * information as well as the user being able to select it. * * * ****************************************************************************/ void Get_data_types(ofp, hdfname, dataitems, ref_num) FILE *ofp; char *hdfname; unsigned short int dataitems[LISTSIZE]; unsigned short int ref_num[NumEventPar]; { static char *EventStr = {"Event Date (yymmdd.0) Event Time (hhmmss.0) Subtangent Latitude Subtangent Longitude Event Type (0.0 = sunrise, 1.0 = sunset) Geometric Altitude "}; static char *EventStrNO2 = {"Event Date (yymmdd.0) Event Time (hhmmss.0) Subtangent Latitude Subtangent Longitude Event Type (1.0 = sunset) Geometric Altitude "}; int nlabels, itemnumber, startpos; int cnt0, cnt1, cnt2, cnt3; unsigned short int reflist[LISTSIZE]; int index[LISTSIZE]; int numchoices; char labellist[LISTSIZE * MAXLNG + 1]; char datalabellist[MAXLNG][MAXLABLEN]; /* 08/10/94 */ int datalabelval[MAXLNG]; /* 08/10/94 */ int datacount; /* 08/10/94 */ char yesno[2]; /* 08/10/94 */ int iret, numdims, numtype; int32 dimsize[MAXRANK]; char datalabel[MAXLABLEN], dataunit[MAXLABLEN], datafmt[MAXLABLEN], datacoord[3]; char dimlab[2][40], dimunt[30], dimfmt[5]; char all_flag[2]; TRYAGAIN: /* 08/10/94 */ cnt0 = 0; cnt2 = 1, cnt3 = 0; startpos = 1; numchoices = 0; /* initialize dataitems array */ for (cnt1 = 0; cnt1 < LISTSIZE; cnt1++) { dataitems[cnt1] = 65535; reflist[cnt1] = 0; index[cnt1] = 0; }/* end of for */ for (cnt1 = 0; cnt1 "); scanf("%s",all_flag); if ((strcmp(all_flag,"Y")==0) || (strcmp(all_flag,"y")==0) ) { for (cnt1=1; cnt1 <= numchoices; cnt1++) { itemnumber = index[cnt1 - 1]; dataitems[cnt0] = reflist[itemnumber]; datalabelval[cnt0] = itemnumber; cnt0++; } } else { /* print labels in groups of 15 to ask for users input */ for (cnt1 = 0; cnt1 < numchoices; ++cnt1) { if (cnt2 == 1) { itemnumber = 1; printf(" Item Number Label\n\n"); }/* end of if */ /* 08/10/94 Modified this line of code so that the data labels would */ /* be printed onto the screen instead of the annotation labels. The */ /* data labels contain more information in them compared to the */ /* annotation label. This was changed at the request of the data */ /* producer. */ /* printf(" %3d %s\n", cnt1 + 1, labellist + (index[cnt1] * MAXLNG)); */ printf(" %3d %s\n", cnt1 + 1, datalabellist[cnt1]); cnt2++; if (cnt2 > 15 || cnt1 == numchoices - 1) { printf("\nPlease choose the numbers of the data items you wish to output.\n"); printf("Enter -1 to continue to next list or 0 to begin processing.\n\n"); while (itemnumber != 0 || itemnumber != -1) { /* read the user's selection */ scanf("%d", &itemnumber); /* If user's selection equals -1, then */ /* display 15 more parameters. */ if (itemnumber == -1) break; /* If the user's selection equals 0, then */ /* the user has finished his/her selection */ /* and we can return to the calling routine. */ if (itemnumber == 0) { /* At this time, the code will print out the list of parameters */ /* the user has selected. At this time, the user has the option */ /* to continue with the program or re-enter in his selection. */ printf("\n\n\n"); printf("The following is a list of the parameters you have selected:\n\n"); for (datacount = 0; datacount < cnt0; datacount++) { printf(" %d %s\n",datalabelval[datacount]+1,datalabellist[datalabelval[datacount]]); } printf("\n\n"); printf("Would you like to make a new selection of these parameters or\n"); printf("would you like this program to exit the selection process and\n"); printf("begin retrieving the data? \n"); printf("Enter Y for yes to retrieve data or N for no make a new selection. --> "); scanf("%s",yesno); if (strcmp(yesno,"N")==0) goto TRYAGAIN; else if (strcmp(yesno,"n")==0) goto TRYAGAIN; else printf("\n\n"); dataitems[cnt0] = 0; return; } else { /* If the user's selection is not -1 or 0, */ /* then they have selected a parameter and */ /* we will add the reference number for */ /* that parameter to the dataitems array. */ itemnumber = index[itemnumber - 1]; dataitems[cnt0] = reflist[itemnumber]; datalabelval[cnt0] = itemnumber; cnt0++; }/* end of else */ }/* end of while */ cnt2 = 1; }/* end of if (cnt2 > 15 || cnt1 == numchoices - 1) */ }/* end of for */ }/* end of outside else */ dataitems[cnt0] = 0; return; }/* end of Getdatatypes */ /**************************************************************************** * * * FUNCTION: Print_data_info * * * * PURPOSE: This function prints out all of the label information for those* * parameters that the user has just selected. * * * ****************************************************************************/ int Print_data_info(ofp, hdfname, dataitems, ref_num) FILE *ofp; char *hdfname; unsigned short int dataitems[LISTSIZE]; unsigned short int ref_num[NumEventPar]; { int winst[MAXRANK], windims[MAXRANK], winend[MAXRANK]; int dims[MAXRANK], ref_dims[MAXRANK]; int i, j, k, l, iret; int numdims, rnumdims; int32 dimsize[MAXRANK], numtype; int index, event; char datalabel[MAXLABLEN], dataunit[MAXLABLEN]; char datafmt[MAXLABLEN], datacoord[3]; char dimlab[2][40], dimunt[30], dimfmt[5]; float data[MAXDATA]; float ref_data[MAXDATA]; float max, min; int num_events; int16 max16, min16; int8 max8, min8; uint16 umax16, umin16; /* according to reference numbers go to next data set */ printf("\n\nReading labels....\n"); k = 0; while (dataitems[k] != 0) { iret = DFSDreadref(hdfname, dataitems[k]); if (iret == -1) { printf("***********************************************\n"); printf("* ERROR - Not able to get specified reference *\n"); printf("* number %d. *\n",dataitems[k]); printf("***********************************************\n"); exit ( -1 ); } /* get dimensions of SDS */ iret = DFSDgetdims(hdfname, &numdims, dimsize, MAXRANK); if (iret != 0) { printf("***************************************\n"); printf("* ERROR - Not able to get dimensions. *\n"); printf("* Program has terminated. *\n"); printf("***************************************\n"); exit ( -1 ); } else { /* 08/09/94 */ /* The data producer has asked to comment this line out. Please feel */ /* free to remove these comments to print out the dimensions of the */ /* parameters in the output report file. */ /* fprintf(ofp, "\n\nDimensions are %d by %d\n\n", dimsize[0], dimsize[1]); */ num_events = dimsize[1]; }/* end of else */ /* get number type */ iret = DFSDgetNT(&numtype); if (iret != 0) { printf("**********************************************\n"); printf("* ERROR - Not able to get DFSDgetNT numtype. *\n"); printf("* Program has terminated. *\n"); printf("**********************************************\n"); exit ( -1 ); } /* Print message indicating there are no dimension scales */ fprintf(ofp, "*** There are no dimension scales for this data set. ***\n\n"); /* set up slice dimensions */ /* no subsetting required */ winst[0] = 1; winst[1] = 1; windims[0] = dimsize[0]; windims[1] = dimsize[1]; dims[0] = windims[0]; dims[1] = windims[1]; /* Print dimension attributes */ for (l = 1; l <= numdims; l++) { iret = DFSDgetdimstrs(l, dimlab[l - 1], dimunt, dimfmt); if (iret != 0) { printf("*************************************************\n"); printf("* ERROR - Not able to get dimension attributes. *\n"); printf("* Program has terminated. *\n"); printf("*************************************************\n"); exit ( -1 ); } else { fprintf(ofp, "%s%s\n%s%s\n%s%s\n\n", "Description : ", dimlab[l - 1], "Units : ", dimunt, "Format : ", dimfmt); } } /* get data attributes */ iret = DFSDgetdatastrs(datalabel, dataunit, datafmt, datacoord); if (iret != 0) { printf("********************************************\n"); printf("* ERROR - Not able to get data attributes. *\n"); printf("* Program has terminated. *\n"); printf("********************************************\n"); exit ( -1 ); } else { /* Print the data attributes */ fprintf(ofp, "Data attributes are as follows:\n\n"); fprintf(ofp, "%s%s\n%s%s\n%s%s\n\n", "Label : ", datalabel, "Units : ", dataunit, "Format: ", datafmt); } /* Get data max and min values */ switch (numtype) { case DFNT_FLOAT32: iret = DFSDgetrange((void *)&max, (void *)&min); if (iret == -1) { printf("*******************************************\n"); printf("* ERROR - Not able to get 32-bit data max *\n"); printf("* and min values. *\n"); printf("* Program has terminated. *\n"); printf("*******************************************\n"); exit ( -1 ); } else { /* print the data max and mins */ fprintf(ofp, "%s%.8f\n", "Data Max: ", max); fprintf(ofp, "%s%.8f\n\n", "Data Min: ", min); } break; case DFNT_UINT16: iret = DFSDgetrange((void *)&umax16,(void *)&umin16); if (iret == -1) { printf("*******************************************\n"); printf("* ERROR - Not able to get 16-bit data max *\n"); printf("* and min values (unsigned). *\n"); printf("* Program has terminated. *\n"); printf("*******************************************\n"); exit ( -1 ); } else { /* print the data max and mins */ fprintf(ofp, "%s%x\n", "Data Max: ", umax16); fprintf(ofp, "%s%x\n\n", "Data Min: ", umin16); } break; case DFNT_INT16: iret = DFSDgetrange((void *)&max16,(void *)&min16); if (iret == -1) { printf("*******************************************\n"); printf("* ERROR - Not able to get 16-bit data max *\n"); printf("* and min values. *\n"); printf("* Program has terminated. *\n"); printf("*******************************************\n"); exit ( -1 ); } else { /* print the data max and mins */ fprintf(ofp, "%s%d\n", "Data Max: ", max16); fprintf(ofp, "%s%d\n\n", "Data Min: ", min16); } break; case DFNT_INT8: iret = DFSDgetrange((void *)&max16,(void *)&min16); if (iret == -1) { printf("******************************************\n"); printf("* ERROR - Not able to get 8-bit data max *\n"); printf("* and min values. *\n"); printf("* Program has terminated. *\n"); printf("******************************************\n"); exit ( -1 ); } else { /* print the data max and mins */ fprintf(ofp, "%s%d\n", "Data Max: ", max8); fprintf(ofp, "%s%d\n\n", "Data Min: ", min8); } break; default: exit ( -1 ); break; } k++; fprintf(ofp, "\n\n"); }/* end of while */ return (num_events); } /* End of function, Print_data_info. */ /**************************************************************************** * * * FUNCTION: Read_data * * * * PURPOSE: This function prints out all of the data for those parameters * * the user has just selected. * * * ****************************************************************************/ void Read_data(ofp, hdfname, dataitems, ref_num, num_events, exp) FILE *ofp; char *hdfname; unsigned short int dataitems[LISTSIZE]; unsigned short int ref_num[NumEventPar]; int num_events; int exp; { int32 winst[MAXRANK], windims[MAXRANK], winend[MAXRANK]; int32 dims[MAXRANK], ref_dims[MAXRANK]; int ii, i,j, k, l, iret; int numdims, rnumdims; int32 dimsize[MAXRANK], numtype; int index, event,firstevent; char datalabel[MAXLABLEN], dataunit[MAXLABLEN]; char datafmt[MAXLABLEN], datacoord[3]; char dimlab[2][40], dimunt[30], dimfmt[5]; float data[MAXDATA]; float ref_data[MAXDATA]; float max, min; char stringdate[7], stringtime[7]; /* 08/10/94 */ uint16 udata16[MAXDATA],uref_data16[MAXDATA],umax16,umin16; int16 data16[MAXDATA],ref_data16[MAXDATA],max16,min16; int8 data8[MAXDATA],ref_data8[MAXDATA],max8,min8; int16 temp; /* According to reference numbers go to next data set */ printf("\n\nReading data, Please wait ...\n"); /* print out message for data arrangement */ fprintf(ofp, "Data is printed from left to right in event order.\n\n\n\n"); for (ii=0; ii