OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
main_l3bindump.cpp
Go to the documentation of this file.
1 /*
2  This program extracts data from level-3 HDF bin files and
3  writes them out as an ASCII table.
4 
5  Regions of interest can be specified by latitude and longitude
6  boundaries or by a central coordinate and a radius in kilometers.
7 
8  Norman Kuring 14-Feb-2003 Original development
9  Norman Kuring 11-Dec-2007 Fix memory-overrun bug and add a
10  couple of calls to free().
11  Norman Kuring 21-Dec-2011 Give a precision when printing out
12  bit strings to avoid unwanted printing
13  of uninitialized memory.
14  Norman Kuring 21-Mar-2013 Change the latbin array from 32-bit
15  floats to 64-bit to reduce rounding-
16  error effects on bin numbers at smaller
17  bin sizes. Thanks to George White for
18  pointing this one out.
19  Sean Bailey 25-Mar-2014 Redesigned to use libbin++ to be able
20  to work with new netCDF4 formatted files, as well as the Aquarius HDF5
21  versions, modified output to include mean and stdev but exclude selcat,
22  flag and time trend bits - Joel Gales made numerous mods to libbin++
23  for this to work...
24  Don Shea 28-Luly-2015 Started using L3File class to read bin files.
25  Changed the looping which increased the speed quite a bit.
26  */
27 #include "l3bindump.h"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include <clo.h>
34 #include <strings.h>
35 #include <L3File.h>
36 
37 #include "compareObj.h"
38 
39 #define EARTH_RADIUS 6371.229
40 #define BIN_NOT_FOUND 110
41 
42 using namespace l3;
43 
44 void printBin(FILE *outfp, int32_t row, int32_t col, L3Bin *l3Bin, L3Shape* shape) {
45  int64_t bin = l3Bin->getBinNum();
46  float lat, lon;
47  shape->rowcol2latlon(row, col, lat, lon);
48  float north, south, east, west;
49  shape->rowcol2bounds(row, col, north, south, east, west);
50 
51  fprintf(outfp, "%07ld %9.5f %10.5f %9.5f %9.5f %10.5f %10.5f ", (long)bin,
52  lat, lon, north, south, west, east);
53  fprintf(outfp, "%4d %3d ", l3Bin->getNobs(), l3Bin->getNscenes());
54  fprintf(outfp, "% .8e % .8e % .8e ", l3Bin->getSum(), l3Bin->getSumSquares(), l3Bin->getWeights());
55  fprintf(outfp, "%10.5f %10.5f", l3Bin->getMean(), l3Bin->getStdev());
56  fprintf(outfp, "\n");
57 }
58 
59 void printWholeFile(FILE *outfp, L3File &l3File) {
60  L3Shape* shape = l3File.getShape();
61  int32_t row, col;
62  L3Bin *l3Bin;
63  bool binFound = false;
64  for (row = 0; row < shape->getNumRows(); row++) {
65  for (col = 0; col < shape->getNumCols(row); col++) {
66  l3Bin = l3File.getBin(row, col);
67  if (l3Bin) {
68  binFound = true;
69  printBin(outfp, row, col, l3Bin, shape);
70  }
71  }
72  }
73  if (!binFound) {
74  fprintf(stderr, "No bins found in file.\n");
75  exit(BIN_NOT_FOUND);
76  }
77  exit(EXIT_SUCCESS);
78 }
79 
80 int main(int argc, char *argv[]) {
81  want_verbose = 0;
82 
83  int32_t i;
84  instr *input; // input parameters structure
85 
86  FILE *outfp = stdout;
87  char outfile[FILENAME_MAX] = "\0";
88 
89  L3File l3File;
90 
91  /* hold all of the command line options */
93 
94  if (argc == 1) {
96  return 0;
97  }
98 
99  for (i = 0; i < argc; i++) {
100  // see if help on command line
101  if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "-help") == 0)) {
102  l3bindump_usage();
103  return 0;
104  }
105  }
106 
107  input = (instr*) malloc(sizeof (instr));
108  if (!input) {
109  fprintf(stderr, "-E- %s %d: Error allocating input structure.\n", __FILE__,
110  __LINE__);
111  exit(EXIT_FAILURE);
112  }
113 
115 
116  // create an option list
117  list = clo_createList();
118 
119  /* initialize the option list with descriptions and default values */
121 
122  // Parse input parameters
123 
124  if (l3bindump_read_options(list, argc, argv) != 0) {
125  fprintf(stderr, "-E- %s: Error reading program options.\n", __FILE__);
126  return (EXIT_FAILURE);
127  }
128 
129  /* */
130  /* Now, loop through command arguments again and update input struct*/
131  /* */
132  if (l3bindump_load_input(list, input) != 0) {
133  fprintf(stderr, "-E- %s: Error loading options into input structure.\n",
134  __FILE__);
135  return (EXIT_FAILURE);
136  }
137 
138  if (input->verbose == 1) {
139  want_verbose = 1;
140  }
141 
142  // open the file
143  if (!l3File.open(input->ifile)) {
144  fprintf(stderr, "%s: Error: Unable to open %s for reading.\n",
145  argv[0], input->ifile);
146  exit(EXIT_FAILURE);
147  }
148 
149  // set the product to read
150  if (!l3File.setActiveProductList(input->l3bprod)) {
151  fprintf(stderr, "%s: Error: Product %s not found in file.\n",
152  argv[0], input->l3bprod);
153  exit(EXIT_FAILURE);
154  }
155 
156  // Open output file if requested
157  if (strlen(input->ofile) > 0) {
158  strcpy(outfile, input->ofile);
159  if ((outfp = fopen(outfile, "w")) == NULL) {
160  fprintf(stderr, "%s: Error: Unable to open %s for writing.\n",
161  argv[0], outfile);
162  exit(EXIT_FAILURE);
163  }
164  }
165 
166  //
167  // write out the header info
168  //
169  if (strcmp(input->oformat, "SeaBASS") == 0) {
170  fprintf(outfp, "/begin_header\n");
171  fprintf(outfp, "/delimiter=space\n");
172  fprintf(outfp, "/missing=-999\n");
173  if (input->north > -999) {
174  fprintf(outfp, "/north_latitude=%10.5f\n", input->north);
175  fprintf(outfp, "/south_latitude=%10.5f\n", input->south);
176  fprintf(outfp, "/east_longitude=%10.5f\n", input->east);
177  fprintf(outfp, "/west_longitude=%10.5f\n", input->west);
178  }
179  fprintf(outfp, "/fields=bin,lat,lon,north,south,west,east,nobs,nscenes,sum,sum_squared,weight,mean,stdev\n");
180  fprintf(outfp, "/end_header\n");
181 
182  } else {
183  fprintf(outfp, "%80s%15.15s %15.15s\n", " ", input->l3bprod, input->l3bprod);
184  fprintf(outfp, " bin centerlat centerlon");
185  fprintf(outfp, " north south west east");
186  fprintf(outfp, " n N sum sum_squared weight");
187  fprintf(outfp, " mean stdev\n");
188  fprintf(outfp, "------- --------- ----------");
189  fprintf(outfp, " --------- --------- ---------- ----------");
190  fprintf(outfp, " ---- --- --------------- --------------- ---------------");
191  fprintf(outfp, " ---------- ----------\n");
192  }
193 
194  if (want_verbose)
195  fprintf(outfp, "! Input file: %s\n", input->ifile);
196 
197  CompareObj *compareObj = NULL;
198  L3Bin *l3Bin;
199  L3Shape *shape = l3File.getShape();
200  int32_t row, col;
201  int32_t startRow=0, stopRow=0;
202  if (want_verbose)
203  fprintf(outfp, "! Number of Rows: %d\n", shape->getNumRows());
204 
205  // handle lat/lon without radius
206  if(input->radius == -999 && input->lat != -999 && input->lon != -999) {
207  input->bin_number = shape->latlon2bin(input->lat, input->lon);
208  }
209 
210  if (input->bin_number > 0) {
211  /* Input arguments are: main_file_path parameter bin_number. */
212  shape->bin2rowcol(input->bin_number, row, col);
213 
214  l3Bin = l3File.getBin(row, col);
215  if (l3Bin) {
216  printBin(outfp, row, col, l3Bin, shape);
217  exit(EXIT_SUCCESS);
218  } else {
219  fprintf(stderr, "Requested bin number = %ld was not in the file.\n", (long)input->bin_number);
220  exit(BIN_NOT_FOUND);
221  }
222 
223 
224  } else if (input->radius > 0) {
225  /* Input arguments are: main_file_path parameter lat lon radius. */
226 
227  input->lat = constrainLat(input->lat);
228  input->lon = constrainLon(input->lon);
229 
230  float radius_degrees = (input->radius / EARTH_RADIUS) * (180.0 / M_PI);
231  if (radius_degrees > 180) {
232 
233  /* The entire globe has been selected. */
234  printWholeFile(outfp, l3File);
235 
236  } else {
237  double north, south;
238 
239  north = input->lat + radius_degrees;
240  south = input->lat - radius_degrees;
241  if (north >= 90.0) {
242  stopRow = shape->getNumRows();
243  } else {
244  stopRow = shape->lat2row(north) + 1; // add an extra row
245  if (stopRow >= shape->getNumRows())
246  stopRow = shape->getNumRows();
247  }
248 
249  if (south <= -90.0) {
250  startRow = 0;
251  } else {
252  startRow = shape->lat2row(south) - 1; // add an extra row
253  if (startRow < 0)
254  startRow = 0;
255  }
256  compareObj = new CompareObjCircle(input->lat, input->lon, input->radius);
257  }
258 
259 
260  } else if (input->north != -999) {
261  /* Input arguments are: main_file_path parameter north south west east. */
262 
263  input->north = constrainLat(input->north);
264  input->south = constrainLat(input->south);
265  input->west = constrainLon(input->west);
266  input->east = constrainLon(input->east);
267 
268  if (input->south > input->north) {
269  double tmp;
270 
271  fprintf(stderr, "-W- %s line %d: ", __FILE__, __LINE__);
272  fprintf(stderr,
273  "Specified south latitude is greater than specified north latitude.\n");
274  fprintf(stderr, "I will swap the two.\n");
275  tmp = input->north;
276  input->north = input->south;
277  input->south = tmp;
278  }
279 
280  if (input->north == 90.0 && input->south == -90.0 &&
281  input->east == 180.0 && input->west == -180.0) {
282 
283  /* The entire globe has been selected. */
284  printWholeFile(outfp, l3File);
285 
286  }
287 
288  stopRow = shape->lat2row(input->north);
289  startRow = shape->lat2row(input->south);
290  compareObj = new CompareObjLonOnly(input->east, input->west);
291 
292  } else {
293  l3bindump_usage();
294  return (EXIT_FAILURE);
295  }
296 
297  float lat, lon;
298  bool binFound = false;
299  for (row = startRow; row <= stopRow; row++) {
300  for (col = 0; col < shape->getNumCols(row); col++) {
301  shape->rowcol2latlon(row, col, lat, lon);
302  if (compareObj->isInside(lat, lon)) {
303  l3Bin = l3File.getBin(row, col);
304  if (l3Bin) {
305  binFound = true;
306  printBin(outfp, row, col, l3Bin, shape);
307  } // bin found in file
308  } // if inside
309  } // col
310  } // row
311  if (!binFound) {
312  fprintf(stderr, "No bins found in file.\n");
313  exit(BIN_NOT_FOUND);
314  }
315 
316  return (EXIT_SUCCESS);
317 } /* End of main() function */
double constrainLat(double lat)
Definition: L3Shape.cpp:13
virtual int64_t latlon2bin(double lat, double lon) const =0
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
list(APPEND LIBS ${PGSTK_LIBRARIES}) add_executable(atteph_info_modis atteph_info_modis.c) target_link_libraries(atteph_info_modis $
Definition: CMakeLists.txt:7
virtual int32_t getNumCols(int32_t row) const =0
virtual bool isInside(double lat, double lon)=0
virtual void bin2rowcol(int64_t bin, int32_t &row, int32_t &col)=0
float getSumSquares(int32_t prodId=0) const
Definition: L3File.cpp:253
#define NULL
Definition: decode_rs.h:63
virtual bool open(const char *fileName)
Definition: L3File.cpp:430
int main(int argc, char *argv[])
#define EARTH_RADIUS
virtual L3Bin * getBin(int32_t row, int32_t col)
Definition: L3File.cpp:761
float * lat
virtual int32_t lat2row(double lat) const =0
virtual void rowcol2bounds(int32_t row, int32_t col, double &north, double &south, double &east, double &west) const =0
double constrainLon(double lon)
Definition: L3Shape.cpp:26
float getWeights() const
Definition: L3File.cpp:226
virtual L3Shape * getShape() const
Definition: L3File.h:317
instr * input
virtual bool setActiveProductList(const char *prodStr)
Definition: L3File.cpp:591
clo_optionList_t * clo_createList()
Definition: clo.c:532
int l3bindump_usage()
data_t tmp
Definition: decode_rs.h:74
virtual void rowcol2latlon(int32_t row, int32_t col, double &lat, double &lon) const =0
void printWholeFile(FILE *outfp, L3File &l3File)
#define BIN_NOT_FOUND
#define M_PI
Definition: pml_iop.h:15
int want_verbose
int64_t getBinNum() const
Definition: L3File.cpp:186
int32_t getNobs() const
Definition: L3File.cpp:194
float getMean(int32_t prodId=0) const
Definition: L3File.cpp:263
virtual int32_t getNumRows() const
Definition: L3Shape.cpp:55
int l3bindump_init_options(clo_optionList_t *list)
float getStdev(int32_t prodId=0) const
Definition: L3File.cpp:288
float * lon
Definition: L3File.cpp:10
void l3bindump_input_init(instr *input)
int l3bindump_load_input(clo_optionList_t *list, instr *input)
int l3bindump_read_options(clo_optionList_t *list, int argc, char *argv[])
void printBin(FILE *outfp, int32_t row, int32_t col, L3Bin *l3Bin, L3Shape *shape)
int32_t getNscenes() const
Definition: L3File.cpp:202
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
float getSum(int32_t prodId=0) const
Definition: L3File.cpp:243