OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_read_param_file.c
Go to the documentation of this file.
1 /*
2  * $Log: GEO_read_param_file.c,v $
3  * Revision 6.4 2010/04/23 14:48:52 kuyper
4  * Bug 2472: Converted new numbers controlling setting of quality flags into
5  * parameters retrieved from the parameter file.
6  *
7  * Revision 6.3 2009/09/15 20:11:30 kuyper
8  * Corrected #include list.
9  *
10  * James Kuyper James.R.Kuyper@nasa.gov
11  *
12  * Revision 6.2 2009/06/12 20:34:50 kuyper
13  * Changed to allow modification to the characteristics of band 0, without
14  * inappropriate consequences for the calculation of u_tel.
15  *
16  * Revision 6.1 2009/05/26 18:35:21 ltan
17  * Added hires_scale.
18  *
19  * Revision 5.3 2005/10/11 14:55:15 vlin
20  * Code updated to read in orbit descend time, orbit tolerance, orbit period, and
21  * transition orbit number. vlin@saicmodis.com
22  *
23  * Revision 5.2 2005/03/24 17:31:52 kuyper
24  * Corrected handling of macros with empty arguments.
25  *
26  * Revision 5.1 2004/08/03 15:40:17 vlin
27  * Add new spacecraft orientation correction matrix dependent
28  * in a piece-wise linear manner on solar elevation angle.
29  *
30  * Revision 4.8 2003/09/09 19:34:29 kuyper
31  * Corrected handling of rpy_count==0 case.
32  *
33  * Revision 4.7 2003/08/22 22:19:22 kuyper
34  * Changed T_inst2SD to T_sc2SD.
35  *
36  * Revision 4.6 2003/04/02 21:41:37 vlin
37  * Updated after code walk through
38  *
39  * Revision 4.5 2003/01/29 21:14:45 vlin
40  * Updated to get the expected LUT RCS revision value from PCF.
41  * vlin@saicmodis.com
42  *
43  * Revision 4.4 2002/06/06 14:27:12 vlin
44  * Read the value of "rpy_count" from the parameter file.
45  *
46  * Revision 4.3 2002/06/04 14:04:39 vlin
47  * Updated after code walkthrough.
48  *
49  * Revision 4.2 2002/06/03 18:32:43 vlin
50  * Allow return value "PGSTD_E_NO_LEAP_SECS" from function PGS_TD_UTCtoTAI().
51  *
52  */
53 
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <errno.h>
57 #include <ctype.h>
58 #include <stddef.h>
59 #include "PGS_TD.h"
60 #include "GEO_main.h"
61 #include "GEO_main_func.h"
62 
63 
64 typedef enum{integral, floating, revise, string} datatype_enum;
65 
66 static PGSt_SMF_status GEO_read_param(
67  FILE * const param_file,
68  const char name[],
70  size_t size,
71  int elements,
72  char data[])
73 
74 {
75 /***************************************************************************
76 !C
77 
78 !Description:
79  Routine for reading in a single parameter from the parameter file.
80 
81 !Input Parameters:
82  param_file Points at the file handle for parameter file.
83  name Name of the parameter.
84  type The category of the data type.
85  size The size of a single element, in bytes.
86  elements The number of elements in the parameter
87 
88 !Output Parameters:
89  data char pointer to the place where the parameter
90  is to be stored.
91 
92 Return Values:
93  MODIS_E_BAD_SCAN If a call to fscanf() failed.
94  MODIS_E_PREMATURE_EOF If end of file reached unexpectedly.
95  MODIS_E_WRONG_FIELD If a field doesn't have the expected name.
96  PGS_E_UNIX If a standard library function failed.
97  PGS_S_SUCCESS Otherwise
98 
99 Externally Defined:
100  errno errno.h
101  MODIS_E_BAD_SCAN PGS_MODIS_35251.h
102  MODIS_E_PREMATURE_EOF PGS_MODIS_35251.h
103  MODIS_E_WRONG_FIELD PGS_MODIS_35251.h
104  PGS_E_UNIX PGS_SMF.h
105  PGS_S_SUCCESS PGS_SMF.h
106 
107 Called by:
108  GEO_read_param_file()
109 
110 Routines Called:
111  PGS_SMF_SetUnixMsg Reports message based upon 'errno'.
112  modsmf Logs status messages.
113 
114 !Revision History:
115  Please see the top of the file.
116 
117 Requirements:
118  PR03-F-1-1
119  PR03-F-1-2
120  PR03-F-1-3
121  PR03-F-1-4
122  PR03-F-1-5
123  PR03-F-1-6
124 
125 !Team-unique Header:
126 
127  This software is developed by the MODIS Science Data Support
128  Team for the National Aeronautics and Space Administration,
129  Goddard Space Flight Center, under contract NAS5-32373.
130 
131 Design Notes
132 
133 !END
134 *****************************************************************************/
135 
136 /* No need to validate arguments, since caller, which sets their value, is in
137  * the same file.
138  */
139 
140  int i, next_char=0;
141  int ret_val; /* value returned to this function */
142  const char *scanstr="";
143  char buffer[128] = "";
144  char msgbuf[128] = "";
145  char filefunc[] = __FILE__ ", GEO_read_param";
146 
147  while ((next_char=fgetc(param_file))=='#') { /* Skip comment lines. */
148  if (fgets(buffer, sizeof(buffer), param_file)!=buffer) {
149  if (ferror(param_file)) {
150  PGS_SMF_SetUNIXMsg(errno, "fgets()", filefunc);
151  return PGS_E_UNIX;
152  }
153  else {
154  sprintf(msgbuf, "parameter file, for parameter %s \n", name);
155  modsmf(MODIS_E_PREMATURE_EOF, msgbuf, filefunc);
156  return MODIS_E_PREMATURE_EOF;
157  }
158  }
159  }
160 
161  if (next_char==EOF) { /* Failed to read characters. */
162  if (ferror(param_file)) {
163  PGS_SMF_SetUNIXMsg(errno, "fgetc()", filefunc);
164  return PGS_E_UNIX;
165  }
166  else {
167  modsmf(MODIS_E_PREMATURE_EOF, "parameter file.", filefunc);
168  return MODIS_E_PREMATURE_EOF;
169  }
170  }
171  ungetc(next_char, param_file); /* Push character read back into input buffer */
172 
173  ret_val = fscanf(param_file,"%32s = " , buffer); /* Read in parameter name. */
174  if (ret_val!=1) {
175  if (ferror(param_file))
176  PGS_SMF_SetUNIXMsg(errno, "fscanf()", filefunc);
177  sprintf(msgbuf, "(\"%.20s\") returned %d", name, ret_val);
178  modsmf(MODIS_E_BAD_SCAN, msgbuf, filefunc);
179  return MODIS_E_BAD_SCAN;
180  }
181 
182  if (strcmp(name, buffer)!=0) {/* Compare with expected name. */
183  sprintf(msgbuf, "%.20s, actual:%.20s", name, buffer);
184  modsmf(MODIS_E_WRONG_FIELD, msgbuf, filefunc);
185  return MODIS_E_WRONG_FIELD;
186  }
187 
188  /* NOTE: use of sizeof() below allows correct handling of typedefed
189  parameters, such as int32, or PGSt_double. */;
190 
191  if (type == revise) {
192  /* the 31 below must be < sizeof(revision). */
193  scanstr = "%*[$]Revision: %31s $ ";
194  /* The %*[] serves solely to prevent interpretation of this scanstr
195  value as an RCS keyword. The scanstr is supposed to match an RCS
196  Revision keyword string; it's not supposed to be one itself. */
197  }
198  else if (type == string) {
199  scanstr = "%s\n";
200  }
201  else if (type == integral) {
202  if(size == sizeof(int))
203  scanstr = "%d ";
204  else if(size == sizeof(long))
205  scanstr = "%ld ";
206  else if(size == sizeof(short))
207  scanstr = "%hd ";
208  else
209  scanstr = "invalid integral size";
210  }
211  else if (type == floating) {
212  if(size == sizeof(double))
213  scanstr = "%lf ";
214  else if(size == sizeof(float))
215  scanstr = "%f ";
216  else
217  scanstr = "invalid floating point size";
218  }
219  else
220  scanstr = "invalid type";
221 
222  /* Note: the 'invalid' scanstr values above will cause fscanf() to fail
223  below, and the resulting error message will contain 'scanstr'. This
224  should only occur if initialization of members[] is invalid; never
225  during production runs. */
226 
227  /* Scan in each element. */
228  for (i=0; i<elements; i++) {
229  ret_val = fscanf(param_file, scanstr, data);
230  if (ret_val != 1) {
231  if (ferror(param_file))
232  PGS_SMF_SetUNIXMsg(errno, "fscanf()", filefunc);
233  else if (feof(param_file))
234  modsmf(MODIS_E_PREMATURE_EOF, "parameter file. while scanning element.",
235  filefunc);
236  sprintf(msgbuf, "(param_file, \"%.16s\",&%.20s[%d]) returned %d",
237  scanstr, name, i, ret_val);
238  modsmf(MODIS_E_BAD_SCAN, msgbuf, filefunc);
239  return MODIS_E_BAD_SCAN;
240  }
241  data += size;
242  } /* For each element */
243 
244  return PGS_S_SUCCESS;
245 }
246 
247 /*============================================================================*/
248 
249 PGSt_SMF_status GEO_read_param_file(GEO_param_struct *param)
250 {
251 
252 /******************************************************************************
253 !C
254 
255 !Description: Subroutine in Main group of the Level-1A geolocation software
256  to open, read, and close the parameter file, and to compute the telescope
257  view vector from the other parameters.
258 
259 !Input Parameters: None
260 
261 !Output Parameters: GEO_param_struct *param
262 
263 Return parameters:
264  MODIS_E_BAD_INPUT_ARG If any argument was detected as invalid.
265  MODIS_E_GEO If any subroutine (other than PGS_IO_GenClose)
266  fails.
267  MODIS_E_GEO_WRONG_PLATFORM If the platform from the PCF doesn't match the
268  parameters file.
269  MODIS_E_PREMATURE_EOF Reached the end of the parameter file without
270  finding all expected contents.
271  MODIS_E_WRONG_FILE The PCF points to a file which isn't a valid
272  Geolocation parameters file.
273  MODIS_E_WRONG_LUT The incorrect version of the parameters file
274  was used.
275  PGS_E_UNIX An I/O error occurred, for which the value of
276  errno may be a useful diagnostic.
277  PGS_S_SUCCESS Otherwise
278 
279 Externally Defined:
280  errno errno.h
281  BASE_SAMPLES GEO_geo.h
282  MAX_BAND_NUMBER GEO_geo.h
283  MAX_SAMPLES GEO_geo.h
284  MODIS_E_BAD_INPUT_ARG PGS_MODIS_35251.h
285  MODIS_E_GEO PGS_MODIS_35251.h
286  MODIS_E_GEO_WRONG_PLATFORM PGS_MODIS_35251.h
287  MODIS_E_PREMATURE_EOF PGS_MODIS_35251.h
288  MODIS_E_WRONG_FILE PGS_MODIS_35251.h
289  MODIS_E_WRONG_LUT PGS_MODIS_35251.h
290  PARAM GEO_main.h
291  PARAM_TAG GEO_parameters.h
292  PGS_E_UNIX PGS_SMF.h
293  PGS_S_SUCCESS PGS_SMF.h
294  PGSd_IO_Gen_Read PGS_IO_Gen.h
295  PGSd_PC_LINE_LENGTH_MAX PGS_PC.h
296  TIMECODEASIZE smfio.h
297 
298 Called by:
299  main()
300 
301 Routines Called:
302  GEO_read_param - reads in one parameter (which may be an array).
303  modsmf - writes error status messages to log
304  PGS_IO_Gen_Close - closes an ascii file
305  PGS_IO_Gen_Open - opens a general file
306  PGS_SMF_SetUNIXMsg - writes UNIX error status messages to log.
307  PGS_SMF_GetConfigData - reads configuration values from PCF
308 
309 !Revision History:
310  Please see the top of the file.
311 
312 Requirements:
313  PR03-F-1-1
314  PR03-F-1-2
315  PR03-F-1-3
316  PR03-F-1-4
317  PR03-F-1-5
318  PR03-F-1-6
319 
320 !Team-unique Header:
321 
322  This software is developed by the MODIS Science Data Support
323  Team for the National Aeronautics and Space Administration,
324  Goddard Space Flight Center, under contract NAS5-32373.
325 
326 !END
327 ****************************************************************************/
328 
329 #define LUT_REVISION_LUN 600021
330 
331 #define SCALAR_PARM(sub,d,name,type) \
332  GEO_read_param(fp, #name, type, sizeof(param->sub d name), 1, \
333  (char *)&param->sub d name)
334 
335 #define VECTOR_PARM(sub, d, name,type) \
336  GEO_read_param(fp, #name, type, sizeof(param->sub d name[0]), \
337  (int)(sizeof(param->sub d name)/sizeof(param->sub d name[0])), \
338  (char *)&param->sub d name[0])
339 
340 #define ARRAY_PARM(sub, d, name,type) \
341  GEO_read_param(fp, #name, type, sizeof(param->sub d name[0][0]), \
342  (int)(sizeof(param->sub d name)/sizeof(param->sub d name[0][0])), \
343  (char *)&param->sub d name[0][0])
344 
345 /* Local variable declarations */
346 
347  char satellite_instrument[PGSd_PC_LINE_LENGTH_MAX];
348  /* satellite instrument: AM1M for terra, PM1M for aqua */
349  char expected_revision[PGSd_PC_VALUE_LENGTH_MAX];
350  PGSt_IO_Gen_FileHandle *fp;
351  PGSt_PC_Logical SATELLITE_INSTRUMENT_LUN = 800510;
352  /* Logical Unit Number for satellite instrument */
353  PGSt_integer version; /* parameter file version
354  version = 1 for Terra satellite
355  = 2 for Aqua satellite */
356  double center_detector;
357  int i = 0; /* iteration parameter */
358  int det; /* detector number */
359  int band;
360  PGSt_SMF_status status, ret_code = PGS_S_SUCCESS;
361  char (*asciiUTC)[TIMECODEASIZE] = NULL;
362  char msgbuf[64] = "";
363  char buffer[128] = "";
364  char filefunc[] = __FILE__ ", GEO_read_param_file";
365 
366 /* Take configuration parameter value (AM1M/Terra or PM1M/Aqua) from pcf file */
367  status = PGS_PC_GetConfigData(SATELLITE_INSTRUMENT_LUN,
368  satellite_instrument);
369  if (status != PGS_S_SUCCESS) {
370  sprintf(msgbuf, "PGS_PC_GetConfigData()");
371  modsmf(MODIS_E_GEO, msgbuf, filefunc);
372  return MODIS_E_GEO;
373  }
374 
375  if (strcmp(satellite_instrument, "AM1M") == 0)
376  version = 1;
377  else if (strcmp(satellite_instrument, "PM1M") == 0)
378  version = 2;
379  else {
380  sprintf(msgbuf, " SatelliteInstrument is %s", satellite_instrument);
381  modsmf(MODIS_E_GEO_WRONG_PLATFORM, msgbuf, filefunc);
383  }
384 
385 /* Open parameter file for reading */
386  status = PGS_IO_Gen_Open(PARAM, PGSd_IO_Gen_Read, &fp, version);
387  if (status != PGS_S_SUCCESS) {
388  sprintf(msgbuf, "PGS_IO_Gen_Open(%ld) ", (long)PARAM);
389  modsmf(MODIS_E_GEO, msgbuf, filefunc);
390  return MODIS_E_GEO;
391  }
392 
393 /* Read the first line of parameter file */
394  if (fgets(buffer, sizeof(buffer), fp)!=buffer) {
395  if (ferror(fp)) {
396  PGS_SMF_SetUNIXMsg(errno, "fgets()", filefunc);
397  ret_code = PGS_E_UNIX;
398  }
399  else {
400  modsmf(MODIS_E_PREMATURE_EOF, "parameter file.", filefunc);
401  ret_code = MODIS_E_PREMATURE_EOF;
402  }
403  }
404  else { /* Skip leading white space */
405  for(i=0; buffer[i]!='\0' && isspace((int)buffer[i]); i++);
406 
407  if(strncmp(PARAM_TAG, buffer+i, sizeof(PARAM_TAG)-1)!=0)
408  { /* First line of parameter file doesn't contain required PARAM_TAG */
409  modsmf(MODIS_E_WRONG_FILE, buffer+i, filefunc);
410  ret_code = MODIS_E_WRONG_FILE;
411  }
412  }
413 
414 /* Read each geolocation parameter */
415  if ((SCALAR_PARM(, , revision, revise) != PGS_S_SUCCESS) ||
416  (SCALAR_PARM(, , spacecraft_ID, string) != PGS_S_SUCCESS) ||
417  (SCALAR_PARM(geometry_params, ., band_number, integral)!=PGS_S_SUCCESS) ||
418  (VECTOR_PARM(geometry_params, ., N_samp, integral) != PGS_S_SUCCESS) ||
419  (VECTOR_PARM(geometry_params,.,band_position, floating)!=PGS_S_SUCCESS) ||
420  (ARRAY_PARM(geometry_params,.,det_position, floating) != PGS_S_SUCCESS) ||
421  (VECTOR_PARM(geometry_params,.,det_space, floating) != PGS_S_SUCCESS) ||
422  (VECTOR_PARM(geometry_params,.,focal_length, floating)!=PGS_S_SUCCESS) ||
423  (SCALAR_PARM(mirror_prep_params,., N_reset, floating) != PGS_S_SUCCESS) ||
424  (SCALAR_PARM(geometry_params,., t_reset, floating) != PGS_S_SUCCESS) ||
425  (SCALAR_PARM(geometry_params,., t_frame, floating) != PGS_S_SUCCESS) ||
426  (SCALAR_PARM(mirror_prep_params,.,t_vernier, floating)!=PGS_S_SUCCESS) ||
427  (SCALAR_PARM(mirror_prep_params,.,t_encoder, floating)!=PGS_S_SUCCESS) ||
428  (SCALAR_PARM(mirror_prep_params,.,sample_impulse,integral)!=PGS_S_SUCCESS) ||
429  (VECTOR_PARM(geometry_params,.,F_offset, floating) != PGS_S_SUCCESS) ||
430  (VECTOR_PARM(mirror_model,.,mirr_side1_range,floating)!=PGS_S_SUCCESS) ||
431  (SCALAR_PARM(, , poly_degree, integral) != PGS_S_SUCCESS) ||
432  (ARRAY_PARM(, , poly_coef, floating) != PGS_S_SUCCESS) ||
433  (SCALAR_PARM(mirror_model, ., alpha, floating) != PGS_S_SUCCESS) ||
434  (SCALAR_PARM(mirror_model, ., beta, floating) != PGS_S_SUCCESS) ||
435  (SCALAR_PARM(mirror_model, ., gammaa, floating) != PGS_S_SUCCESS) ||
436  (ARRAY_PARM(coord_trans, ., T_tel2inst, floating) != PGS_S_SUCCESS) ||
437  (ARRAY_PARM(coord_trans, ., T_mirr2inst, floating) != PGS_S_SUCCESS) ||
438  (ARRAY_PARM(coord_trans, ., T_inst2sc, floating) != PGS_S_SUCCESS) ||
439  (ARRAY_PARM(coord_trans, ., T_sc2SD, floating) != PGS_S_SUCCESS) ||
440  (SCALAR_PARM(, , max_extrap, floating) != PGS_S_SUCCESS) ||
441  (SCALAR_PARM(ancil_params.ancil_scale_factors, ., S_angvel, floating)
442  !=PGS_S_SUCCESS)||
443  (SCALAR_PARM(ancil_params.ancil_scale_factors, ., S_attitude, floating)
444  !=PGS_S_SUCCESS)||
445  (SCALAR_PARM(ancil_params.ancil_scale_factors, .,S_position, floating)
446  !=PGS_S_SUCCESS) ||
447  (SCALAR_PARM(ancil_params.ancil_scale_factors, .,S_velocity, floating)
448  !=PGS_S_SUCCESS) ||
449  (SCALAR_PARM(, , angle_scale, floating) != PGS_S_SUCCESS) ||
450  (SCALAR_PARM(, , hires_scale, floating) != PGS_S_SUCCESS) ||
451  (SCALAR_PARM(, , range_scale, floating) != PGS_S_SUCCESS) ||
452  (VECTOR_PARM(ancil_params.ancil_words, ., attit_words, integral)
453  != PGS_S_SUCCESS) ||
454  (VECTOR_PARM(ancil_params.ancil_words, ., orbit_words, integral)
455  != PGS_S_SUCCESS) ||
456  (VECTOR_PARM(ancil_params.ancil_words, ., time_words, integral)
457  != PGS_S_SUCCESS) ||
458  (VECTOR_PARM(mirror_prep_params, ., sector_word, integral)
459  != PGS_S_SUCCESS) ||
460  (VECTOR_PARM(mirror_prep_params, ., vernier_word, integral)
461  != PGS_S_SUCCESS) ||
462  (SCALAR_PARM(, , max_non_gap, floating) != SUCCESS) ||
463  (VECTOR_PARM(orbit_valid_params, ., ang_mom_limit, floating)
464  != PGS_S_SUCCESS) ||
465  (VECTOR_PARM(orbit_valid_params, ., ang_mom_z_limit, floating)
466  != PGS_S_SUCCESS) ||
467  (SCALAR_PARM(orbit_valid_params, ., orbit_consistency, floating)
468  != PGS_S_SUCCESS) ||
469  (VECTOR_PARM(orbit_valid_params, ., descend_time_0, floating)
470  !=PGS_S_SUCCESS) ||
471  (VECTOR_PARM(orbit_valid_params, ., orbit_tolerance, floating)
472  !=PGS_S_SUCCESS) ||
473  (VECTOR_PARM(orbit_valid_params, ., period, floating) !=PGS_S_SUCCESS) ||
474  (SCALAR_PARM(orbit_valid_params, ., transition_orbit, integral)
475  !=PGS_S_SUCCESS) ||
476  (VECTOR_PARM(orbit_valid_params, ., position_abs_limit, floating)
477  !=PGS_S_SUCCESS) ||
478  (VECTOR_PARM(orbit_valid_params, ., position_mag_limit, floating)
479  !=PGS_S_SUCCESS) ||
480  (VECTOR_PARM(orbit_valid_params, ., velocity_abs_limit, floating)
481  !=PGS_S_SUCCESS) ||
482  (VECTOR_PARM(orbit_valid_params, ., velocity_mag_limit, floating)
483  !=PGS_S_SUCCESS) ||
484  (SCALAR_PARM(orbit_valid_params, ., eph_max_short_gap, floating)
485  !=PGS_S_SUCCESS) ||
486  (VECTOR_PARM(attit_valid_params, ., angvel_abs_limit, floating)
487  != PGS_S_SUCCESS) ||
488  (SCALAR_PARM(attit_valid_params, ., angvel_del_limit, floating)
489  != PGS_S_SUCCESS) ||
490  (SCALAR_PARM(attit_valid_params, ., attit_consistency, floating)
491  !=PGS_S_SUCCESS) ||
492  (VECTOR_PARM(attit_valid_params, ., attitude_abs_limit, floating)
493  !=PGS_S_SUCCESS) ||
494  (SCALAR_PARM(attit_valid_params, ., attitude_del_limit, floating)
495  !=PGS_S_SUCCESS) ||
496  (VECTOR_PARM(attit_valid_params, ., att_valid_range, integral)
497  !=PGS_S_SUCCESS) ||
498  (SCALAR_PARM(attit_valid_params, ., att_max_short_gap, floating)
499  !=PGS_S_SUCCESS) ||
500  (VECTOR_PARM(mirror_prep_params, ., mirr_abs_limit, floating)
501  != PGS_S_SUCCESS) ||
502  (SCALAR_PARM(mirror_prep_params, ., mirr_del_limit, floating)
503  != PGS_S_SUCCESS) ||
504  (VECTOR_PARM(mirror_prep_params, ., encoder_gap, floating)
505  != PGS_S_SUCCESS) ||
506  (SCALAR_PARM(mirror_prep_params, ., encoder_adjustment, floating)
507  != PGS_S_SUCCESS) ||
508  (SCALAR_PARM(mirror_prep_params, ., packet_interval, floating)
509  != PGS_S_SUCCESS) ||
510  (SCALAR_PARM(, , RMS_error, floating) != PGS_S_SUCCESS) ||
511  (ARRAY_PARM(, , temp_coeff, floating) != PGS_S_SUCCESS) ||
512  (ARRAY_PARM(, , sol_elev_cor, floating) != PGS_S_SUCCESS) ||
513  (SCALAR_PARM(coord_trans, ., rpy_count, integral) != PGS_S_SUCCESS) )
514  {
515  modsmf(MODIS_E_GEO, "GEO_read_param()", filefunc);
516  ret_code = MODIS_E_GEO;
517  }
518  else {
519  if (PGS_PC_GetConfigData(LUT_REVISION_LUN, expected_revision) != PGS_S_SUCCESS) {
520  sprintf(msgbuf, "PGS_PC_GetConfig_data(%d)", LUT_REVISION_LUN);
521  modsmf(MODIS_E_GEO, msgbuf, filefunc);
522  ret_code = MODIS_E_GEO;
523  }
524  else if (strncmp(param->revision, expected_revision, sizeof(expected_revision))){
525  sprintf(msgbuf, "%s, expected: %s", param->revision, expected_revision);
526  modsmf(MODIS_E_WRONG_LUT, msgbuf, filefunc);
527  ret_code = MODIS_E_WRONG_LUT;
528  }
529 
530  if(param->coord_trans.rpy_count)
531  {
532  asciiUTC = (char(*)[TIMECODEASIZE])
533  malloc(param->coord_trans.rpy_count*TIMECODEASIZE);
534  param->coord_trans.rpy_times = (double *)
535  malloc(param->coord_trans.rpy_count*sizeof(double));
536  param->coord_trans.rpy_inst2sc = (double(*)[3])
537  malloc(param->coord_trans.rpy_count*sizeof(double)*3);
538  if (asciiUTC == NULL || param->coord_trans.rpy_times == NULL ||
539  param->coord_trans.rpy_inst2sc == NULL)
540  {
541  modsmf(MODIS_E_GEO, "malloc()", filefunc);
542  ret_code = MODIS_E_GEO;
543  }
544  else {
545  if (GEO_read_param(fp, "rpy_times", string, TIMECODEASIZE,
546  param->coord_trans.rpy_count, (char *)asciiUTC)
547  != PGS_S_SUCCESS ||
548  GEO_read_param(fp, "rpy_inst2sc",floating, sizeof(double),
549  param->coord_trans.rpy_count*3,
550  (char *)param->coord_trans.rpy_inst2sc) != PGS_S_SUCCESS ||
551  GEO_read_param(fp, "end_of_parameters", integral, (size_t)0, 0,
552  0) != PGS_S_SUCCESS)
553  {
554  modsmf(MODIS_E_GEO, "GEO_read_param(rpy params)", filefunc);
555  ret_code = MODIS_E_GEO;
556  }
557 
558  for (i = 0; i < param->coord_trans.rpy_count; i++)
559  {
560  status = PGS_TD_UTCtoTAI(asciiUTC[i],
561  &param->coord_trans.rpy_times[i]);
562  if (status != PGS_S_SUCCESS && status != PGSTD_E_NO_LEAP_SECS)
563  {
564  sprintf(msgbuf, "PGS_TD_UTCtoTAI(%s)", asciiUTC[i]);
565  modsmf(MODIS_E_GEO, msgbuf, filefunc);
566  ret_code = MODIS_E_GEO;
567  }
568  }
569 
570  free(asciiUTC);
571  }
572  }
573  }
574 
575  if (PGS_IO_Gen_Close(fp)!=PGS_S_SUCCESS)
576  modsmf(MODIS_E_GEO, "PGS_IO_GenClose()", filefunc);
577 
578  /* Delayed exit for errors detected while file was open. */
579  if (ret_code != PGS_S_SUCCESS)
580  return ret_code;
581 
582  /* tested the matches between satellite_instruments and spacecraft_IDs.
583  the right couplings are "AM1M/Terra" and "PM1M/Aqua" */
584  if ( (strcmp(satellite_instrument, "AM1M") == 0 &&
585  strcmp(param->spacecraft_ID, "Terra") != 0) ||
586  (strcmp(satellite_instrument, "PM1M") == 0 &&
587  strcmp(param->spacecraft_ID, "Aqua") != 0))
588  {
589  sprintf(msgbuf, ": parameter file is for %s", param->spacecraft_ID);
590  modsmf(MODIS_E_GEO_WRONG_PLATFORM, msgbuf, filefunc);
592  }
593 
594  /* Validity checks of parameters needed for calculation of telescope view
595  vector. */
597  if (band <0 || band > MAX_BAND_NUMBER) {
598  sprintf(msgbuf, "band_number = %d", band);
599  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
600  return MODIS_E_BAD_INPUT_ARG;
601  }
602 
603  if (param->geometry_params.N_samp[band] < 1 ||
605  sprintf(msgbuf, "N_samp[%d] = %hd", band,
606  (short)param->geometry_params.N_samp[band]);
607  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
608  return MODIS_E_BAD_INPUT_ARG;
609  }
610 
611  if (param->geometry_params.focal_length[0]<=0.0) {
612  sprintf(msgbuf, "focal_length[0]=%f",
613  param->geometry_params.focal_length[0]);
614  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
615  return MODIS_E_BAD_INPUT_ARG;
616  }
617 
619  center_detector = 0.5*(double)(param->num_detectors-1);
620 
621  /* Calculate telescope view vector */
622  for (det=0; det<param->num_detectors; det++)
623  {
624  param->u_tel[det][0] = param->geometry_params.det_position[band][0]
626  - 0.5/(double)param->geometry_params.N_samp[band])*
627  param->geometry_params.focal_length[band] * 0.00054/0.380859;
628  /* The band_position is offset by 0.5, because it gives the trailing edge
629  of the detector, rather than the center. */
630 
631  param->u_tel[det][1] = param->geometry_params.det_position[band][1]
632  + (center_detector-(double)det) * param->geometry_params.det_space[band];
633  /* We add (center_detector-det), instead of subtracting it, to implement the
634  detector renumbering required by CCR-184. The purpose is to have
635  increasing detector numbers in the positive track direction. */
636 
637  param->u_tel[det][2] = param->geometry_params.focal_length[band];
638  }
639 
640  return PGS_S_SUCCESS;
641 }
double orbit_consistency
double position_mag_limit[2]
double gammaa
@ revise
@ floating
#define SUCCESS
Definition: ObpgReadGrid.h:15
int status
Definition: l1_czcs_hdf.c:32
#define VECTOR_PARM(sub, d, name, type)
int vernier_word[2]
@ integral
double velocity_abs_limit[2]
#define LUT_REVISION_LUN
double T_mirr2inst[3][3]
#define PARAM_TAG
#define NULL
Definition: decode_rs.h:63
#define MODIS_E_BAD_INPUT_ARG
#define MODIS_E_WRONG_FIELD
internal_coord_trans_struct coord_trans
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 band
char rpy_times[MAX_RPY_COUNT][RPY_TIMECODE_SIZE]
datatype_enum
double ang_mom_limit[2]
double position_abs_limit[2]
#define TIMECODEASIZE
Definition: Metadata.c:59
const double * poly_coef
#define PARAM
Definition: GEO_main.h:69
double band_position[MAX_BAND_NUMBER_PLUS_ONE]
#define MODIS_E_GEO
double attitude_del_limit
#define SCALAR_PARM(sub, d, name, type)
float64 det_space[MAX_BAND_NUMBER+1]
PGSt_SMF_status GEO_read_param_file(GEO_param_struct *param)
#define MAX_SAMPLES
Definition: GEO_geo.h:102
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan to ensure that all gflag bits get accumulated Changed GEO_write_ECS_metadata to write PGEVERSION as Changed GEO_locate_one_granule c to make a failure to find an orbit number in the staged ephemeris files be non fatal Updated GEO_parameters dat to reflect latest estimate of T_inst2sc
Definition: HISTORY.txt:472
double ang_mom_z_limit[2]
unsigned short N_samp[MAX_BAND_NUMBER_PLUS_ONE]
unsigned char revision[10]
#define BASE_SAMPLES
Definition: GEO_geo.h:101
focal_plane_geometry_struct geometry_params
#define SATELLITE_INSTRUMENT_LUN
Definition: FNames.h:85
double velocity_mag_limit[2]
#define ARRAY_PARM(sub, d, name, type)
double attitude_abs_limit[2]
#define MODIS_E_GEO_WRONG_PLATFORM
double focal_length[MAX_BAND_NUMBER_PLUS_ONE]
#define MODIS_E_WRONG_FILE
int errno
double T_tel2inst[3][3]
double det_position[MAX_BAND_NUMBER_PLUS_ONE][2]
integer, parameter double
constexpr float focal_length
double angvel_abs_limit[2]
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define isspace(c)
double beta
#define MODIS_E_WRONG_LUT
double angvel_del_limit
#define MODIS_E_PREMATURE_EOF
const int MAX_BAND_NUMBER
double mirr_side1_range[2]
#define MODIS_E_BAD_SCAN
double u_tel[DETECTORS_QKM][3]
MOD_PR01 Production producing one five minute granule of output data in each run It can be configured to produce as many as three five minute granules per run Each execution with one construction record and one date file for each dataset In normal these are created by which splits them out of the hour datasets For LANCE they are created by which merges all session MODIS L0 datasets overlapping the requested time period
Definition: MOD_PR01_pr.txt:15
double attit_consistency
int i
Definition: decode_rs.h:71
int sector_word[2]
version
Definition: setup.py:15
int poly_degree