OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
sstval_extract-main.c
Go to the documentation of this file.
1 #include "argpar.h"
2 #include "olog.h"
3 #include "olog/loader.h"
4 #include "shash.h"
5 #include "val_extract.h"
6 #include "vincenty.h"
7 
8 #include <errno.h>
9 #include <float.h>
10 #include <string.h>
11 
12 #define OFILE_DEFAULT_EXT ".qc"
13 
14 #ifdef DEBUG
15 #define dprintf(...) do { printf(__VA_ARGS__); } while(0)
16 #else
17 #define dprintf(...) do {} while (0)
18 #endif
19 
20 #define eprintf(...) do { fprintf(stderr, __VA_ARGS__); } while(0)
21 
22 #define str(s) #s
23 #define expanded_str(s) str(s)
24 
25 typedef struct sstval_extract_main_input {
26  char *ofile;
27  unsigned product_count;
29  FILE *base_ofile_h;
30  char *qual_check;
34  int box_size;
38 
39 static argpar_option options[] = {
40  { "ofile", 'o', "FILE", 0, "base output file path" },
41  { "qual_check", 'q', "VAR", 0, "quality variable (lower = better)" },
42  { "qual_check_distance", 'd', "Km", OPTION_DBL, "max distance to find better quality" },
43  { 0, 0, 0, 0, "Output files:", -2 },
44  { 0, 0, 0, OPTION_DOC,
45  "Any number of products may be specified. If none are given, every product that appears to be "
46  "geospatial, having scan line and pixel as the only dimensions, are processed, outputting statistics "
47  "such as min, max, and mean." },
48  { 0, 0, 0, OPTION_DOC, "Two sets of output files are created, one base file describing the extract as a whole, "
49  "located at <ofile> or, if not set, <ifile>" OFILE_DEFAULT_EXT ", and one file for each product requested, "
50  "located at <base>.<product>. If the file is ignored by the L2QC, the product files are omitted." },
51  { 0, 0, 0, 0, "Return values:", -1 },
53  "Extract successfully processed" },
55  "NetCDF file is malformed" },
57  "NetCDF file is fine but isn't in the format expected (doesn't have geospatial dimensions, etc)" },
59  "Error processing/finding flags" },
61  "Error processing/finding a product" },
63  "Bad or no input given" },
65  "L2QC flag over threshold" },
67  "Unknown error, such as a malloc failure or permissions problem." },
68  { 0 } // tell argpar to stop checking options
69 };
70 
71 static const char doc[] =
72  "val_extract is a utility designed to process a small section of a Level-2 "
73  "NetCDF file given either a bounding box or a center point and a box size. "
74  "A product list can be given, as well, to limit processing targets. sstval_extract "
75  "is a proxy for this library that can also find higher quality pixels in order to "
76  "re-center the extract.";
77 
78 static const char args_doc[] = "ifile=<file> <box definition> [products...]";
79 
80 const char *argpar_program_name = "sstval_extract";
81 const char *argpar_program_version = "1.3.11";
82 
83 static int parse_options(int key, char *argv, struct argpar_state *state) {
84  int ret = 0;
85 
87  switch (key) {
88  case 'o':
89  arguments->ofile = (void*) argv;
90  break;
91  case 'q':
92  arguments->qual_check = (void*) argv;
93  break;
94  case 'd':
95  if (state->argv_as_dbl_err) {
96  eprintf("qual_check_distance must be valid number\n");
97  return ARGPAR_ERR_ABORT;
98  } else {
99  arguments->qual_check_distance = state->argv_as_dbl;
100  }
101  break;
102  case ARGPAR_KEY_ARG:
103  arguments->val_extract_arguments->products[arguments->val_extract_arguments->product_count++] = argv;
104  break;
105  case ARGPAR_KEY_INIT:
106  state->child_inputs[0] = arguments->val_extract_arguments;
107  arguments->val_extract_arguments->product_count = 0;
108  arguments->qual_check = NULL;
109  arguments->qual_check_distance = 0;
110 
111  arguments->val_extract_arguments->products = malloc(state->argc * sizeof(char*));
112  if (arguments->val_extract_arguments->products == NULL) {
113  return ARGPAR_ERR_UNKNOWN;
114  }
115  break;
116  }
117  return ret;
118 }
119 
120 static const argpar_child argpar_children[] = { { &val_extract_argpar }, { 0 } };
121 static argpar sstval_extract_main_argpar = { options, parse_options, args_doc, doc, argpar_children };
122 
123 static const char *TOTAL_PIXEL_STR = "pixel_count";
124 static const char *TOTAL_PIXEL_NOT_FLAGGED_STR = "unflagged_pixel_count";
125 static const char *TOTAL_PIXEL_FLAGGED_STR = "flagged_pixel_count";
126 static const char *ASCII_TIME_STR = "time";
127 static const char *PROD_NAME_STR = "name";
128 static const char *MAX_PIXEL_STR = "max";
129 static const char *MIN_PIXEL_STR = "min";
130 static const char *MEAN_PIXEL_STR = "mean";
131 static const char *STDDEV_STR = "stddev";
132 static const char *RMS_STR = "rms";
133 static const char *VALID_PIXEL_STR = "valid_pixel_count";
134 static const char *MEDIAN_PIXEL_STR = "median";
135 static const char *CENTER_PIXEL_STR = "center_value";
136 
137 static void print_stats_to_file(FILE *h, const char *prefix, nc_var_stats *stats) {
138  fprintf(h, "%s%s=%d\n", prefix, VALID_PIXEL_STR, stats->count);
139  fprintf(h, "%s%s=%f\n", prefix, MAX_PIXEL_STR, stats->max);
140  fprintf(h, "%s%s=%f\n", prefix, MIN_PIXEL_STR, stats->min);
141  fprintf(h, "%s%s=%f\n", prefix, MEAN_PIXEL_STR, stats->mean);
142  fprintf(h, "%s%s=%f\n", prefix, MEDIAN_PIXEL_STR, stats->median);
143  fprintf(h, "%s%s=%f\n", prefix, STDDEV_STR, stats->stddev);
144  fprintf(h, "%s%s=%f\n", prefix, RMS_STR, stats->rms);
145 }
146 
147 static unsigned count_char(const char *haystack, char needle) {
148  unsigned i, count;
149  for (i = 0, count = 0; haystack[i]; i++) {
150  count += (haystack[i] == needle);
151  }
152  return count;
153 }
154 static int strcmp_p(const void *p1, const void *p2) {
155  unsigned p1_slashes = count_char(*(char * const *) p1, '/');
156  unsigned p2_slashes = count_char(*(char * const *) p2, '/');
157  if (p1_slashes < p2_slashes) {
158  return -1;
159  } else if (p1_slashes > p2_slashes) {
160  return 1;
161  }
162  return strcmp(*(char * const *) p1, *(char * const *) p2);
163 }
164 
165 static int save_extract(int key, void *nc_input, void *user_input) {
166  sstval_extract_main_input *input = user_input;
167  switch (key) {
168  case VALEXTRACT_KEY_INIT:
169  break;
171  break;
173  break;
174  case VALEXTRACT_KEY_FINI:
175  if (input->base_ofile_h) {
176  fprintf(input->base_ofile_h, "\n");
177  fprintf(input->base_ofile_h, "versions=val_extract=%s sstval_extract-main=%s\n", val_extract_version(), argpar_program_version);
178  fclose(input->base_ofile_h);
179  }
180  if (input->products_printed) {
181  shash_destroy(input->products_printed);
182  }
183  break;
184  case VALEXTRACT_KEY_FILE: {
185  nc_region *region = nc_input;
186  nc_file *file = region->file;
187  FILE *ofile_h = NULL;
188  if ((ofile_h = fopen(input->ofile, "w")) == NULL) {
189  eprintf("Error opening output file %s, %s\n", input->ofile, strerror(errno));
190  return -1;
191  }
192 
193  fprintf(ofile_h, "%s=%s\n", ASCII_TIME_STR, region->ascii_time);
194  fprintf(ofile_h, "utime=%zd\n", region->utime);
195  fprintf(ofile_h, "dim_length_lines=%d\n", file->dim_lengths[file->line_dimid]);
196  fprintf(ofile_h, "dim_length_pixels=%d\n", file->dim_lengths[file->pixel_dimid]);
197  if (input->val_extract_arguments->start_lat != VALEXTRACT_UNSET) {
198  if (input->val_extract_arguments->box_size == VALEXTRACT_UNSET) {
199  fprintf(ofile_h, "slat=%f\n", input->val_extract_arguments->start_lat);
200  fprintf(ofile_h, "slon=%f\n", input->val_extract_arguments->start_lon);
201  fprintf(ofile_h, "elat=%f\n", input->val_extract_arguments->end_lat);
202  fprintf(ofile_h, "elon=%f\n", input->val_extract_arguments->end_lon);
203  } else {
204  fprintf(ofile_h, "slat=%f\n", input->slat_orig);
205  fprintf(ofile_h, "slon=%f\n", input->slon_orig);
206  fprintf(ofile_h, "qual_check=%s\n", input->qual_check);
207  fprintf(ofile_h, "qual_check_distance=%f\n", input->qual_check_distance);
208  fprintf(ofile_h, "qual_check_distance_actual=%f\n", vincenty_distance(input->slat_orig, input->slon_orig, input->val_extract_arguments->start_lat, input->val_extract_arguments->start_lon) / 1000.);
209  }
210  } else {
211  fprintf(ofile_h, "sline=%d\n", input->val_extract_arguments->start_line);
212  fprintf(ofile_h, "spixl=%d\n", input->val_extract_arguments->start_pixel);
213  if (input->val_extract_arguments->box_size == VALEXTRACT_UNSET) {
214  fprintf(ofile_h, "eline=%d\n", input->val_extract_arguments->end_line);
215  fprintf(ofile_h, "epixl=%d\n", input->val_extract_arguments->end_pixel);
216  }
217  }
218  if (input->val_extract_arguments->box_size != VALEXTRACT_UNSET) {
219  fprintf(ofile_h, "boxsize=%d\n", input->val_extract_arguments->box_size);
220  }
221  fprintf(ofile_h, "center_lat=%f\n", region->lat);
222  fprintf(ofile_h, "center_lon=%f\n", region->lon);
223  fprintf(ofile_h, "center_line=%zd\n", region->center.line);
224  fprintf(ofile_h, "center_pixel=%zd\n", region->center.pixel);
225  fprintf(ofile_h, "%s=%d\n", TOTAL_PIXEL_STR, region->pixel_count);
226  fprintf(ofile_h, "%s=%d\n", TOTAL_PIXEL_NOT_FLAGGED_STR, region->unflagged_pixel_count);
227  fprintf(ofile_h, "%s=%d\n", TOTAL_PIXEL_FLAGGED_STR, region->flagged_pixel_count);
228  fprintf(ofile_h, "flag_counts=");
229  int flag_i;
230  for (flag_i = 0; flag_i < file->flag_count; flag_i++) {
231  if (strcmp("SPARE", file->flag_meanings[flag_i])) {
232  fprintf(ofile_h, "%*s%s=%d", flag_i ? 1 : 0, "", file->flag_meanings[flag_i], region->flag_counts[flag_i]);
233  }
234  }
235  fprintf(ofile_h, "\nflag_percents=");
236  for (flag_i = 0; flag_i < file->flag_count; flag_i++) {
237  if (strcmp("SPARE", file->flag_meanings[flag_i])) {
238  double flag_percent = (double) region->flag_counts[flag_i] / region->pixel_count;
239  fprintf(ofile_h, "%*s%s=%f", flag_i ? 1 : 0, "", file->flag_meanings[flag_i], flag_percent);
240  }
241  }
242  fprintf(ofile_h, "\nvariables=");
243  input->base_ofile_h = ofile_h;
244  input->product_count = 0;
245  if ((input->products_printed = shash_create(0)) == NULL) {
246  eprintf("Error creating product hash\n");
247  return -1;
248  }
249 
250  if (file->attributes) {
251  char attr_filename[255];
252  strcpy(attr_filename, input->ofile);
253  strcat(attr_filename, ".global_attrs");
254  FILE *attr_file_h = NULL;
255  if ((attr_file_h = fopen(attr_filename, "w")) == NULL) {
256  eprintf("Error opening output file %s, %s\n", attr_filename, strerror(errno));
257  return -1;
258  }
259  int attr_count = shash_rewind(file->attributes), att_i = 0;
260  const char *attribute_names[attr_count], *v;
261  while (!shash_next(file->attributes, &attribute_names[att_i++], &v))
262  ;
263  qsort(attribute_names, attr_count, sizeof(char*), strcmp_p);
264  for (att_i = 0; att_i < attr_count; att_i++) {
265  fprintf(attr_file_h, "%s=%s\n", attribute_names[att_i], shash_get(file->attributes, attribute_names[att_i]));
266  }
267  fclose(attr_file_h);
268  }
269  }
270  break;
271  case VALEXTRACT_KEY_VAR: {
272  nc_var *var = nc_input;
273  nc_region *region = var->region;
274  nc_file *file = var->file;
275 
276  size_t center = SIZE_MAX;
277 
278  if (!var->is_geospatial) {
279  if (var->dim_ids[0] == file->line_dimid) {
280  center = region->center.line;
281  } else if (var->dim_ids[0] == file->pixel_dimid) {
282  center = region->center.pixel;
283  }
284  }
285 
286  if (var->is_geospatial || center != SIZE_MAX) {
287  if (input->product_count++) {
288  fprintf(input->base_ofile_h, ",");
289  }
290  char output_filename[255];
291  strcpy(output_filename, input->ofile);
292  strcat(output_filename, ".");
293  if (shash_get(input->products_printed, var->name) == NULL) {
294  shash_set(input->products_printed, var->name, "");
295  strcat(output_filename, var->name);
296  fprintf(input->base_ofile_h, "%s", var->name);
297  } else {
298  char var_filename[strlen(var->name) + 4];
299  sprintf(var_filename, "%s_", var->name);
300  char *where_to_write = var_filename + strlen(var->name) + 1;
301  unsigned i = 1;
302  do {
303  sprintf(where_to_write, "%u", ++i);
304  } while (shash_get(input->products_printed, var_filename) != NULL);
305  shash_set(input->products_printed, var_filename, "");
306  strcat(output_filename, var_filename);
307  fprintf(input->base_ofile_h, "%s", var_filename);
308  }
309 
310  FILE *output_h = NULL;
311  if ((output_h = fopen(output_filename, "w")) == NULL) {
312  eprintf("Error opening output file %s, %s\n", output_filename, strerror(errno));
313  return -1;
314  }
315 
316  fprintf(output_h, "%s=%s\n", PROD_NAME_STR, var->name);
317  fprintf(output_h, "group_name=%s\n", var->group_name);
318 
319  if (var->attributes) {
320  int attr_count = shash_rewind(var->attributes), att_i = 0;
321  const char *attribute_names[attr_count], *v;
322  while (!shash_next(var->attributes, &attribute_names[att_i++], &v))
323  ;
324  qsort(attribute_names, attr_count, sizeof(char*), strcmp_p);
325  for (att_i = 0; att_i < attr_count; att_i++) {
326  fprintf(output_h, "%s=%s\n", attribute_names[att_i], shash_get(var->attributes, attribute_names[att_i]));
327  }
328  }
329 
330  if (var->is_geospatial) {
331  fprintf(output_h, "%s=%f\n", CENTER_PIXEL_STR, var->stats.center_value);
332  if (var->valid_data){
333  print_stats_to_file(output_h, "", &var->stats);
334  print_stats_to_file(output_h, "filtered_", &var->filtered_stats);
335  print_stats_to_file(output_h, "iqr_", &var->iqr_stats);
336  }
337  } else {
338  if (center != SIZE_MAX) {
339  double v = 0;
340  int nc_ret;
341  if ((nc_ret = nc_get_var1_double(var->gid, var->varid, &center, &v)) != NC_NOERR) {
342  printf("Error getting center for %s, error %d\n", var->name, nc_ret);
343  return -1;
344  }
345  fprintf(output_h, "%s=%f\n", CENTER_PIXEL_STR, v);
346  }
347  }
348  fclose(output_h);
349  }
350  }
351  break;
352  }
353  return 0;
354 }
355 
356 static int find_best_quality(int key, void *nc_input, void *user_input) {
357  sstval_extract_main_input *input = user_input;
358  switch (key) {
359  case VALEXTRACT_KEY_INIT:
360  break;
361  case VALEXTRACT_KEY_SUCCESS: {
362  nc_var *var = input->qual_check_var_copies[2];
363  nc_file *file = var->file;
364 
365  const int line_length = file->dim_lengths[file->line_dimid];
366  const int pixl_length = file->dim_lengths[file->pixel_dimid];
367 
368  const int border_bottom = (input->box_size >> 1);
369  const int line_border_top = line_length - border_bottom;
370  const int pixl_border_top = pixl_length - border_bottom;
371 
372  const double max_distance = input->qual_check_distance * 1000;
373 
374  double *lat = input->qual_check_data_copies[0];
375  double *lon = input->qual_check_data_copies[1];
376  double *qual = input->qual_check_data_copies[2];
377 
378  int best_i = -1;
379  double best_quality = DBL_MAX, closest_best_quality = DBL_MAX;
380 
381  int line = 0, pixel = 0;
382 
383  for (int i = 0; i < var->region->pixel_count; i++) {
384  if (lat[i] != -999 && qual[i] >= 0 && (var->region->pixel_flags[i] & input->val_extract_arguments->ignore_flags_mask) == 0) {
385  if (!(line < border_bottom || pixel < border_bottom || line > line_border_top || pixel > pixl_border_top)) {
386  const double distance = vincenty_distance(input->slat_orig, input->slon_orig, lat[i], lon[i]);
387  if (distance <= max_distance && (qual[i] < best_quality || (qual[i] == best_quality && distance < closest_best_quality))) {
388  best_quality = qual[i];
389  closest_best_quality = distance;
390  best_i = i;
391  }
392  }
393  }
394  ++pixel;
395  if (pixel >= pixl_length) {
396  pixel = 0;
397  ++line;
398  }
399  }
400 
401  if (best_i >= 0) {
402  input->val_extract_arguments->start_lat = lat[best_i];
403  input->val_extract_arguments->start_lon = lon[best_i];
404  } else {
405  input->val_extract_arguments->start_lat = DBL_MAX;
406  input->val_extract_arguments->start_lon = DBL_MAX;
407  }
408 // printf("find_best: %f, %f (%f)\n", input->val_extract_arguments->start_lat, input->val_extract_arguments->start_lon, best_quality);
409 // printf("find_best distance: %f\n", vincenty_distance(input->val_extract_arguments->start_lat, input->val_extract_arguments->start_lon, var->region->lat, var->region->lon));
410  }
411  break;
413  break;
414  case VALEXTRACT_KEY_FINI:
415  break;
416  case VALEXTRACT_KEY_FILE: {
417 // nc_region *region = nc_input;
418  }
419  break;
420  case VALEXTRACT_KEY_VAR: {
421  nc_var *var = nc_input;
422  int copy_location = 2;
423  if (!strcmp(var->name, "latitude")) {
424  copy_location = 0;
425  } else if (!strcmp(var->name, "longitude")) {
426  copy_location = 1;
427  }
428  input->qual_check_var_copies[copy_location] = malloc(sizeof(nc_var));
429  memcpy(input->qual_check_var_copies[copy_location], var, sizeof(nc_var));
430  input->qual_check_data_copies[copy_location] = malloc(sizeof(double) * var->region->pixel_count);
431  memcpy(input->qual_check_data_copies[copy_location], var->data, sizeof(double) * var->region->pixel_count);
432  }
433  break;
434  }
435  return 0;
436 }
437 
438 int main(int argc, char *argv[]) {
439 
440  if (argc <= 1) {
441  argpar_usage_default(&sstval_extract_main_argpar);
442  return VALEXTRACT_ERR_INPUT;
443  }
446  .geospatial_only = 1, .geospatial_to_double = 1,
447  .val_extract_parser = (val_extract_parser) save_extract,
448  .user_input = (void*) &input
449  };
450  input.val_extract_arguments = &arguments;
451 
452  olog *olog_default = olog_load_default();
453 
454  int ret = VALEXTRACT_ERR_NONE;
455  if (argpar_parse_args(&sstval_extract_main_argpar, argc, argv, 0, NULL, &input)) {
456  ret = VALEXTRACT_ERR_INPUT;
457  } else {
458  input.slat_orig = arguments.start_lat;
459  input.slon_orig = arguments.start_lon;
460 
461  if (input.qual_check) {
462  double box_size_km_save = arguments.box_size_km;
463  int box_size_save = arguments.box_size;
464  int product_count_save = arguments.product_count;
465  int ignore_flag_count_save = arguments.ignore_flag_count;
466  int count_flag_count_save = arguments.count_flag_count;
467  int l2qc_threshold_count_save = arguments.l2qc_threshold_count;
468  int valid_range_count_save = arguments.valid_range_count;
469  char **products_save = arguments.products;
470  char **ignore_flags_save = arguments.ignore_flags;
471  char **count_flags_save = arguments.count_flags;
472  char **l2qc_flags_save = arguments.l2qc_flags;
473  double *l2qc_thresholds_save = arguments.l2qc_thresholds;
474  const char *ifile_save = arguments.ifile;
475  bool global_atts_save = arguments.global_atts;
476  bool variable_atts_save = arguments.variable_atts;
477  val_extract_valid_range *valid_ranges_save = arguments.valid_ranges;
478 
479  char *qual_products[] = { "latitude", "longitude", input.qual_check };
480  arguments.product_count = 3;
481  arguments.products = qual_products;
482 // arguments.box_size_km = input.qual_check_distance;
483 // arguments.box_size = -1;
484  arguments.start_lat = -90;
485  arguments.end_lat = 90;
486  arguments.start_lon = -180;
487  arguments.end_lon = 180;
488 // arguments.ignore_flags = NULL;
489  arguments.count_flags = NULL;
490  arguments.l2qc_flags = NULL;
491  arguments.l2qc_thresholds = NULL;
492  arguments.valid_ranges = NULL;
493  arguments.global_atts = false;
494  arguments.variable_atts = false;
495 
496 // arguments.ignore_flag_count = 0;
497  arguments.count_flag_count = 0;
498  arguments.l2qc_threshold_count = 0;
499  arguments.valid_range_count = 0;
500 
501  arguments.val_extract_parser = (val_extract_parser) find_best_quality;
502 
503  input.box_size = box_size_save;
504  input.qual_check_var_copies = malloc(sizeof(nc_var*) * 3);
505  input.qual_check_data_copies = calloc(sizeof(double*), 3);
506 
507  ret = val_extract(&arguments);
508 // arguments.products = NULL;
509 // val_extract_clean(&arguments);
510 
511  for (int i = 0; i < 3; i++) {
512  if (input.qual_check_data_copies[i]) {
513  free(input.qual_check_data_copies[i]);
514  free(input.qual_check_var_copies[i]);
515  }
516  }
517  free(input.qual_check_data_copies);
518  free(input.qual_check_var_copies);
519 
520  double start_lat_save = arguments.start_lat;
521  double start_lon_save = arguments.start_lon;
522 
524 
525  arguments.products = products_save;
526  arguments.ignore_flags = ignore_flags_save;
527  arguments.count_flags = count_flags_save;
528  arguments.l2qc_flags = l2qc_flags_save;
529  arguments.valid_ranges = valid_ranges_save;
530  arguments.l2qc_thresholds = l2qc_thresholds_save;
531  arguments.ifile = ifile_save;
532  arguments.lat_and_lon = true;
533  arguments.product_count = product_count_save;
534  arguments.box_size = box_size_save;
535  arguments.box_size_km = box_size_km_save;
536  arguments.ignore_flag_count = ignore_flag_count_save;
537  arguments.count_flag_count = count_flag_count_save;
538  arguments.l2qc_threshold_count = l2qc_threshold_count_save;
539  arguments.valid_range_count = valid_range_count_save;
540  arguments.start_lat = start_lat_save;
541  arguments.start_lon = start_lon_save;
542  arguments.global_atts = global_atts_save;
543  arguments.variable_atts = variable_atts_save;
544  arguments.val_extract_parser = (val_extract_parser) save_extract;
545 
546  if (ret != VALEXTRACT_ERR_NONE || start_lat_save == DBL_MAX) {
547  olog_crit(olog_default, "Error finding closest best-quality pixel\n");
548  if (ret == VALEXTRACT_ERR_NONE) {
549  olog_crit(olog_default, "val-extract succeeded, a close-enough point was likely not found in file\n");
551  }
552  }
553  }
554  if (ret == VALEXTRACT_ERR_NONE) {
555  char output_filename[255];
556  if (!input.ofile) {
557  strcpy(output_filename, arguments.ifile);
558  strcat(output_filename, OFILE_DEFAULT_EXT);
559  input.ofile = output_filename;
560  }
561  ret = val_extract(&arguments);
562  }
563  }
565  argpar_clean(&sstval_extract_main_argpar);
566 
567  olog_destroy(olog_default);
568 
569  return ret;
570 }
void * data
Definition: val_extract.h:288
int olog_crit(olog *olog,...)
Master structure containing options, document strings, child parsers, and text filters....
Definition: argpar.h:398
#define VALEXTRACT_ERR_FLAG
Returned when the something goes wrong processing l2_flags.
Definition: val_extract.h:37
#define eprintf(...)
int main(int argc, char *argv[])
#define VALEXTRACT_KEY_SUCCESS
Passed to parser when the processing is finished and no errors were encountered.
Definition: val_extract.h:58
int * flag_counts
Definition: val_extract.h:259
time_t utime
Definition: val_extract.h:262
#define VALEXTRACT_ERR_POINT_NOT_FOUND
Returned when the desired point is not in the file boundaries.
Definition: val_extract.h:28
int pixel_count
Definition: val_extract.h:258
int gid
Definition: val_extract.h:277
nc_point center
Definition: val_extract.h:255
int16_t * qual
Definition: l2bin.cpp:86
#define VALEXTRACT_ERR_NONE
Returned on successful processing.
Definition: val_extract.h:26
#define NULL
Definition: decode_rs.h:63
const char * argpar_program_version
Used as the program version string. If set, a version=1 option is automatically added....
Provides a single function to calculate geographical distances.
Passed into the library function to control the processing. Many of the fields will be unspecified.
Definition: val_extract.h:103
double vincenty_distance(double lat1, double lon1, double lat2, double lon2)
Calculate geographical distances using Vincenty's algorithm.
Definition: vincenty.c:47
#define ARGPAR_KEY_ARG
This is not an option at all, but rather a command line argument. If a parser receiving this key retu...
Definition: argpar.h:271
float h[MODELMAX]
Definition: atrem_corl1.h:131
float * lat
Given to val_extract_arguments, these contain the valid ranges, inclusive, of variables....
Definition: val_extract.h:87
int flagged_pixel_count
Definition: val_extract.h:258
shash * shash_create(uint32_t options)
Initialize a shash object.
Definition: shash.c:105
int shash_set(shash *h, const char *key, const char *value)
Add or overwrite a pointer, associating it with the given key.
Definition: shash.c:224
Implementation-specific, generic type to store the shash object.
Definition: shash.c:40
const char * ofile
Definition: argpar.c:45
Child parser for nesting argpars.
Definition: argpar.h:377
#define ARGPAR_KEY_INIT
Passed as the key to each parser callback function before any parsing occurs. For most cases,...
Definition: argpar.h:287
bool is_geospatial
Definition: val_extract.h:278
const char * val_extract_version()
Returns a string representation of the library's version number, without a label.
Definition: val_extract.c:2632
#define VALEXTRACT_KEY_INIT
Passed to parser when beginning the processing.
Definition: val_extract.h:50
A simple logger, capable of dispatching log events to multiple end points.
#define str(s)
struct packet_stats stats
const char * argpar_program_name
int(* val_extract_parser)(int key, void *nc_input, void *user_input)
Pointer to a callback function to call for each argument parsed.
Definition: val_extract.h:79
size_t pixel
Definition: val_extract.h:234
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 file
Definition: HISTORY.txt:413
double center_value
Definition: val_extract.h:270
instr * input
nc_region * region
Definition: val_extract.h:275
char * name
Definition: val_extract.h:276
#define ARGPAR_ERR_UNKNOWN
What to return for unrecognized keys within an argpar_parser function.
Definition: argpar.h:341
nc_var_stats iqr_stats
Definition: val_extract.h:283
int state(double tjdTDB, JPLIntUtilType *util, double posvel[13][6], double *pnut)
shash * attributes
Definition: val_extract.h:282
#define VALEXTRACT_ERR_INPUT
Returned when given bad or no arguments.
Definition: val_extract.h:42
const char * shash_get(shash *h, const char *key)
Find a pointer associated with the given string.
Definition: shash.c:205
nc_var_stats filtered_stats
Definition: val_extract.h:283
int argpar_clean(argpar *p)
Free any space consumed by argpar for parfiles.
Definition: argpar.c:649
#define VALEXTRACT_ERR_VARIABLE
Returned when the something goes wrong processing a product or when finding a product specified on th...
Definition: val_extract.h:40
olog * olog_load_default()
Definition: olog_loader.c:12
#define VALEXTRACT_KEY_VAR
Passed to parser when a variable is processed. The parser is passed a pointer to an nc_var structure ...
Definition: val_extract.h:56
#define ARGPAR_ERR_ABORT
Returned from the parser callback to signal argpar to stop parsing and return to the caller.
Definition: argpar.h:334
int varid
Definition: val_extract.h:277
int shash_next(shash *h, const char **key, const char **value)
Retrieves the next key-value pair in the shash. The order in which the pointers are returned shall be...
Definition: shash.c:283
const char * ifile
Definition: argpar.c:44
int errno
Definition: olog.c:11
integer, parameter double
int shash_rewind(shash *h)
Rewind iterator for traversing all the keys and values.
Definition: shash.c:277
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution pixel
Definition: HISTORY.txt:192
int argpar_parse_args(argpar *p, unsigned argc, char *argv[], unsigned flags, unsigned *end_index, void *input)
Parse an array of key=value pairs and/or key arguments.
Definition: argpar.c:679
argpar val_extract_argpar
argpar structure used for making programs that inherit options from this library.
Definition: val_extract.c:523
def center
Definition: sort_gring.py:68
double lon
Definition: val_extract.h:261
#define OPTION_DOC
This option isn't actually an option, merely text for the usage summary.
Definition: argpar.h:152
#define VALEXTRACT_KEY_FINI
Passed to parser when ending the processing.
Definition: val_extract.h:62
#define VALEXTRACT_ERR_L2QC
Not a real error, but returned when the L2QC step says it's a poor quality file.
Definition: val_extract.h:44
nc_var_stats stats
Definition: val_extract.h:283
State variable to be filled before each call to the parser callback.
Definition: argpar.h:196
A simple dictionary library for storing strings.
int argpar_usage_default(argpar *argpar)
Print the default usage summary with all available sections.
Definition: argpar-help.c:509
#define VALEXTRACT_UNSET
Initial value for location arguments (lat/lon/line/pixl) before argument parsing.
Definition: val_extract.h:68
#define VALEXTRACT_ERR_NCFILE_INVALID
Returned when the NetCDF file isn't in the format expected (not an L2, etc).
Definition: val_extract.h:35
Library for reading command-line arguments in the form of key=value.
float * lon
int * dim_ids
Definition: val_extract.h:281
Process a small section of a Level-2 NetCDF file.
#define DBL_MAX
Definition: make_L3_v1.1.c:60
int val_extract(val_extract_arguments *arguments)
Process a small section of a Level-2 NetCDF file.
Definition: val_extract.c:589
val_extract_arguments * val_extract_arguments
char * group_name
Definition: val_extract.h:276
int shash_destroy(shash *h)
Destroy a shash object, free'ing the memory used.
Definition: shash.c:136
char ascii_time[24]
Definition: val_extract.h:263
#define expanded_str(s)
int unflagged_pixel_count
Definition: val_extract.h:258
#define VALEXTRACT_ERR_NCFILE_ERR
Returned when the NetCDF file can't be opened (due to errors or corruption).
Definition: val_extract.h:33
int val_extract_clean(val_extract_arguments *arguments)
Clean up stuff malloc'd by the argpar callback. Should be called at the end of processing if val_extr...
Definition: val_extract.c:2540
double lat
Definition: val_extract.h:261
int i
Definition: decode_rs.h:71
nc_file * file
Definition: val_extract.h:254
#define VALEXTRACT_ERR_UNKNOWN
Returned for unexpected errors like malloc failures or, possibly, permissions problems and the like.
Definition: val_extract.h:31
#define VALEXTRACT_KEY_FILE
Passed to parser when first opening the NetCDF file. The parser is passed a pointer to an nc_region s...
Definition: val_extract.h:53
void val_extract_clear_args(val_extract_arguments *arguments)
Clear an argument struct to make it suitable for using the library without using argpar.
Definition: val_extract.c:127
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
void olog_destroy(olog *olog)
Definition: olog.c:60
#define OFILE_DEFAULT_EXT
Stores the configuration for a par argument.
Definition: argpar.h:87
#define VALEXTRACT_KEY_ERROR
Passed to parser when the processing is finished and an error was encountered.
Definition: val_extract.h:60
#define OPTION_DBL
Cast this option as a double. The value and any error will be reflected in the argpar_state struct du...
Definition: argpar.h:156
size_t line
Definition: val_extract.h:234
nc_file * file
Definition: val_extract.h:274
double * valid_data
Definition: val_extract.h:286
uint32_t * pixel_flags
Definition: val_extract.h:260
int count
Definition: decode_rs.h:79