OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
main_l1info.cpp
Go to the documentation of this file.
1 /* ========================================================================
2  *
3  * MSl1b2info input-l1b-filename
4  *
5  * Description:
6  *
7  * Modification history:
8  *
9  * Programmer Organization Date Description of change
10  * -------------- ------------ -------- ---------------------
11  * Bryan A. Franz GSC 28 March 1999 Original development
12  * Dan Knowles SAIC 2004 Complete rewrite to create geoboxes
13  * W. Robinson SAIC 10 dec 2004 add CZCS sensor
14  * Dan Knowles SAIC 18 Aug 2005 Changed daynight logic to be based on solar zenith angle
15  * Sean Bailey NASA 23 Oct 2015 Added logic to determine if sun in SD for VIIRS
16  * Gwyn Fireman SAIC 2018-04-19 Determine if non-nominal pointing
17  * Steve Lockhart SAIC 2018-04-27 Add support for gring, changing from C to C++
18  *
19  * ======================================================================== */
20 
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <stdlib.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <libgen.h>
30 #include <math.h>
31 
32 #include "l12_proto.h"
33 #include <timeutils.h>
34 #include "version.h"
35 #include <stdbool.h>
36 #include "gringHelper.h"
37 #include "allocate2d.h"
38 #include <string>
39 
40 #define NUM_SPACECRAFT_DIRECTION_MODES 3
41 #define DEFAULT_SPACECRAFT_DIRECTION 0 /* set to an invalid value */
42 #define ASCENDING_TRACK 1
43 #define DESCENDING_TRACK 2
44 
45 #define NORTH 1
46 #define SOUTH 0
47 
48 #ifdef TRUE
49 #undef TRUE
50 #endif
51 
52 #define TRUE 1
53 #define FALSE 0
54 
55 #define TMP_FILENAME_MAX 255
56 
57 #define DEFAULT_COORD_VALUE -999. /* set to an invalid value */
58 
59 #define DEFAULT_DAYNIGHT_MODE 0
60 #define DAY_MODE (1<<0)
61 #define NIGHT_MODE (1<<1)
62 
63 /* equatorial radius, didn't bother to use polar value also since precision not that important for current use */
64 #define EARTH_RADIUS_EQUATORIAL 6378
65 
66 #define MAX_ATTERR 1.0 /* degrees deviation considered as non-nominal attitude */
67 
68 enum {
69  ALL_NAVFAIL = 100,
70  NO_VALID_NAV = 101,
74  NON_NADIR = 105
75 };
76 
77 typedef struct {
78  float32 north_lat;
79  float32 south_lat;
80  float32 west_lon;
81  float32 east_lon;
82  unsigned char daynightflag;
83 } box_t;
84 
85 typedef struct {
86  int sensor_id;
87  int day_node;
88 } day_node_t;
89 
90 
91 void set_north_south_boundaries(float32, float32 *, float32 *);
92 void set_west_east_boundaries(float32, float32 *, float32 *);
93 void set_west_east_boundaries2(float32, float32 *, float32 *);
94 int check_if_in_west_east_boundaries(float32, float32, float32);
95 int check_if_in_box(float32, float32, float32, float32, float32, float32);
96 
97 #define USAGESTR \
98 "%s %d.%d.%d-%s (%s %s)\n\n\
99 Usage: %s [-n number-of-boxes] [-s] L1-filename [met-file]\n\n\
100 Where:\n\
101 \t-d degree limits to set on boxes (use instead of -n)\n\
102 \t-i set subsampling increment (default=1 gets all scan lines and pixels)\n\
103 \t-n generates up to this number of lat/lon boxes per orbit-side\n\
104 \t-s prints only data needed for database fields\n\
105 \t-v verify number of pixels that match in boxed region\n\
106 \t-o [output file]\n\n\
107 Return status codes:\n\
108 \t0 - good\n\
109 \t1 - general error\n\
110 \t100 - all pixels have NAVFAIL or NAVWARN flag set\n\
111 \t101 - no 'good' navigation was found\n\
112 \t102 - direction (ascending/descending) not set\n\
113 \t103 - day night flag not set\n\
114 \t104 - total box count = 0\n\
115 \t105 - non-nominal pointing\n\
116 (For multiple conditions, lowest value status code takes priority)\n\
117 \n\
118 "
119 
120 
121 #define PRINT_USAGE(x) printf(USAGESTR,(x),VERSION_MAJOR,VERSION_MINOR,VERSION_PATCH,GITSHA,__DATE__,__TIME__,(x))
122 
123 /* -------------------------------------------------------------------- *
124  * main *
125  * -------------------------------------------------------------------- */
126 int main(int argc, char *argv[]) {
127  l1str *l1rec; /* generic level-1b scan structure */
128  filehandle *l1file; /* input file handle */
129 
130  char ofile[FILENAME_MAX];
131  FILE *fp;
132  char isodatetime_first[30], isodatetime_last[30];
133 
134 #if 0
135  char geofile[FILENAME_MAX] = "";
136  char geofile[TMP_FILENAME_MAX] = "";
137 #endif
138  float32 mem_st_lat=DEFAULT_COORD_VALUE;
139  float32 mem_st_lon=DEFAULT_COORD_VALUE;
140  float32 mem_en_lat=DEFAULT_COORD_VALUE;
141  float32 mem_en_lon=DEFAULT_COORD_VALUE;
142 
143  int32_t spix = 0; /* start pixel for subscene process */
144  int32_t cpix = -1; /* center pixel of subscene scan */
145  int32_t epix = -1; /* end pixel for subscene process */
146  int32_t sscan = 0; /* start scan for subscene process */
147  int32_t cscan = -1; /* center scan for subscene process */
148  int32_t escan = -1; /* end scan for subscene process */
149  int32_t iscan;
150  int32_t ip;
151  int32_t num_match = 0;
152  int32_t num_no_match = 0;
153  int32_t num_nav_fail = 0;
154  int32_t num_pixels = 0;
155  int32_t navwarn_all_set = 1;
156  int32_t good_spix, good_epix, good_cpix;
157 
158  int box_index;
159  int spacecraft_direction_index;
160  int curr_spacecraft_direction = DEFAULT_SPACECRAFT_DIRECTION;
161  int prev_spacecraft_direction = DEFAULT_SPACECRAFT_DIRECTION;
162  int initial_spacecraft_direction = DEFAULT_SPACECRAFT_DIRECTION;
163  int final_spacecraft_direction = DEFAULT_SPACECRAFT_DIRECTION;
164  int match;
165  int in_box;
166  int num_boxes = 0;
167  float num_degrees = 20;
168  float max_num_degrees = 20;
169  int show_standard_info = TRUE;
170  int show_sdps_info = FALSE;
171  int case_n = FALSE;
172  int case_s = FALSE;
173  int case_d = FALSE;
174  int case_v = FALSE;
175  int case_o = FALSE;
176  int user_defined_increment = 1;
177  int exitflag = EXIT_SUCCESS;
178  int line_nav_ok;
179  static int first_good_scan = -1;
180  static int first_good_scantime = FALSE;
181  double scantime_first, scantime_last;
182 
183  double percent_match;
184 
185  unsigned char curr_daynight_mode = DAY_MODE;
186  unsigned char master_daynightflag = DEFAULT_DAYNIGHT_MODE;
187 
188  static char *node[3] = {"Unidentified", "Ascending", "Descending"};
189  static char *daynight_string[4] = {"Unidentified", "Day", "Night", "Both"};
190 
191  float32 epix_northern_lat = DEFAULT_COORD_VALUE;
192  float32 epix_southern_lat = DEFAULT_COORD_VALUE;
193  float32 spix_northern_lat = DEFAULT_COORD_VALUE;
194  float32 spix_southern_lat = DEFAULT_COORD_VALUE;
195  float32 northern_lat = DEFAULT_COORD_VALUE;
196  float32 southern_lat = DEFAULT_COORD_VALUE;
197  float32 eastern_lon = DEFAULT_COORD_VALUE;
198  float32 western_lon = DEFAULT_COORD_VALUE;
199  float32 center_lon = DEFAULT_COORD_VALUE;
200  float32 center_lat = DEFAULT_COORD_VALUE;
201  float32 prev_lat_cpix = DEFAULT_COORD_VALUE;
202  float32 lat_breakpoint;
203  float32 increment;
204 
205  box_t ****box = NULL; /* will become 3 dimensional box array in [DNF][direction][box_num][lonFlag] */
206  int num_args;
207 
208  char *option_string = "d:hi:n:sv:o:";
209  int options = 0;
210  while ((options = getopt(argc, argv, option_string)) != -1) {
211  switch (options) {
212  case 'd':
213  case_d = TRUE;
214  num_degrees = atof(optarg);
215  break;
216  case 'i':
217  user_defined_increment = atoi(optarg);
218  break;
219  case 'h':
220  PRINT_USAGE(argv[0]);
221  exit(EXIT_FAILURE);
222  break;
223  case 'n':
224  case_n = TRUE;
225  num_boxes = atoi(optarg);
226  break;
227  case 's':
228  case_s = TRUE;
229  break;
230  case 'v':
231  case_v = TRUE;
232  break;
233  case 'o':
234  case_o = TRUE;
235  snprintf(ofile, FILENAME_MAX, "%s", optarg);
236  break;
237  default:
238  break;
239  }
240  }
241 
242  want_verbose = 0;
243 
244  /*******************************************************************************************
245  * Check options and set num_boxes
246  *******************************************************************************************/
247  if (case_d == TRUE) {
248  if (num_degrees > 0 && num_degrees <= 180) {
249  if (case_n != TRUE) {
250  num_boxes = (int) (180 / num_degrees);
251  printf("num_boxes=%d\n", num_boxes);
252  } else {
253  printf("INPUT ERROR: Cannot choose both -d and -n options\n");
254  PRINT_USAGE(argv[0]);
255  exit(EXIT_FAILURE);
256  }
257  } else {
258  printf("INPUT ERROR: -d (degrees lat) option must be between 1 and 180\n");
259  PRINT_USAGE(argv[0]);
260  exit(EXIT_FAILURE);
261  }
262  } else if (case_n == TRUE) {
263  if (num_boxes < 0) {
264  printf("INPUT ERROR: -n (number of lat divisions) option must be greater than or equal to 0\n");
265  PRINT_USAGE(argv[0]);
266  exit(EXIT_FAILURE);
267  }
268  } else {
269  num_boxes = 0;
270  }
271 
272  /*******************************************************************************************
273  * Setup print options
274  *******************************************************************************************/
275 
276  if (case_s == TRUE) {
277  show_sdps_info = TRUE;
278  show_standard_info = FALSE;
279  }
280  if (case_o == TRUE) {
281  fp = fopen(ofile, "w");
282  } else {
283  fp = stdout;
284  }
285 
286  num_args = argc - optind;
287 
288  // make the l1 readers quiet
289  want_verbose = 0;
290 
291  cdata_();
293  l1file = (filehandle*)allocateMemory(sizeof (filehandle), "filehandle structure");
295  l1rec = (l1str*)allocateMemory(sizeof (l1str), "l1rec structure");
296 
297 
298  /* */
299  /* Process required command-line arguments */
300  /* */
301  switch (num_args) {
302  case 2:
303  strcpy(l1file->name, argv[optind + 0]);
304  /* strcpy(geofile,argv[optind+1]);*/
305  l1file->geofile = argv[optind + 1];
306  break;
307  case 1:
308  strcpy(l1file->name, argv[optind + 0]);
309  break;
310  case 0:
311  PRINT_USAGE(argv[0]);
312  exit(EXIT_SUCCESS);
313  break;
314  default:
315  PRINT_USAGE(argv[0]);
316  exit(EXIT_FAILURE);
317  break;
318  }
319 
320  /* Set default input parameters */
321  if (msl12_input_defaults(l1file) != 0) {
322  printf("-E- %s: Error parsing input parameters.\n", argv[0]);
323  exit(EXIT_FAILURE);
324  }
325  input->proc_sst = 0;
326  input->proc_ocean = 0;
327  input->atmocor = 0;
328  input->proc_land = 0;
329 
330 
331  /*
332  * The following tidbit calculates if the Sun is visible to the solar
333  * diffuser for VIIRS so that the OBC files can be flagged to keep
334  * Since this requires reading from the geolocation file, this bit is
335  * done prior to opening the L1 file (which would also open the geo file)
336  */
337  int sun_in_sd = FALSE;
338  int non_nadir = FALSE;
339  int filledScans = 0;
340  std::string instName = sensorId2InstrumentName(l1file->sensorID);
341 
342  // The bowtie effect...if an extract is small enough and on the scene
343  // edge, the bowtie effect can confuse the geobox logic, so bump the
344  // subsampling increment to make things happy
345 
346  //TODO: Check l1file->ndets ...should be a better way to do one per scan
347  if ((instName == "MODIS") &&
348  (user_defined_increment < 10)) {
349  user_defined_increment = 10;
350  }
351  if(instName == "VIIRS") {
352  if (user_defined_increment < 16)
353  user_defined_increment = 16;
354  // Get the ACTUAL scans for printing the real number not the
355  // arbitrary dimension size
356  int32_t ncid, status;
357  if ((nc_open((const char*) input->ifile, NC_NOWRITE, &ncid)) == NC_NOERR) {
358  nc_get_att_int(ncid, NC_GLOBAL, "number_of_filled_scans", &filledScans);
359  status = nc_close(ncid);
360  if (status != NC_NOERR) {
361  printf("-E- %s: Error closing %s.\n", argv[0], (char*) input->ifile);
362  exit(EXIT_FAILURE);
363  }
364  }
365  int32_t geoid;
366  //Only bother to do this if provided a geolocation file
367  if (input->geofile[0] && (nc_open(input->geofile, NC_NOWRITE, &geoid)) == NC_NOERR) {
368 
369  int32_t grpid, varid, dimid;
370  size_t nscans, nvectors;
371 
372  // don't try this for the SDR files...only the NASA L1 format files
373  if ((nc_inq_ncid(geoid, "All_Data", &grpid)) != NC_NOERR) {
374  status = nc_inq_dimid(geoid, "number_of_scans", &dimid);
375  if (status != NC_NOERR) {
376  printf("-E- Error reading number_of_scans attribute.\n");
377  exit(EXIT_FAILURE);
378  }
379  nc_inq_dimlen(geoid, dimid, &nscans);
380  status = nc_inq_dimid(geoid, "vector_elements", &dimid);
381  if (status != NC_NOERR) {
382  printf("-E- Error reading vector_elements attribute.\n");
383  exit(EXIT_FAILURE);
384  }
385  nc_inq_dimlen(geoid, dimid, &nvectors);
386 
387  if ((nc_inq_ncid(geoid, "navigation_data", &grpid)) == NC_NOERR) {
388  int i = 0;
389  size_t start[] = {0, 0}; /* start at first value */
390  size_t cnt[] = {nscans, nvectors};
391 
392  // sun in solar diffuser?
393  float **solar_inst = allocate2d_float(nscans, nvectors);
394  status = nc_inq_varid(grpid, "solar_inst", &varid);
395  if (status != NC_NOERR) {
396  printf("-E- Error finding solar_inst variable.\n");
397  exit(EXIT_FAILURE);
398  }
399  status = nc_get_vara_float(grpid, varid, start, cnt, &solar_inst[0][0]);
400  if (status != NC_NOERR) {
401  printf("-E- Error reading solar_inst variable.\n");
402  exit(EXIT_FAILURE);
403  }
404  for (i = 0; i < (int)nscans; i++) {
405  if (solar_inst[i][0] >= -1 && solar_inst[i][0] <= 1) {
406  float solar_inst_az = RADEG * atan2f(solar_inst[i][0], -solar_inst[i][2]);
407  if (solar_inst_az >= 100.0 && solar_inst_az <= 110.0) {
408  sun_in_sd = TRUE;
409  break;
410  }
411  }
412  }
413  free2d_float(solar_inst);
414 
415  // attitude not nominal?
416  float **att_ang= allocate2d_float(nscans, nvectors);
417  status = nc_inq_varid(grpid, "att_ang_mid", &varid);
418  if (status != NC_NOERR) { // try old name
419  status = nc_inq_varid(grpid, "att_ang", &varid);
420  if (status != NC_NOERR) {
421  printf("-E- Error finding attitude angles.\n");
422  exit(EXIT_FAILURE);
423  }
424  }
425  status = nc_get_vara_float(grpid, varid, start, cnt, &att_ang[0][0]);
426  if (status != NC_NOERR) {
427  printf("-E- Error reading attitude angles.\n");
428  exit(EXIT_FAILURE);
429  }
430  for (i = 0; (i < (int)nscans) && !non_nadir; i++) {
431  for (int j = 0; j < (int)nvectors; j++) {
432  if (fabs(att_ang[i][j]) > MAX_ATTERR) {
433  non_nadir = TRUE;
434  break;
435  }
436  }
437  }
439  }
440  }
441 
442  status = nc_close(geoid);
443  if (status != NC_NOERR) {
444  printf("-E- %s: Error closing %s.\n", argv[0], input->geofile);
445  exit(EXIT_FAILURE);
446  }
447  }
448  }
449 
450  /* */
451  /* Open input file and get sensor and scan information from handle */
452  /* */
453  if (openl1(l1file) != 0) {
454  printf("-E- %s: Error opening %s for reading.\n", argv[0], l1file->name);
455  exit(EXIT_FAILURE);
456  }
457 
458  /* */
459  /* Allocate memory for L1 scan data */
460  /* */
461  if (alloc_l1(l1file, l1rec) == 0) {
462  printf("-E- %s: Unable to allocate L1 record.\n", argv[0]);
463  exit(EXIT_FAILURE);
464  }
465 
466  spix = 0;
467  epix = l1file->npix - 1;
468  cpix = spix + (epix - spix + 1) / 2;
469 
470  sscan = 0;
471  escan = l1file->nscan - 1;
472  cscan = sscan + (escan - sscan + 1) / 2;
473 
474  l1file->spix = spix;
475  l1file->epix = epix;
476 
477  if (show_standard_info == TRUE) {
478  fprintf(fp, "Sensor=%s\n", sensorId2SensorName(l1file->sensorID));
479  }
480 
481  if (show_sdps_info == TRUE || show_standard_info == TRUE) {
482  fprintf(fp, "Orbit_Number=%d\n", l1file->orbit_number);
483  if (l1file->format == FT_VIIRSL1A || l1file->format == FT_VIIRSL1BNC) {
484  fprintf(fp, "Number_of_Scans=%d\n", filledScans);
485  } else {
486  fprintf(fp, "Number_of_Scans=%d\n", l1file->nscan);
487  }
488  }
489 
490  if (show_standard_info == TRUE) {
491  fprintf(fp, "Number_of_Pixels_per_Scan=%d\n", l1file->npix);
492  }
493 
494 
495  if (num_boxes) {
496  /***********************************************************************************************
497  * Allocate boxes
498  ***********************************************************************************************/
499  box = (box_t ****) calloc(2, sizeof (box_t***));
500  if (box == NULL) {
501  printf("can not allocate box\n");
502  exit(EXIT_FAILURE);
503  }
504  for(int day_night = 0; day_night < 2; day_night++) {
505  box[day_night] = (box_t ***) calloc(NUM_SPACECRAFT_DIRECTION_MODES, sizeof (box_t**));
506  if (box[day_night] == NULL) {
507  printf("can not allocate box[day_night]\n");
508  exit(EXIT_FAILURE);
509  }
511  box[day_night][direction] = (box_t **) calloc(num_boxes, sizeof (box_t*));
512  if (box == NULL) {
513  printf("can not allocate box[day_night][direction]\n");
514  exit(EXIT_FAILURE);
515  }
516  for(box_index=0; box_index<num_boxes; box_index++) {
517  box[day_night][direction][box_index] = (box_t *) calloc(2, sizeof (box_t));
518  if (box[day_night][direction][box_index] == NULL) {
519  printf("can not allocate box[day_night][direction][box_index]\n");
520  exit(EXIT_FAILURE);
521  }
522  }
523  }
524  }
525 
526  /***********************************************************************************************
527  * Initialize boxes
528  ***********************************************************************************************/
529  for(int day_night = 0; day_night < 2; day_night++) {
531  for (box_index = 0; box_index < num_boxes; box_index++) {
532  for(int lonFlag = 0; lonFlag < 2; lonFlag++) {
533  box[day_night][direction][box_index][lonFlag].north_lat = DEFAULT_COORD_VALUE;
534  box[day_night][direction][box_index][lonFlag].south_lat = DEFAULT_COORD_VALUE;
535  box[day_night][direction][box_index][lonFlag].west_lon = DEFAULT_COORD_VALUE;
536  box[day_night][direction][box_index][lonFlag].east_lon = DEFAULT_COORD_VALUE;
537  box[day_night][direction][box_index][lonFlag].daynightflag = DEFAULT_DAYNIGHT_MODE;
538  }
539  }
540  }
541  }
542 
543  }
544 
545  /***************************************************************************
546  * Loop through all scan lines
547  ***************************************************************************/
548 
549  /*
550  for (iscan=sscan; iscan<=escan; iscan++)
551  { */
552 
553  iscan = sscan;
554  line_nav_ok = 0;
555 
556  // Before looping on scans, prepare to instantiate gringHelper
557  gringConfig_t *gringConfig = new gringConfig_t;
558  // Get scan direction for this sensor
559  // Most instruments scan to the left (so, use default scan_direction = -1); however, some exceptions scan to the right.
560  // Set scan_direction = 1 for these exceptions.
561  if (l1file->sensorID == CZCS) {
562  gringConfig->scan_direction = 1;
563  } else {
564  gringConfig->scan_direction = -1;
565  }
566 
567  // set the number of lines between direction test
568  if (strcmp(sensorId2InstrumentName(l1file->sensorID), "MODIS") == 0) {
569  gringConfig->direction_delta = 10;
570  } else if(strcmp(sensorId2InstrumentName(l1file->sensorID), "VIIRS") == 0) {
571  gringConfig->direction_delta = 16;
572  } else {
573  gringConfig->direction_delta = 5;
574  }
575 
576  if (num_degrees < max_num_degrees) {
577  gringConfig->delta_degrees_lat = num_degrees;
578  } else {
579  gringConfig->delta_degrees_lat = max_num_degrees;
580  //printf("Setting delta_degrees_lat = %d\n", (int)gringConfig->delta_degrees_lat);
581  }
582  // instantiate a gringHelper
583  gringHelper *gring_helper = new gringHelper(gringConfig);
584 
585  // loop on scans
586  while (iscan <= escan) {
587  good_spix = -1;
588  good_epix = -1;
589  good_cpix = -1;
591  /*
592  * get info for each line and remember the info if end
593  * and center geolocation are OK
594  */
595 
596  if (l1rec->scantime > 0) {
597  scantime_last = l1rec->scantime;
598  if (first_good_scantime == FALSE) {
599  first_good_scantime = TRUE;
600  scantime_first = l1rec->scantime;
601  }
602  }
603 
604  /*
605  * establish good start, end, center pixels if any
606  */
607  for (ip = spix; ip <= epix; ip++) {
608  if ((l1rec->flags[ip] & NAVFAIL) == 0) {
609  if (good_spix == -1)
610  good_spix = ip;
611  good_epix = ip;
612  if ((ip <= cpix) || (good_cpix == -1))
613  good_cpix = ip;
614  if ((l1rec->flags[ip] & NAVWARN) == 0)
615  navwarn_all_set = 0;
616  }
617  }
618  if (good_spix != -1) {
619  line_nav_ok = 1;
620  if (first_good_scan == -1) {
621  first_good_scan = iscan;
622  if (show_standard_info == TRUE) {
623  fprintf(fp, "Upper_Left_Lon=%f\n", l1rec->lon[good_spix]);
624  fprintf(fp, "Upper_Left_Lat=%f\n", l1rec->lat[good_spix]);
625  fprintf(fp, "Upper_Right_Lon=%f\n", l1rec->lon[good_epix]);
626  fprintf(fp, "Upper_Right_Lat=%f\n", l1rec->lat[good_epix]);
627  }
628  }
629 
630 
631  mem_st_lat = l1rec->lat[good_spix];
632  mem_st_lon = l1rec->lon[good_spix];
633  mem_en_lat = l1rec->lat[good_epix];
634  mem_en_lon = l1rec->lon[good_epix];
635 
636  }
637 
638  if (iscan == escan) {
639  // Last scan
640  if (scantime_first > scantime_last) {
641  strncpy(isodatetime_first, unix2isodate(scantime_last, 'G'), 30);
642  strncpy(isodatetime_last, unix2isodate(scantime_first, 'G'), 30);
643  } else {
644  strncpy(isodatetime_last, unix2isodate(scantime_last, 'G'), 30);
645  strncpy(isodatetime_first, unix2isodate(scantime_first, 'G'), 30);
646  }
647  if (show_standard_info == TRUE) {
648  fprintf(fp, "\n");
649  fprintf(fp, "INFO: FIRST SCAN LINE\n");
650  fprintf(fp, "Start_Date=%s\n", isodatetime_first);
651  fprintf(fp, "\n");
652  fprintf(fp, "INFO: LAST SCAN LINE\n");
653  fprintf(fp, "End_Date=%s\n", isodatetime_last);
654  fprintf(fp, "Lower_Left_Lon=%f\n", mem_st_lon);
655  fprintf(fp, "Lower_Left_Lat=%f\n", mem_st_lat);
656  fprintf(fp, "Lower_Right_Lon=%f\n", mem_en_lon);
657  fprintf(fp, "Lower_Right_Lat=%f\n", mem_en_lat);
658  }
659 
660  if (show_sdps_info == TRUE) {
661  fprintf(fp, "Start_Date=%.*s\n", 10, isodatetime_first);
662  fprintf(fp, "Start_Time=%.*s\n", 12, isodatetime_first + 11);
663  fprintf(fp, "End_Date=%.*s\n", 10, isodatetime_last);
664  fprintf(fp, "End_Time=%.*s\n", 12, isodatetime_last + 11);
665  }
666  }
667 
668 
669  /***************************************************************************************************
670  * Determine MAX and MIN values for epix_lat and spix_lat based on current and all preceeding scan lines
671  ***************************************************************************************************/
672 
673 
674  if (line_nav_ok) {
675  set_north_south_boundaries(l1rec->lat[good_spix], &spix_northern_lat, &spix_southern_lat);
676  set_north_south_boundaries(l1rec->lat[good_epix], &epix_northern_lat, &epix_southern_lat);
677  }
678 
679  /**************************************************************
680  * Find lat and lon of the center pixel of the middle scan
681  **************************************************************/
682 
683  if (center_lat == DEFAULT_COORD_VALUE || center_lon == DEFAULT_COORD_VALUE) {
684  if (iscan >= cscan && (l1rec->flags[good_cpix] & NAVFAIL) == 0) {
685  center_lat = l1rec->lat[good_cpix];
686  center_lon = l1rec->lon[good_cpix];
687  }
688  }
689 
690 
691  /***************************************************************************
692  * Determine spacecraft direction based on center pixel of the scan
693  ***************************************************************************/
694 
695  if ((l1rec->flags[good_cpix] & NAVFAIL) == 0) {
696  if (prev_lat_cpix != DEFAULT_COORD_VALUE) {
697  if (l1rec->lat[good_cpix] > prev_lat_cpix) {
698  curr_spacecraft_direction = ASCENDING_TRACK;
699  } else if (l1rec->lat[good_cpix] < prev_lat_cpix) {
700  curr_spacecraft_direction = DESCENDING_TRACK;
701  } else {
702  curr_spacecraft_direction = prev_spacecraft_direction;
703  }
704 
705  if (initial_spacecraft_direction == DEFAULT_SPACECRAFT_DIRECTION &&
706  curr_spacecraft_direction != DEFAULT_SPACECRAFT_DIRECTION) {
707  initial_spacecraft_direction = curr_spacecraft_direction;
708  }
709 
710  }
711  prev_lat_cpix = l1rec->lat[good_cpix];
712  prev_spacecraft_direction = curr_spacecraft_direction;
713 
714  }
715 
716 
717  /***************************************************************************
718  * Loop through all pixels
719  ***************************************************************************/
720 
721  if (good_spix != -1) {
722  ip = good_spix;
723  while (ip <= good_epix) {
724 
725  if ((l1rec->flags[ip] & NAVFAIL) == 0) {
726  /***************************************************************************
727  * Determine day/night mode of pixel
728  ***************************************************************************/
729 
730  // needed to test for valid solz - invalid ones were incorrectly
731  // changing the daynight mode
732  if (l1rec->solz[ip] > 0. && l1rec->solz[ip] < 180.) {
733  if (l1rec->solz[ip] < 90) {
734  curr_daynight_mode = DAY_MODE;
735  } else {
736  curr_daynight_mode = NIGHT_MODE;
737  }
738  }
739 
740  master_daynightflag |= curr_daynight_mode;
741 
742 
743  /***************************************************************************************************
744  * Determine MAX and MIN values for both lat and lon based on current and all preceeding scan lines
745  ***************************************************************************************************/
746  if (line_nav_ok) {
747  set_north_south_boundaries(l1rec->lat[ip], &northern_lat, &southern_lat);
748  set_west_east_boundaries2(l1rec->lon[ip], &western_lon, &eastern_lon);
749  }
750 
751 
752  if (num_boxes) {
753  /***************************************************************************
754  * Determine and set boundaries for regular boxes
755  ***************************************************************************/
756 
757  if (l1rec->lat[ip] >= -90. && l1rec->lat[ip] <= 90. && l1rec->lon[ip] >= -180. && l1rec->lon[ip] <= 180.) {
758  int i = 0;
759  box_index = num_boxes;
760  increment = 180. / num_boxes;
761 
762  for (lat_breakpoint = 90. - increment; lat_breakpoint >= -90.; lat_breakpoint -= increment) {
763  if (l1rec->lat[ip] >= lat_breakpoint && l1rec->lat[ip] < (lat_breakpoint + increment)) {
764  box_index = i;
765  break;
766  }
767  i++;
768  }
769 
770  if (box_index < num_boxes) {
771  int lonFlag;
772  if(l1rec->lon[ip] < 0)
773  lonFlag = 0;
774  else
775  lonFlag = 1;
777  &box[curr_daynight_mode-1][curr_spacecraft_direction][box_index][lonFlag].north_lat,
778  &box[curr_daynight_mode-1][curr_spacecraft_direction][box_index][lonFlag].south_lat);
780  &box[curr_daynight_mode-1][curr_spacecraft_direction][box_index][lonFlag].west_lon,
781  &box[curr_daynight_mode-1][curr_spacecraft_direction][box_index][lonFlag].east_lon);
782  box[curr_daynight_mode-1][curr_spacecraft_direction][box_index][lonFlag].daynightflag = curr_daynight_mode;
783  }
784  } else {
785 
786  if (l1rec->lat[ip] < -90 || l1rec->lat[ip] > 90 || l1rec->lon[ip] < -180 || l1rec->lon[ip] > 180) {
787  fprintf(stderr, "-W- lat/lon pixel out of range: lat=%f, lon=%f, pixel_index=%d\n", l1rec->lat[ip], l1rec->lon[ip], ip);
788  }
789 
790  }
791  }
792  } else {
793  num_nav_fail++; /* count failed pixels */
794  }
795 
796  num_pixels++; /* count total pixels */
797 
798  if (ip < epix - user_defined_increment) {
799  ip += user_defined_increment;
800  } else {
801  ip++;
802  }
803  }
804  }
805 
806  // gring-related processing (per scan)
807  gring_helper->process_scan(l1rec, iscan, escan);
808 
809  if (iscan < escan - user_defined_increment) {
810  iscan += user_defined_increment;
811  } else {
812  iscan++;
813  }
814  }
815 
816  final_spacecraft_direction = curr_spacecraft_direction;
817 
818 
819 
820  /***************************************************************************************************
821  * Merge initial scans box with appropriate box now that we know the initial_spacecraft_direction
822  ***************************************************************************************************/
823 
824  if (num_boxes) {
825  for(int day_night = 0; day_night < 2; day_night++) {
826  for (box_index = 0; box_index < num_boxes; box_index++) {
827  for(int lonFlag=0; lonFlag<2; lonFlag++) {
828  if (box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].north_lat != DEFAULT_COORD_VALUE) {
829  set_north_south_boundaries(box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].north_lat,
830  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].north_lat,
831  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].south_lat);
832  set_north_south_boundaries(box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].south_lat,
833  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].north_lat,
834  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].south_lat);
835  set_west_east_boundaries(box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].west_lon,
836  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].west_lon,
837  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].east_lon);
838  set_west_east_boundaries(box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].east_lon,
839  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].west_lon,
840  &box[day_night][initial_spacecraft_direction][box_index][lonFlag].east_lon);
841  box[day_night][initial_spacecraft_direction][box_index][lonFlag].daynightflag = box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].daynightflag;
842 
843  /* re initialize default spacecraft direction box */
844  box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].north_lat = DEFAULT_COORD_VALUE;
845  box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].south_lat = DEFAULT_COORD_VALUE;
846  box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].west_lon = DEFAULT_COORD_VALUE;
847  box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].east_lon = DEFAULT_COORD_VALUE;
848  box[day_night][DEFAULT_SPACECRAFT_DIRECTION][box_index][lonFlag].daynightflag = DEFAULT_DAYNIGHT_MODE;
849  }
850  }
851  }
852  }
853 
854  if (num_pixels == num_nav_fail) {
855  exitflag = ALL_NAVFAIL;
856  } else if (northern_lat == DEFAULT_COORD_VALUE ||
857  southern_lat == DEFAULT_COORD_VALUE ||
858  eastern_lon == DEFAULT_COORD_VALUE ||
859  western_lon == DEFAULT_COORD_VALUE) {
860  exitflag = NO_VALID_NAV;
861  } else if (case_n == TRUE && (initial_spacecraft_direction == DEFAULT_SPACECRAFT_DIRECTION ||
862  final_spacecraft_direction == DEFAULT_SPACECRAFT_DIRECTION)
863  ) {
864  exitflag = DIRECTION_NOT_SET;
865  }
866  }
867 
868  if (navwarn_all_set == 1) {
869  exitflag = ALL_NAVFAIL;
870  }
871 
872  /***************************************************************************************************
873  * Print summary info
874  ***************************************************************************************************/
875 
876  if (show_standard_info == TRUE) {
877  fprintf(fp, "\n");
878  fprintf(fp, "SUMMARY STATS\n");
879  fprintf(fp, "Northernmost_Lat=%f\n", northern_lat);
880  fprintf(fp, "Southernmost_Lat=%f\n", southern_lat);
881  fprintf(fp, "Easternmost_Lon=%f\n", eastern_lon);
882  fprintf(fp, "Westernmost_Lon=%f\n", western_lon);
883  fprintf(fp, "Center_Lat=%f\n", center_lat);
884  fprintf(fp, "Center_Lon=%f\n", center_lon);
885  fprintf(fp, "Start_Node=%s\n", node[initial_spacecraft_direction]);
886  fprintf(fp, "End_Node=%s\n", node[final_spacecraft_direction]);
887  fprintf(fp, "Daynight=%s\n", daynight_string[master_daynightflag]);
888  fprintf(fp, "Moon_in_SV=%1d\n", l1file->sv_with_moon);
889  if ((l1file->sensorID == VIIRSN) || (l1file->sensorID == VIIRSJ1)) {
890  fprintf(fp, "Sun_in_SD=%1d\n", sun_in_sd);
891  fprintf(fp, "Non_Nadir=%1d\n", non_nadir);
892  }
893  }
894 
895  if (show_sdps_info == TRUE) {
896  fprintf(fp, "DayNightFlag=%d\n", master_daynightflag);
897  fprintf(fp, "Moon_in_SV=%1d\n", l1file->sv_with_moon);
898  if ((l1file->sensorID == VIIRSN) || (l1file->sensorID == VIIRSJ1)) {
899  fprintf(fp, "Sun_in_SD=%1d\n", sun_in_sd);
900  fprintf(fp, "Non_Nadir=%1d\n", non_nadir);
901  }
902  }
903 
904  if (exitflag == 0 && master_daynightflag == 0) {
905  exitflag = DAY_NIGHT_NOT_SET;
906  }
907 
908 
909  /***************************************************************************************************
910  * Print box info
911  ***************************************************************************************************/
912 
913  if (show_sdps_info == TRUE && num_boxes) {
914  int geobox_found = 0;
915  int box_count = 1;
916  for(int day_night = 0; day_night < 2; day_night++) {
917  for (spacecraft_direction_index = 0; spacecraft_direction_index < NUM_SPACECRAFT_DIRECTION_MODES; spacecraft_direction_index++) {
918  for (box_index = 0; box_index < num_boxes; box_index++) {
919  for(int lonFlag = 0; lonFlag < 2; lonFlag++) {
920  if (box[day_night][spacecraft_direction_index][box_index][lonFlag].north_lat != DEFAULT_COORD_VALUE) {
921  geobox_found = 1;
922  fprintf(fp, "GeoBox_%d=%f,%f,%f,%f,%d\n",
923  box_count,
924  box[day_night][spacecraft_direction_index][box_index][lonFlag].north_lat,
925  box[day_night][spacecraft_direction_index][box_index][lonFlag].south_lat,
926  box[day_night][spacecraft_direction_index][box_index][lonFlag].west_lon,
927  box[day_night][spacecraft_direction_index][box_index][lonFlag].east_lon,
928  box[day_night][spacecraft_direction_index][box_index][lonFlag].daynightflag);
929  box_count++;
930  }
931  }
932  }
933  }
934  }
935  if (exitflag == 0 && case_n == TRUE && !geobox_found) {
936  exitflag = GEOBOX_NOT_FOUND;
937  }
938  }
939 
940  if (case_v == TRUE) {
941 
942  for (iscan = sscan; iscan <= escan; iscan++) {
944 
945  for (ip = spix; ip <= epix; ip++) {
946  if ((l1rec->flags[ip] & NAVFAIL) == 0) {
947  match = FALSE;
948 
949  for(int day_night = 0; day_night < 2; day_night++) {
950  for (spacecraft_direction_index = 0; spacecraft_direction_index < NUM_SPACECRAFT_DIRECTION_MODES; spacecraft_direction_index++) {
951  for (box_index = 0; box_index < num_boxes; box_index++) {
952  for(int lonFlag = 0; lonFlag < 2; lonFlag++) {
953  in_box = check_if_in_box(l1rec->lat[ip],
954  l1rec->lon[ip],
955  box[day_night][spacecraft_direction_index][box_index][lonFlag].north_lat,
956  box[day_night][spacecraft_direction_index][box_index][lonFlag].south_lat,
957  box[day_night][spacecraft_direction_index][box_index][lonFlag].west_lon,
958  box[day_night][spacecraft_direction_index][box_index][lonFlag].east_lon);
959  if (in_box == TRUE) {
960  match = TRUE;
961  }
962  }
963  }
964  }
965  }
966  if (match == TRUE) {
967  num_match++;
968  } else {
969  num_no_match++;
970  }
971 
972  }
973  }
974  }
975 
976  if ((num_match + num_no_match) > 0) {
977  percent_match = 100. * num_match / (num_match + num_no_match);
978  } else {
979  percent_match = 0;
980  }
981 
982  fprintf(fp, "percent_match=%f, num_match=%d, num_no_match=%d\n", percent_match, num_match, num_no_match);
983  }
984 
985 
986  /***************************************************************************************************
987  * Print gring info
988  ***************************************************************************************************/
989  int gring_geobox_cnt = gring_helper->get_geobox_cnt();
990  if (gring_geobox_cnt > 1) {
991  // Proceed to print gring info
992  // Prep for call to gring_helper->get_geobox_cnt()
993  std::string gring_lon_string;
994  std::string gring_lat_string;
995  std::string gring_seq_string;
996  // Call gring_helper->get_gring_strings
997  if (gring_helper->get_gring_strings(gring_lon_string, gring_lat_string, gring_seq_string) == SUCCESS) {
998  // fprintf gring-related strings
999  fprintf(fp, "gringpointlongitude=%s\n",gring_lon_string.c_str());
1000  fprintf(fp, "gringpointlatitude=%s\n",gring_lat_string.c_str());
1001  fprintf(fp, "gringpointsequence=%s\n",gring_seq_string.c_str());
1002  } else {
1003  fprintf(stderr, "-W- Could not generate gring\n");
1004  }
1005 
1006  } else {
1007  fprintf(stderr, "-W- Not enough scans to form a gring; number of scans to include in gring = %d\n",gring_geobox_cnt);
1008  }
1009 
1010 
1011 
1012  /* free the dynamically allocated memory */
1013  delete(gringConfig);
1014  delete(gring_helper);
1015 
1016  if (num_boxes > 0) {
1017  for(int day_night = 0; day_night < 2; day_night++) {
1018  for (spacecraft_direction_index = 0; spacecraft_direction_index < NUM_SPACECRAFT_DIRECTION_MODES; spacecraft_direction_index++) {
1019  for(box_index=0; box_index<num_boxes; box_index++) {
1020  free(box[day_night][spacecraft_direction_index][box_index]);
1021  }
1022  free(box[day_night][spacecraft_direction_index]);
1023  }
1024  free(box[day_night]);
1025  }
1026  free(box);
1027  }
1028  if (case_o == TRUE)
1029  fclose(fp);
1030 
1031  if (exitflag == 0 && non_nadir) {
1032  exitflag = NON_NADIR;
1033  }
1034 
1035  exit(exitflag);
1036 }
1037 
1038 /* take first arg (lat) and adjust northern_boundary or southern_boundary if needed */
1039 
1040 void
1041 set_north_south_boundaries(float32 lat, float32 *northern_boundary, float32 *southern_boundary) {
1042  if (lat > 90.) {
1043  lat = 90.;
1044  }
1045 
1046  if (lat < -90.) {
1047  lat = -90.;
1048  }
1049 
1050  if (*northern_boundary != DEFAULT_COORD_VALUE) {
1051  *northern_boundary = MAX(lat, *northern_boundary);
1052  } else {
1053  *northern_boundary = lat;
1054  }
1055 
1056  if (*southern_boundary != DEFAULT_COORD_VALUE) {
1057  *southern_boundary = MIN(lat, *southern_boundary);
1058  } else {
1059  *southern_boundary = lat;
1060  }
1061 
1062 }
1063 
1064 int
1065 check_if_in_box(float32 lat, float32 lon, float32 northern_boundary, float32 southern_boundary,
1066  float32 western_boundary, float32 eastern_boundary) {
1067  int results;
1068  int east_west_results;
1069  int north_south_results;
1070 
1071  east_west_results = check_if_in_west_east_boundaries(lon, western_boundary, eastern_boundary);
1072 
1073  if (lat >= southern_boundary && lat <= northern_boundary) {
1074  north_south_results = TRUE;
1075  } else {
1076  north_south_results = FALSE;
1077  }
1078 
1079  if (north_south_results == TRUE && east_west_results == TRUE) {
1080  results = TRUE;
1081  } else {
1082  results = FALSE;
1083  }
1084 
1085  return results;
1086 }
1087 
1088 int
1089 check_if_in_west_east_boundaries(float32 lon, float32 western_boundary, float32 eastern_boundary) {
1090 
1091  int results = FALSE;
1092 
1093  if (eastern_boundary >= western_boundary) {
1094  /* no date line crossing */
1095 
1096  if (lon >= western_boundary &&
1097  lon <= eastern_boundary) {
1098  results = TRUE;
1099  }
1100  } else {
1101  /* date line crossing */
1102 
1103  if (lon >= western_boundary ||
1104  lon <= eastern_boundary) {
1105  results = TRUE;
1106  }
1107  }
1108 
1109  return results;
1110 }
1111 
1112 void
1113 set_west_east_boundaries(float32 lon, float32 * western_boundary, float32 * eastern_boundary) {
1114  if (lon > 180.) {
1115  lon = 180.;
1116  }
1117 
1118  if (lon < -180.) {
1119  lon = -180.;
1120  }
1121 
1122  if(lon > *eastern_boundary || *eastern_boundary == DEFAULT_COORD_VALUE)
1123  *eastern_boundary = lon;
1124  if(lon < *western_boundary || *western_boundary == DEFAULT_COORD_VALUE)
1125  *western_boundary = lon;
1126 }
1127 
1128 void
1129 set_west_east_boundaries2(float32 lon, float32 * western_boundary, float32 * eastern_boundary) {
1130  float32 boundary_width;
1131  float32 width_to_west;
1132  float32 width_to_east;
1133 
1134  if (*western_boundary != -180. || *eastern_boundary != 180.) {
1135  if (*eastern_boundary != DEFAULT_COORD_VALUE && *western_boundary != DEFAULT_COORD_VALUE) {
1136  if (check_if_in_west_east_boundaries(lon, *western_boundary, *eastern_boundary) != TRUE) {
1137  /************************************************************************
1138  * Determine longitude width to east of current boundary
1139  ************************************************************************/
1140 
1141  if (lon > *eastern_boundary) {
1142  /* dateline not crossed */
1143  width_to_east = lon - *eastern_boundary;
1144  } else {
1145  /* dateline crossed */
1146  width_to_east = 360. + lon - *eastern_boundary;
1147  }
1148 
1149  /************************************************************************
1150  * Determine longitude width to west of current boundary
1151  ************************************************************************/
1152 
1153  if (*western_boundary > lon) {
1154  /* dateline not crossed */
1155  width_to_west = *western_boundary - lon;
1156  } else {
1157  /* dateline crossed */
1158  width_to_west = *western_boundary + 360. - lon;
1159  }
1160 
1161  /************************************************************************
1162  * Set closest west-east boundary
1163  ************************************************************************/
1164 
1165  if (fabs(width_to_west) <= fabs(width_to_east)) {
1166  *western_boundary = lon;
1167  } else {
1168  *eastern_boundary = lon;
1169  }
1170 
1171  /************************************************************************
1172  * Determine longitude width between western_boundary and eastern_boundary
1173  ************************************************************************/
1174 
1175  if (*eastern_boundary >= *western_boundary) {
1176  /* no date line crossing */
1177  boundary_width = *eastern_boundary - *western_boundary;
1178  } else {
1179  /* date line crossing */
1180  boundary_width = 360. + *eastern_boundary - *western_boundary;
1181  }
1182 
1183  /************************************************************************
1184  * if west-to-east span > 355 then just set span to -180 to 180
1185  ************************************************************************/
1186 
1187  if (boundary_width > 355.) {
1188  *western_boundary = -180.;
1189  *eastern_boundary = 180.;
1190  }
1191  }
1192  } else {
1193  *eastern_boundary = lon;
1194  *western_boundary = lon;
1195  }
1196  }
1197 }
int32 l1file(int32 sdfid, int32 *nsamp, int32 *nscans, int16 *dtynum)
Definition: l1stat_chk.c:586
#define MAX(A, B)
Definition: swl0_utils.h:26
#define MIN(x, y)
Definition: rice.h:169
#define FALSE
Definition: main_l1info.cpp:53
int readl1(filehandle *l1file, int32_t recnum, l1str *l1rec)
Definition: l1_io.c:400
#define SUCCESS
Definition: ObpgReadGrid.h:15
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:32
#define TMP_FILENAME_MAX
Definition: main_l1info.cpp:55
#define DAY_MODE
Definition: main_l1info.cpp:60
#define NIGHT_MODE
Definition: main_l1info.cpp:61
#define NUM_SPACECRAFT_DIRECTION_MODES
Definition: main_l1info.cpp:40
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
#define NULL
Definition: decode_rs.h:63
void filehandle_init(filehandle *file)
size_t direction_delta
Definition: gringHelper.h:16
read l1rec
#define VIIRSN
Definition: sensorDefs.h:23
@ DAY_NIGHT_NOT_SET
Definition: main_l1info.cpp:72
int get_geobox_cnt()
@ FT_VIIRSL1A
Definition: filetype.h:50
float * lat
void msl12_input_init()
Definition: msl12_input.c:485
unsigned char daynightflag
Definition: main_l1info.cpp:82
@ string
instr * input
u5 which has been done in the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT production Changes from v6 which may affect scientific the sector rotation may actually occur during one of the scans earlier than the one where it is first reported As a the b1 values are about the LOCALGRANULEID metadata should have an extension NRT It is requested to identify the NRT to fill pixels affected by dead subframes with a special value Output the metadata of noisy and dead subframe Dead Subframe EV and Detector Quality Flag2 Removed the function call of Fill_Dead_Detector_SI to stop interpolating SI values for dead but also for all downstream products for science test only Changes from v5 which will affect scientific to conform to MODIS requirements Removed the Mixed option from the ScanType in the code because the L1A Scan Type is never Mixed Changed for ANSI C compliance and comments to better document the fact that when the HDF_EOS metadata is stricly the and products are off by and in the track direction
Definition: HISTORY.txt:273
@ NON_NADIR
Definition: main_l1info.cpp:74
@ GEOBOX_NOT_FOUND
Definition: main_l1info.cpp:73
#define DEFAULT_COORD_VALUE
Definition: main_l1info.cpp:57
void set_north_south_boundaries(float32, float32 *, float32 *)
@ FT_VIIRSL1BNC
Definition: filetype.h:52
#define DEFAULT_SPACECRAFT_DIRECTION
Definition: main_l1info.cpp:41
void set_west_east_boundaries2(float32, float32 *, float32 *)
#define DESCENDING_TRACK
Definition: main_l1info.cpp:43
@ NO_VALID_NAV
Definition: main_l1info.cpp:70
void free2d_float(float **p)
Free a two-dimensional array created by allocate2d_float.
Definition: allocate2d.c:142
void cdata_()
int want_verbose
int get_gring_strings(std::string &gring_lon_string, std::string &gring_lat_string, std::string &gring_seq_string)
#define MAX_ATTERR
Definition: main_l1info.cpp:66
#define RADEG
Definition: czcs_ctl_pt.c:5
Utility functions for allocating and freeing two-dimensional arrays of various types.
bool match(char *first, char *second)
Definition: l2qc_viirs.cpp:45
int check_if_in_box(float32, float32, float32, float32, float32, float32)
int main(int argc, char *argv[])
int msl12_input_defaults(filehandle *l1file)
Definition: msl12_input.c:4225
const char * sensorId2SensorName(int sensorId)
Definition: sensorInfo.c:198
@ ALL_NAVFAIL
Definition: main_l1info.cpp:69
int32 spix
Definition: l1_czcs_hdf.c:21
#define fabs(a)
Definition: misc.h:93
int32_t iscan
char * unix2isodate(double dtime, char zone)
Definition: unix2isodate.c:10
const char * sensorId2InstrumentName(int sensorId)
Definition: sensorInfo.c:212
#define CZCS
Definition: sensorDefs.h:17
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 * lon
float32 south_lat
Definition: main_l1info.cpp:79
int32 epix
Definition: l1_czcs_hdf.c:23
float delta_degrees_lat
Definition: gringHelper.h:14
int32_t alloc_l1(filehandle *l1file, l1str *l1rec)
Definition: alloc_l1.c:15
float ** allocate2d_float(size_t h, size_t w)
Allocate a two-dimensional array of type float of a given size.
Definition: allocate2d.c:125
void set_west_east_boundaries(float32, float32 *, float32 *)
float32 * att_ang
Definition: l1_czcs_hdf.c:34
int check_if_in_west_east_boundaries(float32, float32, float32)
@ DIRECTION_NOT_SET
Definition: main_l1info.cpp:71
float32 north_lat
Definition: main_l1info.cpp:78
#define TRUE
Definition: main_l1info.cpp:52
#define ASCENDING_TRACK
Definition: main_l1info.cpp:42
void process_scan(l1str *l1rec, size_t recnum, size_t escan)
Definition: gringHelper.cpp:70
#define DEFAULT_DAYNIGHT_MODE
Definition: main_l1info.cpp:59
#define NAVWARN
Definition: l2_flags.h:27
int i
Definition: decode_rs.h:71
int openl1(filehandle *l1file)
Definition: l1_io.c:207
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define VIIRSJ1
Definition: sensorDefs.h:37
float32 east_lon
Definition: main_l1info.cpp:81
int scan_direction
Definition: gringHelper.h:15
float32 west_lon
Definition: main_l1info.cpp:80
#define PRINT_USAGE(x)
#define NAVFAIL
Definition: l2_flags.h:36