OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
val_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 
7 #include <ctype.h>
8 #include <errno.h>
9 #include <stdbool.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 val_extract_main_input {
26  char *ofile;
27  bool dump_all;
28  char dump_type;
29  char **dump_products;
31  unsigned product_count;
33  FILE *base_ofile_h;
36 
37 static argpar_option options[] = {
38  { "ofile", 'o', "FILE", 0, "base output file path" },
39  { "dump", 'd', "PRODUCT ...", 0, "product(s) to dump all pixels" },
40  { 0, 0, 0, OPTION_DOC, "(use dump=1 to dump every product)" },
41  { "dump_type", 'D', "N", OPTION_INT, "style of pixel printing" },
42  { 0, 0, 0, OPTION_DOC, "0 = print pixel matrix (as seen by val-extract)" },
43  { 0, 0, 0, OPTION_DOC, "1 = print valid pixels (scaled, offset, and sorted)" },
44  { 0, 0, 0, 0, "Output files:", -2 },
45  { 0, 0, 0, OPTION_DOC,
46  "Any number of products may be specified. If none are given, every product that appears to be "
47  "geospatial, having scan line and pixel as the only dimensions, are processed, outputting statistics "
48  "such as min, max, and mean." },
49  { 0, 0, 0, OPTION_DOC, "Two sets of output files are created, one base file describing the extract as a whole, "
50  "located at <ofile> or, if not set, <ifile>" OFILE_DEFAULT_EXT ", and one file for each product requested, "
51  "located at <base>.<product>. If the file is ignored by the L2QC, the product files are omitted." },
52  { 0, 0, 0, 0, "Return values:", -1 },
54  "Extract successfully processed" },
56  "Requested point not within file boundaries" },
58  "NetCDF file is malformed" },
60  "NetCDF file is fine but isn't in the format expected (doesn't have geospatial dimensions, etc)" },
62  "Error processing/finding flags" },
64  "Error processing/finding a product" },
66  "Bad or no input given" },
68  "L2QC flag over threshold" },
70  "Unknown error, such as a malloc failure or permissions problem." },
71  { 0 } // tell argpar to stop checking options
72 };
73 
74 static const char doc[] =
75  "val_extract is a utility designed to process a small section of a Level-2 "
76  "NetCDF file given either a bounding box or a center point and a box size. "
77  "A product list can be given, as well, to limit processing targets.";
78 
79 static const char args_doc[] = "ifile=<file> <box definition> [products...]";
80 
81 const char *argpar_program_name = "val_extract";
82 const char *argpar_program_version = "1.3.2";
83 
84 static int parse_options(int key, char *argv, struct argpar_state *state) {
85  int ret = 0;
87  switch (key) {
88  case 'o':
89  arguments->ofile = (void*) argv;
90  break;
91  case 'D':
92  arguments->dump_type = state->argv_as_int;
93  break;
94  case 'd': {
95  size_t argv_length = strlen(argv);
96  if (argv_length == 1 && argv[0] == '1'){
97  arguments->dump_all = true;
98  } else if (argv_length > 0){
99  char tmp[strlen(argv) + 1];
100  strncpy(tmp, argv, strlen(argv));
101  tmp[strlen(argv)] = '\0';
102  char *tmp_p = argv;
103  size_t space_count = 0;
104  if (!isspace(*tmp_p)) {
105  ++space_count;
106  }
107  while (*tmp_p) {
108  if (isspace(*tmp_p)) {
109  ++space_count;
110  }
111  ++tmp_p;
112  }
113 
114  arguments->dump_products_count = 0;
115  arguments->dump_products = calloc(space_count, sizeof(const char*));
116  if (!arguments->dump_products) {
117  olog_crit(arguments->val_extract_arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
118  return ARGPAR_ERR_ABORT;
119  }
120 
121  int i = 0;
122  char *token = strtok(tmp, " ");
123  while (token) {
124  if (strlen(token)) {
125  arguments->dump_products[i] = malloc((strlen(token) + 1) * sizeof(char));
126  if (!arguments->dump_products[i]) {
127  olog_crit(arguments->val_extract_arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
128  return ARGPAR_ERR_ABORT;
129  }
130  strcpy(arguments->dump_products[i], token);
131  arguments->dump_products_count++;
132  ++i;
133  }
134  token = strtok(NULL, " ");
135  }
136  }
137  } break;
138  case ARGPAR_KEY_ARG:
139  arguments->val_extract_arguments->products[arguments->val_extract_arguments->product_count++] = argv;
140  break;
141  case ARGPAR_KEY_INIT:
142  state->child_inputs[0] = arguments->val_extract_arguments;
143  arguments->val_extract_arguments->product_count = 0;
144 
145  arguments->val_extract_arguments->products = malloc(state->argc * sizeof(char*));
146  if (arguments->val_extract_arguments->products == NULL) {
147  olog_crit(arguments->val_extract_arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
148  return ARGPAR_ERR_ABORT;
149  }
150  break;
151  }
152  return ret;
153 }
154 
155 static const argpar_child argpar_children[] = { { &val_extract_argpar }, { 0 } };
156 argpar val_extract_main_argpar = { options, parse_options, args_doc, doc, argpar_children };
157 
158 static const char *TOTAL_PIXEL_STR = "pixel_count";
159 static const char *TOTAL_PIXEL_NOT_FLAGGED_STR = "unflagged_pixel_count";
160 static const char *TOTAL_PIXEL_FLAGGED_STR = "flagged_pixel_count";
161 static const char *ASCII_TIME_STR = "time";
162 static const char *PROD_NAME_STR = "name";
163 static const char *MAX_PIXEL_STR = "max";
164 static const char *MIN_PIXEL_STR = "min";
165 static const char *MEAN_PIXEL_STR = "mean";
166 static const char *STDDEV_STR = "stddev";
167 static const char *RMS_STR = "rms";
168 static const char *VALID_PIXEL_STR = "valid_pixel_count";
169 static const char *MEDIAN_PIXEL_STR = "median";
170 static const char *CENTER_PIXEL_STR = "center_value";
171 
172 static void print_stats_to_file(FILE *h, const char *prefix, nc_var_stats *stats) {
173  fprintf(h, "%s%s=%d\n", prefix, VALID_PIXEL_STR, stats->count);
174  fprintf(h, "%s%s=%f\n", prefix, MAX_PIXEL_STR, stats->max);
175  fprintf(h, "%s%s=%f\n", prefix, MIN_PIXEL_STR, stats->min);
176  fprintf(h, "%s%s=%f\n", prefix, MEAN_PIXEL_STR, stats->mean);
177  fprintf(h, "%s%s=%f\n", prefix, MEDIAN_PIXEL_STR, stats->median);
178  fprintf(h, "%s%s=%f\n", prefix, STDDEV_STR, stats->stddev);
179  fprintf(h, "%s%s=%f\n", prefix, RMS_STR, stats->rms);
180 }
181 
182 static unsigned count_char(const char *haystack, char needle) {
183  unsigned i, count;
184  for (i = 0, count = 0; haystack[i]; i++) {
185  count += (haystack[i] == needle);
186  }
187  return count;
188 }
189 static int strcmp_p(const void *p1, const void *p2) {
190  unsigned p1_slashes = count_char(*(char * const *) p1, '/');
191  unsigned p2_slashes = count_char(*(char * const *) p2, '/');
192  if (p1_slashes < p2_slashes) {
193  return -1;
194  } else if (p1_slashes > p2_slashes) {
195  return 1;
196  }
197  return strcmp(*(char * const *) p1, *(char * const *) p2);
198 }
199 static void print_val(FILE *file, nc_var *var, double value){
200  if (var->has_fill && value == var->fill) {
201  fprintf(file, "%s\n", "NULL");
202  } else {
203  if (var->has_scale) {
204  value *= var->scale;
205  }
206  if (var->has_offset) {
207  value += var->offset;
208  }
209  fprintf(file, "%f\n", value);
210  }
211 }
212 
213 static int save_extract(int key, void *nc_input, void *user_input) {
214  val_extract_main_input *input = user_input;
215  switch (key) {
216  case VALEXTRACT_KEY_INIT:
217  break;
219  break;
221  break;
222  case VALEXTRACT_KEY_FINI:
223  if (input->base_ofile_h) {
224  fprintf(input->base_ofile_h, "\n");
225  fprintf(input->base_ofile_h, "versions=val_extract=%s val_extract-main=%s\n", val_extract_version(), argpar_program_version);
226  fclose(input->base_ofile_h);
227  }
228  if (input->products_printed) {
229  shash_destroy(input->products_printed);
230  }
231  break;
232  case VALEXTRACT_KEY_FILE: {
233  nc_region *region = nc_input;
234  nc_file *file = region->file;
235  FILE *ofile_h = NULL;
236  if ((ofile_h = fopen(input->ofile, "w")) == NULL) {
237  eprintf("Error opening output file %s, %s\n", input->ofile, strerror(errno));
238  return -1;
239  }
240 
241  fprintf(ofile_h, "%s=%s\n", ASCII_TIME_STR, region->ascii_time);
242  fprintf(ofile_h, "utime=%zd\n", region->utime);
243  fprintf(ofile_h, "dim_length_lines=%d\n", file->dim_lengths[file->line_dimid]);
244  fprintf(ofile_h, "dim_length_pixels=%d\n", file->dim_lengths[file->pixel_dimid]);
245  if (input->val_extract_arguments->start_lat != VALEXTRACT_UNSET) {
246  fprintf(ofile_h, "slat=%f\n", input->val_extract_arguments->start_lat);
247  fprintf(ofile_h, "slon=%f\n", input->val_extract_arguments->start_lon);
248  if (input->val_extract_arguments->box_size == VALEXTRACT_UNSET) {
249  fprintf(ofile_h, "elat=%f\n", input->val_extract_arguments->end_lat);
250  fprintf(ofile_h, "elon=%f\n", input->val_extract_arguments->end_lon);
251  }
252  } else {
253  fprintf(ofile_h, "sline=%d\n", input->val_extract_arguments->start_line);
254  fprintf(ofile_h, "spixl=%d\n", input->val_extract_arguments->start_pixel);
255  if (input->val_extract_arguments->box_size == VALEXTRACT_UNSET) {
256  fprintf(ofile_h, "eline=%d\n", input->val_extract_arguments->end_line);
257  fprintf(ofile_h, "epixl=%d\n", input->val_extract_arguments->end_pixel);
258  }
259  }
260  if (input->val_extract_arguments->box_size != VALEXTRACT_UNSET) {
261  fprintf(ofile_h, "boxsize=%d\n", input->val_extract_arguments->box_size);
262  }
263  fprintf(ofile_h, "center_lat=%f\n", region->lat);
264  fprintf(ofile_h, "center_lon=%f\n", region->lon);
265  fprintf(ofile_h, "center_line=%zd\n", region->center.line);
266  fprintf(ofile_h, "center_pixel=%zd\n", region->center.pixel);
267  fprintf(ofile_h, "%s=%d\n", TOTAL_PIXEL_STR, region->pixel_count);
268  fprintf(ofile_h, "%s=%d\n", TOTAL_PIXEL_NOT_FLAGGED_STR, region->unflagged_pixel_count);
269  fprintf(ofile_h, "%s=%d\n", TOTAL_PIXEL_FLAGGED_STR, region->flagged_pixel_count);
270  fprintf(ofile_h, "flag_counts=");
271  int flag_i;
272  for (flag_i = 0; flag_i < file->flag_count; flag_i++) {
273  if (strcmp("SPARE", file->flag_meanings[flag_i])) {
274  fprintf(ofile_h, "%*s%s=%d", flag_i ? 1 : 0, "", file->flag_meanings[flag_i], region->flag_counts[flag_i]);
275  }
276  }
277  fprintf(ofile_h, "\nflag_percents=");
278  for (flag_i = 0; flag_i < file->flag_count; flag_i++) {
279  if (strcmp("SPARE", file->flag_meanings[flag_i])) {
280  double flag_percent = (double) region->flag_counts[flag_i] / region->pixel_count;
281  fprintf(ofile_h, "%*s%s=%f", flag_i ? 1 : 0, "", file->flag_meanings[flag_i], flag_percent);
282  }
283  }
284  fprintf(ofile_h, "\nvariables=");
285  input->base_ofile_h = ofile_h;
286  input->product_count = 0;
287  if ((input->products_printed = shash_create(0)) == NULL) {
288  eprintf("Error creating product hash\n");
289  return -1;
290  }
291 
292  if (file->attributes) {
293  char attr_filename[255];
294  strcpy(attr_filename, input->ofile);
295  strcat(attr_filename, ".global_attrs");
296  FILE *attr_file_h = NULL;
297  if ((attr_file_h = fopen(attr_filename, "w")) == NULL) {
298  eprintf("Error opening output file %s, %s\n", attr_filename, strerror(errno));
299  return -1;
300  }
301  int attr_count = shash_rewind(file->attributes), att_i = 0;
302  const char *attribute_names[attr_count], *v;
303  while (!shash_next(file->attributes, &attribute_names[att_i++], &v))
304  ;
305  qsort(attribute_names, attr_count, sizeof(char*), strcmp_p);
306  for (att_i = 0; att_i < attr_count; att_i++) {
307  fprintf(attr_file_h, "%s=%s\n", attribute_names[att_i], shash_get(file->attributes, attribute_names[att_i]));
308  }
309  fclose(attr_file_h);
310  }
311  }
312  break;
313  case VALEXTRACT_KEY_VAR: {
314  nc_var *var = nc_input;
315  if (!var->is_geospatial) {
316  return 0;
317  }
318 
319  if (input->product_count++) {
320  fprintf(input->base_ofile_h, ",");
321  }
322  nc_file *file = var->file;
323  char output_filename[255];
324  strcpy(output_filename, input->ofile);
325  strcat(output_filename, ".");
326  if (shash_get(input->products_printed, var->name) == NULL) {
327  shash_set(input->products_printed, var->name, "");
328  strcat(output_filename, var->name);
329  fprintf(input->base_ofile_h, "%s", var->name);
330  } else {
331  char var_filename[strlen(var->name) + 4];
332  sprintf(var_filename, "%s_", var->name);
333  char *where_to_write = var_filename + strlen(var->name) + 1;
334  unsigned i = 1;
335  do {
336  sprintf(where_to_write, "%u", ++i);
337  } while (shash_get(input->products_printed, var_filename) != NULL);
338  shash_set(input->products_printed, var_filename, "");
339  strcat(output_filename, var_filename);
340  fprintf(input->base_ofile_h, "%s", var_filename);
341  }
342 
343  FILE *output_h = NULL;
344  if ((output_h = fopen(output_filename, "w")) == NULL) {
345  eprintf("Error opening output file %s, %s\n", output_filename, strerror(errno));
346  return -1;
347  }
348 
349  fprintf(output_h, "%s=%s\n", PROD_NAME_STR, var->name);
350  fprintf(output_h, "group_name=%s\n", var->group_name);
351 
352  if (var->attributes) {
353  int attr_count = shash_rewind(var->attributes), att_i = 0;
354  const char *attribute_names[attr_count], *v;
355  while (!shash_next(var->attributes, &attribute_names[att_i++], &v))
356  ;
357  qsort(attribute_names, attr_count, sizeof(char*), strcmp_p);
358  for (att_i = 0; att_i < attr_count; att_i++) {
359  fprintf(output_h, "%s=%s\n", attribute_names[att_i], shash_get(var->attributes, attribute_names[att_i]));
360  }
361  }
362 
363  fprintf(output_h, "%s=%f\n", CENTER_PIXEL_STR, var->stats.center_value);
364 
365  if (var->is_geospatial && var->valid_data) {
366  print_stats_to_file(output_h, "", &var->stats);
367  print_stats_to_file(output_h, "filtered_", &var->filtered_stats);
368  print_stats_to_file(output_h, "iqr_", &var->iqr_stats);
369  }
370  bool dump_product = input->dump_all;
371  if (!dump_product && input->dump_products){
372  for (size_t i = 0; i < input->dump_products_count; i++) {
373  if (strcmp(var->name, input->dump_products[i]) == 0) {
374  dump_product = 1;
375  break;
376  }
377  }
378  }
379  if (dump_product){
380  if (var->is_geospatial){
381  if (input->dump_type == 0 || !var->valid_data){
382  int print_row_i = 0;
383  size_t pixel_i = 0;
384  for (int box_i = 0; box_i < var->region->box_count; box_i++) {
385  nc_box box = var->region->boxes[box_i];
386  for (size_t row_i = 0; row_i < box.count[0]; row_i++){
387  for (size_t col_i = 0; col_i < box.count[1]; col_i++){
388  fprintf(output_h, "value[%d][%lu]=", print_row_i, col_i);
389  double v = ((double*)var->data)[pixel_i++];
390  print_val(output_h, var, v);
391  }
392  print_row_i++;
393  }
394 
395  }
396  } else {
397  for (int i = 0; i < var->valid_data_count; i++) {
398  fprintf(output_h, "value[%d]=%f\n", i, var->valid_data[i]);
399  }
400  }
401  } else {
402  int i, j, nc_ret;
403 
404  int ndims = var->ndims;
405  int dim_lengths[ndims];
406  for (i = 0; i < ndims; i++) {
407  dim_lengths[i] = file->dim_lengths[var->dim_ids[i]];
408  }
409 
410  int value_count = dim_lengths[ndims - 1];
411  for (i = ndims - 2; i >= 0; i--) {
412  value_count *= dim_lengths[i];
413  }
414 
415  double values[value_count];
416  if ((nc_ret = nc_get_var_double(var->gid, var->varid, values)) != NC_NOERR) {
417  eprintf("Error getting entire dataset for %s, error %d\n", var->name, nc_ret);
418  return -1;
419  }
420  FILE *output_h = NULL;
421  if ((output_h = fopen(output_filename, "w")) == NULL) {
422  eprintf("Error opening output file %s, %s\n", output_filename, strerror(errno));
423  return -1;
424  }
425  for (i = 0; i < value_count; i++) {
426  fprintf(output_h, "value");
427  int multidim_index[ndims];
428  unflatten_index(i, ndims, dim_lengths, multidim_index);
429  for (j = 0; j < ndims; j++) {
430  fprintf(output_h, "[%d]", multidim_index[j]);
431  }
432  fprintf(output_h, "value=");
433  print_val(output_h, var, values[i]);
434  }
435  }
436  }
437  fclose(output_h);
438  }
439  break;
440  }
441  return 0;
442 }
443 
444 int main(int argc, char *argv[]) {
445  if (argc <= 1) {
447  return VALEXTRACT_ERR_INPUT;
448  }
451  .geospatial_only = 1, .geospatial_to_double = 1,
452  .val_extract_parser = (val_extract_parser) save_extract,
453  .user_input = (void*) &input
454  };
455  input.val_extract_arguments = &arguments;
456 
457  int ret = EXIT_SUCCESS;
458  if (argpar_parse_args(&val_extract_main_argpar, argc, argv, 0, NULL, &input)) {
459  ret = VALEXTRACT_ERR_INPUT;
460  } else {
461  char output_filename[255];
462  printf("%s\n", arguments.ifile);
463  if (!input.ofile) {
464  strcpy(output_filename, arguments.ifile);
465  strcat(output_filename, OFILE_DEFAULT_EXT);
466  input.ofile = output_filename;
467  }
468  ret = val_extract(&arguments);
469  }
472 
474 
475  if (input.dump_products){
476  for (int i = 0; i < input.dump_products_count; i++){
477  free(input.dump_products[i]);
478  }
479  free(input.dump_products);
480  }
481 
482  return ret;
483 }
void * data
Definition: val_extract.h:288
int32 value
Definition: Granule.c:1235
#define eprintf(...)
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
const char * argpar_program_name
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
int j
Definition: decode_rs.h:73
#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
nc_box * boxes
Definition: val_extract.h:257
bool has_offset
Definition: val_extract.h:279
int pixel_count
Definition: val_extract.h:258
int gid
Definition: val_extract.h:277
nc_point center
Definition: val_extract.h:255
#define VALEXTRACT_ERR_NONE
Returned on successful processing.
Definition: val_extract.h:26
#define NULL
Definition: decode_rs.h:63
int valid_data_count
Definition: val_extract.h:287
#define OPTION_INT
Cast this option as a long. The value and any error will be reflected in the argpar_state struct duri...
Definition: argpar.h:160
void olog_destroy_default()
Definition: olog_loader.c:28
Passed into the library function to control the processing. Many of the fields will be unspecified.
Definition: val_extract.h:103
#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
bool has_scale
Definition: val_extract.h:279
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.
struct packet_stats stats
int ndims
Definition: val_extract.h:281
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
#define expanded_str(s)
char * name
Definition: val_extract.h:276
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
int main(int argc, char *argv[])
data_t tmp
Definition: decode_rs.h:74
#define VALEXTRACT_ERR_INPUT
Returned when given bad or no arguments.
Definition: val_extract.h:42
bool has_fill
Definition: val_extract.h:279
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
#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
val_extract_arguments * val_extract_arguments
int errno
integer, parameter double
argpar val_extract_main_argpar
int shash_rewind(shash *h)
Rewind iterator for traversing all the keys and values.
Definition: shash.c:277
#define isspace(c)
double offset
Definition: val_extract.h:280
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
HISTORY txt for MOD_PR01(step one of PGE01) History follows the following convention needed due to new Aqua ReprocessingActual and the expected LUT revision number from PCF Changed to use PGE version for ProductionHistory Added Archive including ProcessingEnvironment Corrected handling of bad to resovle GSFcd02514 Changed to check staged LUT revision number versus the expected LUT revision number from thereby resolving defect report MODxl02056 This change also avoids the memory access violation reported in MODur00039 Changed the way output arrays were initialized with fill values
Definition: HISTORY.txt:162
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.
#define str(s)
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
int box_count
Definition: val_extract.h:256
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)
const char * argpar_program_version
Used as the program version string. If set, a version=1 option is automatically added....
#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.
int * dim_ids
Definition: val_extract.h:281
Process a small section of a Level-2 NetCDF file.
int val_extract(val_extract_arguments *arguments)
Process a small section of a Level-2 NetCDF file.
Definition: val_extract.c:589
size_t count[2]
Definition: val_extract.h:238
void unflatten_index(int index, int ndims, const int *dims, int *result)
Given dimension lengths from an nc_file and a one dimensional index, find the corresponding n-dimensi...
Definition: val_extract.c:2604
#define OFILE_DEFAULT_EXT
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
double fill
Definition: val_extract.h:280
char ascii_time[24]
Definition: val_extract.h:263
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
double scale
Definition: val_extract.h:280
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
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
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
size_t line
Definition: val_extract.h:234
nc_file * file
Definition: val_extract.h:274
double * valid_data
Definition: val_extract.h:286
int count
Definition: decode_rs.h:79