OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GetStationInfo.c
Go to the documentation of this file.
1 /* ---------------------------------------------------------------------- */
2 /* runl1a version of getstationinfo() */
3 /* ---------------------------------------------------------------------- */
4 
5 /*
6 This function fills a structure with information about the local
7 HRPT station. The information is read from a disk file on the
8 local system.
9 
10 The disk file should be a text file containing lines of the form:
11 
12 NAME: VALUE
13 
14 where NAME is one of the strings listed below in the #define statements,
15 and VALUE is the appropriate string for the local station. The NAME
16 field is not case sensitive, but the VALUE field is. Long VALUE fields
17 may be continued on subsequent lines by beginning each continuation
18 line with whitespace. Only the first colon is significant for separating
19 the NAME and VALUE fields. All whitespace is trimmed from the beginning
20 and end of the NAME and VALUE fields, and adjacent whitespace characters
21 are collapsed into a single space.
22 
23 Norman Kuring 28-Oct-1997
24 
25 Integrated with SEADAS version, 20-May-2003, BAF.
26  */
27 
28 #include <GetStationInfo.h>
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <ctype.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 
37 #include <passthebuck.h>
38 
39 #define CALLOC(ptr,typ,num) { \
40  (ptr) = (typ *)calloc((num) , sizeof(typ)); \
41  if((ptr) == NULL){ \
42  fprintf(stderr,"-E- %s line %d: Memory allocation failure.\n", \
43  __FILE__,__LINE__); \
44  return(MEMORY_ALLOCATION_ERROR); \
45  } \
46 }
47 
48 #define ENVIRONMENT_VAR "HRPT_STATION_IDENTIFICATION_FILE"
49 #define CODE_STR "code"
50 #define DATA_CENTER_STR "data center"
51 #define STATION_NAME_STR "station name"
52 #define STATION_LAT_STR "station latitude"
53 #define STATION_LON_STR "station longitude"
54 
55 int GetStationInfo(char *stationInfoFile, StationInfo *stationInfo) {
56 
57  char *bytes, *string, *bp, *next, **sd, *sp;
58  int gotcolon, word;
59  struct stat stat_struct;
60  FILE *fh;
61  char *code, *data_center, *station_name;
62  char *station_latitude, *station_longitude;
63 
64  code = data_center = station_name = station_latitude = station_longitude = NULL;
65 
66  /* Get the station ID filename */
67  if (stationInfoFile == NULL) {
68  stationInfoFile = getenv(ENVIRONMENT_VAR);
69  if (stationInfoFile == NULL) {
70  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
71  fprintf(stderr, "Environment variable, \"%s\", not set.\n", ENVIRONMENT_VAR);
72  return (MISSING_ENVVAR);
73  }
74  }
75  printf("Station information derived from %s\n", stationInfoFile);
76 
77  /* Get the file size and make sure it's greater than zero. */
78  if (stat(stationInfoFile, &stat_struct) != 0) {
79  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
80  fprintf(stderr, "stat() failed for file, %s. ", stationInfoFile);
81  perror("Reason");
82  return (STAT_FAILURE);
83  }
84  if (stat_struct.st_size < 1) {
85  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
86  fprintf(stderr, "File, %s, is empty.\n", stationInfoFile);
87  return (FILE_IS_EMPTY);
88  }
89 
90  /* Allocate memory to hold the file contents. */
91  CALLOC(bytes, char, stat_struct.st_size + 1);
92  CALLOC(string, char, stat_struct.st_size + 1);
93 
94  /* Open the file and read its contents. */
95  if ((fh = fopen(stationInfoFile, "r")) == NULL) {
96  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
97  fprintf(stderr, "Could not open file, %s . ", stationInfoFile);
98  perror("Reason");
99  return (FOPEN_FAILURE);
100  }
101  if (fread(bytes, 1, stat_struct.st_size, fh) != stat_struct.st_size) {
102  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
103  fprintf(stderr, "Error reading file, %s . ", stationInfoFile);
104  perror("Reason");
105  return (FREAD_FAILURE);
106  }
107  fclose(fh);
108 
109  /* Merge continuation lines (i.e. lines that begin with whitespace). */
110  bp = bytes;
111  next = bp + 1;
112  while (*next) {
113  if (*bp == '\n' && isspace(*next)) *bp = ' ';
114  bp++;
115  next++;
116  }
117 
118  /* Parse the file contents for name=value pairs and fill a structure
119  * with the desirable ones (see the #define lines above). */
120  bp = bytes;
121  sp = string;
122  gotcolon = 0;
123  word = 0;
124  while (*bp) {
125  while (isspace(*bp) && *bp != '\n') bp++;
126  if (*bp == '\n') {
127  gotcolon = 0;
128  *sp = 0;
129  if (sd != NULL) {
130  if (*string)
131  sp--;
132  *sp = 0;
133  *sd = strdup(string);
134  sd = NULL;
135  }
136  sp = string;
137  bp++;
138  }
139  while (*bp && !isspace(*bp) && (gotcolon || *bp != ':')) {
140  word = 1;
141  if (gotcolon)
142  *sp++ = *bp;
143  else
144  *sp++ = tolower(*bp);
145  bp++;
146  }
147  if (word) {
148  *sp = ' ';
149  sp++;
150  word = 0;
151  }
152  if (*bp == ':' && !gotcolon) {
153  gotcolon = 1;
154  bp++;
155  sp--;
156  *sp = 0;
157  if (strcmp(string, CODE_STR) == 0) {
158  sd = &code; /* sd = string destination */
159  } else if (strcmp(string, DATA_CENTER_STR) == 0) {
160  sd = &data_center;
161  } else if (strcmp(string, STATION_NAME_STR) == 0) {
162  sd = &station_name;
163  } else if (strcmp(string, STATION_LAT_STR) == 0) {
164  sd = &station_latitude;
165  } else if (strcmp(string, STATION_LON_STR) == 0) {
166  sd = &station_longitude;
167  } else {
168  sd = NULL;
169  }
170  sp = string;
171  }
172  }
173  /*
174  Account for the case of a line that is terminated by the
175  end of the file rather than by a newline (0x0a) character.
176  */
177  if (sd != NULL && *string) {
178  *sd = strdup(string);
179  }
180 
181  if (code != NULL) {
182  /* Copy at most 4 chars into stationInfo->code then terminate it */
183  strncpy(stationInfo->code, code, 4);
184  stationInfo->code[4] = (char) 0;
185 
186  /***
187  **** This does not work with the 4-char code logic in swl1_hdf.c:DataTypeString():1346.
188  **** JGW 2/24/2006
189  ****
190  if(code != NULL && strlen(code) >= 3){
191  if(isalpha(code[0]) && isalpha(code[1]) && isalpha(code[2])){
192  code[3] = 0;
193  strcpy(stationInfo->code, code);
194  }
195  ****
196  ****/
197  free(code);
198  code = NULL;
199  }
200  if (data_center != NULL) {
201  stationInfo->data_center = data_center;
202  }
203  if (station_name != NULL) {
204  stationInfo->station_name = station_name;
205  }
206  if (station_latitude != NULL) {
207  stationInfo->station_latitude = (float) atof(station_latitude);
208  free(station_latitude);
209  station_latitude = NULL;
210  }
211  if (station_longitude != NULL) {
212  stationInfo->station_longitude = (float) atof(station_longitude);
213  free(station_longitude);
214  station_longitude = NULL;
215  }
216 
217  return (LIFE_IS_GOOD);
218 }
219 
220 
221 
int GetStationInfo(char *stationInfoFile, StationInfo *stationInfo)
===========================================================================V4.1.3 12/18/2002============================================================================Changes which do not affect scientific output:1. The R *LUT was eliminated and the equivalent formulation for R *, i.e. 1/(m1 *e_sun_over_pi), was substituted for it in the only instance of its use, which is in the calculation of the RSB uncertainty index. This reduces the size of the Reflective LUT HDF file by approximately 1/4 to 1/3. The equivalent formulation of R *differed from the new by at most 0.056% in test granules and uncertainty differences of at most 1 count(out of a range of 0-15) were found in no more than 1 in 100, 000 pixels. 2. In Preprocess.c, a small error where the trailing dropped scan counter was incremented when the leading dropped scan counter should have been was fixed. This counter is internal only and is not yet used for any purpose. 3. NEW MYD02OBC Metadata Configuration Files. MCST wishes to have the OBC files archived even when the Orbit Number is recorded as "-1". Accordingly, ECS has delivered new MCF files for OBC output having all elements in the OrbitCalculatedSpatialDomain container set to "MANDATORY=FALSE". 4. pgs_in.version is now reset to "1" in Metadata.c before the call to look up the geolocation gringpoint information.============================================================================V4.1.1 CODE SPECIFIC TO MODIS/AQUA(FM1) 10/03/2002============================================================================Two changes were made to the code which do not affect scientific output:1. A bug which caused PGE02 to fail when scans were dropped between granules was fixed.(The length of the error message generated was shortened.) 2. Messages regarding an invalid MCST LUT Version or an invalid Write High Resolution Night Mode Output value in the PCF file were added.==============================================================================V4.1.0 CODE SPECIFIC TO MODIS/AQUA(FM1)(NEVER USED IN PRODUCTION) 07/30/2002==============================================================================Changes which impact scientific output of code:1. The LUT type of the RVS corrections was changed to piecewise linear. In addition the RVS LUTs were changed from listing the RVS corrections to listing the quadratic coefficients necessary to make the RVS corrections. The coefficients are now calculated by interpolating on the granule collection time and the RVS corrections are then generated using the interpolated coefficients. Previously used Emissive and Reflective RVS LUT tables were eliminated and new ones introduced. Several changes were made to the code which should not affect scientific output. They are:1. The ADC correction algorithm and related LUTs were stripped from the code.(The ADC correction has always been set to "0" so this has no scientific impact.) 2. Some small changes to the code, chiefly to casting of variables, were added to make it LINUX-compatible. Output of code run on LINUX machines displays differences of at most 1 scaled integer(SI) from output of code run on IRIX machines. The data type of the LUT "dn_sat_ev" was changed to float64 to avoid discrepancies seen between MOD_PR02 run on LINUX systems and IRIX systems where values were flagged under one operating system but not the other. 3. Checking for non-functioning detectors, sector rotation, incalculable values of the Emissive calibration factor "b1", and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal.c since none of these quantities are frame-dependent. 4. The code was altered so that if up to five scans are dropped between the leading/middle or middle/trailing granules, the leading or trailing granule will still be used in emissive calibration to form a cross-granule average. QA bits 25 and 26 are set for a gap between the leading/middle and middle/trailing granules respectively. This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule. 5.(MODIS/AQUA ONLY) The name of the seed(error message) file was changed from "MODIS_36100.h" to "MODIS_36110.h". 6. Metadata.c was changed so that the source of the geolocation metadata is the input geolocation file rather than the L1A granule. 7. To reduce to overall size of the reflective LUT HDF files, fill values were eliminated from all LUTs previously dimensioned "BDSM"([NUM_REFLECTIVE_BANDS] *[MAX_DETECTORS_PER_BAND] *[MAX_SAMPLES_PER_BAND] *[NUM_MIRROR_SIDES]) in the LUT HDF files. Each table piece is stored in the HDF file with dimensions NUM_REFLECTIVE_INDICES, where NUM_REFLECTIVE_INDICES=[NUM_250M_BANDS *DETECTORS_PER_250M_BAND *SAMPLES_PER_250M_BAND *NUM_MIRROR_SIDES]+[NUM_500M_BANDS *DETECTORS_PER_500M_BAND *SAMPLES_PER_500M_BAND *NUM_MIRROR_SIDES]+[NUM_1000M_BANDS *DETECTORS_PER_1KM_BAND *SAMPLES_PER_1KM_BAND *NUM_MIRROR_SIDES] with SAMPLES_PER_250M_BAND=4, SAMPLES_PER_500M_BAND=2, and SAMPLES_PER_1KM_BAND=1. Values within each table piece appear in the order listed above. The overall dimensions of time dependent BDSM LUTs are now[NUM_TIMES] *[NUM_REFLECTIVE_INDICES], where NUM_TIMES is the number of time dependent table pieces. 8. Checking for non-functioning detectors, sector rotation, incalculable values of the Emissive calibration factor "b1", and incalculable values of SV or BB averages was moved outside the loop over frames in Emissive_Cal.c since none of these quantities are frame-dependent. 9. The code was altered so that if up to five scans are dropped between the leading/middle or middle/trailing granules, the leading or trailing granule will still be used in emissive calibration to form a cross-granule average. QA bits 25 and 26 are set for a gap between the leading/middle and middle/trailing granules respectively. This may in rare instances lead to a change in emissive calibration coefficients for scans at the beginning or end of a granule. 10. The array of b1s in Preprocess.c was being initialized to -1 outside the loop over bands, which meant that if b1 could not be computed, the value of b1 from the previous band for that scan/detector combination was used. The initialization was moved inside the band loop.============================================================================V3.1.0(Original Aqua-specific code version) 02/06/2002============================================================================AQUA-Specific changes made:1. A correction to a problem with blackbody warmup on bands 33, 35, and 36 was inserted. PC Bands 33, 35, and 36 on MODIS Aqua saturate on BB warmup before 310K, which means current code will not provide correct b1 calibration coefficients when the BB temperatures are above the saturation threshold. A LUT with default b1s and band-dependent temperature thresholds will be inserted in code. If the BB temperature is over the saturation threshold for the band, the default b1 from the table is used. 2. The number of possible wavelengths in the Emissive LUT RSR file was changed to 67 in order to accommodate the Aqua RSR tables. 3. Several changes to the upper and lower bound limits on LUT values were inserted. Changes to both Aqua and Terra Code:1. A check was put into Emissive_Cal.c to see whether the value of b1 being used to calibrate a pixel is negative. If so, the pixel is flagged with the newly created flag TEB_B1_NOT_CALCULATED, value 65526, and the number of pixels for which this occurs is counted in the QA_common table. 2. The array of b1s in Preprocess.c was being initialized to -1 outside the loop over bands, which meant that if b1 could not be computed, the value of b1 from the previous band for that scan/detector combination was used. The initialization was moved inside the band loop. 3. Minor code changes were made to eliminate compiler warnings when the code is compiled in 64-bit mode. 4. Temperature equations were upgraded to be MODIS/Aqua or MODIS/Terra specific and temperature conversion coefficients for Aqua were inserted.========================================================================================================================================================ALL CHANGES BELOW ARE TO COMMON TERRA/AQUA CODE USED BEFORE 02/06/2002========================================================================================================================================================v3.0.1 11/26/2001============================================================================Several small changes to the code were made, none of which changes the scientific output:1. The code was changed so that production of 250m and 500m resolution data when all scans of a granule are in night mode may be turned off/on through the PCF file. 2. A check on the times of the leading and trailing granules was inserted. If a leading or trailing granule does not immediately precede or follow(respectively) the middle granule, it is treated as a missing granule and a warning message is printed. 3. The code now reads the "MCST Version Number"(e.g. "3.0.1.0_Terra") from the PCF file and checks it against the MCST Version number contained in the LUT HDF files. This was done to allow the user to make sure the code is being run using the correct LUT files.(The designators "0_Terra", "1_Terra", etc.) refer to the LUT versions.) 4. A small bug in Preprocess.c was corrected code
Definition: HISTORY.txt:661
#define CALLOC(ptr, typ, num)
#define NULL
Definition: decode_rs.h:63
#define FREAD_FAILURE
Definition: passthebuck.h:14
#define STATION_LAT_STR
#define MISSING_ENVVAR
Definition: passthebuck.h:10
#define CODE_STR
char * data_center
#define FILE_IS_EMPTY
Definition: passthebuck.h:12
@ string
#define LIFE_IS_GOOD
Definition: passthebuck.h:4
char code[5]
#define STAT_FAILURE
Definition: passthebuck.h:11
char * strdup(const char *)
#define FOPEN_FAILURE
Definition: passthebuck.h:13
#define STATION_NAME_STR
#define ENVIRONMENT_VAR
#define isspace(c)
#define DATA_CENTER_STR
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
float station_longitude
char * station_name
int bp[2]
float station_latitude
#define STATION_LON_STR