/************************************************************/ /* This program is built in a single file, with the */ /* help of the accompaning makefile (also included */ /* in the source file). */ /* */ /* Two lines in the makefile may need to be change */ /* to reflect the address of the HDF include files */ /* and the HDF library file. */ /* CFLAGS = -DSUN -I/usr1/hdf/HDF3.3r3/include -O */ /* OBJECTS = rds4gnshdf.o */ /* rds4gnshdf: $(OBJECTS) */ /* cc -o $@ $(OBJECTS) /usr1/hdf/HDF3.3r3/lib/libdf.a */ /************************************************************/ /* VERSION 2.0 Date: 06/02/94 Programmer: Langley DAAC VERSION 2.1 Date: 07-11-94 Programmer: Langley DAAC VERSION 2.2 Date: 07-13-94 Programmer: Langley DAAC VERSION 2.3 Date: 07-26-94 Programmer: Langley DAAC VERSION 2.4 Date: 08-05-94 Programmer: Langley DAAC * 06/02/94 The longitude values which are stored in the S-4G HDF files are being stored from -180 to 180 where as the data is being stored from 0 to 360 degrees. !!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!! The longitude values in the data files have not been corrected. Only this read program has been modified to correct this presentation of the data. This is only affected when a user selects data from a latitude/longitude option. If the user decides to use an outside piece of software which depends on these latitude/longitude values, please ignore these values. 07-11-94 When presenting the parameter names to the user to make a selection of which parameters to read, the incorrect term was being printed out following each parameter name. I am referring to the Zonal/Global terms. 07-11-94 Reworded user request statements. 07-26-94 The minimum and maximum values are incorrect within the HDF data files for the longwave and shortwave parameters. So that the user would not get this information from the data file, the print lines for this information have been commented out in this code. For the correct values for all parameters, please refer to the ERBE S-4G User's Guide. 08-05-94 It was recomended to change the start the count at 1 instead of 0 when printing out values in the report file. There is no Band or Region number that starts its count at 0. ***********************************************************************/ #ifndef S4GNREAD_H #define S4GNREAD_H #include #include #include #include #define LABEL_LEN 45 #define COLUMNS 5 #define SCREEN_LINES 15 #define ONE_GROUP 0x001 #define TWO_GROUP 0x002 #define THREE_GROUP 0x004 #define FIVE_DEG 0x010 #define TEN_DEG 0x020 #define REGIONAL 0x100 #define ZONAL_GLOBAL 0x200 #define NF5 REGIONAL | FIVE_DEG | ONE_GROUP #define NF10 REGIONAL | TEN_DEG | ONE_GROUP #define NFZG ZONAL_GLOBAL | TEN_DEG | THREE_GROUP #define SF10 REGIONAL | TEN_DEG | ONE_GROUP #define SFZG ZONAL_GLOBAL | TEN_DEG | TWO_GROUP #define NUM_REGIONS_5 180 * 360 / 25 #define NUM_REGIONS_10 180 * 360 / 100 #define MAX_RANK 2 struct area { int ulh; int ulv; int lrh; int lrv; int start; int stop; }; typedef struct area Area; void DumpSelectList PROTO((char *Labels, int Start, int32 NLabels, int FType)); void FinishError PROTO((FILE * RFile, char *DataLabel, uint16 * RefList, int Index)); char *GetDataFileName PROTO((void)); int32 GetDataLabels PROTO((char * FName, char **DLabels, uint16 ** RefList)); int GetFileData PROTO((char *FName, FILE * RFile)); int GetFileType PROTO((char *FileName)); int GetSubSet PROTO((int FType, Area * Region)); void PrintRegions PROTO((FILE * RFile, Area * Region, int RowLength, void *Data, int32 ScaleFactor, int NumType)); void PrintReport PROTO((char *DSelect, int32 NumLabels, Area * Region, char *DLabels, uint16 * Reflist, char *FName, FILE * RFile, int FType)); void PrintValue PROTO((FILE * RFile, void *Data, int Offset, int32 ScaleFactor, int32 NumType)); void SelectHelp PROTO((void)); char *SelectSDS PROTO((char *DLabels, int32 NumLabels, int FType)); int WriteByte PROTO((FILE * RFile, char *FName, Area * Region, int NumDims, int32 * ArrayDims, int FileType, int32 ScaleFactor)); int WriteDimensions PROTO((FILE *RFile, int numtype, int numdims, int32 *arrydims, int FType)); int WriteDoubleWord PROTO((FILE * RFile, char *FName, Area * Region, int NumDims, int32 * ArrayDims, int FileType, int32 ScaleFactor)); int WriteWord PROTO((FILE * RFile, char *FName, Area * Region, int NumDims, int32 * ArrayDims, int FileType, int32 ScaleFactor)); void WriteZonalGlobal PROTO((FILE * RFile, void *Data, int Offset, int32 ScaleFactor, int32 NumElem, int NType)); int main PROTO((void)); #endif /************************************************************************** ** Name - int main() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** A basic program driver. It is intended to get things done, as a ** supervisor will, not by actually doing the work, but making sure ** the work gets done. ** ** Output Files - ** The report file that will contain all the data the user has requested ** from the HDF file. ** ** Input Parameters - ** NONE ** ** Output Parameters - ** NONE ** ** Key Local Parameters - ** For a discussion of the key local parameters, please see the comments ** in the body of the function. ** ** Subroutines Called - ** GetDataFileName() : To get input from the user and build a HDF file name. ** GetFileType() : To inspect the filename and determine the type of data ** GetFileData() : To extract from the HDF file, data about the file ** GetDataLabels() : To get from the HDF file the list of SDS data labels. ** SelectSDS() : Get the user to tell us what data he wishes from the HDf file. ** GetSubSet() : Let the user tell us what portion of the SDS he wishes. ** PrintReport() : After all that, put the results to a file. ** sprintf() : Standard 'C' Library function ** printf() : Standard 'C' Library function ** fopen() : Standard 'C' Library function ** fclose() : Standard 'C' Library function ** free() : Standard 'C' Library function ** ** Exit States - ** 0 : Success ** 1 : Failure, for some reason ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif int main() { FILE *rfile; /* The report file */ char rname[32]; /* The place to hold the report file name */ char *filename; /* The name of the HDF data file */ char *dlabels; /* The array of data labels extracted from the HDF file */ uint16 *reflist; /* The array of references extracted from the HDF file */ char *dselect; /* The array of desired data items. */ char *rselect; /* The array of desired data regions */ int32 numlabels; /* The number of labels/SDSs found in the data file */ int ftype; /* Flag word indicating the type of input data file we have */ Area region; /* To hold definition of area to be extractd */ int iret = 1; memset(®ion, 0x00, sizeof(Area)); /* Need to tell the user where he is */ puts("Welcome to the S-4G Nonscanner HDF data read program.\n\n\n"); printf(" *******************************************************************\n"); printf(" * *\n"); printf(" * S-4G HDF NONSCANNER READ PROGRAM *\n"); printf(" * *\n"); printf(" * *\n"); printf(" * Version 2.4 August 08, 1994 *\n"); printf(" * *\n"); printf(" * NOTE TO THE USER!!!!! *\n"); printf(" * FOR YOUR INFORMATION AS HOW THE DATA HAS BEEN STORED IN THE *\n"); printf(" * S-4G HDF FILE, LATITUDE VALUES AND LONGITUDE VALUES HAVE *\n"); printf(" * BEEN ADDED TO THE INPUT FILE. PLEASE IGNORE THESE VALUES *\n"); printf(" * WHEN USING OTHER HDF PACKAGES BECAUSE THESE NUMBERS WILL NOT *\n"); printf(" * REPRESENT THE DATA CORRECTLY. THIS READ PROGRAM HAS BEEN *\n"); printf(" * MODIFIED TO HANDLE THESE VALUES. IF YOU HAVE ANY QUESTIONS, *\n"); printf(" * PLEASE FEEL FREE TO CONTACT THE LANGLEY DAAC. *\n"); printf(" * THE WAY THAT THE LATITUDE AND LONGITUDE VALUES ARE STORED IN *\n"); printf(" * THE DATA FILE WILL NOT HAVE ANY MEANING OR REPRESENT THE *\n"); printf(" * DATA CORRECTLY IN OUTSIDE SOFTWARE PACKAGES. *\n"); printf(" * *\n"); printf(" * 07-26-94 THE MINIMUM AND MAXIMUM VALUES ARE INCORRECT WITHIN*\n"); printf(" * THE HDF DATA FILES FOR THE LONGWAVE AND SHORTWAVE PARAMETERS.*\n"); printf(" * SO THAT THE USER WOULD NOT GET THIS INFORMATION FROM THE *\n"); printf(" * DATA FILE, THE PRINT LINES FOR THIS INFORMATION HAVE BEEN *\n"); printf(" * COMMENTED OUT IN THIS CODE. FOR THE CORRECT VALUES FOR ALL *\n"); printf(" * PARAMETERS, PLEASE REFER TO THE ERBE S-4G USER'S GUIDE. *\n"); printf(" * PLEASE IGNORE THESE VALUES WHEN USING OUTSIDE SOFTWARE *\n"); printf(" * PACKAGES! *\n"); printf(" * *\n"); printf(" * *\n"); printf(" *******************************************************************\n"); if ((filename = GetDataFileName()) != NULL) { /* Get the type of file we are dealing with. */ /* If we are returned a zero, then the file */ /* name is undefined and we are sunk */ if ((ftype = GetFileType(filename)) != 0) { /* create the report file name */ /* and open the file */ sprintf(rname, "%s.rpt", filename); printf("\n\nThe generated report will be written to \"%s\"\n", rname); if ((rfile = fopen(rname, "w")) != NULL) { /* Now, go get the file specific data, like the */ /* data label strings. */ /* Need to free the memory pointed to by dlabels */ /* because nobody else will. */ if (GetFileData(filename, rfile) == 1) { if ((numlabels = GetDataLabels(filename, &dlabels, &reflist)) != 0) { if ((dselect = SelectSDS(dlabels, numlabels, ftype)) != NULL) { if (GetSubSet(ftype, ®ion) != 0) { PrintReport(dselect, numlabels, ®ion, dlabels, reflist, filename, rfile, ftype); iret = 0; }/* end of if */ free(dselect); }/* end of if */ if (dlabels != NULL) { free(dlabels); dlabels = NULL; }/* end of if */ if (reflist != NULL) { free(reflist); reflist = NULL; }/* end of if */ printf("\n\nThe generated report will be written to \"%s\"\n", rname); }/* end of if */ }/* end of if */ fclose(rfile); }/* end of if */ /* Must be done because GetDataFileName() requested */ /* this resources from the operating system. */ free(filename); }/* end of if */ }/* end of if */ return (0); }/* end of main */ /************************************************************************** ** Name - (char *)GetDataFileName Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** Extract from the user the information needed to determine ** the name of the required data file, check to see if the ** file exists and returning that file name to the calling ** function. ** ** Output Parameters - ** A pointer to the validated data granule file. ** ** Key Local Parameters - ** ** Subroutines Called - ** printf() : Standard 'C' Library I/O routine ** sprintf() : Standard 'C' Library I/O routine ** scanf() : Standard 'C' Library I/O routine ** malloc() : Standard 'C' Library memory allocation routine ** free() : Standard 'C' Library memory deallocation routine ** strcmp() : Standard 'C' Library string manipulation routine ** ** Exit States - ** If successful, a pointer to the validated data granule file. ** If not successful, NULL. ** ** Restrictions - ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif char *GetDataFileName() { int count; /* Just a counter */ int gooddata; /* Flag to indicate whether the user has given us good data */ char fov[8]; /* Place to hold the Field of View string */ char proctype[8]; /* Place to hold the process type string */ char resolution[8]; /* Place to hold the resolution string */ char datadate[8]; /* Place to hold the date of the data */ char satcode[8]; /* Place to hold the sat code */ char *filename = NULL; /* Pointer to allocated memory holding the constructe file name */ printf("The name of the HDF file must conform to the standards\n"); printf("developed by NASA/Langley for HDF granule ids.\n"); printf("If your HDF files fail to conform, this program will\n"); printf("not perform as intended.\n\n"); /* Need to introduce ourself and let him/her know */ /* the options */ printf("In all of the following questions,\ncase of your response is not important.\n"); printf("In addition, if you wish to abort \nyou may enter an 'a' at any query\n\n"); /* Until the user gives us a valid response we will keep */ /* asking him for the required data */ do { /* Get the field of view parameter */ printf("There are two types of field-of-view, (W)ide Field-of-View or (M)edium Field-of-View.\n"); printf("Enter Field-of-View. --> "); scanf("%s", fov); } while (*fov != 'm' && *fov != 'w' && *fov != 'a'); /* Did the user abort on us? */ if (*fov != 'a') { do { /* Need to know what kind of data the user wants from us */ /* numeric filtered or shape factored */ printf("\nS-4G Nonscanner data comes in two types, (N)umerical Filter, (S)hape Factor.\n"); printf("Enter type of data. --> "); scanf("%s", proctype); /* We only need the first character, so make the string */ /* the right length */ *(proctype + 1) = NULL; *proctype = tolower(*proctype); } while (*proctype != 'n' && *proctype != 's' && *proctype != 'a'); /* Did the user abort on us? */ if (*proctype != 'a') { do { /* What kind of resolution does the user want in the data? */ printf("\n"); printf("There are three resolutions of data, 5 degree by 5 degree,\n"); printf("5 by 5 nested to 10 by 10 degree, and Zonal-Global data.\n"); printf("Enter resolution type: (5), (10), or (ZG). --> "); scanf("%s", resolution); *(resolution + 2) = NULL; /* Make the inut all lowercase */ for (count = 0; count < 2; ++count) { *(resolution + count) = tolower(*(resolution + count)); }/* end of for */ } while (*resolution != 'a' && *resolution != '5' && strcmp(resolution, "10") != 0 && strcmp(resolution, "zg") != 0); /* Did the user abort on us? */ if (*resolution != 'a') { /* If the user gave us a 5, we need the "5." string */ if (*resolution == '5') { strcpy(resolution, "5."); }/* end of if */ do { /* And for what time period? */ printf("\nEnter data date in the format YYMM. --> "); scanf("%s", datadate); *(datadate + 4) = NULL; gooddata = 1; *datadate = tolower(*datadate); if (*datadate != 'a') { /* Make sure the string is the right length */ if (strlen(datadate) == 4) { /* and that it is all numeric */ for (count = 0; gooddata == 1 && count < 4; ++count) { gooddata = isdigit(*(datadate + count)); }/* end of for */ }/* end of if */ else { gooddata = 0; }/* end of else */ }/* end of if */ } while (gooddata == 0); /* Did the user abort on us? */ if (*datadate != 'a') { do { printf("\nEnter the satellite combination from the following list:\n"); printf(" (1) NOAA-9 (5) ERBS & NOAA-9\n"); printf(" (2) ERBS (6) ERBS & NOAA-10\n"); printf(" (3) NOAA-10 (7) ERBS, NOAA-9, & NOAA-10\n"); printf(" (4) NOAA-9 & NOAA-10 -->"); scanf("%s", satcode); *satcode = tolower(*satcode); } while (*satcode != 'a' && (*satcode < '1' || *satcode > '7')); /* Did the user abort on us? */ if (*satcode != 'a') { /* Get the memory in which we will build the filename */ if ((filename = (char *) malloc(64 * sizeof(char))) != NULL) { /* Build the file name */ sprintf(filename, "s4g_%c%cf%s_%s_%c", *fov, *proctype, resolution, datadate, *satcode); /* Make sure the file really exists */ if (access(filename, R_OK) == -1) { printf("ERROR, the file (%s) is not available for this read program.\n", filename); free(filename); filename = NULL; }/* end of if */ }/* end of if */ }/* end of if */ }/* end of if */ }/* end of if */ }/* end of if */ }/* end of if */ return (filename); }/* end of function */ /************************************************************************** ** Name - int GetFileType(char *) Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To return to the calling function a flag word indicating everything ** we are able to determine about the characteristics of a file just ** from the file name. See s4gnread.h for the value of set bits int ** the flag word. ** ** Input Parameters - ** We are passed a pointer to the character string holding the file name. ** ** Output Parameters - ** The flag word, as described above. ** ** Key Local Parameters - ** ** Subroutines Called - ** ** Exit States - ** Value > 0 : Success ** 0 : Failure ** ** Restrictions - ** File name must conform to the V0 naming conventions identified for the ** S-4G Nonscanner data granuals. ** The naming conventions dictate that the file name will take on the form: ** ** s4g_??f??_yymm_s ** ** where: ** ?(1) : 'm' for MFOV, 'w' for WFOV ** ?(2) : 'n' for Numerical Filter processing, 's' for Shape Factor processing ** ?(3,4) : '5.' -> 5 by 5 degree regional data ** : '10' -> 10 by 10 degree nested from four 5 by 5 degree regions ** : 'zg' -> Zonal-Global data, averages by region and globally ** yymm : The year and month the data was collected ** s : The satellite code defined as: ** ** (1) NOAA-9 ** (2) ERBS ** (3) NOAA-10 ** (4) NOAA-9 & NOAA-10 ** (5) ERBS & NOAA-9 ** (6) ERBS & NOAA-10 ** (7) ERBS, NOAA-9, & NOAA-10 ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif int GetFileType(FileName) char *FileName; { int filetype; /* Check the processing type */ /* - Numerical Filter */ /* - Shape Factor */ switch (*(FileName + 5)) { case 'n': switch (*(FileName + 7)) { /* Five degree? */ case '5': filetype = NF5; break; /* How about ten degree */ case '1': filetype = NF10; break; /* Must be zonal-global */ case 'z': filetype = NFZG; break; /* Oops */ default: filetype = 0; break; }/* end of switch */ break; /* How about Shape Factor */ case 's': switch (*(FileName + 7)) { /* Ten degree regional */ case '1': filetype = SF10; break; /* Must be zonal-global */ case 'z': filetype = SFZG; break; /* Oops */ default: filetype = 0; break; }/* end of switch */ break; /* Not Shape Factor or Numerical Filter */ /* OOPS!! */ default: filetype = 0; break; }/* end of switch */ /* Return to the caller what we figured out */ return (filetype); }/* end of function */ /************************************************************************** ** Name - char * GetFileData() Module - ** Language - C Type - function ** Version - ?? Date - 2 Dec 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To extract from the HDF file all the file description type data ** ** Output Files - ** The report file will be updated with the file ** ** Input Parameters - ** ** Output Parameters - ** ** Key Local Parameters - ** ** Subroutines Called - ** ** Exit States - ** ** Restrictions - ** ** Attributes - ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif int GetFileData(FName, RFile) char *FName; FILE *RFile; { int32 hdffile; /* Place to hold the handle on the HDF file */ int32 length; /* Place to hold the length of the various strings */ int iret = 0; /* Assume we have problems unless all goes well */ int count; char *fidbuffer; /* Place to hold the file id data */ char *fdsbuffer; /* Place to hold the file description data */ /* Open the HDF file so we can do neat stuff, like get */ /* the file id and the file description. We will also */ /* be getting the data label strings, but this does not */ /* require that the file be open. However, this is a */ /* "file level" activity, so it is fitting that it be */ /* done in this function. */ if ((hdffile = Hopen(FName, DFACC_READ, 0)) != 0) { /* Try to get the length of the file id */ if ((length = DFANgetfidlen(hdffile, 1)) != -1) { length += 16; /* Now, get a buffer to hold the file id */ if ((fidbuffer = (char *) malloc(length * sizeof(char))) != NULL) { /* get the file id */ if (DFANgetfid(hdffile, fidbuffer, length, 1) != -1) { /* and print it in the report */ fprintf(RFile, "File ID:\n\n%s\n", fidbuffer); /* Now, get a buffer to hold the file description */ if ((fdsbuffer = (char *) malloc(5000 * sizeof(char))) != NULL) { /* Now, get the file description */ if (DFANgetfds(hdffile, fdsbuffer, 5000, 1) != -1) { fprintf(RFile, "\nFile Description:\n\n%s\n\n", fdsbuffer); iret = 1; }/* end of if */ else { printf("GetFileData(): Error extracting file description on file (%s)\n", FName); }/* end of else */ free(fdsbuffer); }/* end of if */ else { printf("GetFileData(): Insufficient Free Store for File Description\n"); }/* end of else */ }/* end of if */ else { printf("GetFileData(): Error getting the HDF file id on file (%s)\n", FName); }/* end of else */ free(fidbuffer); }/* end of if */ else { printf("GetFileData(): Insufficient Free Store for File ID buffer\n"); }/* end of else */ }/* end of if */ else { printf("GetFileData(): Error getting length of the file id on file (%s)\n", FName); }/* end of else */ Hclose(hdffile); }/* end of if */ else { printf("Unable to open the HDF file (%s)\n", FName); }/* end of else */ return (iret); }/* end of function */ /************************************************************************** ** Name - int GetDLabels() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To extract from the selected HDF file the list of data labels and ** reference numbers and return these to the calling function. ** ** Output Files - ** ** Input Parameters - ** ** Output Parameters - ** ** Key Local Parameters - ** ** Subroutines Called - ** malloc() : Standard 'C' Library function ** free() : Standard 'C' Library function ** Hopen() : HDF routine to open the HDF file ** Hclose() : HDF routine to close the HDF file ** DFANlablist() : HDF routine to retreive desired number of data labels ** ** Exit States - ** tagnum : The number of data labels in the HDF file, if we are ** successful in getting the data labels. ** 0 : If we are unsuccessful, for any reason, we will return ** zero (0) to the calling routine. ** ** Restrictions - ** ** Attributes - ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif int32 GetDataLabels(FName, DLabels, RefList) char *FName; char **DLabels; uint16 **RefList; { int32 tagnum; /* a place to hold the number of tags */ int iret = 0; /* Unless we know better, there was an error */ int nlabs; /* To hold the number of SDS data labels strings */ int count; /* Just a counter */ int32 hdffile; /* An HDF handle for the HDF file */ /* Make sure we start with a clean slate */ *DLabels = NULL; *RefList = NULL; /* Need a special open to get the number of tags in the file */ if ((hdffile = Hopen(FName, DFACC_READ, 0)) != 0) { tagnum = Hnumber(hdffile, 704); /* I seem to remember something about only 1 HDF */ /* being allow to be open at a given time. One */ /* file being open a number of different ways might */ /* also cause problems. */ Hclose(hdffile); /* See if we got a good number of tag numbers */ if (tagnum != -1) { /* Get the memory for the data labels. */ if ((*DLabels = (char *) malloc((tagnum + 1) * (LABEL_LEN + 1) * sizeof(char))) != NULL) { /* Get the memory for the reference list also */ if ((*RefList = (uint16 *) malloc(tagnum * sizeof(int16))) != NULL) { /* Get the list of data labels from the HDF file. */ if ((nlabs = DFANlablist(FName, DFTAG_NDG, *RefList, *DLabels, tagnum, LABEL_LEN, 1)) != -1) { /* Need to return the number of tags acutally returned by the */ /* DFANlablist() function. */ iret = nlabs; }/* end of if */ }/* end of if */ }/* end of if */ }/* end of if */ }/* end of if */ /* Need to return all the allocated resources */ /* to the system if we have encountered a problem. */ if (iret == 0) { /* But, only if we acutally got to the point */ /* where they were allocated */ if (*DLabels != NULL) { printf("We are freeing the DLabels memory\n"); free(*DLabels); *DLabels = NULL; }/* end of if */ if (*RefList != NULL) { free(*RefList); *RefList = NULL; }/* end of if */ }/* end of if */ return (iret); }/* end of function */ /************************************************************************** ** Name - (char *)SelectSDS() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** ** Output Files - ** ** Input Parameters - ** ** Output Parameters - ** Pointer to int32 array, representing the selections made by the user, ** if the user made any selections. ** ** Key Local Parameters - ** ** Subroutines Called - ** ** Exit States - ** ** Restrictions - ** ** Attributes - ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif /* 1) This is static because I do not want (or need) other */ /* functions to have access to the data */ /* 2) The first value on a line is the offset of the beinging */ /* of a particular data set type. Hourly averages have 24 */ /* such data sets, daily averages have a maximum of 31 such */ /* records.*/ /* 3) The second value in the line is the size of the data in */ /* that data set type, expressed in bits/value. */ /* Each Nonscanner HDF file will contain a multiple of 341 (for now) */ /* records. The number of records may change sometime in the future, and */ /* this is why we have computed the value of the last offset and placed it */ /* in rec_count (below */ static int record[48] = { 0, 32, 1, 32, 2, 32, 3, 32, 4, 32, 35, 32, 59, 16, 60, 16, 61, 16, 62, 16, 63, 16, 64, 16, 65, 16, 96, 16, 127, 16, 158, 16, 182, 16, 206, 16, 230, 16, 231, 8, 262, 8, 293, 8, 317, 8, 341, 0 }; char *SelectSDS(DLabels, NumLabels, FType) char *DLabels; /* The array of data label strings */ int32 NumLabels; /* The number of SDSs in the file */ int FType; { int dumpstart; /* Where do we start in the list when the user wants a pick list */ int numlabel; int offset; int loopthru; /* Number of times */ int rec_count; char *selectlist; char selectstring[8]; /* Get the number of records in given set in the HDF file */ rec_count = *(record + (sizeof(record) / sizeof(int)) - 2); /* Get the place to store the selection list */ if ((selectlist = (char *) malloc(NumLabels * sizeof(char))) != NULL) { /* Make sure that all flags have been reset */ memset(selectlist, 0x00, NumLabels * sizeof(char)); /* Introduce ourself and let the user know */ /* what is expected of him */ printf("\n\nThere are %d SDSs in this file.\n", NumLabels); printf("This is the first portion of the list\n\n"); /* Need to dump the first part of the list for the user */ dumpstart = 0; /* Dump a short list of data labels, starting where the */ /* user asked us to start */ DumpSelectList(DLabels, dumpstart, NumLabels, FType); while (dumpstart != -1) { printf("\nEnter option. -> "); /* Get the user's response */ scanf("%s", selectstring); /* Make it something that is easy to handle */ *selectstring = tolower(*(selectstring)); switch (*selectstring) { /* The user has elected to abort his selection from */ /* this file */ case 'a': /* Make sure that no items have been selected */ memset(selectlist, 0x00, sizeof(char) * NumLabels); /* Get us out of the loop */ dumpstart = -1; break; case 'd': dumpstart = atoi((selectstring + 1)); if (dumpstart < NumLabels) { offset = 0; loopthru = (dumpstart / rec_count) * rec_count; while (dumpstart > (loopthru + *(record + offset))) { offset += 2; }/* end of while */ if (dumpstart == (loopthru + *(record + offset))) { loopthru = *(record + offset + 2) - *(record + offset); for (offset = dumpstart; offset < dumpstart + loopthru; ++offset) { *(selectlist + offset) = 0; }/* end of for */ }/* end of if */ else { printf("SDS #%d is not a valid option.", dumpstart); printf(" See above list or press 'h' for help.\n\n"); }/* end of else */ }/* end of if */ else { printf("\n\nError: Selection must fall between 0 and %d\n", NumLabels); }/* end of else */ break; case 'l': /* The user wants to list a new listing of items. */ /* Get the number to start with and ... */ dumpstart = atoi((selectstring + 1)); /* ... dump the list to the screen. */ DumpSelectList(DLabels, dumpstart, NumLabels, FType); break; case 'q': /* The user says he is finished. */ /* Check out to see if he selected anything */ offset = 0; while (offset < NumLabels && *(selectlist + offset) == 0) { ++offset; }/* end of while */ if (offset == NumLabels) { printf("NO PARAMETER WERE SELECTED!\n\n"); }/* end of if */ dumpstart = -1; break; /* The user wants to select one of the labels. */ case 's': /* Find out what that label number is and ... */ dumpstart = atoi((selectstring + 1)); /* Make sure the value is in range */ if (dumpstart < NumLabels) { /* Start at the begining of the list of possible */ /* data label numbers and work our way through */ /* that list in sequential order. Not most */ /* efficient (maybe) but processing time at this */ /* point is not a concern. */ numlabel = 0; /* Need to start at begining of the record count list */ offset = 0; /* And we have not yet gone through the list at all. */ loopthru = 0; /* While our tentative label number is less than that */ /* chosen by our user, we continue to look. */ while (numlabel < dumpstart) { /* Get to the next valid label number */ offset += 2; /* Have we reached the bottom of the list */ /* We know we have when the size of the data item */ /* for a given record group is equal to zero (0) */ if (*(record + offset + 1) == 0) { /* Yes, we have, so we need to go back to the begining */ /* of the list and increment our multiple factor */ offset = 0; ++loopthru; }/* end of if */ /* Tentative is equal to 341 * our multiplier + a little bit */ numlabel = (rec_count * loopthru) + *(record + offset); }/* end of while */ /* We exit the loop when our tentative is no longer less then */ /* the user's selected label number. Now, if our tentative */ /* is equal to the user's selected value,k then we have recieved */ /* from the user a valid data label number */ if (numlabel == dumpstart) { /* Need to compute the number of such records, so the user */ /* will not be surprised bu the size of the listing he receives */ /* The other reason we need to know the number of records is because */ /* we need to indicate that each of these records has been selected */ /* in the 'selectlist' */ numlabel = *(record + offset + 2) - *(record + offset); /* Flag the group of records as having been selected */ for (; numlabel; --numlabel, ++dumpstart) { *(selectlist + dumpstart) = 1; }/* end of for */ }/* end of if */ else { printf("SDS #%d is not a valid option.", dumpstart); printf(" See above list or press 'h' for help.\n\n"); }/* end of else */ }/* end of if */ else { printf("\n\nError: Selection must fall between 0 and %d\n", NumLabels); }/* end of else */ break; /* The user doesn't know what he is doing or */ /* he has asked for help. In either case, we */ /* need to supply him with some help. */ case 'h': default: SelectHelp(); break; }/* end of switch */ }/* end of while */ /* Find the first selected item. If we get to the end */ /* of the selection list without finding an item selected */ /* the user must have aborted the selection */ offset = 0; while (offset < NumLabels && *(selectlist + offset) == 0) { ++offset; }/* end of while */ /* Did we get to the end of the list and still not */ /* find a selected item? If so, the user aborted the */ /* selection process or chose not to select any items. */ if (offset == NumLabels) { /* If the selection was aborted, no need to save the memory */ free(selectlist); /* Need to return a NULL to indicate that we are done */ /* with this program. */ selectlist = NULL; /* Tell the user that we understand that we are finished */ printf("Data read ABORTED!\n\n"); }/* end of if */ }/* end of if */ else { printf("SelectSDS(): Insufficient Free Store for Selection List\n"); }/* end of else */ return (selectlist); }/* end of function */ /************************************************************************** ** Name - void DumpSelectList() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** Dump to the screen a data label pick list to help the user choose the ** the data to be extracted from the HDF file ** ** Input Parameters - ** See comments below ** ** Key Local Parameters - ** ** Subroutines Called - ** printf() ** **************************************************************************/ void DumpSelectList(Labels, Start, NLabels, FType) char *Labels; /* Pointer to data labels array */ int Start; /* What is the first one to be displayed */ int32 NLabels; /* Number of SDS (and labels ) in the file */ int FType; { int counter; /* Just a counter */ int realstart; /* Ordinal position in the record array of our starting point */ int offset; /* Offset into the record array */ int loopthru; /* How many times through the record array */ int labelnum; /* Acutal SDS number matched by our position in record */ int numrecords; /* Number of records of this data type */ int rec_count; /* Get the number of records in given set in the HDF file */ int si; int ri; static char *scope[6] = { "Regional", "Zonal", "Zonal", "Global", "Zonal", "Global" }; static char *resolution[3] = { "Five Degree", "Ten Degree", " " }; /* Get the number of parameters in given set in the HDF file */ rec_count = *(record + (sizeof(record) / sizeof(int)) - 2); if (Start < NLabels) { /* Get the record number of the group he is looking into */ realstart = Start % rec_count; /* Start at the end of the list */ offset = 46; /* Back up until we find a record number less then */ /* the one the user is asking for */ while (offset > 0 && *(record + offset) > realstart) { offset -= 2; }/* end of while */ loopthru = Start / rec_count; switch (FType) { case NF5: si = 0; ri = 0; break; /* Also the same as SF10 */ case NF10: si = 0; ri = 1; break; case NFZG: si = loopthru + 1; ri = loopthru % 3; break; case SFZG: /* 07-11-94 This line presented to the user the string zonal instead of stating that the data was global data. si = loopthru + 1; */ si = loopthru +2; ri = loopthru + 1; break; default: break; }/* end of switch */ /* Start there and work forewards until we fill up the screen */ for (counter = 0; counter < SCREEN_LINES && ((rec_count * loopthru) + *(record + offset)) < NLabels; ++counter, offset += 2) { if (*(record + offset + 1) == 0) { ++loopthru; offset = 0; ++ri; ++si; }/* end of if */ labelnum = (rec_count * loopthru) + *(record + offset); numrecords = *(record + offset + 2) - *(record + offset); printf("[%4d] : %s : %2d records of %2d bit data(%s %s)\n", labelnum, Labels + (labelnum * LABEL_LEN), numrecords, *(record + offset + 1), *(resolution + ri), *(scope + si)); }/* end of for */ SelectHelp(); }/* end of if */ else { printf("Please ask for a list starting between 0 and %d.\n", NLabels); }/* end of else */ return; }/* end of function */ /************************************************************************** ** Name - void SelectHelp() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To print a message to the screen and help the user figure out what ** his/her options might be. ** **************************************************************************/ void SelectHelp() { printf("\n\nThere are 6 commands available:\n"); printf("In all the following, \"nnnn\" refers to the item number\n"); printf("displayed between the \"[\" and \"]\" characters.\n\n"); printf("a : ABORT - discard all selection criteria, generate NO report.\n"); printf("dnnnn : DELETE a chosen parameter \"nnnn\" from the selection list\n"); printf("lnnnn : LIST new selection list to screen, starting at \"nnnn\"\n"); printf("q : QUIT selection portion of program.\n"); printf("snnnn : Add parameter \"nnnn\" to the SELECTION list.\n"); printf("h : HELP - Generate this message.\n"); return; }/* end of function */ /************************************************************************** ** Name - int GetSubset() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To return to the calling function the pointer to an array holding ** the north-west and south-east corners, and all points in between ** of the area to be sliced from the HDF file. ** ** Output Files - ** NONE ** ** Input Parameters - ** NONE ** ** Output Parameters - ** A pointer as described above. ** ** Key Local Parameters - ** ** Subroutines Called - ** ** Exit States - ** Valid pointer : Success ** NULL : Some sort of error **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif #define myabs(x) ((x) < 0) ? -(x) : (x) int GetSubSet(FType, Region) int FType; Area *Region; { int start; /* The user selected starting region */ int stop; /* The user selected ending region */ int degree; /* Resolution of the data in the file */ int done; /* Are we finished getting responses from the user */ float ulat; /* The Upper-Left (North-West) and Lower-Right (South-East) */ float ulong; /* corner of the user selected region, using Lat/Long */ float llat; /* parameters */ float llong; char input_line[32]; /* Just a place to hold the user's responses */ int iret = 1; /* Assume all will be cool */ /* Get a number to represent the resolution */ /* of the data in the file */ if ((FType & FIVE_DEG) == FIVE_DEG) { degree = 5; }/* end of if */ else { degree = 10; }/* end of else */ /* Do we need the user to select the regional pick list */ /* If we are dealing with regional data, we need to give the */ /* user the choice. Zonal-Global data it does not make much */ /* sense to do so, especially since it would be difficult to */ /* do so. */ if ((FType & REGIONAL) == REGIONAL) { /* Need to introduce our purpose */ printf("\n\nThis program has the capability to further subset the regional data\n"); printf("based upon user requirements, expressed in units of either Lat/Long or \n"); printf("by requesting a range of regions numbers.\n\n"); do { printf("Please indicated that you are interested in further subsetting\n"); printf("the data selected by entering (L) for Lat/Long, (R) for Regional\n"); printf("subsetting, (N) for no further subsetting, or (A) to\n"); printf("Abort program. (L/N/R/A) --> "); /* Get the the user's response */ scanf("%s", input_line); /* Make it easier to handle */ /* We are only interested in the first character he */ /* types */ *input_line = tolower(*input_line); switch (*input_line) { case 'a': printf("Data Extraction ABORTED!!\n"); iret = 0; done = 1; break; /* The user wants to select based on Lat/Long */ case 'l': /* 05/31/94 printf("Enter North-West corner Lat/Long (90.0 >= x > -90.0, 180.0 >= y > -180.0) -->"); */ printf("Enter North-West corner Lat/Long (90.0 >= x > -90.0 360.0 >= y >= 0.0) -->"); scanf("%f %f", &ulat, &ulong); /* 05/31/94 printf("Enter South-East corner Lat/Long (90.0 <= x < -90.0, 180.0 >= y > -180.0) -->"); */ printf("Enter South-East corner Lat/Long (90.0 <= x < -90.0 360.0 >= y >= 0.0) -->"); scanf("%f %f", &llat, &llong); /* Need to make sure that the values entered are in range, as */ /* perscribed above. */ /* 05/31/94 if (ulat > 90.0 || ulong < -180.0 || llat <= -90.0 || llong >= 180.0) */ /*if ((ulat > 90.0) || (ulong < 0.0) || (llat <= -90.0) || (llong >= 360.0)) */ if ((ulat > 90.0) || (ulong < 0.0) || (llat < -90.0) || (llong > 360.0)) { printf("\n\nPlease enter the Lat/Longs in the range specified.\n\n"); }/* end of if */ else { /* Assume, if you will, a grid system where the origin is in the */ /* upper left corner. Positive progress along the 'X' axis is to */ /* the right. Positive progress along the 'Y' axis is down. */ /* 'ulh' is the horizontal position of the start of the selected region. */ /* 'lrh' is the horizontal position of the end of the selected region. */ /* 'ulv' is the vertical position of the start of the selected region. */ /* 'blv' is the vertical position of the end of the selected region. */ Region->ulv = (abs((int) (90.0 - ulat))) / degree; /* 05/31/94 Region->ulh = (abs((int) (180.0 + ulong))) / degree; */ Region->ulh = (abs((int) (0.0 + ulong))) / degree; Region->lrv = (abs((int) (90.0 - llat)) + (degree / 2)) / degree; /* Make sure we do not blow our array bounds */ /* 05/31/94 if (Region->lrv > (180 / degree)) */ if (Region->lrv > (360 / degree)) { /* 05/31/94 Region->lrv = (180 / degree) - 1; */ Region->lrv = (360 / degree) - 1; }/* end of if */ /* 05/31/94 Region->lrh = ((abs((int) (180.0 + llong)) + (degree / 2)) / degree); */ Region->lrh = ((abs((int) (0.0 + llong)) + (degree / 2)) / degree); /* This is to make sure we do not get the Eastern most region */ /* printed to the report twice */ if (((Region->lrh) % (360 / degree)) == 0) { --Region->lrh; }/* end of if */ /* Make sure that the North-West point is neither south or east */ /* of the South-East point */ if (Region->ulh > Region->lrh || Region->ulv > Region->lrv) { printf("The North-West corner can never be either South\n"); printf("or East of the South-East corner of the subset!!\n"); }/* end of if */ else { done = 1; }/* end of else */ }/* end of else */ break; /* The user wants to select the regions he/she wants */ case 'r': do { printf("\nPlease enter the starting and ending region numbers,\n"); printf("in the range of 1 -> %d and in the format of\n\n", ((360 * 180) / (degree * degree))); printf(" 'start stop',\n\n"); printf("bearing in mind that the file contains data\n"); printf("at a resolution of %d degrees. --> ", degree); scanf("%d %d", &start, &stop); } while (start < 1 || start > stop || stop > (((360 * 180) / (degree * degree)) + 1)); Region->start = start - 1; Region->stop = stop; done = 1; break; /* The user chose to get all the data, we need to set */ /* our region select list to indicate this */ case 'n': Region->start = 0; Region->stop = ((360 * 180) / (degree * degree)); done = 1; break; default: done = 0; break; }/* end of switch */ } while (done != 1); }/* end of if */ return (iret); }/* end of function */ /************************************************************************** ** Name - void PrintReport() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** This is a driver to make sure the user requested data acutally finds ** its way into a file ** ** Output Files - ** NONE ** ** Input Parameters - ** See comments below. ** ** Key Local Parameters - ** See comments below. ** ** Subroutines Called - ** DFSDreadref() : Random access to a specific SDS in the HDF file ** DFSDgetdims() : Get the array size of the data ** DFSDgetdatastrs() : Get the data label, units, format, and coords ** DFSDgetNT() : What size is the data (byte, int16, int32) ** DFSDgetrange() : What are legal data values ** DFANgetlabel() : Get the scale factor text ** WriteByte() : Write the int8 values ** WriteWord() : Write the int16 values ** WriteDoubleWord() : Write the int32 values ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif void PrintReport(DSelect, NumLabels, Region, DLabels, RefList, FName, RFile, FType) char *DSelect; /* Array of selected data parameters */ int32 NumLabels; /* Number of SDSs in the HDF file */ Area *Region; char *DLabels; /* The array of data labels. */ uint16 *RefList; /* The array of reference numbers associated with data labels */ char *FName; /* The HDF file name. */ FILE *RFile; /* The FILE pointer to the report file */ int FType; /* What type of HDF file do we have, seen s4gnread.h for more */ { int count; /* A counter */ int numdims; /* Number of dimensions in the SDS */ int32 arrydims[MAX_RANK + 5];/* Place to hold the dimensions sizes, plus spare room */ char dlabel[LABEL_LEN + 1]; /* Hold the data label */ char dataunits[32]; /* Hold the data units string */ char dataformat[32]; /* Hold the optimal data print format */ char datacoords[32]; /* Hold the data coordinates, NULL string in our case */ char tlab[32]; /* Temporary place to hold the scale factor string */ int32 numtype; /* Data size, (int8, int16, int32) */ union { struct { int8 maximum; /* Data range -> maximum and minimum */ int8 minimum; } byte; struct { int16 maximum; /* Data range -> maximum and minimum */ int16 minimum; } word; struct { int32 maximum; /* Data range -> maximum and minimum */ int32 minimum; } dword; } maximin; int32 scalefactor; /* The scale factor, binary version of tlab */ for (count = 0; count < NumLabels; ++count) { if (*(DSelect + count) != 0) { printf("Extracting record %d (%s)\n", count, DLabels + (count * LABEL_LEN)); /* Accomplish something very like a random access */ /* to the desired SDS. */ if (DFSDreadref(FName, *(RefList + count)) == 0) { /* Get the number of dimensions, and the size of each */ if (DFSDgetdims(FName, &numdims, arrydims, MAX_RANK) == 0) { /* Get the data strings */ if (DFSDgetdatastrs(dlabel, dataunits, dataformat, datacoords) == 0) { /* What size is the data, (int8, int16, int32) */ if (DFSDgetNT(&numtype) == 0) { /* Get the scale factor string */ if (DFANgetlabel(FName, DFTAG_SD, *(RefList + count), tlab, sizeof(tlab)) == 0) { /* Make the scale factor a real string */ scalefactor = atoi(tlab); /* Print what we know about the data item selected */ fprintf(RFile, "Data attributes are as follows:\n\n"); fprintf(RFile, "Label: %s\nUnits: %s\nFormat: %s\n", dlabel, dataunits, dataformat); /* Print the data to the report file, using the appropriate */ /* write routine based upon the size of the data elements. */ switch (numtype) { case DFNT_INT8: /* What is the valid value range */ if (DFSDgetrange(&maximin.byte.maximum, &maximin.byte.minimum) == 0) { /* 07/26/94 The minimum and maximum values are incorrect within the HDF data files for the Longwave and Shortwave parameters. So that the user would not get this information from the data file, the print lines for this information have been commented out in this code. For the correct values for all parameters, please refer to the ERBE S-4G User's Guide. Please ignore these values when using outside software packages! fprintf(RFile, "Data Maximum: %d\nData Minimum: %d\n\n", maximin.byte.maximum, maximin.byte.minimum); */ /* Need to write to the report such things as the number of */ /* dimensions, the dimension label string, and the dimension */ /* scales. */ WriteDimensions(RFile, numtype, numdims, arrydims, FType); fprintf(RFile, "The scale factor of %d has been applied", scalefactor); fprintf(RFile, " to the following data:\n\n"); WriteByte(RFile, FName, Region, numdims, arrydims, FType, scalefactor); }/* end of if */ else { fprintf(RFile, "\n\nError getting data maximums and minimums"); FinishError(RFile, DLabels, RefList, count); }/* end of else */ break; case DFNT_INT16: /* What is the valid value range */ if (DFSDgetrange(&maximin.word.maximum, &maximin.word.minimum) == 0) { /* 07/26/94 The minimum and maximum values are incorrect within the HDF data files for the Longwave and Shortwave parameters. So that the user would not get this information from the data file, the print lines for this information have been commented out in this code. For the correct values for all parameters, please refer to the ERBE S-4G User's Guide. Please ignore these values when using outside software packages! fprintf(RFile, "Data Maximum: %d\nData Minimum: %d\n\n", maximin.word.maximum, maximin.word.minimum); */ /* Need to write to the report such things as the number of */ /* dimensions, the dimension label string, and the dimension */ /* scales. */ WriteDimensions(RFile, numtype, numdims, arrydims, FType); fprintf(RFile, "The scale factor of %d has been applied", scalefactor); fprintf(RFile, " to the following data:\n\n"); WriteWord(RFile, FName, Region, numdims, arrydims, FType, scalefactor); }/* end of if */ else { fprintf(RFile, "\n\nError getting data maximums and minimums"); FinishError(RFile, DLabels, RefList, count); }/* end of else */ break; case DFNT_INT32: /* What is the valid value range */ if (DFSDgetrange(&maximin.dword.maximum, &maximin.dword.minimum) == 0) { /* 07/26/94 The minimum and maximum values are incorrect within the HDF data files for the Longwave and Shortwave parameters. So that the user would not get this information from the data file, the print lines for this information have been commented out in this code. For the correct values for all parameters, please refer to the ERBE S-4G User's Guide. Please ignore these values when using outside software packages! fprintf(RFile, "Data Maximum: %d\nData Minimum: %d\n\n", maximin.dword.maximum, maximin.dword.minimum); */ /* Need to write to the report such things as the number of */ /* dimensions, the dimension label string, and the dimension */ /* scales. */ WriteDimensions(RFile, numtype, numdims, arrydims, FType); fprintf(RFile, "The scale factor of %d has been applied", scalefactor); fprintf(RFile, " to the following data:\n\n"); WriteDoubleWord(RFile, FName, Region, numdims, arrydims, FType, scalefactor); }/* end of if */ else { fprintf(RFile, "\n\nError getting data maximums and minimums"); FinishError(RFile, DLabels, RefList, count); }/* end of else */ break; default: break; }/* end of switch */ }/* end of if */ }/* end of if */ else { fprintf(RFile, "\n\nError getting data types"); FinishError(RFile, DLabels, RefList, count); }/* end of else */ }/* end of if */ else { fprintf(RFile, "\n\nError getting data attributes"); FinishError(RFile, DLabels, RefList, count); }/* end of else */ }/* end of if */ else { fprintf(RFile, "\n\nError getting data dimensions"); FinishError(RFile, DLabels, RefList, count); }/* end of else */ }/* end of if */ else { fprintf(RFile, "\n\nError setting file pointer"); FinishError(RFile, DLabels, RefList, count); }/* end of else */ }/* end of if */ }/* end of for */ }/* end of function */ /************************************************************************** ** Name - void FinishError() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To limit the number of times the same statement (and associated) ** static string is compiled into the program code. This function ** really only completes an error message by telling the user where ** the problem occured. ** ** Output Files - ** The error message is printed into the report file ** ** Input Parameters - ** See the comments below ** ** Subroutines Called - ** fprintf() : Standard 'C' Library function ** **************************************************************************/ void FinishError(RFile, DataLabel, RefList, Index) FILE *RFile; /* The FILE pointer to the report file */ char *DataLabel; /* The array of data labels. */ uint16 *RefList; /* The array of data reference tag values */ int Index; /* Which SDS had the problem */ { fprintf(RFile, " DataLabel = (%s), Referece = %d\n\n", DataLabel + (Index * LABEL_LEN), *(RefList + Index)); return; }/* end of function */ /************************************************************************** ** Name - int WriteDimensions() Module - ** Language - C Type - function ** Version - ?? Date - 11 Feb 93 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** Need to write to the report such things as the number of ** dimensions, the dimension label string, and the dimension ** scales. ** ** Output Files - ** NONE ** ** Input Parameters - ** See comments below. ** ** Key Local Parameters - ** See comments below. ** ** Subroutines Called - ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif #define NUM_ELEMS 5 int WriteDimensions(RFile, NumType, NumDims, ArrayDims, FType) FILE *RFile; int NumType; int NumDims; int32 *ArrayDims; int FType; { int degrees; int count0; int count1; int8 *dimscale8; int16 *dimscale16; int32 *dimscale32; int iret = 1; char label[32]; char unit[32]; char format[32]; int newlong; if ((FType & REGIONAL) == REGIONAL) { if ((FType & FIVE_DEG) == FIVE_DEG) { degrees = 5; }/* end of if */ else { if ((FType & TEN_DEG) == TEN_DEG) { degrees = 10; }/* end of if */ else { degrees = 0; }/* end of else */ }/* end of else */ }/* end of if */ else { degrees = 1; }/* end of else */ switch (NumType) { case DFNT_INT32: /* For each dimension, we need to put out a description of the */ /* dimension and the data */ for (count0 = 0; count0 < NumDims; ++count0) { /* Get the description data */ if (DFSDgetdimstrs(count0 + 1, label, unit, format) == 0) { /* Figure out just how much of what we put out we need */ /* to write to the report file */ if (strncmp(label, "Global", 6) != 0) { fprintf(RFile, "This dimension represents %s,\nexpressed in %s\n\n", label, unit); /* Need to get some memory for the data we need to extract from */ /* the HDF file. */ if ((dimscale32 = (int32 *) malloc(*(ArrayDims + count0) * sizeof(int32))) != NULL) { /* We have the memory, now get the data */ if (DFSDgetdimscale(count0 + 1, *(ArrayDims + count0), dimscale32) == 0) { /* We have the data, need to print the data to the report */ /* file, five data elements per line */ for (count1 = 0; count1 < *(ArrayDims + count0); ++count1) { /* Insert a carriage return, if it is needful */ if ((count1 % NUM_ELEMS) == 0) { if (count0 == 1) { if (count1 == 0) newlong = 0; else newlong = newlong + degrees; fprintf(RFile, "\n%10d", newlong); } else fprintf(RFile, "\n%10d", (*(dimscale32 + count1) * degrees)); }/* end of if */ else { if (count0 == 1) { if (count1 == 0) newlong = 0; else newlong = newlong + degrees; fprintf(RFile, "%10d", newlong); } else fprintf(RFile, "%10d", (*(dimscale32 + count1) * degrees)); }/* end of else */ }/* end of for */ fprintf(RFile, "\n\n"); }/* end of if */ else { printf("WriteDimensions(): Error getting dimension scales %d\n", count0); iret = 0; }/* end of else */ free(dimscale32); }/* end of if */ else { printf("WriteDimensions(): Insufficent Free Store\n"); iret = 0; }/* end of else */ }/* end of if */ else { fprintf(RFile, "%s\n", label); }/* end of else */ }/* end of if */ else { printf("WriteDimensions(): Error getting dimension strings\n"); iret = 0; }/* end of else */ }/* end of for */ break; case DFNT_INT16: /* For each dimension, we need to put out a description of the */ /* dimension and the data */ for (count0 = 0; count0 < NumDims; ++count0) { /* Get the description data */ if (DFSDgetdimstrs(count0 + 1, label, unit, format) == 0) { /* Figure out just how much of what we put out we need */ /* to write to the report file */ if (strncmp(label, "Global", 6) != 0) { fprintf(RFile, "This dimension represents %s,\nexpressed in %s\n\n", label, unit); /* Need to get some memory for the data we need to extract from */ /* the HDF file. */ if ((dimscale16 = (int16 *) malloc(*(ArrayDims + count0) * sizeof(int16))) != NULL) { /* We have the memory, now get the data */ if (DFSDgetdimscale(count0 + 1, *(ArrayDims + count0), dimscale16) == 0) { /* We have the data, need to print the data to the report */ /* file, five data elements per line */ for (count1 = 0; count1 < *(ArrayDims + count0); ++count1) { /* Insert a carriage return, if it is needful */ if ((count1 % NUM_ELEMS) == 0) { if (count0 == 1) /* 05/31/94 to correct longitude error */ { if (count1 == 0) newlong = 0; else newlong = newlong + degrees; fprintf(RFile, "\n%10d", newlong); } else fprintf(RFile, "\n%10d", (*(dimscale16 + count1) * degrees)); }/* end of if */ else { if (count0 == 1) /* 05/31/94 to correct longitude error */ { if (count1 == 0) newlong = 0; else newlong = newlong + degrees; fprintf(RFile, "%10d", newlong); } else fprintf(RFile, "%10d", (*(dimscale16 + count1) * degrees)); }/* end of else */ }/* end of for */ fprintf(RFile, "\n\n"); }/* end of if */ else { printf("WriteDimensions(): Error getting dimension scales %d\n", count0); iret = 0; }/* end of else */ free(dimscale16); }/* end of if */ else { printf("WriteDimensions(): Insufficent Free Store\n"); iret = 0; }/* end of else */ }/* end of if */ else { fprintf(RFile, "%s\n", label); }/* end of else */ }/* end of if */ else { printf("WriteDimensions(): Error getting dimension strings\n"); iret = 0; }/* end of else */ }/* end of for */ break; case DFNT_INT8: /* For each dimension, we need to put out a description of the */ /* dimension and the data */ for (count0 = 0; count0 < NumDims; ++count0) { /* Get the description data */ if (DFSDgetdimstrs(count0 + 1, label, unit, format) == 0) { /* Figure out just how much of what we put out we need */ /* to write to the report file */ if (strncmp(label, "Global", 6) != 0) { fprintf(RFile, "This dimension represents %s,\nexpressed in %s\n\n", label, unit); /* Need to get some memory for the data we need to extract from */ /* the HDF file. */ if ((dimscale8 = (int8 *) malloc(*(ArrayDims + count0) * sizeof(int8))) != NULL) { /* We have the memory, now get the data */ if (DFSDgetdimscale(count0 + 1, *(ArrayDims + count0), dimscale8) == 0) { /* We have the data, need to print the data to the report */ /* file, five data elements per line */ for (count1 = 0; count1 < *(ArrayDims + count0); ++count1) { /* Insert a carriage return, if it is needful */ if ((count1 % NUM_ELEMS) == 0) { if (count0 == 1) /* 05/31/94 to correct longitude error */ { if (count1 == 0) newlong = 0; else newlong = newlong + degrees; fprintf(RFile, "\n%10d", newlong); } else fprintf(RFile, "\n%10d", (*(dimscale8 + count1) * degrees)); }/* end of if */ else { if (count0 == 1) /* 05/31/94 to correct longitude error */ { if (count1 == 0) newlong = 0; else newlong = newlong + degrees; fprintf(RFile, "%10d", newlong); } else fprintf(RFile, "%10d", (*(dimscale8 + count1) * degrees)); }/* end of else */ }/* end of for */ fprintf(RFile, "\n\n"); }/* end of if */ else { printf("WriteDimensions(): Error getting dimension scales %d\n", count0); iret = 0; }/* end of else */ free(dimscale8); }/* end of if */ else { printf("WriteDimensions(): Insufficent Free Store\n"); iret = 0; }/* end of else */ }/* end of if */ else { fprintf(RFile, "%s\n", label); }/* end of else */ }/* end of if */ else { printf("WriteDimensions(): Error getting dimension strings\n"); iret = 0; }/* end of else */ }/* end of for */ break; default: printf("WriteDimensions(): Unknown File Type\n"); iret = 0; break; }/* end of switch */ return (iret); }/* end of function */ /************************************************************************** ** Name - int WriteByte() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To extract all the data for a given region from the HDF file, prepare it ** for printing and to pass all the required data to the print routine ** so that it can be printed very nicely. ** ** Input Parameters - ** So many, see the discussion below. ** ** Output Parameters - ** The return value, see Exit States (below) ** ** Key Local Parameters - ** The variables holding the North-West and South-East corners of the ** selection region. ** ** Subroutines Called - ** ** Exit States - ** ** Restrictions - ** ** Attributes - ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif int WriteByte(RFile, FName, Region, NumDims, ArrayDims, FileType, ScaleFactor) FILE *RFile; /* Report file pointer */ char *FName; /* Name of the HDF file */ Area *Region; int NumDims; /* The number of dimensions in the current SDS */ int32 *ArrayDims; /* The array to hold the dimensions of the current SDS */ int FileType; /* Just what is says. See s4gnread.h for more */ int32 ScaleFactor; /* What is the scale factor to apply to the data */ { int degrees; /* The resolution of the data */ int8 *data; /* A pointer to memory allocated to hold the data */ int numelem; /* A temporary place to hold element count */ int offset; int iret = 1; /* Assume that all will go well */ /* Allocate the appropriate number of bytes */ /* of storage to hold the incoming data */ if ((data = (int8 *) malloc(NUM_REGIONS_5 * sizeof(int8))) != NULL) { /* Get the all the data for the desired parameter */ /* We will probably not use all the data, but */ /* it will be there if we do. */ if (DFSDgetdata(FName, NumDims, ArrayDims, data) == 0) { /* Are we regional data or Zonal-Global? */ if (((FileType & REGIONAL) == REGIONAL) && (Region->start == 0) && (Region->stop == 0)) { /* Determine the number of regions that we */ /* might have to deal with */ if ((FileType & FIVE_DEG) == FIVE_DEG) { degrees = 5; }/* end of if */ else { degrees = 10; }/* end of else */ /* Now to print the desired regions. */ PrintRegions(RFile, Region, (360 / degrees), data, ScaleFactor, (int) DFNT_INT8); }/* end of if */ else { if (Region->start != 0 || Region->stop != 0) { numelem = Region->stop - Region->start; offset = Region->start; }/* end of if */ else { numelem = *ArrayDims; offset = 0; }/* end of else */ /* We are working with zonal-global data */ WriteZonalGlobal(RFile, data, offset, ScaleFactor, numelem, (int) DFNT_INT8); }/* end of else */ }/* end of if */ /* We are done with this memory, at least until */ /* the next time we enter this function, so we */ /* should return it to the system. */ free(data); }/* end of if */ else { printf("WriteByte(): Insufficient Free Store for data buffer\n"); iret = 0; }/* end of else */ }/* end of function */ /************************************************************************** ** Name - Module - ** Language - C Type - ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** Will print the entire rectangle of regional data to the report file ** in one fell-swoop. ** ** Output Files - ** RFile points to a disk file that may (or may not) be printed by the user. ** This file will contain a "printed" version of the data requested by the user ** to be extracted from the HDF file. ** ** Input Parameters - ** See the comments below. ** ** Output Parameters - ** ** Key Local Parameters - ** See the comments below. ** ** Subroutines Called - ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif void PrintRegions(RFile, Region, RowLength, Data, ScaleFactor, NumType) FILE *RFile; /* The FILE pointer to the report file */ Area *Region; int RowLength; /* How long is the "raster" */ void *Data; /* The array holding acutall data values. */ int32 ScaleFactor; /* The scale factor to be applied to the data */ int NumType; /* Flag indicating data is byte, 16-bit int, or 32-bit int */ { int c0; int c1; int c2; int c3; int raster; int first; /* Need to put the column headers in the report */ /* 08/05/94 To be consistent with all of the other S-4G */ /* programs, the next two lines have been commented out. */ /* fprintf(RFile,"\t\t\t\t\tD A T A\n\n"); */ /* fprintf(RFile,"REGION"); */ /* Start on first raster, go to the last one. */ for (c0 = Region->ulv; c0 < Region->lrv + 1; ++c0) { /* This says that we are working on the first */ /* record for the current raster */ first = 1; raster = c0 * RowLength; /* For every region in this raster */ for (c1 = Region->ulh; c1 < Region->lrh + 1; ++c1) { /* This (c2) modulas COLUMNS give us the column that */ /* the current data item will be printed in. */ c2 = c1 + raster + 1; /* 08/05/94 Changes made below for the data to be printed in */ /* the correct columns after adjusting the region numbers to */ /* start at 1 instead of zero. There should be no representation */ /* of a region number starting at zero - only at 1. */ /* if (first == 1 || (c2 % COLUMNS) == 0) */ if (first == 1 || ((c2-1) % COLUMNS) == 0) { /* Print the row header every five regions, and on the */ /* first row printed */ /*08/05/94 fprintf(RFile, "\n%4d: ", (c2 - (c2 % COLUMNS))); */ fprintf(RFile, "\n%4d: ", ((((c2-1) / COLUMNS)*COLUMNS)+1)); /* 08/05/94 if (first == 1 && (c2 % COLUMNS) != 0) */ if (first == 1) { /* For the very first print line of the raster, and only */ /* if we need to, we will print a series of blank */ /* "spreadsheet cells" in the report */ /* 08/05/94 for (c3 = 0; c3 < (c2 % COLUMNS); ++c3) */ for (c3 = 0; c3 < (((c2%COLUMNS)==0)?(COLUMNS-1) : ((c2 % COLUMNS)-1)); c3++) { fprintf(RFile, " "); }/* end of for */ }/* end of if */ /* We no longer need to worry about first row/data item problems, */ /* at least not until next time */ first = 0; }/* end of if */ /* Print the value to the report */ PrintValue(RFile, Data, (c1 + raster), ScaleFactor, NumType); }/* end of for */ fprintf(RFile, "\n"); }/* end of for */ /* Need a file carriage return */ fprintf(RFile, "\n"); return; }/* end of function */ /************************************************************************** ** Name - Module - ** Language - C Type - ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** Common print routine used by WriteByte(), WriteWord(), and WriteDoubleWord(). ** This routine would have to be duplicated in all the above if we did not ** use a couple of extra pointers, (the choice of which is used is determined ** by the size of the data. ** ** Output Files - ** The report file ** ** Input Parameters - ** See the comments below ** ** Key Local Parameters - ** See the comments below ** ** Subroutines Called - ** fprintf() : Standard 'C' Library function ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif void PrintValue(RFile, Data, Offset, ScaleFactor, NumType) FILE *RFile; /* The FILE pointer to the report file */ void *Data; /* The pointer to start of data array */ int Offset; /* The offset into Data where we will find the desired data item */ int32 ScaleFactor; /* The scale factor to be applied to the data value */ int32 NumType; /* Size of the data */ { /* The next three items are used only as determined by the size */ /* of the data. We have to have them because pointer arithmetic is */ /* dependant on the size of the data. */ int8 *bdata = (int8 *) Data; int16 *wdata = (int16 *) Data; int32 *dwdata = (int32 *) Data; int32 tempdata; /* Place to hold the integer version of data element */ double print_value; /* Place to hold the double version of data element */ /* Yep, get the integer value at that location. */ switch (NumType) { case DFNT_INT8: /* Get the data value into a real integer */ tempdata = (int32) (*(bdata + Offset)); switch (tempdata) { case 0x7F: case -127: print_value = (double) tempdata; break; default: print_value = ((double) tempdata) / ScaleFactor; break; }/* end of switch */ break; /* You want to know what is happening here? See the comments */ case DFNT_INT16: tempdata = (int32) (*(wdata + Offset)); switch (tempdata) { case 0x7FFF: case -32767: case -127: print_value = (double) tempdata; break; default: print_value = ((double) tempdata) / ScaleFactor; break; }/* end of switch */ break; case DFNT_INT32: tempdata = (int32) (*(dwdata + Offset)); switch (tempdata) { case 0x7FFFFFFF: case 0x7FFF: case -32767: case -127: print_value = (double) tempdata; break; default: print_value = ((double) tempdata) / ScaleFactor; break; }/* end of switch */ break; }/* end of switch */ /* What ever the print_value might be, print it */ fprintf(RFile, "%17.4f", print_value); return; }/* end of function */ /************************************************************************** ** Name - Module - ** Language - C Type - ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** ** Output Files - ** ** Input Parameters - ** ** Output Parameters - ** ** Key Local Parameters - ** ** Subroutines Called - ** ** Exit States - ** ** Restrictions - ** ** Attributes - ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif void WriteZonalGlobal(RFile, Data, Offset, ScaleFactor, NumElem, NType) FILE *RFile; void *Data; int Offset; int32 ScaleFactor; /* The scale factor to be applied to the data value */ int32 NumElem; int NType; { int count0; int count2; int first = 1; /* Need to print the header row accross the page */ /* 08/05/94 Removed these two lines so that report files would */ /* be consistent with all other ERBE S-4G read programs. */ /* fprintf(RFile,"\t\t\t\t\tD A T A\n\n"); */ /* fprintf(RFile,"REGION"); */ for (count0 = Offset; count0 < NumElem + Offset; count0++) { /* Do we need to write a NL and the raster number */ /* at the begining of the line? */ /* 08/05/94 Scientist requested that region/band numbers follow format */ /* as of scanner program which means never start format at zero. To */ /* do this, some of the following lines of code had to be modified for */ /* this to work. */ /* 08/05/94 if ((((count0+1) % COLUMNS) == 0) || (first == 1))*/ if ((first == 1) || (((count0) % COLUMNS) == 0)) { /* 08/05/94 fprintf(RFile, "\n%4d:", ((count0 + 1) - ((count0 + 1) % COLUMNS)));*/ fprintf(RFile, "\n%4d:", ((count0 + 1) - ((count0) % COLUMNS))); /* 08/05/94 To avoid writing a zero block of blanks. */ if (Offset == 0) first = 0; if (first == 1) { /* 08/05/94 for (count2 = 0; count2 < ((count0 + 1) % COLUMNS); ++count2)*/ for (count2 = 0; count2 < ((count0 ) % COLUMNS); ++count2) { fprintf(RFile, " "); } first = 0; }/* end of if */ }/* end of if */ PrintValue(RFile, Data, count0, ScaleFactor, NType); }/* end of for */ fprintf(RFile, "\n\n"); return; }/* end of function */ /************************************************************************** ** Name - int WriteWord() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To extract all the data for a given region from the HDF file, prepare it ** for printing and to pass all the required data to the print routine ** so that it can be printed very nicely. ** ** Input Parameters - ** So many, see the discussion below. ** ** Output Parameters - ** The return value, see Exit States (below) ** ** Key Local Parameters - ** The variables holding the North-West and South-East corners of the ** selection region. ** ** Subroutines Called - ** ** Exit States - ** ** Restrictions - ** ** Attributes - ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif int WriteWord(RFile, FileName, Region, NumDims, ArrayDims, FileType, ScaleFactor) FILE *RFile; /* Report file pointer */ char *FileName; /* Name of the HDF file */ Area *Region; int NumDims; /* The number of dimensions in the current SDS */ int32 *ArrayDims; /* The array to hold the dimensions of the current SDS */ int FileType; /* Just what is says. See s4gnread.h for more */ int32 ScaleFactor; /* What is the scale factor to apply to the data */ { int degrees; /* The resolution of the data */ int16 *data; /* A pointer to memory allocated to hold the data */ int numelem; /* A temporary place to hold element count */ int offset; int iret = 1; /* Assume that all will go well */ /* Allocate the appropriate number of bytes */ /* of storage to hold the incoming data */ if ((data = (int16 *) malloc(NUM_REGIONS_5 * sizeof(int16))) != NULL) { /* Get the all the data for the desired parameter */ /* We will probably not use all the data, but */ /* it will be there if we do. */ if (DFSDgetdata(FileName, NumDims, ArrayDims, data) == 0) { /* Are we regional data or Zonal-Global? */ if (((FileType & REGIONAL) == REGIONAL) && (Region->start == 0) && (Region->stop == 0)) { /* Determine the number of regions that we */ /* might have to deal with */ if ((FileType & FIVE_DEG) == FIVE_DEG) { degrees = 5; }/* end of if */ else { degrees = 10; }/* end of else */ /* Now to print the desired regions. */ PrintRegions(RFile, Region, (360 / degrees), data, ScaleFactor, (int) DFNT_INT16); }/* end of if */ else { if (Region->start != 0 || Region->stop != 0) { numelem = Region->stop - Region->start; offset = Region->start; }/* end of if */ else { numelem = *ArrayDims; offset = 0; }/* end of else */ /* We are working with zonal-global data */ WriteZonalGlobal(RFile, data, offset, ScaleFactor, numelem, (int) DFNT_INT16); }/* end of else */ }/* end of if */ /* We are done with this memory, at least until */ /* the next time we enter this function, so we */ /* should return it to the system. */ free(data); }/* end of if */ else { printf("WriteWord(): Insufficient Free Store for data buffer\n"); iret = 0; }/* end of else */ }/* end of function */ /************************************************************************** ** Name - int WriteDoubleWord() Module - ** Language - C Type - function ** Version - ?? Date - 13 Oct 92 Programmer - Scott R. Quier (SAIC) ** ** Purpose - ** To extract all the data for a given region from the HDF file, prepare it ** for printing and to pass all the required data to the print routine ** so that it can be printed very nicely. ** ** Input Parameters - ** So many, see the discussion below. ** ** Output Parameters - ** The return value, see Exit States (below) ** ** Key Local Parameters - ** The variables holding the North-West and South-East corners of the ** selection region. ** ** Subroutines Called - ** ** Exit States - ** ** Restrictions - ** ** Attributes - ** ** Comments ** **************************************************************************/ #ifndef S4GNREAD_H #include "s4gnread.h" #endif int WriteDoubleWord(RFile, FileName, Region, NumDims, ArrayDims, FileType, ScaleFactor) FILE *RFile; /* Report file pointer */ char *FileName; /* Name of the HDF file */ Area *Region; int NumDims; /* The number of dimensions in the current SDS */ int32 *ArrayDims; /* The array to hold the dimensions of the current SDS */ int FileType; /* Just what is says. See s4gnread.h for more */ int32 ScaleFactor; /* What is the scale factor to apply to the data */ { int degrees; /* The resolution of the data */ int32 *data; /* A pointer to memory allocated to hold the data */ int numelem; /* A temporary place to hold element count */ int offset; int iret = 1; /* Assume that all will go well */ /* Allocate the appropriate number of bytes */ /* of storage to hold the incoming data */ if ((data = (int32 *) malloc(NUM_REGIONS_5 * sizeof(int32))) != NULL) { /* Get the all the data for the desired parameter */ /* We will probably not use all the data, but */ /* it will be there if we do. */ if (DFSDgetdata(FileName, NumDims, ArrayDims, data) == 0) { /* Are we regional data or Zonal-Global? */ if (((FileType & REGIONAL) == REGIONAL) && (Region->start == 0) && (Region->stop == 0)) { /* Determine the number of regions that we */ /* might have to deal with */ if ((FileType & FIVE_DEG) == FIVE_DEG) { degrees = 5; }/* end of if */ else { degrees = 10; }/* end of else */ /* Now to print the desired regions. */ PrintRegions(RFile, Region, (360 / degrees), data, ScaleFactor, (int) DFNT_INT32); }/* end of if */ else { if (Region->start != 0 || Region->stop != 0) { numelem = Region->stop - Region->start; offset = Region->start; }/* end of if */ else { numelem = *ArrayDims; offset = 0; }/* end of else */ /* We are working with zonal-global data */ WriteZonalGlobal(RFile, data, offset, ScaleFactor, numelem, (int) DFNT_INT32); }/* end of else */ }/* end of if */ /* We are done with this memory, at least until */ /* the next time we enter this function, so we */ /* should return it to the system. */ free(data); }/* end of if */ else { printf("WriteDoubleWord(): Insufficient Free Store for data buffer\n"); iret = 0; }/* end of else */ }/* end of function */