OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
leveltwo2csv-main.c
Go to the documentation of this file.
1 #include "argpar.h"
2 #include "val_extract.h"
3 
4 #include <errno.h>
5 #include <math.h>
6 #include <stdio.h>
7 #include <string.h>
8 
9 #define OFILE_DEFAULT_EXT ".csv"
10 
11 #ifdef DEBUG
12 #define dprintf(...) do { printf(__VA_ARGS__); } while(0)
13 #else
14 #define dprintf(...) do {} while (0)
15 #endif
16 
17 #define eprintf(...) do { fprintf(stderr, __VA_ARGS__); } while(0)
18 
19 #define str(s) #s
20 #define expanded_str(s) str(s)
21 
22 typedef struct leveltwo2csv_main_input {
23  char *ofile;
24  char *product;
27 
28 static argpar_option options[] = {
29  { "ofile", 'o', "FILE", 0, "output file path" },
30  { "product", 'p', "FILE", 0, "product to dump" },
31  { 0, 0, 0, 0, "Return values:", -1 },
33  "Extract successfully processed" },
35  "NetCDF file is malformed" },
37  "NetCDF file is fine but isn't in the format expected (doesn't have geospatial dimensions, etc)" },
39  "Error processing/finding flags" },
41  "Error processing/finding a product" },
43  "Bad or no input given" },
45  "L2QC flag over threshold" },
47  "Unknown error, such as a malloc failure or permissions problem." },
48  { 0 } // tell argpar to stop checking options
49 };
50 
51 static const char doc[] =
52  "A wrapper around val-extract to dump a product of an L2 file to a CSV";
53 
54 static const char args_doc[] = "ifile=<file> [<box definition>] [products...]";
55 
56 static int parse_options(int key, char *argv, struct argpar_state *state) {
57  int ret = 0;
58 
60  switch (key) {
61  case 'o':
62  arguments->ofile = (void*) argv;
63  break;
64  case 'p':
65  arguments->product = (void*) argv;
66  break;
67  case ARGPAR_KEY_SUCCESS:
68  arguments->val_extract_arguments->products = malloc((arguments->product ? 3 : 2) * sizeof(char*));
69  if (arguments->val_extract_arguments->products == NULL) {
70  return ARGPAR_ERR_UNKNOWN;
71  }
72  arguments->val_extract_arguments->products[0] = "latitude";
73  arguments->val_extract_arguments->products[1] = "longitude";
74  if (arguments->product) {
75  arguments->val_extract_arguments->products[2] = arguments->product;
76  arguments->val_extract_arguments->product_count = 3;
77  } else {
78  arguments->val_extract_arguments->product_count = 2;
79  }
80  break;
81  case ARGPAR_KEY_INIT:
82  state->child_inputs[0] = arguments->val_extract_arguments;
83  arguments->val_extract_arguments->product_count = 0;
84  arguments->val_extract_arguments->box_size = 0;
85  arguments->val_extract_arguments->start_lat = -90;
86  arguments->val_extract_arguments->end_lat = 90;
87  arguments->val_extract_arguments->start_lon = -180;
88  arguments->val_extract_arguments->end_lon = 180;
89  break;
90  }
91  return ret;
92 }
93 
94 static const argpar_child argpar_children[] = { { &val_extract_argpar }, { 0 } };
95 static argpar leveltwo2csv_main_argpar = { options, parse_options, args_doc, doc, argpar_children };
96 
97 const char *argpar_program_name = "leveltwo2csv";
98 const char *argpar_program_version = "0.0.1";
99 
100 static int save_extract(int key, void *nc_input, void *user_input) {
101  leveltwo2csv_main_input *input = user_input;
102  switch (key) {
103  case VALEXTRACT_KEY_INIT:
104  break;
105  case VALEXTRACT_KEY_SUCCESS: {
106  FILE *ofile_h = NULL;
107  if ((ofile_h = fopen(input->ofile, "w")) == NULL) {
108  eprintf("Error opening output file %s, %s\n", input->ofile, strerror(errno));
109  return -1;
110  }
111  FILE *ivar_h[input->val_extract_arguments->product_count];
112  int i;
113  char input_filename[3][255];
114  for (i = 0; i < input->val_extract_arguments->product_count; i++) {
115  strcpy(input_filename[i], input->ofile);
116  strcat(input_filename[i], ".");
117  strcat(input_filename[i], input->val_extract_arguments->products[i]);
118  if ((ivar_h[i] = fopen(input_filename[i], "r")) == NULL) {
119  eprintf("Error opening output file %s, %s\n", input_filename[i], strerror(errno));
120  return -1;
121  }
122  if (i) {
123  fprintf(ofile_h, ",");
124  }
125  fprintf(ofile_h, "%s", input->val_extract_arguments->products[i]);
126  }
127 
128  int file_ret = 0;
129  while (file_ret != EOF) {
130  fprintf(ofile_h, "\n");
131  for (i = 0; i < input->val_extract_arguments->product_count && file_ret != EOF; i++) {
132  double v = NAN;
133  file_ret = fscanf(ivar_h[i], "%lf\n", &v);
134  if (file_ret != EOF) {
135  if (i) {
136  fprintf(ofile_h, ",");
137  }
138  fprintf(ofile_h, "%f", v);
139  }
140  }
141  }
142  fprintf(ofile_h, "\n");
143 
144  for (i = 0; i < input->val_extract_arguments->product_count; i++) {
145  fclose(ivar_h[i]);
146  remove(input_filename[i]);
147  }
148  fclose(ofile_h);
149  }
150  break;
152  break;
153  case VALEXTRACT_KEY_FINI:
154  break;
155  case VALEXTRACT_KEY_VAR: {
156  nc_var *var = nc_input;
157  if (!var->is_geospatial) {
158  return 0;
159  }
160  char output_filename[255];
161  strcpy(output_filename, input->ofile);
162  strcat(output_filename, ".");
163  strcat(output_filename, var->name);
164 
165  FILE *output_h = NULL;
166  if ((output_h = fopen(output_filename, "w")) == NULL) {
167  eprintf("Error opening output file %s, %s\n", output_filename, strerror(errno));
168  return -1;
169  }
170 
171  int i;
172  double *values = (double*) var->data;
173  for (i = 0; i < var->region->pixel_count; i++) {
174  if (var->has_fill && values[i] == var->fill) {
175  fprintf(output_h, "%s\n", "NULL");
176  } else {
177  double v = values[i];
178  if (var->has_scale) {
179  v *= var->scale;
180  }
181  if (var->has_offset) {
182  v += var->offset;
183  }
184  fprintf(output_h, "%f\n", v);
185  }
186  }
187  fclose(output_h);
188  }
189  break;
190  }
191  return 0;
192 }
193 
194 int main(int argc, char *argv[]) {
195  if (argc <= 1) {
196  argpar_usage_default(&leveltwo2csv_main_argpar);
197  return VALEXTRACT_ERR_INPUT;
198  }
201  .geospatial_only = 1, .geospatial_to_double = 1,
202  .val_extract_parser = (val_extract_parser) save_extract,
203  .user_input = (void*) &input
204  };
205  input.val_extract_arguments = &arguments;
206 
207  int ret = EXIT_SUCCESS;
208  if (argpar_parse_args(&leveltwo2csv_main_argpar, argc, argv, 0, NULL, &input)) {
209  ret = VALEXTRACT_ERR_INPUT;
210  } else {
211  char output_filename[255];
212  printf("%s\n", arguments.ifile);
213  if (!input.ofile) {
214  strcpy(output_filename, arguments.ifile);
215  strcat(output_filename, OFILE_DEFAULT_EXT);
216  input.ofile = output_filename;
217  }
218  ret = val_extract(&arguments);
219  }
221  argpar_clean(&leveltwo2csv_main_argpar);
222  return ret;
223 }
224 
void * data
Definition: val_extract.h:288
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 EXIT_SUCCESS
Definition: GEO_basic.h:72
#define eprintf(...)
#define VALEXTRACT_KEY_SUCCESS
Passed to parser when the processing is finished and no errors were encountered.
Definition: val_extract.h:58
bool has_offset
Definition: val_extract.h:279
int pixel_count
Definition: val_extract.h:258
#define VALEXTRACT_ERR_NONE
Returned on successful processing.
Definition: val_extract.h:26
#define NULL
Definition: decode_rs.h:63
const char * argpar_program_name
How to display the program name. If not given, it will be derived during a call to argpar_parse_args.
Passed into the library function to control the processing. Many of the fields will be unspecified.
Definition: val_extract.h:103
#define OFILE_DEFAULT_EXT
#define ARGPAR_KEY_SUCCESS
Passed as the key to each parser callback function when parsing has finished and no errors were retur...
Definition: argpar.h:295
bool has_scale
Definition: val_extract.h:279
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
#define VALEXTRACT_KEY_INIT
Passed to parser when beginning the processing.
Definition: val_extract.h:50
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
def remove(file_to_delete)
Definition: ProcUtils.py:319
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
int state(double tjdTDB, JPLIntUtilType *util, double posvel[13][6], double *pnut)
#define VALEXTRACT_ERR_INPUT
Returned when given bad or no arguments.
Definition: val_extract.h:42
const char * argpar_program_version
Used as the program version string. If set, a version=1 option is automatically added....
bool has_fill
Definition: val_extract.h:279
int main(int argc, char *argv[])
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
val_extract_arguments * val_extract_arguments
const char * ifile
Definition: argpar.c:44
int errno
#define expanded_str(s)
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
#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
State variable to be filled before each call to the parser callback.
Definition: argpar.h:196
int argpar_usage_default(argpar *argpar)
Print the default usage summary with all available sections.
Definition: argpar-help.c:509
#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.
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
for(i=0;i< NROOTS;i++) s[i]
Definition: decode_rs.h:85
double fill
Definition: val_extract.h:280
#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
int i
Definition: decode_rs.h:71
double scale
Definition: val_extract.h:280
#define VALEXTRACT_ERR_UNKNOWN
Returned for unexpected errors like malloc failures or, possibly, permissions problems and the like.
Definition: val_extract.h:31
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
#define str(s)