NASA Logo
Ocean Color Science Software

ocssw V2022
l3mapgen_input.cpp
Go to the documentation of this file.
1 #include "l3mapgen.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <assert.h>
7 #include <genutils.h>
8 #include <clo.h>
9 #include <dfutils.h>
10 #include <sensorInfo.h>
11 #include <unistd.h>
12 
14 int l3mapgen_init_options(clo_optionList_t* list, const char* softwareVersion) {
15 
16  clo_setVersion2("l3mapgen", softwareVersion);
17 
18  clo_setHelpStr("Usage: l3mapgen argument-list"
19  "\n"
20  "\n This program takes a product (or products if netCDF output) from an L3 bin"
21  "\n or SMI file, reprojects the data using proj.4 and writes a mapped file in"
22  "\n the requested output format."
23  "\n"
24  "\n Return values"
25  "\n 0 = All Good"
26  "\n 1 = Error"
27  "\n 110 = No valid data to map"
28  "\n"
29  "\n The argument list is a set of keyword=value pairs. Arguments can"
30  "\n be specified on the command line, or put into a parameter file, or the"
31  "\n two methods can be used together, with command line overriding."
32  "\n"
33  "\nThe list of valid keywords follows:"
34  "\n");
35 
36  clo_addOption(list, "suite", CLO_TYPE_STRING, NULL, "suite for default parameters");
37 
38  // files
39  clo_addOption(list, "ifile", CLO_TYPE_IFILE, NULL, "input L3 bin filename"
40  "\n");
41 
42  clo_addOption(list, "ofile", CLO_TYPE_OFILE, "output", "output filename");
43  clo_addOption(list, "oformat", CLO_TYPE_STRING, "netcdf4",
44  "output file format"
45  "\n netcdf4: netCDF4 file, can contain more than one product"
46  "\n hdf4: HDF4 file (old SMI format)"
47  "\n png: PNG image file"
48  "\n ppm: PPM image file"
49  "\n tiff: TIFF file with georeference tags");
50 
51  clo_addOption(list, "ofile_product_tag", CLO_TYPE_STRING, "PRODUCT",
52  "sub-string in ofile name that will be substituted by the product name");
54  "second output filename");
55  clo_addOption(list, "oformat2", CLO_TYPE_STRING, "png",
56  "second output file format"
57  "\n same options as oformat");
58 
59  clo_addOption(list, "deflate", CLO_TYPE_INT, "4", "netCDF4 deflation level"
60  "\n");
61 
62  // data, projection, coverage
64  "comma separated list of products."
65  "\n Each product can have an optional colon and modifier appended."
66  "\n For example, \"product=chlor_a,chlor_a:stdev,Kd_490:nobs\""
67  "\n Available modifiers:"
68  "\n avg average value (default)"
69  "\n stdev standard deviation"
70  "\n var variance"
71  "\n nobs number of observations in the bin"
72  "\n nscenes number of contributing scenes"
73  "\n obs_time average observation time (TAI93)"
74  "\n bin_num bin ID number"
75  "\n");
76  clo_addOption(list,"wavelength_3d",CLO_TYPE_STRING,NULL, "comma separated list of wavelengths for 3D products");
77  clo_addOption(list, "resolution", CLO_TYPE_STRING, NULL,
78  "size of output pixel (default from input file)"
79  "\n in meters or SMI dimensions"
80  "\n 90km: 432 x 216 image for full globe"
81  "\n 36km: 1080 x 540"
82  "\n 18km: 2160 x 1080"
83  "\n 9km: 4320 x 2160"
84  "\n 4km: 8640 x 4320"
85  "\n 2km: 17280 x 8640"
86  "\n 1km: 34560 x 17280"
87  "\n hkm: 69120 x 34560"
88  "\n qkm: 138240 x 69120"
89  "\n smi: 4096 x 2048"
90  "\n smi4: 8192 x 4096"
91  "\n land: 8640 x 4320"
92  "\n #.#: width of a pixel in meters"
93  "\n #.#km: width of a pixel in kilometers"
94  "\n #.#deg: width of a pixel in degrees");
96  "width of output image in pixels; supercedes resolution parameter.\n");
97 
98  clo_addOption(list, "projection", CLO_TYPE_STRING, "platecarree",
99  "proj.4 projection string or one"
100  "\n of the following predefined projections:"
101  "\n smi: Standard Mapped image, cylindrical projection,"
102  "\n uses central_meridian. NSEW defaults to whole globe."
103  "\n projection=\"+proj=eqc +lon_0=<central_meridian>\""
104  "\n platecarree: Plate Carree image, cylindrical projection,"
105  "\n uses central_meridian."
106  "\n projection=\"+proj=eqc +lon_0=<central_meridian>\""
107  "\n mollweide: Mollweide projection"
108  "\n projection=\"+proj=moll +lon_0=<central_meridian>\""
109  "\n lambert: Lambert conformal conic (2SP) projection"
110  "\n projection=\"+proj=lcc +lon_0=<central_meridian>"
111  "\n +lat_0=<scene center latitude>"
112  "\n +lat_1=<scene south latitude>"
113  "\n +lat_2=<scene north latitude>\""
114  "\n albersconic: Albers Equal Area Conic projection"
115  "\n projection=\"+proj=aea +lon_0=<central_meridian>"
116  "\n +lat_0=<scene center latitude>"
117  "\n +lat_1=<scene south latitude>"
118  "\n +lat_2=<scene north latitude>\""
119  "\n aeqd: Azimuthal Equidistant projection"
120  "\n projection=\"+proj=aeqd +lon_0=<central_meridian>"
121  "\n +lat_0=<scene center latitude>\""
122  "\n mercator: Mercator cylindrical map projection"
123  "\n projection=\"+proj=merc +lon_0=<central_meridian>\""
124  "\n transmerc: Transverse Mercator cylindrical map projection"
125  "\n projection=\"+proj=tmerc +lon_0=<central_meridian>"
126  "\n +lat_0=<scene center latitude>\""
127  "\n utm: Universal Transverse Mercator cylindrical map projection"
128  "\n projection=\"+proj=utm +zone=<utm_zone> [+south]\""
129  "\n obliquemerc: Oblique Mercator cylindrical map projection"
130  "\n projection=\"+proj=omerc +gamma=0 +lat_0=<lat_0>"
131  "\n +lonc=<central_meridian> +alpha=<azimuth>"
132  "\n +k_0=1 +x_0=0 +y_0=0\""
133  "\n ease2: EASE-Grid 2.0 projection"
134  "\n projection=\"EPSG:6933\""
135  "\n ortho: Orthographic projection"
136  "\n projection=\"+proj=ortho +lat_0=<lat_0> +lon_0=<central_meridian>"
137  "\n +ellps=GRS80 +units=m\""
138  "\n stere: Stereographic projection"
139  "\n projection=\"+proj=stere +lat_0=<lat_0> +lat_ts=<lat_ts>"
140  "\n +lon_0=<central_meridian>"
141  "\n +ellps=WGS84 +datum=WGS84 +units=m\""
142  "\n conus: USA Contiguous Albers Equal Area Conic USGS version"
143  "\n projection=\"+proj=aea +lat_1=29.5 +lat_2=45.5"
144  "\n +lat_0=23.0 +lon_0=-96 +x_0=0 +y_0=0"
145  "\n +ellps=GRS80 +datum=NAD83 +units=m\""
146  "\n alaska: Alaskan Albers Equal Area Conic USGS version"
147  "\n projection=\"EPSG:3338\""
148  "\n gibs: latitudinally dependent projection"
149  "\n Plate Carree between 60S and 60N"
150  "\n else use Polar Sterographic"
151  "\n North Polar: projection=\"EPSG:3413\""
152  "\n South Polar: projection=\"EPSG:3031\""
153  "\n raw: Raw dump of bin file contents."
154  "\n");
155  clo_addOption(list, "write_projtext", CLO_TYPE_BOOL, "no", "write projection information to a text file.");
156  clo_addOption(list, "central_meridian", CLO_TYPE_FLOAT, "-999",
157  "central meridian for projection in deg east."
158  "\n Used only for raw dump and predefined projections as above.");
160  "latitude of true scale for projection in deg north."
161  "\n Used only for predefined projections above as required.");
163  "latitude of origin for projection in deg north."
164  "\n Used only for predefined projections above as required.");
166  "latitude of first standard parallel (south)."
167  "\n Used only for predefined projections above as required.");
169  "latitude of second standard parallel (north)."
170  "\n Used only for predefined projections above as required.");
171  clo_addOption(list, "azimuth", CLO_TYPE_FLOAT, NULL,
172  "projection rotation angle in deg north."
173  "\n Used only for predefined projections above as required.");
174  clo_addOption(list, "utm_zone", CLO_TYPE_STRING, NULL,
175  "UTM zone number."
176  "\n Used only for the UTM projection;"
177  "\n Append 'S' for southern hemisphere zones (e.g. 59S).");
178  clo_addOption(list, "north", CLO_TYPE_FLOAT, "-999",
179  "Northernmost Latitude (default: file north)");
180  clo_addOption(list, "south", CLO_TYPE_FLOAT, "-999",
181  "Southernmost Latitude (default: file south)");
182  clo_addOption(list, "east", CLO_TYPE_FLOAT, "-999",
183  "Easternmost Longitude (default: file east)");
184  clo_addOption(list, "west", CLO_TYPE_FLOAT, "-999",
185  "Westernmost Longitude (default: file west)");
186  clo_addOption(list, "trimNSEW", CLO_TYPE_BOOL, "no",
187  "should we trim output"
188  "\n to match input NSEW range"
189  "\n");
190 
191  clo_addOption(list, "interp", CLO_TYPE_STRING, "nearest",
192  "interpolation method:"
193  "\n nearest: use the value of the nearest bin for the pixel"
194  "\n bin: bin all of the pixels that intersect the area of the"
195  "\n output pixel"
196  "\n area: bin weighted by area of all the pixels that intersect"
197  "\n the area of the output pixel"
198  "\n");
199 
200  // color table, scaling
201  clo_addOption(list, "apply_pal", CLO_TYPE_BOOL, "yes",
202  "apply color palette:"
203  "\n yes: color image"
204  "\n no: grayscale image");
205  clo_addOption(list, "palfile", CLO_TYPE_IFILE, NULL,
206  "palette filename (default from product.xml)");
207  clo_addOption(list, "use_transparency", CLO_TYPE_BOOL, "no",
208  "make missing data transparent (only valid for color PNG and TIFF)");
209  clo_addOption(list, "datamin", CLO_TYPE_FLOAT, NULL,
210  "minimum value for scaling (default from product.xml)");
211  clo_addOption(list, "datamax", CLO_TYPE_FLOAT, NULL,
212  "maximum value for scaling (default from product.xml)");
213  clo_addOption(list, "scale_type", CLO_TYPE_STRING, NULL,
214  "data scaling type (default from product.xml)"
215  "\n linear: linear scaling"
216  "\n log: logarithmic scaling"
217  "\n arctan: arc tangent scaling"
218  "\n");
219 
220  // other options
221  clo_addOption(list, "quiet", CLO_TYPE_BOOL, "false",
222  "stop the status printing");
223  clo_addOption(list, "pversion", CLO_TYPE_STRING, "Unspecified",
224  "processing version string");
225  clo_addOption(list, "use_quality", CLO_TYPE_BOOL, "yes",
226  "should we do quality factor processing");
227  clo_addOption(list, "quality_product", CLO_TYPE_STRING, NULL,
228  "product to use for quality factor processing");
229  clo_addOption(list, "use_rgb", CLO_TYPE_BOOL, "no",
230  "should we use product_rgb to make a"
231  "\n pseudo-true color image");
232  clo_addOption(list, "product_rgb", CLO_TYPE_STRING,
233  "rhos_670,rhos_555,rhos_412",
234  "\n Three products to use for RGB. Default is sensor-specific.");
235  clo_addOption(list, "fudge", CLO_TYPE_FLOAT, "1.0",
236  "fudge factor used to modify size of L3 pixels");
237  clo_addOption(list, "threshold", CLO_TYPE_FLOAT, "0",
238  "minimum percentage of filled pixels before"
239  "\n an image is generated");
240  clo_addOption(list, "num_cache", CLO_TYPE_INT, "500",
241  "number of rows to cache in memory.");
242  clo_addOption(list, "mask_land", CLO_TYPE_BOOL, "no",
243  "set land pixels to pixel value 254");
244  clo_addOption(list, "rgb_land", CLO_TYPE_STRING, "160,82,45",
245  "RGB value to use for land mask; comma separate string");
247  "$OCDATAROOT/common/landmask_GMT15ARC.nc", "land mask file");
248  clo_addOption(list, "full_latlon", CLO_TYPE_BOOL, "yes",
249  "write full latitude and longitude arrays."
250  "\n");
251  clo_addOption(list, "doi", CLO_TYPE_STRING, NULL, "Digital Object Identifier (DOI) string");
252 
253  return 0;
254 }
255 
256 int getSensorId(const char* fileName) {
257  idDS dsId;
258  int sensorId = -1;
259 
260  dsId = openDS(fileName);
261  if (dsId.fid == -1) {
262  printf("-E- %s: Input file '%s' does not exist or cannot open. \n",
263  __FILE__, fileName);
264  exit(EXIT_FAILURE);
265  }
266 
267  if (dsId.fftype == DS_NCDF) {
268  char* instrumentStr = readAttrStr(dsId, "instrument");
269  if (instrumentStr) {
270  char* platformStr = readAttrStr(dsId, "platform");
271  if (platformStr) {
272  sensorId = instrumentPlatform2SensorId(instrumentStr,
273  platformStr);
274  }
275  } else {
276  char* sensorStr = readAttrStr(dsId, "Sensor");
277  if (sensorStr) {
278  sensorId = sensorName2SensorId(sensorStr);
279  }
280  }
281  } else {
282  char* sensorNameStr = readAttrStr(dsId, "Sensor Name");
283  if (sensorNameStr) {
284  sensorId = sensorName2SensorId(sensorNameStr);
285  }
286  }
287 
288  if (sensorId == -1) {
289  printf("Did not find a valid sensor ID - using OCRVC as the sensor ID.\n");
290  sensorId = OCRVC;
291  }
292 
293  endDS(dsId);
294  return sensorId;
295 }
296 
297 /*
298  Read the command line option and all of the default parameter files.
299 
300  This is the order for loading the options:
301  - load the main program defaults file
302  - load the command line (including specified par files)
303  - re-load the command line disabling file descending so command
304  line arguments will over ride
305 
306  */
308  char *dataRoot;
309  char tmpStr[FILENAME_MAX];
310 
311  assert(list);
312 
313  if ((dataRoot = getenv("OCDATAROOT")) == NULL) {
314  fprintf(stderr, "-E- OCDATAROOT environment variable is not defined. \n");
315  return (-1);
316  }
317 
318  // disable the dump option until we have read all of the files
320 
321  // load program defaults
322  sprintf(tmpStr, "%s/common/l3mapgen_defaults.par", dataRoot);
323  clo_readFile(list, tmpStr);
324 
325  // read all arguments
326  clo_readArgs(list, argc, argv);
327 
328  // get sensor directory
329  int sensorId = getSensorId(clo_getString(list, "ifile"));
330  int subsensorId = sensorId2SubsensorId(sensorId);
331  const char* sensorDir = sensorId2SensorDir(sensorId);
332 
333  // load the sensor specific defaults file
334  sprintf(tmpStr, "%s/%s/l3mapgen_defaults.par", dataRoot, sensorDir);
335  int defaultLoaded = 0;
336  if (access(tmpStr, R_OK) != -1) {
337  if (want_verbose)
338  printf("Loading default parameters from %s\n", tmpStr);
339  clo_readFile(list, tmpStr);
340  defaultLoaded = 1;
341  }
342 
343  if (subsensorId != -1) {
344  sprintf(tmpStr, "%s/%s/%s/l3mapgen_defaults.par", dataRoot, sensorDir,
345  subsensorId2SubsensorDir(subsensorId));
346  if (access(tmpStr, R_OK) != -1) {
347  if (want_verbose)
348  printf("Loading default parameters from %s\n", tmpStr);
349  clo_readFile(list, tmpStr);
350  defaultLoaded = 1;
351  }
352  }
353 
354  if (!defaultLoaded) {
355  printf("-E- Failed to load sensor program defaults for %s \n",
356  sensorId2SensorName(sensorId));
357  exit(EXIT_FAILURE);
358  }
359 
360  // load the suite specific defaults file
361  clo_option_t *option = clo_findOption(list, "suite");
362  if (clo_isOptionSet(option)) {
363  int suiteLoaded = 0;
364  sprintf(tmpStr, "%s/common/l3mapgen_defaults_%s.par", dataRoot,
365  clo_getOptionString(option));
366  if (access(tmpStr, R_OK) != -1) {
367  if (want_verbose)
368  printf("Loading default parameters from %s\n", tmpStr);
369  clo_readFile(list, tmpStr);
370  suiteLoaded = 1;
371  }
372 
373  sprintf(tmpStr, "%s/%s/l3mapgen_defaults_%s.par", dataRoot, sensorDir,
374  clo_getOptionString(option));
375  if (access(tmpStr, R_OK) != -1) {
376  if (want_verbose)
377  printf("Loading default parameters from %s\n", tmpStr);
378  clo_readFile(list, tmpStr);
379  suiteLoaded = 1;
380  }
381 
382  if (subsensorId != -1) {
383  sprintf(tmpStr, "%s/%s/%s/l3mapgen_defaults_%s.par", dataRoot,
384  sensorDir, subsensorId2SubsensorDir(subsensorId),
385  clo_getOptionString(option));
386  if (access(tmpStr, R_OK) != -1) {
387  if (want_verbose)
388  printf("Loading default parameters from %s\n", tmpStr);
389  clo_readFile(list, tmpStr);
390  suiteLoaded = 1;
391  }
392  }
393 
394  if (!suiteLoaded) {
395  printf("-E- Failed to load parameters for suite %s for sensor %s\n", clo_getOptionString(option),
396  sensorId2SensorName(sensorId));
397  exit(EXIT_FAILURE);
398  }
399  }
400  // enable the dump option
402  // make the command line over ride
403  clo_readArgs(list, argc, argv);
404 
405  return 0;
406 }
clo_option_t * clo_addOption(clo_optionList_t *list, const char *key, enum clo_dataType_t dataType, const char *defaultVal, const char *desc)
Definition: clo.c:684
const char * sensorId2SensorDir(int sensorId)
Definition: sensorInfo.c:315
char * clo_getString(clo_optionList_t *list, const char *key)
Definition: clo.c:1357
void clo_readArgs(clo_optionList_t *list, int argc, char *argv[])
Definition: clo.c:2103
int instrumentPlatform2SensorId(const char *instrument, const char *platform)
Definition: sensorInfo.c:405
int l3mapgen_init_options(clo_optionList_t *list, const char *softwareVersion)
idDS openDS(const char *filename)
Definition: wrapper.c:606
#define NULL
Definition: decode_rs.h:63
int sensorName2SensorId(const char *name)
Definition: sensorInfo.c:371
clo_option_t * clo_findOption(clo_optionList_t *list, const char *key)
Definition: clo.c:967
@ CLO_TYPE_FLOAT
Definition: clo.h:84
ds_format_t fftype
Definition: dfutils.h:31
int sensorId2SubsensorId(int sensorId)
Definition: sensorInfo.c:438
int clo_isOptionSet(clo_option_t *option)
Definition: clo.c:2257
@ CLO_TYPE_BOOL
Definition: clo.h:81
void clo_setVersion2(const char *programName, const char *versionStr)
Definition: clo.c:464
int l3mapgen_read_options(clo_optionList_t *list, int argc, char *argv[])
void clo_setEnableDumpOptions(int val)
Definition: clo.c:410
char * readAttrStr(idDS ds_id, const char *name)
Definition: wrapper.c:99
int getSensorId(const char *fileName)
list(APPEND LIBS ${NETCDF_LIBRARIES}) find_package(GSL REQUIRED) include_directories($
Definition: CMakeLists.txt:8
void clo_setHelpStr(const char *str)
Definition: clo.c:487
@ CLO_TYPE_INT
Definition: clo.h:82
char * clo_getOptionString(clo_option_t *option)
Definition: clo.c:1050
int want_verbose
@ CLO_TYPE_IFILE
Definition: clo.h:87
@ CLO_TYPE_OFILE
Definition: clo.h:88
@ DS_NCDF
Definition: dfutils.h:20
void clo_readFile(clo_optionList_t *list, const char *fileName)
Definition: clo.c:2210
const char * sensorId2SensorName(int sensorId)
Definition: sensorInfo.c:273
int32_t fid
Definition: dfutils.h:29
Definition: dfutils.h:28
const char * subsensorId2SubsensorDir(int subsensorId)
Definition: sensorInfo.c:329
#define OCRVC
Definition: sensorDefs.h:24
int endDS(idDS ds_id)
Definition: wrapper.c:624
@ CLO_TYPE_STRING
Definition: clo.h:86