OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_locate_one_scan.c
Go to the documentation of this file.
1 #include "GEO_earth.h"
2 #include "GEO_global_arrays.h"
3 #include "GEO_input.h"
4 #include "GEO_inst.h"
5 #include "GEO_output.h"
6 #include "GEO_validation.h"
7 #include "PGS_MODIS_35251.h"
8 #include <strings.h>
9 
10 /* sample time for all the pixels in a scan (relative to sector start time */
11 double *sample_time;
12 
13 PGSt_SMF_status GEO_locate_one_scan(
14  GEO_param_struct const * const geo_params,
15  l1a_data_struct * const l1a_data,
16  int const scan_number,
17  qa_metadata_struct * const qa_metadata,
18  GEO_bcoord_struct * const bounding_coords,
19  MODFILE * const geo_file
20 )
21 /*****************************************************************************
22 !C
23 
24 !Description:
25  Routine in Output group of the Level-1A geolocation software to
26  geolocate one scan and write to output file. For each sample in a
27  scan, it call routines to: compute and validate the Earth locations
28  for the pixels, and compute and validate the sensor and solar angles
29  for the pixels. It then calls the routine to write the data for the
30  entire scan to the geolocation product file.
31 
32 !Input Parameters:
33 
34  geo_params structure containing geolocation process parameters
35  from the parameter file.
36  scan_number the scan number
37  geo_file structure used to reference the geolocation file in
38  the MAPI library
39 
40 !Output Parameters:
41 
42  qa_metadata structure for accumulating data quality measures
43  bounding_coords structure of the granules bounding coordinates
44 
45 Input/Output Parameters:
46  l1a_data data read from L1A file.
47 
48 Return values:
49  MODIS_E_BAD_INPUT_ARG One of the input arguments had an invalid value
50  MODIS_E_GEO A subroutine failed.
51  PGS_S_SUCCESS Otherwise.
52 
53 Externally Defined:
54  BAD_DATA "GEO_validation.h"
55  DBL_MIN "float.h"
56  DETECTORS_1KM "GEO_geo.h"
57  DETECTORS_QKM "GEO_geo.h"
58  GEO_DOUBLE_FILLVALUE "GEO_output.h"
59  GOOD_DATA "GEO_validation.h"
60  INVALID_INPUT_DATA "GEO_geo.h"
61  INVALID_SOLAR_ANGLES "GEO_geo.h"
62  MAX_FRAMES "GEO_geo.h"
63  MAX_PADDED "GEO_geo.h"
64  MAX_SCAN_NUMBER "GEO_geo.h"
65  MODIS_E_BAD_INPUT_ARG "PGS_MODIS_35251.h"
66  MODIS_E_GEO "PGS_MODIS_35251.h"
67  NO_ELLIPSE_INTERSECT "GEO_geo.h"
68  SAMPLES_QKM "GEO_geo.h"
69  sample_time "GEO_global_arrays.h"
70  SUCCESS "GEO_basic.h"
71  TIMECODEASIZE "smfio.h"
72 
73  Note: sample_time has external linkage, but is to be defined in this
74  module.
75 
76 Called by:
77  GEO_locate_one_granule
78 
79 Routines called:
80  GEO_aggregate "GEO_earth.h"
81  GEO_cumulate_GRing "GEO_input.h"
82  GEO_derived_products "GEO_output.h"
83  GEO_earth_location "GEO_earth.h"
84  GEO_get_bounding_coords "GEO_output.h"
85  GEO_get_sample_time "GEO_inst.h"
86  GEO_interp_ECR "GEO_earth.h"
87  GEO_validate_derived_products "GEO_validation.h"
88  GEO_validate_earth_location "GEO_validation.h"
89  GEO_write_one_scan "GEO_output.h"
90  modsmf "smfio.h"
91 
92 !Revision History:
93 $Log: GEO_locate_one_scan.c,v $
94 Revision 6.7 2011/02/18 21:59:34 kuyper
95 In order to resolve feature-request Bug 3446, changed to retrieve landsea
96  mask at high resolution, and then aggregate to low resolution, filling in
97  new waterpresent array.
98 
99 Revision 6.6 2010/06/29 20:11:22 kuyper
100 Declared many arrays static, solely to reduce strain on stack.
101 
102 Revision 6.5 2010/06/18 20:11:25 kuyper
103 Corrected handling of int32 arguments passed to sprintf().
104 
105 Revision 6.4 2010/05/27 17:58:07 kuyper
106 Helped resolve Bug 1969 by creating rpy, filling it in by calling
107  GEO_interp_ECR(), and passing it to GEO_write_one_scan().
108 Helped resolve Bug 2470 by removing a parameter.
109 Helped resolve Bug 2472 by filling in, aggregating, and writing out
110  the ephemeris and attitude quality flags, and passing the entire Geolocation
111  parameters struct to GEO_interp_ECR().
112 Resolved Bug 2949 by removing pointless and dangerous code.
113 Stopped passing num_detectors as an argument to GEO_aggregate().
114 Changed to return a status code.
115 
116 James Kuyper James.R.Kuyper@NASA.gov
117 
118 Revision 6.3 2009/05/31 22:08:40 kuyper
119 Corrected to initialize sample_flags.
120 Corrected to use DETECTORS_1KM as loop limit.
121 
122 Revision 6.2 2009/05/30 23:32:12 kuyper
123 Corrected definition of sample_time to be at file scope.
124 Removed macros no longer referenced.
125 Corrected to validate geo_file.
126 Corrected frame->samp.
127 Changed to pass l1b_data to GEO_earth_location(), rather than
128  scan_start_time[scan_number]
129 Corrected expected return value for GEO_validate_derived_products().
130 
131 Revision 6.1 2009/05/28 22:51:25 kuyper
132 Changed to support both high-resolution and low-resolution data, connected
133  by a call to GEO_aggregate.
134 Changed most global arrays to local arrays.
135 Moved definition and setting of sample_time global into this function.
136 Moved definition and setting of parameter globals into GEO_earth_location().
137 Corrected to cumulate gflags only after validation of derived products,
138  resolving Bug 2199.
139 Changed interface of most subroutines.
140 Dropped qa_flag member of frame_state_struct.
141 Improved error messaging.
142 Removed sc_ev_frame_state argument from GEO_write_one_scan; long obsolete..
143 
144 James Kuyper Jr. James.R.Kuyper@nasa.gov
145 
146 Revision 5.4 2006/01/27 17:19:06 kuyper
147 Corrected to set impulse_flag to GOOD_DATA only if GEO_interp_ECR() call
148  succeeds.
149 
150 Revision 5.3 2005/12/02 22:42:05 kuyper
151 Corrected to write scan data that does not depend upon earth view start time,
152  even if earth view start time is a fill value.
153 
154 Revision 5.2 2004/10/14 20:22:53 kuyper
155 Changed to pass geo_params->sol_elev_cor to GEO_interp_ECR().
156 
157 Revision 5.1 2004/08/30 17:02:27 vlin
158 1. input parameter maneuver_list added.
159 2. Check for invalid EV start time.
160 3. call to GEO_write_one_scan updated.
161 
162 Revision 4.8 2004/05/12 19:45:26 kuyper
163 Corrected to initialize impulse flag with GOOD_DATA, where appropriate,
164 rather than relying upon default initialization (which is not actually
165 guaranteed to occur).
166 
167 Revision 4.7 2004/04/09 18:09:08 kuyper
168 Corrected to make MODIS_E_GEO error from GEO_interp_ECR() non-fatal.
169 
170 Revision 4.6 2003/12/26 19:08:49 vlin
171 Two functions added in "Routines called" section.
172 
173 Revision 4.5 2003/10/22 19:31:06 vlin
174 Beef up message for invalid input argument(s).
175 
176 Revision 4.4 2003/08/26 19:31:53 kuyper
177 Corrected test for INVALID_SOLAR_ANGLES bit.
178 
179 Revision 4.3 2003/08/22 22:08:49 kuyper
180 Changed to give a T_sc2ecr work area to GEO_interp_ECR().
181 
182 Revision 4.2 2003/08/22 14:24:50 kuyper
183 Moved in definition of T_inst2ecr.
184 Corrected transfer of eulerAngles.
185 
186 Revision 4.1 2003/08/13 20:40:15 kuyper
187 Added calls to GEO_get_sample_time() and GEO_interp_ECR().
188 Changed interface of GEO_derived_products to process an entire scan in one
189  call, requiring splitting of the frame loop.
190 Moved the definitions of sample_to_sensor and sample_solar_angles into this
191  module.
192 Added code to move eulerangles to sc_attitude.
193 
194 5/23/95
195 Frederick S. Patt (patt@modis-xl.gsfc.nasa.gov)
196 Finished coding.
197 
198 Requirements:
199  PR03-F-3.1.1-1
200  PR03-F-3.1.1-2
201  PR03-F-3.1.2-1
202  PR03-F-3.1.2-2
203  PR03-F-3.1.3-1
204  PR03-F-3.1.4-1
205  PR03-F-3.2.1-1
206  PR03-F-3.2.1-2
207  PR03-F-3.2.2-1
208  PR03-F-3.2.3-1
209  PR03-F-3.2.3-2
210  PR03-F-3.2.4-1
211  PR03-F-3.3.1-1
212  PR03-F-3.3.2-1
213  PR03-F-3.3.3-1
214  PR03-F-3.3.3-2
215  PR03-F-3.4.1-1
216  PR03-F-3.4.2-1
217  PR03-F-3.4.3-1
218  PR03-F-3.4.4-1
219  PR03-F-3.5.1-1
220  PR03-F-3.5.2-1
221  PR03-F-3.5.3-1
222  PR03-F-3.5.3-2
223  PR03-F-3.5.3-3
224  PR03-F-3.6.1-1
225  PR03-F-3.6.2-1
226  PR03-F-3.6.3-1
227  PR03-F-3.6.3-2
228  PR03-F_4.2-1
229  PR03-F_4.2-2
230 
231 
232 !Team-unique Header:
233 
234  This software is developed by the MODIS Science Data Support
235  Team for the National Aeronautics and Space Administration,
236  Goddard Space Flight Center, under contract NAS5-32373.
237 
238 !END
239 **************************************************************************/
240 
241 {
242  frame_state_struct sc_ev_frame_state[MAX_FRAMES] = {{0.0}};
243  int samp, frame, det;
244  int missing_count, outofbounds_count; /* flag counters */
245  uint32 mask;
246 
247  /* sample time relative to sector start time*/
248  static double *frame_time;
249 
250  /* The largest of the following arrays are declared static, not so their
251  * values can be retained from one call to the next, but to minimize
252  * strain on stack.
253  */
254  /* pixel-to-satellite angles (azimuth, zenith), and range */
255  typedef double frame_to_sensor_t[MAX_FRAMES][3];
256  static frame_to_sensor_t *frame_to_sensor;
257 
258  /* solar azimuth and zenith angles for all the pixels in a scan */
259  /* azimuth, zenith */
260  typedef double frame_solar_angles_t[MAX_FRAMES][2];
261  static frame_solar_angles_t *frame_solar_angles;
262 
263  /* instrument to ECR transformation */
264  typedef double T_inst2ecr_t[3][3];
265  static T_inst2ecr_t *T_inst2ecr;
266 
267  /* ECR ground location */
268  typedef double ecr_sample_position_t[MAX_PADDED][3];
269  static ecr_sample_position_t *ecr_sample_position;
270 
271  typedef double ecr_frame_position_t[MAX_FRAMES][3];
272  static ecr_frame_position_t *ecr_frame_position;
273 
274  /* terrain corrected position in geodetic coordinates:
275  * latitude, longitude, height
276  */
277  typedef double terrain_sample_position_t[MAX_PADDED][3];
278  static terrain_sample_position_t *terrain_sample_position;
279 
280  typedef double terrain_frame_position_t[MAX_FRAMES][3];
281  static terrain_frame_position_t *terrain_frame_position;
282 
283  /* Land/Water mask, and WaterPresent */
284  typedef uint8 sample_landsea_t[MAX_PADDED];
285  static sample_landsea_t *sample_landsea;
286 
287  typedef uint8 frame_landsea_t[MAX_FRAMES];
288  static frame_landsea_t *frame_landsea;
289 
290  typedef uint8 frame_waterpresent_t[MAX_FRAMES];
291  static frame_waterpresent_t *frame_waterpresent;
292 
293  uint8 land_seamask_qaflag;
294 
295  /* geolocation flags */
296  typedef uint8 sample_flags_t[MAX_PADDED];
297  static sample_flags_t *sample_flags;
298 
299  typedef uint8 frame_flags_t[MAX_FRAMES];
300  static frame_flags_t *frame_flags;
301 
302  /* spacecraft ECR position */
303  typedef double ecr_sc_t[3];
304  static ecr_sc_t *ecr_sc_sample_position;
305  static ecr_sc_t *ecr_sc_frame_position;
306 
307  /* spacecraft ECR velocity */
308  static ecr_sc_t *ecr_sc_velocity;
309 
310  static sc_state_struct *sc_state;
311 
312  char asciiUTC[TIMECODEASIZE];
313  PGSt_SMF_status interp_ecr_status;
314 
315  typedef int8 hires_offsets_t[DETECTORS_QKM][SAMPLES_QKM];
316  static hires_offsets_t *hires_offsets;
317 
318  static PGSt_double *offsets;
319 
320  typedef double T_sc2ecr_t[3][3];
321  static T_sc2ecr_t *T_sc2ecr;
322 
323  typedef uint32 *sample_quality_t[2];
324  static sample_quality_t *sample_quality;
325 
326  typedef uint32 *frame_quality_t[MAX_FRAMES];
327  static frame_quality_t *frame_quality;
328 
329  static int firstRun = 1;
330  if(firstRun) {
331  firstRun = 0;
332 
333  sample_time = (double*) malloc(MAX_PADDED * sizeof(double));
334  frame_time = (double*) malloc(MAX_FRAMES * sizeof(double));
335  frame_to_sensor = (frame_to_sensor_t*) calloc(DETECTORS_1KM, sizeof(frame_to_sensor_t));
336  frame_solar_angles = (frame_solar_angles_t*) calloc(DETECTORS_1KM, sizeof(frame_solar_angles_t));
337  T_inst2ecr = (T_inst2ecr_t*) calloc(MAX_PADDED, sizeof(T_inst2ecr_t));
338  ecr_sample_position = (ecr_sample_position_t*) calloc(DETECTORS_QKM, sizeof(ecr_sample_position_t));
339  ecr_frame_position = (ecr_frame_position_t*) calloc(DETECTORS_1KM, sizeof(ecr_frame_position_t));
340  terrain_sample_position = (terrain_sample_position_t*) calloc(DETECTORS_QKM, sizeof(terrain_sample_position_t));
341  terrain_frame_position = (terrain_frame_position_t*) calloc(DETECTORS_1KM, sizeof(terrain_frame_position_t));
342  sample_landsea = (sample_landsea_t*) calloc(DETECTORS_QKM, sizeof(sample_landsea_t));
343  frame_landsea = (frame_landsea_t*) calloc(DETECTORS_1KM, sizeof(frame_landsea_t));
344  frame_waterpresent = (frame_waterpresent_t*) calloc(DETECTORS_1KM, sizeof(frame_waterpresent_t));
345  sample_flags = (sample_flags_t*) calloc(DETECTORS_QKM, sizeof(sample_flags_t));
346  frame_flags = (frame_flags_t*) calloc(DETECTORS_1KM, sizeof(frame_flags_t));
347  ecr_sc_sample_position = (ecr_sc_t*) calloc(MAX_PADDED, sizeof(ecr_sc_t));
348  ecr_sc_frame_position = (ecr_sc_t*) calloc(MAX_FRAMES, sizeof(ecr_sc_t));
349  ecr_sc_velocity = (ecr_sc_t*) calloc(MAX_PADDED, sizeof(ecr_sc_t));
350  sc_state = (sc_state_struct*) calloc(MAX_PADDED, sizeof(sc_state_struct));
351  hires_offsets = (hires_offsets_t*) calloc(3, sizeof(hires_offsets_t));
352  offsets = calloc(MAX_PADDED, sizeof(PGSt_double));
353  T_sc2ecr = (T_sc2ecr_t*) calloc(MAX_PADDED, sizeof(T_sc2ecr_t));
354  sample_quality = (sample_quality_t*) calloc(MAX_PADDED, sizeof(sample_quality_t));
355  frame_quality = (frame_quality_t*) calloc(2, sizeof(frame_quality_t));
356 
357  }
358 
359  bzero(sample_flags, DETECTORS_QKM * sizeof(sample_flags_t));
360 
361 
362  PGSt_double rpy[3] =
364  int N_samp;
365  int padded_samples;
366  char filefunc[] = __FILE__ ", GEO_locate_one_scan";
367  char msgbuf[PGS_SMF_MAX_MSGBUF_SIZE];
368  PGSt_SMF_status retval = PGS_S_SUCCESS;
369 
370  if(geo_params == NULL || l1a_data == NULL || qa_metadata == NULL ||
371  geo_file == NULL || scan_number < 0 || scan_number >= MAX_SCAN_NUMBER)
372  {
373  sprintf(msgbuf, "geo_params:%p, l1a_data:%p, \n"
374  "qa_metadata:%p, geo_file:%p, scan_number:%d",
375  (void *)geo_params, (void *)l1a_data, (void *)qa_metadata,
376  (void*)geo_file, scan_number);
377  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
378 
379  return MODIS_E_BAD_INPUT_ARG;
380  }
381 
382  l1a_data->mirr_data[scan_number].impulse_flag = BAD_DATA;
383 
384  if ((fabs(scan_start_time[scan_number]-
385  l1a_data->fill_values.EV_start_time) < DBL_MIN)
386  || (l1a_data->frame_data[scan_number].EV_frames < 0)
387  || (l1a_data->frame_data[scan_number].EV_frames > MAX_FRAMES))
388  {
389  sprintf(msgbuf, "EV_start_time:%f EV_frames:%ld",
390  scan_start_time[scan_number],
391  (long)(l1a_data->frame_data[scan_number].EV_frames));
392  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
393  l1a_data->frame_data[scan_number].EV_frames = 0;
394  padded_samples = 0;
395  interp_ecr_status = MODIS_E_BAD_INPUT_ARG;
396  }
397  else
398  {
399  N_samp = geo_params->geometry_params.N_samp
400  [geo_params->geometry_params.band_number];
401  padded_samples =
402  (l1a_data->frame_data[scan_number].EV_frames + 1) * N_samp - 1;
403 
404  for (samp = 0; samp < padded_samples; samp++)
405  {
406  sample_time[samp] =
407  GEO_get_sample_time(&geo_params->geometry_params, samp);
408  if(sample_time[samp] >= GEO_DOUBLE_FILLVALUE)
409  {
410  sprintf(msgbuf, "GEO_get_sample_time(%d)", samp);
411  modsmf(MODIS_E_GEO, msgbuf, filefunc);
412 
413  return MODIS_E_GEO;
414  }
415  offsets[samp] = (PGSt_double)sample_time[samp];
416  }
417 
418  for(frame=0; frame<l1a_data->frame_data[scan_number].EV_frames; frame++)
419  frame_time[frame] = sample_time[N_samp * (frame + 1) - 1];
420 
421  if(padded_samples < MAX_PADDED) /* Mark the end of the data. */
422  sample_time[padded_samples] = GEO_DOUBLE_FILLVALUE;
423 
424  interp_ecr_status = GEO_interp_ECR(
425  l1a_data->frame_data[scan_number].EV_start, padded_samples, offsets,
426  geo_params, asciiUTC, sc_state, T_sc2ecr, T_inst2ecr,
427  ecr_sc_sample_position, ecr_sc_velocity, rpy, sample_quality);
428  if(interp_ecr_status != PGS_S_SUCCESS)
429  {
430  sprintf(msgbuf, "GEO_interp_ECR(%f, %d)",
431  l1a_data->frame_data[scan_number].EV_start, padded_samples);
432  modsmf(MODIS_E_GEO, msgbuf, filefunc);
433 
434  /* Most MODIS_E_GEO returns are for reasons that should be
435  * non-fatal.
436  */
437  if(interp_ecr_status != MODIS_E_GEO)
438  retval = MODIS_E_GEO;
439  }
440  else
441  l1a_data->mirr_data[scan_number].impulse_flag = GOOD_DATA;
442  }
443 
444  /* Loop on samples in scan */
445 
446  for (samp=0; samp<padded_samples; samp++)
447  {
448  if(interp_ecr_status != PGS_S_SUCCESS)
449  {
450  for (det = 0; det < geo_params->num_detectors; det++)
451  sample_flags[det][samp] |= INVALID_INPUT_DATA;
452  }
453  else if (l1a_data->mirr_data[scan_number].impulse_flag == GOOD_DATA)
454  {
455  /* Perform Earth location */
456 
457  if(GEO_earth_location(scan_number, samp,
458  (GEO_param_struct*)geo_params, sample_time[samp], l1a_data,
459  ecr_sc_sample_position, ecr_sc_velocity, T_inst2ecr,
460  sample_flags, ecr_sample_position, terrain_sample_position)
461  != PGS_S_SUCCESS)
462  {
463  sprintf(msgbuf, "GEO_earth_location(%d, %d)",
464  scan_number, frame);
465  modsmf(MODIS_E_GEO, msgbuf, filefunc);
466  for (det = 0; det < geo_params->num_detectors; det++)
467  sample_flags[det][samp] |= INVALID_INPUT_DATA;
468 
469  retval = MODIS_E_GEO;
470  }
471 
472  /* Validate Earth location */
474  l1a_data->mirr_data[scan_number].impulse_flag,
475  terrain_sample_position, samp, geo_params->num_detectors,
476  sample_flags) != SUCCESS)
477  {
478  sprintf(msgbuf, "GEO_validate_earth_location(%d, %d)",
479  scan_number, samp);
480  modsmf(MODIS_E_GEO, msgbuf, filefunc);
481 
482  retval = MODIS_E_GEO;
483  }
484  }
485 
486  } /* End of sample loop */
487 
488  if(interp_ecr_status == PGS_S_SUCCESS)
489  {
490  if(l1a_data->mirr_data[scan_number].impulse_flag!=GOOD_DATA)
491  land_seamask_qaflag = 1;
492  else
493  {
494  if(GEO_landsea_mask(padded_samples, geo_params->num_detectors,
495  terrain_sample_position, sample_flags, &land_seamask_qaflag,
496  sample_landsea) != PGS_S_SUCCESS)
497  {
498  sprintf(msgbuf, "GEO_landsea_mask(%d, %d) failed.\n",
499  padded_samples, geo_params->num_detectors);
500  modsmf(MODIS_E_GEO, msgbuf, filefunc);
501 
502  retval = MODIS_E_GEO;
503  }
504  }
505 
506  if(GEO_aggregate(l1a_data->frame_data[scan_number].EV_frames, N_samp,
507  geo_params->hires_scale, sample_flags, ecr_sample_position,
508  ecr_sc_sample_position, terrain_sample_position, sample_quality,
509  sample_landsea, ecr_frame_position, terrain_frame_position,
510  frame_flags, ecr_sc_frame_position, hires_offsets, frame_quality,
511  frame_landsea, frame_waterpresent) != PGS_S_SUCCESS)
512  {
513  sprintf(msgbuf, "GEO_aggregate(%d, %ld, %d, %f)",
514  geo_params->num_detectors,
515  (long)l1a_data->frame_data[scan_number].EV_frames, N_samp,
516  geo_params->hires_scale);
517  modsmf(MODIS_E_GEO, msgbuf, filefunc);
518 
519  retval = MODIS_E_GEO;
520  }
521 
522  if(GEO_derived_products(l1a_data->frame_data[scan_number].EV_frames,
523  DETECTORS_1KM, ecr_frame_position, ecr_sc_frame_position,
524  frame_flags, terrain_frame_position, asciiUTC, frame_time,
525  frame_solar_angles, frame_to_sensor) != PGS_S_SUCCESS)
526  {
527  sprintf(msgbuf, "GEO_derived_products(%ld, %d, \"%s\")",
528  (long)l1a_data->frame_data[scan_number].EV_frames,
529  DETECTORS_1KM, asciiUTC);
530  modsmf(MODIS_E_GEO, msgbuf, filefunc);
531 
532  retval = MODIS_E_GEO;
533  }
534 
535  for(frame=0; frame<l1a_data->frame_data[scan_number].EV_frames; frame++)
536  {
537  int ecr;
538 
539  if((frame_flags[0][frame] & INVALID_SOLAR_ANGLES) == 0)
540  {
541  /* Validate derived products */
543  geo_params->range_scale, frame_to_sensor, frame_flags)
544  != PGS_S_SUCCESS)
545  {
546  sprintf(msgbuf, "GEO_validate_derived_products(%d, %d, %f)",
547  frame, DETECTORS_1KM, geo_params->range_scale);
548  modsmf(MODIS_E_GEO, msgbuf, filefunc);
549 
550  retval = MODIS_E_GEO;
551  }
552  }
553 
554  /* Update data quality measurments */
555  missing_count = 0;
556  outofbounds_count = 0;
557  for (det = 0; det < DETECTORS_1KM; det++)
558  {
559  int bit;
560 
561  if ((frame_flags[det][frame] & INVALID_INPUT_DATA) != 0)
562  missing_count++;
563 
564  if ((frame_flags[det][frame] & INVALID_INPUT_DATA) == 0 &&
565  (frame_flags[det][frame] & NO_ELLIPSE_INTERSECT) != 0 )
566  outofbounds_count++;
567 
568  for (mask=1, bit=0; bit<8; bit++, mask*=2)
569  {
570  if ((unsigned)frame_flags[det][frame] & mask)
571  qa_metadata->cumulated_gflags[bit]++;
572  }
573  }
574  qa_metadata->no_of_pixels += DETECTORS_1KM;
575  qa_metadata->missingdata += missing_count;
576  qa_metadata->outofboundsdata += outofbounds_count;
577 
578  /* Subsampled frame data. */
579  samp = N_samp*(frame + 1) - 1;
580 
581  for (ecr = 0; ecr < 3; ecr++)
582  {
583  sc_ev_frame_state[frame].positionECR[ecr] =
584  ecr_sc_sample_position[samp][ecr];
585  sc_ev_frame_state[frame].velocityECR[ecr] =
586  ecr_sc_velocity[samp][ecr];
587  /* This array is ued only by GEO_cumulate_GRing(), and those
588  * are the only two fields used by that function.
589  */
590  }
591  }
592  }
593 
594  /* Write one scan of geolocation data to file */
595  if (GEO_write_one_scan(frame_time, scan_number, l1a_data, geo_params,
596  frame_to_sensor, frame_solar_angles, terrain_frame_position,
597  frame_flags, hires_offsets, rpy, frame_quality, frame_landsea,
598  frame_waterpresent, land_seamask_qaflag, geo_file) != PGS_S_SUCCESS)
599  {
600  sprintf(msgbuf, "GEO_write_one_scan(%d, \"%s\")",
601  scan_number, geo_file->filename);
602  modsmf(MODIS_E_GEO, msgbuf, filefunc);
603 
604  retval = MODIS_E_GEO;
605  }
606 
607  if(interp_ecr_status == PGS_S_SUCCESS)
608  {
609  if (GEO_cumulate_GRing(geo_params,
610  l1a_data->frame_data[scan_number].EV_frames, sc_ev_frame_state,
611  frame_flags, ecr_frame_position) != PGS_S_SUCCESS)
612  {
613  sprintf(msgbuf, "GEO_cumulate_GRing(%ld)",
614  (long)l1a_data->frame_data[scan_number].EV_frames);
615  modsmf(MODIS_E_GEO, msgbuf, filefunc);
616 
617  retval = MODIS_E_GEO;
618  }
619 
620  if (GEO_get_bounding_coords(terrain_frame_position, frame_flags,
622  l1a_data->frame_data[scan_number].EV_frames, bounding_coords)
623  != SUCCESS)
624  {
625  sprintf(msgbuf, "GEO_get_bounding_coords(%d, %ld)", DETECTORS_1KM,
626  (long)l1a_data->frame_data[scan_number].EV_frames);
627  modsmf(MODIS_E_GEO, msgbuf, filefunc);
628 
629  retval = MODIS_E_GEO;
630  }
631  }
632 
633  return retval;
634 }
635 
PGSt_SMF_status GEO_validate_earth_location(int const mirr_impulse_flag, double terrain_sample_position[][MAX_PADDED][3], int const sample_number, int const num_detectors, unsigned char sample_flags[][MAX_PADDED])
#define SUCCESS
Definition: ObpgReadGrid.h:15
PGSt_SMF_status GEO_aggregate(int32 EV_frames, uint16 N_samp, double hires_scale, unsigned char sample_flags[][MAX_PADDED], double ecr_sample_position[][MAX_PADDED][3], double ecr_sc_sample_position[][3], double terrain_sample_position[][MAX_PADDED][3], uint32 sample_quality[][QFL_IDXS], uint8 sample_landsea[][MAX_PADDED], double ecr_frame_position[][MAX_FRAMES][3], double terrain_frame_position[][MAX_FRAMES][3], uint8 frame_flags[][MAX_FRAMES], double ecr_sc_frame_position[MAX_FRAMES][3], int8 hires_offsets[][DETECTORS_QKM][SAMPLES_QKM], uint32 frame_quality[][MAX_FRAMES], uint8 frame_landsea[][MAX_FRAMES], uint8 frame_waterpresent[][MAX_FRAMES])
double * sample_time
int GEO_get_bounding_coords(double terrain_sample_position[MAX_DETECTORS][MAX_SCAN_SAMPLE][3], unsigned char pixel_flags[MAX_DETECTORS][MAX_SCAN_SAMPLE], int const num_detectors, int const num_frames, GEO_bcoord_struct *const bounding_coords)
#define NULL
Definition: decode_rs.h:63
#define MODIS_E_BAD_INPUT_ARG
#define MAX_FRAMES
Definition: GEO_geo.h:79
PGSt_SMF_status GEO_earth_location(int const, int const, GEO_param_struct const *, double, l1a_data_struct *, double[][3], double[][3], double[][3][3], unsigned char[][MAX_PADDED], double[][MAX_PADDED][3], double[][MAX_PADDED][3])
PGSt_SMF_status GEO_cumulate_GRing(GEO_param_struct const *const params, int32 const num_frames, frame_state_struct const sc_ev_frame_state[], unsigned char frame_flags[DETECTORS_1KM][MAX_FRAMES], double ecr_frame_position[DETECTORS_1KM][MAX_FRAMES][3])
PGSt_SMF_status GEO_interp_ECR(PGSt_double const base_time, PGSt_integer const numValues, const PGSt_double offsets[], GEO_param_struct const *params, char asciiUTC[], sc_state_struct sc_state[], double T_sc2ecr[][3][3], double T_inst2ecr[][3][3], double positionECR[][3], double velocityECR[][3], PGSt_double rpy[], uint32 sample_quality[][2])
Definition: GEO_interp_ECR.c:4
PGSt_SMF_status GEO_locate_one_scan(GEO_param_struct const *const geo_params, l1a_data_struct *const l1a_data, int const scan_number, qa_metadata_struct *const qa_metadata, GEO_bcoord_struct *const bounding_coords, MODFILE *const geo_file)
const unsigned char NO_ELLIPSE_INTERSECT
int16_t * l1a_data
Definition: l1a_seawifs.c:84
#define MAX_PADDED
Definition: GEO_geo.h:84
const int BAD_DATA
#define TIMECODEASIZE
Definition: Metadata.c:59
void bzero()
#define MODIS_E_GEO
#define GEO_DOUBLE_FILLVALUE
Definition: GEO_output.h:106
unsigned short N_samp[MAX_BAND_NUMBER_PLUS_ONE]
PGSt_SMF_status GEO_landsea_mask(int num_samples, int num_detectors, double terrain_sample_position[][MAX_PADDED][3], uint8 sample_flags[][MAX_PADDED], uint8 *land_seamask_qaflag, uint8 sample_landsea[][MAX_PADDED])
focal_plane_geometry_struct geometry_params
float64 positionECR[3]
const int GOOD_DATA
a context in which it is NOT documented to do so subscript which cannot be easily calculated when extracting TONS attitude data from the Terra L0 files Corrected several defects in extraction of entrained ephemeris and and as HDF file for both the L1A and Geolocation enabling retrieval of South Polar DEM data Resolved Bug by changing to opent the geolocation file only after a successful read of the L1A and also by checking for fatal errors from not restoring C5 and to report how many of those high resolution values were water in the new WaterPresent SDS Added valid_range attribute to Land SeaMask Changed to bilinearly interpolate the geoid_height to remove artifacts at one degree lines Made corrections to const qualification of pointers allowed by new version of M API library Removed casts that are no longer for same not the geoid Corrected off by one error in calculation of high resolution offsets Corrected parsing of maneuver list configuration parameter Corrected to set Height SDS to fill values when geolocation when for elevation and land water mask
Definition: HISTORY.txt:114
PGSt_SMF_status GEO_validate_derived_products(int const frame, int const num_detectors, double const range_scale, double frame_to_sensor[][MAX_FRAMES][3], uint8 frame_flags[][MAX_FRAMES])
#define DETECTORS_1KM
Definition: GEO_geo.h:85
float64 velocityECR[3]
const int MAX_SCAN_NUMBER
#define fabs(a)
Definition: misc.h:93
PGSt_SMF_status GEO_derived_products(int const num_frames, int const num_detectors, double ecr_sample_position[][MAX_SCAN_SAMPLE][3], double ecr_sc_position[][3], unsigned char pixel_flags[][MAX_SCAN_SAMPLE], double terrain_sample_position[][MAX_SCAN_SAMPLE][3], char utc[], PGSt_double toff[], double sample_solar_angles[][MAX_SCAN_SAMPLE][2], double sample_to_sensor[][MAX_SCAN_SAMPLE][3])
PGSt_SMF_status GEO_write_one_scan(PGSt_double const [], int const, l1a_data_struct const *const, GEO_param_struct const *const, double[][MAX_FRAMES][3], double[][MAX_FRAMES][2], double[][MAX_FRAMES][3], uint8[][MAX_FRAMES], int8[][DETECTORS_QKM][SAMPLES_QKM], PGSt_double const [], uint32[][MAX_FRAMES], uint8[][MAX_FRAMES], uint8[][MAX_FRAMES], uint8, MODFILE *const)
#define INVALID_SOLAR_ANGLES
Definition: GEO_geo.h:123
double scan_start_time[MAX_SCAN_NUMBER]
const unsigned char INVALID_INPUT_DATA
PGSt_double GEO_get_sample_time(focal_plane_geometry_struct const *geometry_params, const int sample_number)
#define SAMPLES_QKM
Definition: GEO_geo.h:83
#define DETECTORS_QKM
Definition: GEO_geo.h:87
uint32 cumulated_gflags[8]
#define THERMCORR_FVALUE
Definition: GEO_geo.h:155