OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
parse_eng_data_list.c
Go to the documentation of this file.
1 #include <ctype.h>
2 #include "L1A_prototype.h"
3 #include "PGS_SMF.h"
4 #include "PGS_IO.h"
5 #include "EN_eng_data.h"
6 #include "PC_pcf_info.h"
7 #include "MS_misc.h"
8 #include "PGS_MODIS_35005.h"
9 #include "hdfi.h"
10 #include "hdf.h"
11 #include "PGS_TD.h"
12 
13 
14 PGSt_SMF_status parse_eng_data_list (EN_VDATA_TYPE_t *eng_data)
15 
16 /*
17 !C************************************************************************
18 
19 !Description: This function parses the eng_data_list_file creating Vdata
20  in the eng_data array structure.
21 
22 !Input Parameters:
23  None
24 
25 !Output Parameters:
26  None
27 
28 !Input/Output Parameters:
29  EN_VDATA_TYPE_t *eng_data ** The eng_data array **
30  ** structure **
31 
32 Return Values:
33  MODIS_F_INVALID_ENG_DATA_LIST (MODIS_35005.h)
34  MODIS_S_SUCCESS (MODIS_35005.h)
35  FAIL (hdf.h)
36 
37 Externally Defined:
38  EN_MAX_FIELD_NAME_LENGTH (EN_eng_data.h)
39  EN_MAX_LINE_LEN (EN_eng_data.h)
40  EN_MAX_VDATA_NAME_LENGTH (EN_eng_data.h)
41  EN_MAX_VDATA_NUM_BITS (EN_eng_data.h)
42  EN_MAX_VDATA_ORDER (EN_eng_data.h)
43  EN_MAX_VDATA_TYPE (EN_eng_data.h)
44  EN_MIN_VDATA_NUM_BITS (EN_eng_data.h)
45  EN_MIN_VDATA_ORDER (EN_eng_data.h)
46  EN_MIN_VDATA_TYPE (EN_eng_data.h)
47  EN_NUM_SCAN_ELEMENTS (EN_eng_data.h)
48  EN_NUM_VDATAS (EN_eng_data.h)
49  EN_VDATA_TYPE_t (EN_eng_data.h)
50  FAIL (hdf.h)
51  global_input_pointer (L1A_prototype.h)
52  MODIS_E_GET_CONFIG_FAILED (PGS_MODIS_35005.h)
53  MODIS_E_NULL_POINTER (PGS_MODIS_35005.h)
54  MODIS_E_PGS_IO_GEN_CLOSE (PGS_MODIS_35005.h)
55  MODIS_E_PGS_IO_GEN_OPEN (PGS_MODIS_35005.h)
56  MODIS_F_INVALID_ENG_DATA_LIST (PGS_MODIS_35005.h)
57  MODIS_S_SUCCESS (PGS_MODIS_39501.h)
58  MODIS_W_EXCESS_DATA_LIST (PGS_MODIS_35005.h)
59  MS_BLANK (MS_misc.h)
60  MS_COMMENT (MS_misc.h)
61  MS_NEW_LINE (MS_misc.h)
62  PC_L1A_ENG_DATA_LIST_FILE (PC_pcf_info.h)
63  PGS_S_SUCCESS (PGS_SMF.h)
64  PGS_TRUE (PGS_SMF.h)
65  PGSd_IO_Gen_Read (PGS_IO_Gen.h)
66  PGSt_IO_Gen_FileHandle (PGS_IO.h)
67  PGSd_PC_VALUE_LENGTH_MAX (PGS_PC.h)
68  PGSt_integer (PGS_IO.h)
69  PGSt_SMF_status (PGS_SMF.h)
70  PGSt_tag (PGS_TYPES.h)
71 
72 Called By:
73  initialize_level1a
74 
75 Routines Called:
76  create_eng_data_vdata_array
77  create_eng_data_vdata_array_field
78  log_fmt_msg
79  PGS_IO_Gen_Close
80  PGS_IO_Gen_Open
81  PGS_PC_GetUniversalRef
82  PGS_SMF_TestSuccessLevel
83 
84 !Revision History:
85  $Log: parse_eng_data_list.c,v $
86  Revision 5.1 2005/08/15 16:27:40 kuyper
87  Corrected code to handle properly the possibility that field_name[0]<0.
88 
89  Revision 3.2 2002/10/03 19:45:38 vlin
90  global_input_pointer removed.
91  vlin@saicmodis.com
92 
93  Revision 3.1 2002/09/09 20:59:00 vlin
94  Updated according to parse_eng_data_list.pdl revision 3.2
95 
96  Revision 2.1 2000/07/17
97  John Seaton (seaton@ltpmail.gsfc.nasa.gov)
98  Added code to work with aqua instrument.
99 
100 !Team-unique Header:
101 
102  This software is developed by the MODIS Science Data Support Team
103  for the National Aeronautics and Space Administration,
104  Goddard Space Flight Center, under contract NAS5-32373.
105 
106 References and Credits:
107  None
108 
109 Design Notes:
110  The input list must have the following format:
111 
112 The first line of the ENG_DATA_LIST MUST be as follows:
113 -| 3333 $Revision: 5.1 $ Satellite Instrument (3333 - Auqa) (2222 - Terra)
114 
115 This line designates the Satellite Instrument that the ENG_DATA_LIST is for.
116 The line starts as a comment for backward compatibility.
117 
118 ---------------------- (<== Lines beginning w/ a dash are)
119 - Comment Line (<== considered comments... )
120 ---------------------- (<== Comments are only allowed outside)
121  (<== eng_data definition blocks)
122 ------------------------------------ (<== Start of a eng_data definition block)
123 eng_data #1 Name (<== eng_data name)
124 ------------------------------------ (<== a comment line separates eng_data name and field(s))
125 field_name_1 num_bits start_bit_pos order type (<== field 1 )
126 field_name_2 num_bits start_bit_pos order type ( etc )
127  .
128  .
129  .
130 field_name_j num_bits start_bit_pos order type
131 ------------------------------------ (<== comment line signals end of fields)
132 
133 ------------------------------------
134 eng_data #2 Name
135 ------------------------------------
136 field_name_1 num_bits start_bit_pos order type
137 field_name_2 num_bits start_bit_pos order type
138  .
139  .
140  .
141 field_name_k num_bits start_bit_pos order type
142 ------------------------------------
143 
144 ..etc...
145 ------------------------------------
146 
147  NOTES:
148  1) Field names can't have spaces in them (although eng_data names can).
149 
150  2) An extra field called "LAST_VALID_SCAN" will be added to each
151  eng_data as its first field (field 0). Except for the
152  Current/Prior S/C Ancillary Data Vdata. They do not need a
153  LAST_VALID_SCAN field.
154 
155  3) Field.values can be any of the following types:
156  int8 uint8 int16 uint16 int32 uint32.
157 
158  4) The bit positions listed in the eng_data starting with
159  "Engineering BB data" and below, are bit positions within eng.
160  packet 1-2 (so subtract offset 144 from these bit positions to
161  reference the corresponding bit positions within the
162  packet->data field)
163 
164 !END*************************************************************************/
165 
166 {
167  PGSt_SMF_status returnStatus=MODIS_S_SUCCESS;
168  /* SMF-style message returned by function */
169  PGSt_SMF_status PGSstatus; /* SMF-style message returned by function */
170  PGSt_SMF_status fileStatus; /* SMF-style message returned by function */
171 
172  int scanStatus; /* stores the status of fscanf routines */
173  char *readStatus; /* stores lines read from eng_data_list */
174 
175  char *routine = "parse_eng_data_list"; /* pointer to name of function */
176 
177  char msg [300]; /* array to store error messages */
178 
179  PGSt_integer version_num=1; /* version number */
180  PGSt_IO_Gen_AccessType access_mode=PGSd_IO_Gen_Read; /* access mode to
181  eng_data_list */
182  PGSt_integer file_version=1; /* file version */
183  PGSt_IO_Gen_FileHandle *eng_data_list_handle; /* file handle to
184  eng_data_list */
185 
186  unsigned short num_bits; /* stores the number of bits for the field */
187  unsigned short start_bit_pos;/* stores the start bit position for data
188  in the packet for the field */
189  unsigned short order; /* stores the order for the field */
190  unsigned short type; /* stores the type of field (int8, uint8, etc...)*/
191 
192  uint16 curr_eng_data_index=0; /* stores the current vdata index */
193  uint16 curr_field_index; /* stores the current field count for a vdata */
194  int extra_lines; /* counts the extra lines at end of eng_data_list */
195  int total_lines; /* counts the total lines read from eng_data_list */
196  int num_vdatas_created; /* stores the number of vdata created */
197  int number_of_vdata_fields; /* stores the number of fields
198  for each vdata */
199  char line[EN_MAX_LINE_LEN]; /* stores line read in from eng_data_list
200  file */
201  char field_name[EN_MAX_FIELD_NAME_LENGTH]; /* stores vdata field name */
202  char eng_data_name[EN_MAX_VDATA_NAME_LENGTH]; /* stores vdata name */
203 
204 /**************************************************************************/
205 /* Check for NULL input parameters */
206 /**************************************************************************/
207  if (eng_data == NULL) {
208  log_fmt_msg(MODIS_E_NULL_POINTER, routine, " ");
209  return FAIL;
210  }
211 
212 /**************************************************************************/
213 /* Get Engineering Data List File Name */
214 /**************************************************************************/
215  PGSstatus = PGS_PC_GetUniversalRef(PC_L1A_ENG_DATA_LIST_FILE,
216  &version_num,
218 
219  if (PGS_SMF_TestSuccessLevel(PGSstatus) != PGS_TRUE)
221  "unable to retrieve eng data list file name from pcf file");
222 
223 /**************************************************************************/
224 /* Open Engineering Data List File */
225 /**************************************************************************/
226  PGSstatus = PGS_IO_Gen_Open(PC_L1A_ENG_DATA_LIST_FILE,
227  access_mode,
228  &eng_data_list_handle,
229  file_version);
230 
231  if (PGSstatus != PGS_S_SUCCESS)
232  {
234  "error opening eng_data_list file");
235  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
236  }
237 
238 /***************************************************************************/
239 /* Begin Parsing the Engineering Data List File */
240 /***************************************************************************/
241  else
242  {
243  num_vdatas_created = 0;
244  total_lines = 0;
245  readStatus = fgets(line, sizeof(line), eng_data_list_handle);
246 
247  if (readStatus == line) {
248  total_lines++;
249  scanStatus = sscanf(line, "%s %d %*[$]Revision: %s $ ", field_name,
250  &eng_data->instrument, (char *)&eng_data->revision);
251  /* The %*[$] serves solely to prevent interpretation of this format
252  string as an RCS keyword in this code. It's eng_data->revision
253  which is supposed to match an RCS Revision keyword string. */
254  if (scanStatus < 2) {
256  "Spacecraft Instrument not valid");
257  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
258  }
259  if (scanStatus < 3) {
261  "No RCS Revision number");
262  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
263  }
264  }
265  else
266  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
267 
268 /***************************************************************************/
269 /* Loop until all vdata have been read, or an error has occurred */
270 /***************************************************************************/
271  while ((num_vdatas_created < EN_NUM_VDATAS) &&
272  (returnStatus == MODIS_S_SUCCESS))
273  {
274  line[0] = MS_BLANK;
275 
276 /***************************************************************************/
277 /* Loop until first non-comment or blank line line has been read */
278 /***************************************************************************/
279  while (((line[0] == MS_BLANK) ||
280  (line[0] == MS_COMMENT) ||
281  (line[0] == MS_NEW_LINE)) &&
282  (returnStatus == MODIS_S_SUCCESS))
283  {
284  readStatus = fgets(line, sizeof(line),
285  eng_data_list_handle);
286  if (readStatus == line)
287  total_lines++;
288  else
289  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
290  }
291 /****************************************************************************/
292 /* Create a new vdata with the vdata name = line just read in */
293 /****************************************************************************/
294  if (returnStatus == MODIS_S_SUCCESS)
295  {
296  strncpy (eng_data_name, line, sizeof(eng_data_name));
297  eng_data_name[strlen(line)-1]='\0';
298  create_eng_data_vdata_array(eng_data_name,
299  eng_data,
300  &curr_eng_data_index,
301  &curr_field_index);
302 /*****************************************************************************/
303 /* Read next line, if not a comment, eng_data_list file not correct */
304 /*****************************************************************************/
305  readStatus = fgets(line, EN_MAX_VDATA_NAME_LENGTH,
306  eng_data_list_handle);
307  if (readStatus == line)
308  {
309  if (line[0] != MS_COMMENT)
310  {
311  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
313  "missing separator line in eng_data_list");
314  }
315  }
316  else
317  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
318  }
319 /******************************************************************************/
320 /* Read the first Vdata field line. Field name, number of bits, starting bit */
321 /* position, order and type. */
322 /******************************************************************************/
323  if (returnStatus == MODIS_S_SUCCESS)
324  {
325  total_lines++;
326  memset(field_name, '\0', sizeof(field_name));
327  number_of_vdata_fields = 0;
328 
329  readStatus = fgets(line, sizeof(line),
330  eng_data_list_handle);
331 
332  if (readStatus != line)
333  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
334 
335  scanStatus = sscanf(line, "%s %hu %hu %hu %hu", field_name,
336  &num_bits, &start_bit_pos, &order, &type);
337 /******************************************************************************/
338 /* Read lines from Engineering Data List File which will be Vdata fields */
339 /* until a comment line is reached, signaling the end of the field list. */
340 /******************************************************************************/
341  while ((field_name[0] != MS_COMMENT) &&
342  (returnStatus == MODIS_S_SUCCESS) &&
343  (scanStatus != EOF))
344  {
345  total_lines++;
346  number_of_vdata_fields++;
347 /******************************************************************************/
348 /* If first character is not a letter, invalid Vdata field has been read */
349 /******************************************************************************/
350  if (!isalpha((int)*(unsigned char*)field_name))
351  {
352  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
353  sprintf(msg, "In line %d vdata field name %s in eng_data_list does not begin with a letter",
354  total_lines, field_name);
356  }
357 /******************************************************************************/
358 /* Check num_bits, order, and type for valid input ranges. */
359 /******************************************************************************/
360  if ((num_bits < EN_MIN_VDATA_NUM_BITS) || (num_bits > EN_MAX_VDATA_NUM_BITS))
361  {
362  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
363  sprintf(msg, "In line %d the number of bits is invalid for "
364  "vdata field %s in %s. Value: %d Range: %d to %d", total_lines,
365  field_name, eng_data_name, num_bits, EN_MIN_VDATA_NUM_BITS,
368  }
369  if (scanStatus != EN_NUM_SCAN_ELEMENTS)
370  {
371  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
372  sprintf(msg, "In line %d the number of attributes read for "
373  "vdata field %s in %s was %d.", total_lines, field_name,
374  eng_data_name, scanStatus);
376  }
377  if ((order < EN_MIN_VDATA_ORDER) || (order > EN_MAX_VDATA_ORDER))
378  {
379  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
380  sprintf(msg, "In line %d the order number is invalid for "
381  "vdata field %s in %s. Value: %d Range: %d to %d",
382  total_lines, field_name, eng_data_name, order,
385  }
387  {
388  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
389  sprintf(msg, "In line %d the type is invalid for vdata field "
390  " %s in %s. Value: %d Range: %d to %d", total_lines, field_name,
391  eng_data_name, type, EN_MIN_VDATA_TYPE, EN_MAX_VDATA_TYPE);
393  }
394 
395 /*******************************************************************************/
396 /* Create Vdata Field with data read in from Engineering Data List File, and */
397 /* read the next line from Engineering Data List File. */
398 /*******************************************************************************/
399  if (returnStatus == MODIS_S_SUCCESS)
401  num_bits,
402  start_bit_pos,
403  order,
404  type,
405  eng_data,
406  curr_eng_data_index,
407  &curr_field_index);
408 
409  readStatus = fgets(line, sizeof(line), eng_data_list_handle);
410  if (readStatus != line)
411  returnStatus = MODIS_F_INVALID_ENG_DATA_LIST;
412  else
413  scanStatus = sscanf(line, "%s %hu %hu %hu %hu", field_name,
414  &num_bits, &start_bit_pos, &order, &type);
415  }
416  }
417  else
419  "Unexpected end of file in eng_data_list file");
420 
421  num_vdatas_created++;
422  } /* end while < EN_NUM_VDATAS && returnStatus = MODIS_S_SUCCESS */
423 /********************************************************************************/
424 /* If all Vdata were created successfully, check to see if any extra lines */
425 /* are in the Engineering Data List File. */
426 /********************************************************************************/
427  if (returnStatus == MODIS_S_SUCCESS)
428  {
429  extra_lines = 0;
430  fgets(line, sizeof(line), eng_data_list_handle);
431  fileStatus = MODIS_S_SUCCESS;
432 /********************************************************************************/
433 /* Continue through Engineering Data List File, counting the number of extra */
434 /* lines at the end of the file. */
435 /********************************************************************************/
436  while ((!feof(eng_data_list_handle))&&(!ferror(eng_data_list_handle)))
437  {
438  total_lines++;
439  extra_lines++;
440  fileStatus = MODIS_W_EXCESS_DATA_LIST;
441  fgets(line, sizeof(line), eng_data_list_handle);
442  }
443 /*********************************************************************************/
444 /* If there were extra lines of data in Engineering Data List File, Print warning*/
445 /*********************************************************************************/
446  if (fileStatus == MODIS_W_EXCESS_DATA_LIST)
447  {
448  sprintf(msg, "There are %d additional lines after the end of the "
449  "Engineering Vdata. They were ignored", extra_lines);
451  }
452  }
453  else
455  "General Error Reading from ENG_DATA_LIST File");
456 
457 /*********************************************************************************/
458 /* Close the Engineering Data List File */
459 /*********************************************************************************/
460  PGSstatus = PGS_IO_Gen_Close(eng_data_list_handle);
461  if (PGSstatus != PGS_S_SUCCESS)
463  "error closing eng_data_list_file");
464 
465  } /* end else */
466 
467  return returnStatus;
468 
469 }
#define EN_MAX_VDATA_NUM_BITS
Definition: EN_eng_data.h:92
#define FAIL
Definition: ObpgReadGrid.h:18
#define PC_L1A_ENG_DATA_LIST_FILE
Definition: PC_pcf_info.h:53
#define NULL
Definition: decode_rs.h:63
char global_input_pointer[MAX_INPUTS][PGSd_PC_VALUE_LENGTH_MAX]
Definition: level1a.c:23
#define MS_COMMENT
Definition: MS_misc.h:59
#define EN_MIN_VDATA_TYPE
Definition: EN_eng_data.h:98
#define EN_MAX_VDATA_ORDER
Definition: EN_eng_data.h:95
void create_eng_data_vdata_array_field(char *field_name, uint16 num_bits, uint16 start_bit_pos, uint16 order, uint16 type, EN_VDATA_TYPE_t *eng_data, uint16 curr_eng_data_index, uint16 *curr_field_index)
#define MODIS_E_GETCONFIG_FAILED
#define MODIS_F_INVALID_ENG_DATA_LIST
#define MODIS_E_PGS_IO_GEN_CLOSE
#define EN_MIN_VDATA_ORDER
Definition: EN_eng_data.h:96
PGSt_SMF_status parse_eng_data_list(EN_VDATA_TYPE_t *eng_data)
#define EN_NUM_SCAN_ELEMENTS
Definition: EN_eng_data.h:94
#define EN_MAX_LINE_LEN
Definition: EN_eng_data.h:85
void log_fmt_msg(PGSt_SMF_status code, const char *routine, const char *msg_fmt,...)
Definition: log_fmt_msg.c:6
#define EN_MAX_VDATA_NAME_LENGTH
Definition: EN_eng_data.h:70
#define EN_MAX_VDATA_TYPE
Definition: EN_eng_data.h:97
#define MS_BLANK
Definition: MS_misc.h:58
#define EN_MAX_FIELD_NAME_LENGTH
Definition: EN_eng_data.h:71
PGSt_tag instrument
Definition: EN_eng_data.h:127
#define EN_MIN_VDATA_NUM_BITS
Definition: EN_eng_data.h:93
#define EN_NUM_VDATAS
Definition: EN_eng_data.h:64
#define MODIS_S_SUCCESS
void create_eng_data_vdata_array(char *eng_data_name, EN_VDATA_TYPE_t *eng_data, uint16 *curr_eng_data_index, uint16 *curr_field_index)
#define MODIS_E_PGS_IO_GEN_OPEN
#define isalpha(c)
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)
#define MS_NEW_LINE
Definition: MS_misc.h:60
string msg
Definition: mapgen.py:227
#define MODIS_E_NULL_POINTER
#define MODIS_W_EXCESS_DATA_LIST
char revision[PGSd_PC_VALUE_LENGTH_MAX]
Definition: EN_eng_data.h:126