OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
bin_io.cpp
Go to the documentation of this file.
1 #include "netcdf.h"
2 #include "hdf_bin.h"
3 #include "hdf5utils.h"
4 #include "passthebuck.h"
5 #include <seaproto.h>
6 #include <sensorInfo.h>
7 #include <timeutils.h>
8 #include <genutils.h>
9 #include <nc4utils.h>
10 #include <ncdfbin_utils.h>
11 #include "L3ShapeIsine.h"
12 
13 #include <hdf.h>
14 #include <mfhdf.h>
15 
16 // max # rows where the ISIN grid bin num fits into a 32bit int
17 #define MAX_ROWS_32BIT 41068
18 
19 using namespace std;
20 
21 //bool hdf5Type;
22 
23 namespace Hdf {
24 
32 hdf_bin* openBinObject(const char* binFileName) {
33  hdf_bin* binFile = NULL;
34  int ncid;
35  int status;
36 
37  if (Hishdf(binFileName) == TRUE) {
38  binFile = new hdf4_bin;
39  } else if (H5Fis_hdf5(binFileName) == TRUE) {
40  char nam_buf[80];
41 
42  /* Turn off HDF5 warning/error handling - it's ugly stuff anyway */
43  H5Eset_auto(H5E_DEFAULT, NULL, NULL);
44 
45  if (nc_open(binFileName, NC_NOWRITE, &ncid) == NC_NOERR) {
46  status = nc_get_att(ncid, NC_GLOBAL, "Mission", nam_buf);
47  if (status == NC_NOERR) {
48  nc_close(ncid);
49  if (strcmp(nam_buf, "SAC-D Aquarius") == 0) {
50  binFile = new hdf5_bin;
51  }
52  } else {
53  binFile = new cdf4_bin;
54  }
55  }
56  }
57 
58  if (binFile) {
59  // open the bin file
60  status = binFile->open(binFileName);
61  if (status) {
62  delete binFile;
63  return NULL;
64  }
65 
66  int numProducts = binFile->nprod();
67  if (want_verbose) {
68  printf("numProducts = %d\n", numProducts);
69  char prodName[1024];
70  for (int i = 0; i < numProducts; i++) {
71  binFile->get_prodname(i, prodName);
72  printf(" %2d - %s\n", i, prodName);
73  }
74  }
75  }
76 
77  return binFile;
78 }
79 
80 hdf_bin::hdf_bin() {
81  binShape = NULL;
82  totbins = 0;
83  nrows = 0;
84 
85  binListPtr = 0;
86  lastBinListPtr = -1;
87  lastNumBins = 0;
88 
89  product_array[0] = NULL;
90  n_data_prod = 0;
91  n_data_records = 0;
92  n_active_prod = 0;
93  isHDF5 = false;
94  isCDF4 = false;
95  hasQual = false;
96  hasNoext = true;
97  deflate = 0;
98 }
99 
100 hdf_bin::~hdf_bin() {
101  if(binShape)
102  delete binShape;
103 }
104 
105 hdf4_bin::hdf4_bin() {
106  file_id = -1;
107  bin_ptr = 0;
108  noext = 0;
109  totbins = 0;
110  binqual_idx = -1;
111 
112  // cout << "in hdf4_bin constructor" << endl;
113  // for (size_t i=0; i<MAXNPROD; i++) product_array[i] = NULL;
114  for (size_t i = 0; i < MAXNPROD; i++) aid[i] = -1;
115  for (size_t i = 0; i < MAXNVDATA; i++) vdata_id[i] = -1;
116 }
117 
118 hdf4_bin::~hdf4_bin() {
119 }
120 
121 hdf5_bin::hdf5_bin() {
122  isHDF5 = true;
123  h5fid = -1;
124  n_datasets = 0;
125  binDataPtr = 0;
126 
127  for (size_t i = 0; i < MAXNPROD; i++) h5table_id[0][i] = -1;
128  for (size_t i = 0; i < MAXNPROD; i++) h5table_id[1][i] = -1;
129  for (size_t i = 0; i < MAXNPROD; i++) h5table_id[2][i] = -1;
130 }
131 
132 hdf5_bin::~hdf5_bin() {
133 }
134 
135 cdf4_bin::cdf4_bin() {
136  isCDF4 = true;
137  is64bit = false;
138  ncid = -1;
139  grp0 = -1;
140  grp1 = -1;
141  access_mode = NC_NOWRITE;
142  n_datasets = 0;
143 
144  bindata_idx = -1;
145  binqual_idx = -1;
146  binlist_idx = -1;
147  binindex_idx = -1;
148 
149  binDataPtr = 0;
150  binQualityPtr = 0;
151  binList = NULL;
152  binList64 = NULL;
153 }
154 
155 cdf4_bin::~cdf4_bin() {
156 }
157 
158 // Create Bin File
159 
160 int hdf4_bin::create(const char* l3b_filename, int32_t nrows) {
161  uint8_t *a;
162  int32_t i32;
163  int32_t type[16];
164 
165  const char* fldname1[] = {"registration", "straddle", "bins", "radius",
166  "max_north", "max_south", "seam_lon"};
167 
168  file_id = Hopen(l3b_filename, DFACC_CREATE, 0);
169  sd_id = SDstart(l3b_filename, DFACC_RDWR);
170  access_mode = DFACC_CREATE;
171  this->nrows = nrows;
172  if (this->hasNoext == true)
173  noext = 1;
174 
175  Vstart(file_id);
176 
177  vg_id = Vattach(file_id, -1, "w");
178 
179  Vsetname(vg_id, "Level-3 Binned Data");
180  Vsetclass(vg_id, "PlanetaryGrid");
181 
182  // Write "SEAGrid"
183  // ---------------
184  a = (uint8_t *) malloc(44);
185 
186  int32_t zero = 0;
187  int32_t five = 5;
188 
189  double radius = 6378.137000;
190  double north = 90.0;
191  double south = -90.0;
192  double seam_lon = -180.0;
193 
194  memcpy(&a[0], &five, 4);
195  memcpy(&a[4], &zero, 4);
196  i32 = 2 * nrows;
197  memcpy(&a[8], &i32, 4);
198  memcpy(&a[12], &radius, 8);
199  memcpy(&a[20], &north, 8);
200  memcpy(&a[28], &south, 8);
201  memcpy(&a[36], &seam_lon, 8);
202 
203  type[0] = DFNT_INT32;
204  type[1] = DFNT_INT32;
205  type[2] = DFNT_INT32;
206  type[3] = DFNT_FLOAT64;
207  type[4] = DFNT_FLOAT64;
208  type[5] = DFNT_FLOAT64;
209  type[6] = DFNT_FLOAT64;
210 
211  seagrid_idx = 0;
212  create_vdata(file_id, vg_id, &vdata_id[seagrid_idx], "SEAGrid",
213  "Geometry", 7, fldname1, type, noext, NULL);
214 
215  write_vdata(vdata_id[seagrid_idx], 1, a);
216 
217  free(a);
218 
219  n_data_records = 0;
220 
221  binShape = new l3::L3ShapeIsine(nrows);
222  totbins = binShape->getNumBins();
223 
224  binList = (binListStruct *) calloc(2 * nrows, sizeof (binListStruct));
225 
226  binqual_idx = -1;
227 
228  return 0;
229 }
230 
231 // Open Bin File
232 
233 int hdf4_bin::open(const char* l3b_filename) {
234  int32_t vg_ref;
235  int32_t tag;
236  int32_t ref;
237  char nam_buf[80];
238  char cls_buf[80];
239 
240  hasQual = this->has_qual();
241  n_data_prod = this->nprod();
242  for (int32_t i = 0; i < n_data_prod; i++)
243  this->get_prodname(i, proddata_name[i]);
244 
245  binqual_idx = -1;
246 
247  if ((file_id = Hopen(l3b_filename, DFACC_RDONLY, 0)) < 0) {
248  fprintf(stderr, "Error: Cannot open input HDF file on Hopen - %s\n",
249  l3b_filename);
250  return FAIL;
251  }
252 
253  Vstart(file_id);
254 
255  if ((sd_id = SDstart(l3b_filename, DFACC_RDONLY)) < 0) {
256  fprintf(stderr, "Error: Cannot open input HDF file on SDstart- %s\n",
257  l3b_filename);
258  return FAIL;
259  }
260 
261  access_mode = DFACC_RDONLY;
262 
263  // Read metadata
264  if (read_l3b_meta_hdf4(sd_id, &meta_l3b)) {
265  fprintf(stderr, "Error: Cannot read metadata from file - %s\n",
266  l3b_filename);
267  return FAIL;
268  }
269 
270  vg_id = -1;
271  for (size_t i = 0; i < MAXNVDATA; i++) vdata_id[i] = -1;
272 
273  vg_ref = Vfind(file_id, "Level-3 Binned Data");
274  if (vg_ref > 0) {
275  vg_id = Vattach(file_id, vg_ref, "r");
276 
277  // status = HXsetdir((const char*) dirname(l3b_filename));
278 
279  // Loop through Vdatas
280  bool first = true;
281  for (int32_t i = 0; i < Vntagrefs(vg_id); i++) {
282  Vgettagref(vg_id, i, &tag, &ref);
283  vdata_id[i] = VSattach(file_id, ref, "r");
284 
285  if (vdata_id[i] == -1) {
286  printf("Error opening Vdata (reference # %d)\n", ref);
287  exit(-1);
288  }
289 
290  VSgetname(vdata_id[i], nam_buf);
291  VSgetclass(vdata_id[i], cls_buf);
292 
293  if (strcmp(cls_buf, "Geometry") == 0) {
294  seagrid_idx = i;
295  }
296 
297  if (strcmp(cls_buf, "Index") == 0) {
298  nrows = VSelts(vdata_id[i]);
299  binindex_idx = i;
300  }
301 
302  if (strcmp(cls_buf, "DataMain") == 0) {
303  n_data_records = VSelts(vdata_id[i]);
304  binlist_idx = i;
305  }
306 
307  if (strcmp(cls_buf, "DataSubordinate") == 0) {
308  strcpy(proddata_name[n_data_prod++], nam_buf);
309  if (first) {
310  bindata_idx = i;
311  first = false;
312  }
313  // Don't include quality vdata as product vdata
314  // ??? if (strcmp("qual_l3", nam_buf) == 0) n_data_prod--;
315  }
316 
317  if (strcmp(cls_buf, "DataQuality") == 0) {
318  binqual_idx = i;
319  }
320  }
321  }
322 
323  binShape = new l3::L3ShapeIsine(nrows);
324  totbins = binShape->getNumBins();
325 
326  binList = (binListStruct *) calloc(2 * nrows, sizeof (binListStruct));
327 
328  return SUCCEED;
329 }
330 
331 // Read BinIndex
332 
333 int hdf4_bin::readBinIndex(int row_num_to_read) {
334  const char *binIndexFields =
335  "row_num,vsize,hsize,start_num,begin,extent,max";
336 
337  // row_num_to_read is 0-based
338  VSseek(vdata_id[binindex_idx], row_num_to_read);
339 
340  VSsetfields(vdata_id[binindex_idx], binIndexFields);
341 
342  int records_read = VSread(vdata_id[binindex_idx], (uint8_t *) & binIndex,
343  1, NO_INTERLACE);
344 
345  // Correction for 64 bit
346  if (sizeof (binIndex) == 40) {
347  memmove(((char *) &binIndex) + 8,
348  ((char *) &binIndex) + 4,
349  32);
350  memset(((char *) &binIndex) + 4, 0, 4);
351  }
352 
353  return records_read;
354 }
355 
356 // Read Bin File Product Data Size
357 
358 int hdf_bin::read(char* product_list) {
359  int n = strlen(product_list);
360  char *buf = (char *) malloc(n + 1);
361  strcpy(buf, product_list);
362 
363  for (int32_t i = 0; i < n_data_prod; i++)
364  active_data_prod[i] = false;
365 
366  char *pch = strtok(buf, ",");
367  while (pch != NULL) {
368  if (strcmp(pch, "qual_l3") == 0) {
369  pch = strtok(NULL, ",");
370  continue;
371  }
372 
373  bool found = false;
374  for (int32_t i = 0; i < n_data_prod; i++) {
375  if (strcmp(pch, proddata_name[i]) == 0) {
376  found = true;
377  active_data_prod[i] = true;
378  break;
379  }
380  }
381  if (!found) {
382  cout << "Product: " << pch << " not found.";
383  free(buf);
384  return FAIL;
385  }
386  pch = strtok(NULL, ",");
387  }
388 
389  n_active_prod = 0;
390  for (int32_t i = 0; i < n_data_prod; i++)
391  if (active_data_prod[i])
392  n_active_prod++;
393 
394  free(buf);
395  return (n_data_records * n_active_prod);
396 }
397 
398 // Read Bin File Product Data
399 
400 int hdf4_bin::read(float* data, binListStruct* binList, int nbins_to_read) {
401  char buf2[512];
402  int32_t records_read;
403 
404  int32_t records_remaining = VSelts(vdata_id[binlist_idx]) - bin_ptr;
405  if (records_remaining < nbins_to_read) {
406  cout << nbins_to_read << " requested, ";
407  cout << records_remaining << " to be read at bin_ptr: ";
408  cout << bin_ptr << endl;
409  nbins_to_read = records_remaining;
410  }
411 
412  VSsetfields(vdata_id[binlist_idx],
413  "bin_num,nobs,nscenes,time_rec,weights,sel_cat,flags_set");
414 
415  read_binList(nbins_to_read, vdata_id[binlist_idx], binList, binShape);
416 
417  binListStruct binListRec;
418  int k = 0;
419  bool first = true;
420  int bin_ptr0 = bin_ptr;
421  for (int32_t i = 0; i < n_data_prod; i++) {
422  if (active_data_prod[i] == true) {
423  strcpy(buf2, proddata_name[i]);
424  strcat(buf2, "_sum");
425  VSsetfields(vdata_id[bindata_idx + i], buf2);
426 
427  VSseek(vdata_id[bindata_idx + i], bin_ptr0);
428 
429  records_read = VSread(vdata_id[bindata_idx + i],
430  (uint8_t *) & data[k * nbins_to_read],
431  nbins_to_read, FULL_INTERLACE);
432 
433  if (records_read == -1) {
434  cout << "Read failure at bin_ptr: " << bin_ptr << endl;
435  exit(4);
436  }
437 
438  if (first) {
439  bin_ptr += records_read;
440  first = false;
441  }
442 
443  for (int32_t j = 0; j < nbins_to_read; j++) {
444  memcpy((void *) &binListRec, &binList[j],
445  sizeof (binListStruct));
446  // cout << binListRec.weights << endl;
447  data[k * nbins_to_read + j] /= binListRec.weights;
448  }
449  k++;
450  } // if active vdata
451  } // vdata loop
452 
453  return records_read;
454 }
455 
456 // Read Bin File Product Data
457 
458 int hdf4_bin::read(float* data, float* var,
459  binListStruct* binList, int nbins_to_read) {
460  char buf2[512 * 2];
461  int32_t records_read;
462 
463  int32_t records_remaining = VSelts(vdata_id[binlist_idx]) - bin_ptr;
464  if (records_remaining < nbins_to_read) {
465  cout << nbins_to_read << " requested, ";
466  cout << records_remaining << " to be read at bin_ptr: ";
467  cout << bin_ptr << endl;
468  nbins_to_read = records_remaining;
469  }
470 
471  VSsetfields(vdata_id[binlist_idx],
472  "bin_num,nobs,nscenes,time_rec,weights,sel_cat,flags_set");
473 
474  read_binList(nbins_to_read, vdata_id[binlist_idx], binList, binShape);
475 
476  binListStruct binListRec;
477  int k = 0;
478  bool first = true;
479  int bin_ptr0 = bin_ptr;
480  for (int32_t i = 0; i < n_data_prod; i++) {
481  if (active_data_prod[i] == true) {
482 
483  // Read sum
484  strcpy(buf2, proddata_name[i]);
485  strcat(buf2, "_sum");
486  VSsetfields(vdata_id[bindata_idx + i], buf2);
487 
488  VSseek(vdata_id[bindata_idx + i], bin_ptr0);
489  records_read = VSread(vdata_id[bindata_idx + i],
490  (uint8_t *) & data[k * nbins_to_read],
491  nbins_to_read, FULL_INTERLACE);
492 
493  if (records_read == -1) {
494  cout << "Read failure at bin_ptr: " << bin_ptr << endl;
495  exit(4);
496  }
497 
498  // Read sum_sq
499  strcpy(buf2, proddata_name[i]);
500  strcat(buf2, "_sum_sq");
501  VSsetfields(vdata_id[bindata_idx + i], buf2);
502 
503  VSseek(vdata_id[bindata_idx + i], bin_ptr0);
504  records_read = VSread(vdata_id[bindata_idx + i],
505  (uint8_t *) & var[k * nbins_to_read],
506  nbins_to_read, FULL_INTERLACE);
507 
508  if (records_read == -1) {
509  cout << "Read failure at bin_ptr: " << bin_ptr << endl;
510  exit(4);
511  }
512 
513  if (first) {
514  bin_ptr += records_read;
515  first = false;
516  }
517 
518  for (int32_t j = 0; j < nbins_to_read; j++) {
519  memcpy((void *) &binListRec, &binList[j],
520  sizeof (binListStruct));
521  float sum = data[k * nbins_to_read + j];
522  float wgt = binListRec.weights;
523  data[k * nbins_to_read + j] /= wgt;
524 
525  if (binListRec.nscenes > 1) {
526  float tmp = var[k * nbins_to_read + j] * wgt;
527  tmp -= sum * sum;
528  tmp /= (wgt * wgt - binListRec.nobs);
529  var[k * nbins_to_read + j] = tmp;
530  } else
531  var[k * nbins_to_read + j] = 1.0;
532  }
533  k++;
534  } // if active vdata
535  } // vdata loop
536 
537  return records_read;
538 }
539 
540 // Read BinList
541 
542 int hdf4_bin::readBinList(int nbins_to_read) {
543  int32_t records_read;
544 
545  // return if we are reading the exact same data we already have
546  if (lastBinListPtr == binListPtr && lastNumBins == nbins_to_read)
547  return nbins_to_read;
548  lastBinListPtr = binListPtr;
549  lastNumBins = nbins_to_read;
550 
551  if (nbins_to_read == 0)
552  return 0;
553 
554  const char *binListFields =
555  "bin_num,nobs,nscenes,time_rec,weights,sel_cat,flags_set";
556 
557  VSsetfields(vdata_id[binlist_idx], binListFields);
558 
559  records_read = read_binList(nbins_to_read, vdata_id[binlist_idx], binList, binShape);
560 
561  binListPtr += records_read;
562 
563  return records_read;
564 }
565 
566 // Read BinList
567 
568 int hdf4_bin::readBinList() {
569  int32_t records_read;
570 
571  records_read = this->readBinList(n_data_records);
572 
573  return records_read;
574 }
575 
576 int hdf4_bin::readBinList(int nbins_to_read, int32_t list_reset_ptr) {
577  int32_t records_read;
578 
579  VSseek(vdata_id[binlist_idx], list_reset_ptr);
580 
581  records_read = this->readBinList(nbins_to_read);
582 
583  binListPtr = list_reset_ptr + records_read;
584 
585  return records_read;
586 }
587 
588 // Read Bin File Product Data
589 
590 int hdf4_bin::read(float* data, binListStruct* binList) {
591  int32_t records_read;
592 
593  records_read = this->read(data, binList, n_data_records);
594 
595  return records_read;
596 }
597 
598 // Read Bin File Product Data/Var
599 
600 int hdf4_bin::read(float* data, float* var, binListStruct* binList) {
601  int32_t records_read;
602 
603  records_read = this->read(data, var, binList, n_data_records);
604 
605  return records_read;
606 }
607 
608 int hdf4_bin::write(char *product_list, int32_t nwrite, float *outData,
609  binListStruct* binList) {
610  // Write BinList Vdata
611  const char* fldname2[] = {"bin_num", "nobs", "nscenes", "time_rec",
612  "weights", "sel_cat", "flags_set"};
613 
614  int32_t type[16];
615 
616  binlist_idx = 1;
617  if (vdata_id[binlist_idx] == -1) {
618  type[0] = DFNT_INT32;
619  type[1] = DFNT_INT16;
620  type[2] = DFNT_INT16;
621  type[3] = DFNT_INT16;
622  type[4] = DFNT_FLOAT32;
623  type[5] = DFNT_UCHAR8;
624  type[6] = DFNT_INT32;
625  create_vdata(file_id, vg_id, &vdata_id[binlist_idx], "BinList",
626  "DataMain", 7, fldname2, type, noext, NULL);
627  }
628  write_binList(nwrite, vdata_id[binlist_idx], binList);
629 
630  // Write Product Data Vdatas
631  bindata_idx = 2; // Previous vdatas: SEAGrid, BinList
632  char *fldname3[2];
633  int n = strlen(product_list);
634  char *buf = (char *) malloc(n + 1);
635  strcpy(buf, product_list);
636  char *pch = strtok(buf, ",");
637  type[0] = DFNT_FLOAT32;
638  type[1] = DFNT_FLOAT32;
639 
640  int i = 0;
641 
642  while (pch != NULL) {
643  // printf ("%s\n",pch);
644 
645  if (vdata_id[bindata_idx + i] == -1) {
646  strcpy(proddata_name[n_data_prod++], pch);
647 
648  fldname3[0] = (char *) calloc(strlen(pch) + 5, sizeof (char));
649  fldname3[1] = (char *) calloc(strlen(pch) + 8, sizeof (char));
650  strcpy(fldname3[0], pch);
651  strcat(fldname3[0], "_sum");
652  strcpy(fldname3[1], pch);
653  strcat(fldname3[1], "_sum_sq");
654 
655  create_vdata(file_id, vg_id, &vdata_id[bindata_idx + i], pch,
656  "DataSubordinate", 2, fldname3, type, noext, &aid[i]);
657 
658  free(fldname3[0]);
659  free(fldname3[1]);
660  }
661  write_prodData(nwrite, vdata_id[bindata_idx + i],
662  &outData[(bindata_idx + i - 2) * nwrite], binList);
663  i++;
664  pch = strtok(NULL, ",");
665  }
666  free(buf);
667 
668  n_data_records += nwrite;
669 
670  return 0;
671 }
672 
673 int hdf4_bin::copy(char *product_list, int32_t nwrite, int32_t *binsToCopy,
674  Hdf::binListStruct *inBinList, Hdf::hdf4_bin *input_binfile) {
675  // Copy BinList Vdata
676  const char* fldname2[] = {"bin_num", "nobs", "nscenes", "time_rec",
677  "weights", "sel_cat", "flags_set"};
678 
679  int32_t type[16];
680 
681  binlist_idx = 1;
682  if (vdata_id[binlist_idx] == -1) {
683  type[0] = DFNT_INT32;
684  type[1] = DFNT_INT16;
685  type[2] = DFNT_INT16;
686  type[3] = DFNT_INT16;
687  type[4] = DFNT_FLOAT32;
688  type[5] = DFNT_UCHAR8;
689  type[6] = DFNT_INT32;
690  create_vdata(file_id, vg_id, &vdata_id[binlist_idx], "BinList",
691  "DataMain", 7, fldname2, type, noext, NULL);
692  }
693  for (int32_t i = 0; i < nwrite; i++) {
694  write_binList(1, vdata_id[binlist_idx], &inBinList[binsToCopy[i]]);
695  }
696 
697  // Copy Product Data Vdatas
698  char *fldname3[2];
699  int n = strlen(product_list);
700  char *buf = (char *) malloc(n + 1);
701  strcpy(buf, product_list);
702  char *pch = strtok(buf, ",");
703  type[0] = DFNT_FLOAT32;
704  type[1] = DFNT_FLOAT32;
705 
706  int i = 0;
707 
708  while (pch != NULL) {
709  strcpy(proddata_name[n_data_prod++], pch);
710 
711  fldname3[0] = (char *) calloc(strlen(pch) + 5, sizeof (char));
712  fldname3[1] = (char *) calloc(strlen(pch) + 8, sizeof (char));
713  strcpy(fldname3[0], pch);
714  strcat(fldname3[0], "_sum");
715  strcpy(fldname3[1], pch);
716  strcat(fldname3[1], "_sum_sq");
717 
718  create_vdata(file_id, vg_id, &vdata_id[bindata_idx + i], pch,
719  "DataSubordinate", 2, fldname3, type, noext, &aid[i]);
720 
721  int32_t ref = VSfind(input_binfile->file_id, pch);
722  int32_t in_vdata_id = VSattach(input_binfile->file_id, ref, "r");
723  if (in_vdata_id == -1) {
724  printf("Error opening Vdata (reference # %d)\n", ref);
725  exit(-1);
726  }
727  copy_prodData(nwrite, binsToCopy, fldname3,
728  in_vdata_id, vdata_id[bindata_idx + i]);
729  VSdetach(in_vdata_id);
730 
731  free(fldname3[0]);
732  free(fldname3[1]);
733 
734  i++;
735  pch = strtok(NULL, ",");
736  }
737  free(buf);
738 
739  n_data_records += nwrite;
740 
741  return 0;
742 }
743 
744 // Read Quality
745 
746 int hdf4_bin::readQual(uint8_t* qual, int32_t nbins_to_read) {
747  int records_read = -1;
748  if (binqual_idx != -1) {
749  if (nbins_to_read > 0) {
750  records_read = VSread(vdata_id[binqual_idx], (uint8_t *) qual,
751  nbins_to_read, FULL_INTERLACE);
752  } else {
753  return 0;
754  }
755  }
756  return records_read;
757 }
758 
759 int hdf4_bin::readQual(uint8_t* qual, int32_t nbins_to_read,
760  int32_t row_num_to_read) {
761  int records_read = -1;
762  if (binqual_idx != -1) {
763  if (nbins_to_read > 0) {
764  // row_num_to_read is 0-based
765  VSseek(vdata_id[binqual_idx], row_num_to_read);
766 
767  records_read = VSread(vdata_id[binqual_idx], (uint8_t *) qual,
768  nbins_to_read, FULL_INTERLACE);
769  } else {
770  return 0;
771  }
772  }
773  return records_read;
774 }
775 
776 // Read Bin File Product Data
777 
778 int hdf4_bin::readSums(float* sums, int32_t nbins_to_read, int iprod) {
779  char buf2[512 * 2];
780  int32_t records_read;
781 
782  int k = 0;
783  for (int32_t i = 0; i < n_data_prod; i++) {
784  if (active_data_prod[i] == true && (i == iprod || iprod == -1)) {
785 
786  // Read sums
787  strcpy(buf2, proddata_name[i]);
788  strcat(buf2, "_sum,");
789  strcat(buf2, proddata_name[i]);
790  strcat(buf2, "_sum_sq");
791  VSsetfields(vdata_id[bindata_idx + i], buf2);
792 
793  records_read = VSread(vdata_id[bindata_idx + i],
794  (uint8_t *) & sums[2 * k * nbins_to_read],
795  nbins_to_read, FULL_INTERLACE);
796 
797  if (records_read == -1) {
798  //cout << "Read failure at bin_ptr: " << bin_ptr << endl;
799  exit(4);
800  }
801 
802  k++;
803  } // if active vdata
804  } // vdata loop
805 
806  return records_read;
807 }
808 
809 // Read Bin File Product Data for a list of bin index numbers
810 
811 int hdf4_bin::readSums(float* sums, int32_t* listOfBins,
812  int32_t nbins_to_read, int iprod) {
813  char buf2[512 * 2];
814  int32_t records_read;
815 
816  int k = 0;
817  for (int32_t i = 0; i < n_data_prod; i++) {
818  if (active_data_prod[i] == true && (i == iprod || iprod == -1)) {
819 
820  // Read sums
821  strcpy(buf2, proddata_name[i]);
822  strcat(buf2, "_sum,");
823  strcat(buf2, proddata_name[i]);
824  strcat(buf2, "_sum_sq");
825  VSsetfields(vdata_id[bindata_idx + i], buf2);
826 
827  for (int32_t j = 0; j < nbins_to_read; j++) {
828 
829  VSseek(vdata_id[bindata_idx + i], listOfBins[j]);
830 
831  records_read = VSread(vdata_id[bindata_idx + i],
832  (uint8_t *) & sums[2 * k], 1, FULL_INTERLACE);
833 
834  if (records_read == -1) {
835  //cout << "Read failure at bin_ptr: " << bin_ptr << endl;
836  exit(4);
837  }
838 
839  k++;
840  } // j-loop
841  } // if active vdata
842  } // vdata loop
843 
844  return records_read;
845 }
846 
847 int hdf4_bin::setDataPtrAbsolute(int32_t recordNum) {
848  for (int32_t i = 0; i < n_data_prod; i++) {
849  if (VSseek(vdata_id[bindata_idx + i], recordNum) < 0)
850  return -1;
851  }
852  return 0;
853 }
854 
855 int hdf4_bin::writeBinList(int32_t nbins_to_write) {
856  // Write BinList Vdata
857  const char* fldname2[] = {"bin_num", "nobs", "nscenes", "time_rec",
858  "weights", "sel_cat", "flags_set"};
859 
860  int32_t type[16];
861 
862  binlist_idx = 1;
863  if (vdata_id[binlist_idx] == -1) {
864  type[0] = DFNT_INT32;
865  type[1] = DFNT_INT16;
866  type[2] = DFNT_INT16;
867  type[3] = DFNT_INT16;
868  type[4] = DFNT_FLOAT32;
869  type[5] = DFNT_UCHAR8;
870  type[6] = DFNT_INT32;
871  create_vdata(file_id, vg_id, &vdata_id[binlist_idx], "BinList",
872  "DataMain", 7, fldname2, type, noext, NULL);
873  }
874  write_binList(nbins_to_write, vdata_id[binlist_idx], &binList[0]);
875 
876  n_data_records += nbins_to_write;
877 
878  return 0;
879 }
880 
881 // Write Quality
882 
883 int hdf4_bin::writeQual(uint8_t* qual, int32_t nbins_to_write) {
884  const char* fldname5[] = {"qual_l3"};
885  int32_t type[1];
886  type[0] = DFNT_UCHAR8;
887 
888  if (binqual_idx == -1) {
889  binqual_idx = bindata_idx + n_data_prod + 1;
890  create_vdata(file_id, vg_id, &vdata_id[binqual_idx], "qual_l3",
891  "DataQuality", 1, fldname5, type, noext, NULL);
892  }
893 
894  int records_written = -1;
895  if (binqual_idx != -1) {
896 
897  if (nbins_to_write > 0) {
898  records_written = VSwrite(vdata_id[binqual_idx], (uint8_t *) qual,
899  nbins_to_write, FULL_INTERLACE);
900  }
901  }
902  return records_written;
903 }
904 
905 int hdf4_bin::writeSums(float* sums, int32_t nbins_to_write,
906  const char *prodname) {
907  bindata_idx = 2; // Previous vdatas: SEAGrid, BinList
908 
909  int iprod;
910  bool found = false;
911  for (iprod = 0; iprod < n_data_prod; iprod++) {
912  if (strcmp(proddata_name[iprod], prodname) == 0) {
913  found = true;
914  break;
915  }
916  }
917 
918  char *fldname3[2];
919  int32_t type[16];
920  type[0] = DFNT_FLOAT32;
921  type[1] = DFNT_FLOAT32;
922  if (found == false) {
923  strcpy(proddata_name[n_data_prod], prodname);
924  iprod = n_data_prod;
925  n_data_prod++;
926  }
927 
928  if (vdata_id[bindata_idx + iprod] == -1) {
929  fldname3[0] = (char *) calloc(strlen(prodname) + 5, sizeof (char));
930  fldname3[1] = (char *) calloc(strlen(prodname) + 8, sizeof (char));
931 
932  strcpy(fldname3[0], prodname);
933  strcat(fldname3[0], "_sum");
934  strcpy(fldname3[1], prodname);
935  strcat(fldname3[1], "_sum_sq");
936 
937  create_vdata(file_id, vg_id, &vdata_id[bindata_idx + iprod],
938  prodname, "DataSubordinate", 2, fldname3, type,
939  noext, &aid[iprod]);
940  free(fldname3[0]);
941  free(fldname3[1]);
942 
943  }
944  int records_written = VSwrite(vdata_id[bindata_idx + iprod],
945  (const uint8_t*) sums, nbins_to_write,
946  FULL_INTERLACE);
947 
948  return records_written;
949 }
950 
951 int hdf4_bin::close() {
952  intn status;
953  int32_t n_total_bins = 0;
954  float slat = +90, nlat = -90, elon = -180, wlon = +180;
955 
956  if (access_mode == DFACC_CREATE) {
957  int32_t *binnum_data = (int32_t *) calloc(n_data_records, sizeof (int32_t));
958 
959  status = VSsetfields(vdata_id[binlist_idx], "bin_num");
960  if (status == -1) {
961  printf("Unable to set \"bin_num\" in VSsetfields for id: %d.\n",
962  vdata_id[binlist_idx]);
963  exit(1);
964  }
965  VSseek(vdata_id[binlist_idx], 0);
966  int32_t nread = VSread(vdata_id[binlist_idx], (uint8_t *) binnum_data,
967  n_data_records, FULL_INTERLACE);
968  if (nread == -1) {
969  printf("Unable to read bin number input in hdf4_bin::close()\n");
970  exit(1);
971  }
972 
973  // for (int32_t i=0; i<n_data_records-1; i++) {
974  // if (binnum_data[i] >= binnum_data[i+1]) {
975  // printf("Improper bin number: %d at element: %d\n",
976  // binnum_data[i], (int)i);
977  // }
978  // }
979 
980  int32_t *beg = (int32_t *) calloc(nrows, sizeof (int32_t));
981  int32_t *ext = (int32_t *) calloc(nrows, sizeof (int32_t));
982 
983  int32_t *numbin_out = (int32_t *) calloc(nrows, sizeof (int32_t));
984  int32_t *basebin_out = (int32_t *) calloc(nrows + 1, sizeof (int32_t));
985 
986  for (int32_t i = 0; i < nrows; i++) {
987  float latbin = (i + 0.5) * (180.0 / (nrows)) - 90.0;
988  numbin_out[i] = (int32_t) (cos(latbin * PI / 180.0) * (2.0 * nrows) + 0.5);
989  n_total_bins += numbin_out[i];
990  }
991 
992  basebin_out[0] = 1;
993  for (int32_t i = 1; i <= nrows; i++) {
994  basebin_out[i] = basebin_out[i - 1] + numbin_out[i - 1];
995  }
996 
997  /* Determine beg and extent values for each row */
998  /* -------------------------------------------- */
999  get_beg_ext32(n_data_records, binnum_data, basebin_out, nrows, beg, ext);
1000 
1001  /* Write BinIndex Vdata */
1002  /* -------------------- */
1003  uint8_t *a = (uint8_t *) calloc(36 * nrows, 1);
1004  int32_t i32 = 0;
1005  for (int32_t i = 0; i < nrows; i++) {
1006  double vsize = 180.0 / nrows;
1007  double hsize = 360.0 / numbin_out[i];
1008  memcpy(&a[i * 36], &i, 4);
1009  memcpy(&a[i * 36 + 4], &vsize, 8);
1010  memcpy(&a[i * 36 + 12], &hsize, 8);
1011  memcpy(&a[i * 36 + 20], &basebin_out[i], 4);
1012  memcpy(&a[i * 36 + 24], &beg[i], 4);
1013  memcpy(&a[i * 36 + 28], &ext[i], 4);
1014  memcpy(&a[i * 36 + 32], &numbin_out[i], 4);
1015 
1016  /* Determine NSEW boundries */
1017  /* ------------------------ */
1018  float lon, lat;
1019  if (beg[i] > 0) {
1020  lat = ((i + 0.5) / nrows) * 180.0 - 90.0;
1021  if (lat > nlat)
1022  nlat = lat;
1023  if (lat < slat)
1024  slat = lat;
1025 
1026  lon = 360.0 * (beg[i] - basebin_out[i] + 0.5)
1027  / numbin_out[i] - 180.0;
1028  if (lon < wlon)
1029  wlon = lon;
1030 
1031  lon = 360.0 * (binnum_data[i32 + ext[i] - 1] - basebin_out[i] + 0.5)
1032  / numbin_out[i] - 180.0;
1033  if (lon > elon)
1034  elon = lon;
1035  }
1036  i32 += ext[i];
1037  }
1038 
1039  const char* fldname4[] = {"row_num", "vsize", "hsize", "start_num",
1040  "begin", "extent", "max"};
1041 
1042  int32_t type[16];
1043  type[0] = DFNT_INT32;
1044  type[1] = DFNT_FLOAT64;
1045  type[2] = DFNT_FLOAT64;
1046  type[3] = DFNT_INT32;
1047  type[4] = DFNT_INT32;
1048  type[5] = DFNT_INT32;
1049  type[6] = DFNT_INT32;
1050 
1051  binindex_idx = 2 + n_data_prod;
1052  create_vdata(file_id, vg_id, &vdata_id[binindex_idx], "BinIndex",
1053  "Index", 7, fldname4, type, noext, NULL);
1054 
1055  write_vdata(vdata_id[binindex_idx], nrows, a);
1056 
1057  free(a);
1058 
1059  free(binnum_data);
1060  free(beg);
1061  free(ext);
1062  free(numbin_out);
1063  free(basebin_out);
1064 
1065  /* Write Global Attributes */
1066  /* ----------------------- */
1067  meta_l3b.north = nlat;
1068  meta_l3b.south = slat;
1069  meta_l3b.east = elon;
1070  meta_l3b.west = wlon;
1071  meta_l3b.data_bins = n_data_records;
1072  meta_l3b.pct_databins = 100 * ((float) n_data_records) / n_total_bins;
1073 
1074  if (nrows == 180) {
1075  meta_l3b.resolution = str2resolution("1deg");
1076  } else if (nrows == 360) {
1077  meta_l3b.resolution = str2resolution("0.5deg");
1078  } else if (nrows == 540) {
1079  meta_l3b.resolution = str2resolution("36km");
1080  } else if (nrows == 720) {
1081  meta_l3b.resolution = str2resolution("0.25deg");
1082  } else if (nrows == 1080) {
1083  meta_l3b.resolution = str2resolution("18km");
1084  } else if (nrows == 2160) {
1085  meta_l3b.resolution = str2resolution("9km");
1086  } else if (nrows == 4320) {
1087  meta_l3b.resolution = str2resolution("4km");
1088  } else if (nrows == 8640) {
1089  meta_l3b.resolution = str2resolution("2km");
1090  } else if (nrows == 17280) {
1091  meta_l3b.resolution = str2resolution("1km");
1092  } else if (nrows == 34560) {
1093  meta_l3b.resolution = str2resolution("hkm");
1094  } else if (nrows == 69120) {
1095  meta_l3b.resolution = str2resolution("qkm");
1096  } else if (nrows == 172800) {
1097  meta_l3b.resolution = str2resolution("hqkm");
1098  } else if (nrows == 345600) {
1099  meta_l3b.resolution = str2resolution("hhkm");
1100  } else {
1101  meta_l3b.resolution = BAD_FLT;
1102  }
1103 
1104  write_l3b_meta_hdf4(sd_id, &meta_l3b);
1105 
1106  } // CREATE
1107 
1108  free(binList);
1109 
1110  // Detach Vdatas
1111  status = VSdetach(vdata_id[seagrid_idx]);
1112  status = VSdetach(vdata_id[binlist_idx]);
1113  status = VSdetach(vdata_id[binindex_idx]);
1114 
1115  if (binqual_idx != -1)
1116  VSdetach(vdata_id[binqual_idx]);
1117 
1118  for (int32_t i = 0; i < n_data_prod; i++) {
1119  status = VSdetach(vdata_id[bindata_idx + i]);
1120  if (aid[i] != -1)
1121  Hendaccess(aid[i]);
1122  }
1123 
1124  // Detach HDF file structures
1125  status = Vdetach(vg_id);
1126  status = Vend(file_id);
1127  status = SDend(sd_id);
1128  status = Hclose(file_id);
1129 
1130  return 0;
1131 }
1132 
1133 // Check whether bin file has qual field
1134 
1135 bool hdf4_bin::has_qual() {
1136 
1137  if (binqual_idx != -1) {
1138  hasQual = true;
1139  } else {
1140  hasQual = false;
1141  }
1142  return hasQual;
1143 }
1144 
1145 // Create Bin File
1146 
1147 int hdf5_bin::create(const char *l3b_filename, int32_t nrows) {
1148  h5fid = H5Fcreate(l3b_filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1149  if (h5fid < 0) {
1150  cout << "Cannot create: " << l3b_filename << endl;
1151  exit(1);
1152  }
1153 
1154  this->nrows = nrows;
1155 
1156  grp0 = H5Gopen1(h5fid, "/");
1157  grp1 = H5Gcreate1(h5fid, "Level-3 Binned Data", 0);
1158 
1159  n_data_records = 0;
1160 
1161  binShape = new l3::L3ShapeIsine(nrows);
1162  totbins = binShape->getNumBins();
1163 
1164  binList = (binListStruct_hdf5 *) calloc(2 * nrows,
1165  sizeof (binListStruct_hdf5));
1166 
1167  return 0;
1168 }
1169 
1170 // Open Bin File
1171 
1172 int hdf5_bin::open(const char* l3b_filename) {
1173  access_mode = H5F_ACC_RDONLY;
1174  h5fid = H5Fopen(l3b_filename, access_mode, H5P_DEFAULT);
1175  if (h5fid < 0) {
1176  cout << l3b_filename << " cannot be opened." << endl;
1177  exit(1);
1178  }
1179 
1180  grp0 = H5Gopen1(h5fid, "/");
1181  grp1 = H5Gopen1(h5fid, "Level-3 Binned Data");
1182  if (grp1 < 0) {
1183  cout << "Group \"Level-3 Binned Data\" cannot be opened in \""
1184  << l3b_filename << "\"" << endl;
1185  exit(1);
1186  }
1187 
1188  // Read metadata
1189  read_l3b_meta_hdf5(grp0, &meta_l3b);
1190 
1191  // Product Type Kludge
1192  strcpy(meta_l3b.prod_type, "");
1193  char *fstunderscore = (char *) strchr(l3b_filename, '_');
1194  if (fstunderscore != NULL) {
1195  char *sndunderscore = strchr(fstunderscore + 1, '_');
1196  if (sndunderscore != NULL) {
1197  char prodtypebuf[8];
1198  memset(prodtypebuf, 0, 8);
1199  memcpy(prodtypebuf, fstunderscore + 1,
1200  sndunderscore - fstunderscore - 1);
1201  strcpy(meta_l3b.prod_type, prodtypebuf);
1202  }
1203  }
1204 
1205  hsize_t numTables;
1206  H5Gget_num_objs(grp1, &numTables);
1207  char nam_buf[80];
1208 
1209  bindata_idx = -1;
1210 
1211  bool first = true;
1212  for (size_t i = 0; i < numTables; i++) {
1213  H5Gget_objname_by_idx(grp1, i, nam_buf, 80);
1214  H5G_obj_t objType = H5Gget_objtype_by_idx(grp1, i);
1215  if (objType == H5G_DATASET) {
1216 
1217  // BinIndex
1218  if (strcmp(nam_buf, "BinIndex") == 0) {
1219  h5table_id[0][i] = H5Dopen1(grp1, "BinIndex");
1220  if (h5table_id[0][i] < 0) {
1221  cout << "BinIndex cannot be opened" << endl;
1222  exit(1);
1223  }
1224 
1225  binindex_idx = i;
1226  h5table_id[1][i] = H5Dget_space(h5table_id[0][i]);
1227  if (h5table_id[1][i] < 0) {
1228  cout << "Filespace error for BinIndex" << endl;
1229  exit(1);
1230  }
1231 
1232  h5table_id[2][i] = H5Dget_type(h5table_id[0][i]);
1233  if (h5table_id[2][i] < 0) {
1234  cout << "Datatype error for BinIndex" << endl;
1235  exit(1);
1236  }
1237 
1238  H5Sget_simple_extent_dims(h5table_id[1][i],
1239  (hsize_t*) & nrows, NULL);
1240 
1241  n_datasets++;
1242  continue;
1243  } // BinIndex
1244 
1245  // BinList
1246  if (strcmp(nam_buf, "BinList") == 0) {
1247  h5table_id[0][i] = H5Dopen1(grp1, "BinList");
1248  if (h5table_id[0][i] < 0) {
1249  cout << "BinList cannot be opened" << endl;
1250  exit(1);
1251  }
1252 
1253  binlist_idx = i;
1254  h5table_id[1][i] = H5Dget_space(h5table_id[0][i]);
1255  if (h5table_id[1][i] < 0) {
1256  cout << "Filespace error for BinList" << endl;
1257  exit(1);
1258  }
1259 
1260  h5table_id[2][i] = H5Dget_type(h5table_id[0][i]);
1261  if (h5table_id[2][i] < 0) {
1262  cout << "Datatype error for BinList" << endl;
1263  exit(1);
1264  }
1265 
1266  H5Sget_simple_extent_dims(h5table_id[1][i],
1267  (hsize_t*) & n_data_records, NULL);
1268  n_datasets++;
1269  continue;
1270  } // BinList
1271 
1272  // BinData Fields
1273  h5table_id[0][i] = H5Dopen1(grp1, nam_buf);
1274  if (h5table_id[0][i] < 0) {
1275  cout << nam_buf << " cannot be opened" << endl;
1276  exit(1);
1277  }
1278 
1279  h5table_id[1][i] = H5Dget_space(h5table_id[0][i]);
1280  if (h5table_id[1][i] < 0) {
1281  cout << "Filespace error for " << nam_buf << endl;
1282  exit(1);
1283  }
1284 
1285  h5table_id[2][i] = H5Dget_type(h5table_id[0][i]);
1286  if (h5table_id[2][i] < 0) {
1287  cout << "Datatype error for " << nam_buf << endl;
1288  exit(1);
1289  }
1290 
1291  strcpy(proddata_name[n_data_prod++], nam_buf);
1292  n_datasets++;
1293  if (first) {
1294  bindata_idx = i;
1295  first = false;
1296  }
1297 
1298  } // objType == H5G_DATASET
1299  }
1300 
1301  binShape = new l3::L3ShapeIsine(nrows);
1302  totbins = binShape->getNumBins();
1303 
1304  binList = (binListStruct_hdf5 *) calloc(2 * nrows,
1305  sizeof (binListStruct_hdf5));
1306 
1307  return SUCCEED;
1308 }
1309 
1310 // Read BinIndex
1311 
1312 int hdf5_bin::readBinIndex(int row_num_to_read) {
1313  herr_t status;
1314  hsize_t one = 1;
1315 
1316  // row_num_to_read is 0-based
1317  hid_t dataset = h5table_id[0][binindex_idx];
1318  if (dataset < 0) {
1319  cout << "Improper BinIndex id" << endl;
1320  exit(1);
1321  }
1322 
1323  hid_t filespace = h5table_id[1][binindex_idx];
1324  if (filespace < 0) {
1325  cout << "Improper Filespace id for BinIndex" << endl;
1326  exit(1);
1327  }
1328 
1329  hid_t datatype = h5table_id[2][binindex_idx];
1330  if (datatype < 0) {
1331  cout << "Improper Datatype id for BinIndex" << endl;
1332  exit(1);
1333  }
1334 
1335  hsize_t strt = row_num_to_read;
1336  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1337  &strt, NULL, &one, NULL);
1338  if (status < 0) {
1339  cout << "H5Sselect_hyperslab error (readBinIndex)" << endl;
1340  exit(1);
1341  }
1342 
1343  hid_t dataspace = H5Screate_simple(1, &one, NULL);
1344  if (dataspace < 0) {
1345  cout << "Dataspace cannot be created for BinIndex." << endl;
1346  exit(1);
1347  }
1348 
1349  status = H5Dread(dataset, datatype, dataspace, filespace,
1350  H5P_DEFAULT, &binIndex);
1351  if (status < 0) {
1352  cout << "H5Dread error (readBinIndex)" << endl;
1353  exit(1);
1354  }
1355 
1356  H5Sclose(dataspace);
1357 
1358  // Correction for 64 bit
1359  if (sizeof (binIndex) == 40) {
1360  memmove(((char *) &binIndex) + 8,
1361  ((char *) &binIndex) + 4,
1362  32);
1363  memset(((char *) &binIndex) + 4, 0, 4);
1364  }
1365 
1366  return status;
1367 }
1368 
1369 // Read BinIndex
1370 
1371 int hdf5_bin::readBinList(int nbins_to_read) {
1372  herr_t status;
1373  hsize_t n2read = nbins_to_read;
1374 
1375  // return good status if already read the requested data
1376  if (lastBinListPtr == binListPtr && lastNumBins == nbins_to_read)
1377  return 0;
1378  lastBinListPtr = binListPtr;
1379  lastNumBins = nbins_to_read;
1380 
1381  hid_t dataset = h5table_id[0][binlist_idx];
1382  if (dataset < 0) {
1383  cout << "Improper BinList id" << endl;
1384  exit(1);
1385  }
1386 
1387  hid_t filespace = h5table_id[1][binlist_idx];
1388  if (filespace < 0) {
1389  cout << "Improper Filespace id for BinList" << endl;
1390  exit(1);
1391  }
1392 
1393  hid_t datatype = h5table_id[2][binlist_idx];
1394  if (datatype < 0) {
1395  cout << "Improper Datatype id for BinList" << endl;
1396  exit(1);
1397  }
1398 
1399  hsize_t binListPtr_hsize;
1400  binListPtr_hsize = binListPtr;
1401  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1402  &binListPtr_hsize, NULL,
1403  &n2read, NULL);
1404  if (status < 0) {
1405  cout << "H5Sselect_hyperslab error (readBinList)" << endl;
1406  exit(1);
1407  }
1408 
1409  hid_t dataspace = H5Screate_simple(1, &n2read, NULL);
1410  if (dataspace < 0) {
1411  cout << "Dataspace cannot be created for BinList." << endl;
1412  exit(1);
1413  }
1414 
1415  status = H5Dread(dataset, datatype, dataspace, filespace,
1416  H5P_DEFAULT, binList);
1417  if (status < 0) {
1418  cout << "H5Dread error (readBinList)" << endl;
1419  exit(1);
1420  }
1421 
1422  binListPtr += nbins_to_read;
1423 
1424  H5Sclose(dataspace);
1425 
1426  return status;
1427 }
1428 
1429 int hdf5_bin::readBinList(int nbins_to_read, int32_t list_reset_ptr) {
1430  int32_t records_read;
1431 
1432  binListPtr = list_reset_ptr;
1433 
1434  records_read = this->readBinList(nbins_to_read);
1435 
1436  binListPtr = list_reset_ptr + records_read;
1437 
1438  return records_read;
1439 }
1440 
1441 // Read BinList
1442 
1443 int hdf5_bin::readBinList() {
1444  // stub
1445  return 0;
1446 }
1447 
1448 // Read Bin File Quality Data
1449 
1450 int hdf5_bin::readQual(unsigned char* qual, int32_t nbins_to_read) {
1451  // Currently no HDF5 binfiles have quality
1452  return -1;
1453 }
1454 
1455 int hdf5_bin::readQual(unsigned char* qual, int32_t nbins_to_read,
1456  int32_t row_num_to_read) {
1457  // Currently no HDF5 binfiles have quality
1458  return -1;
1459 }
1460 
1461 // Read Bin File Product Data
1462 
1463 int hdf5_bin::readSums(float* sums, int32_t nbins_to_read, int iprod) {
1464 
1465  herr_t status;
1466  hsize_t n2read = nbins_to_read;
1467 
1468  int k = 0;
1469  for (int32_t i = 0; i < n_data_prod; i++) {
1470  if (active_data_prod[i] == true && (i == iprod || iprod == -1)) {
1471 
1472  hid_t dataset = h5table_id[0][bindata_idx + i];
1473  if (dataset < 0) {
1474  cout << "Improper BinData id for product: "
1475  << iprod << endl;
1476  exit(1);
1477  }
1478 
1479  hid_t filespace = h5table_id[1][bindata_idx + i];
1480  if (filespace < 0) {
1481  cout << "Improper Filespace id for product: "
1482  << iprod << endl;
1483  exit(1);
1484  }
1485 
1486  hid_t datatype = h5table_id[2][bindata_idx + i];
1487  if (datatype < 0) {
1488  cout << "Improper Datatype id for product: "
1489  << iprod << endl;
1490  exit(1);
1491  }
1492 
1493  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1494  &binDataPtr, NULL, &n2read, NULL);
1495  if (status < 0) {
1496  cout << "H5Sselect_hyperslab error for product: "
1497  << iprod << endl;
1498  exit(1);
1499  }
1500 
1501  hid_t dataspace = H5Screate_simple(1, &n2read, NULL);
1502  if (dataspace < 0) {
1503  cout << "Dataspace cannot be created for product: "
1504  << iprod << endl;
1505  exit(1);
1506  }
1507 
1508  status = H5Dread(dataset, datatype, dataspace, filespace,
1509  H5P_DEFAULT, &sums[2 * k * nbins_to_read]);
1510  if (status < 0) {
1511  cout << "H5Dread error for product: "
1512  << iprod << endl;
1513  exit(1);
1514  }
1515 
1516  H5Sclose(dataspace);
1517 
1518  k++;
1519  } // if active vdata
1520  } // vdata loop
1521 
1522  return status;
1523 }
1524 
1525 // Read Bin File Product Data for list of bins
1526 
1527 int hdf5_bin::readSums(float* sums, int32_t* listOfBins,
1528  int32_t nbins_to_read, int iprod) {
1529 
1530  herr_t status;
1531  hsize_t one = 1;
1532  hsize_t binPtr;
1533 
1534  int k = 0;
1535  for (int32_t i = 0; i < n_data_prod; i++) {
1536  if (active_data_prod[i] == true && (i == iprod || iprod == -1)) {
1537 
1538  hid_t dataset = h5table_id[0][bindata_idx + i];
1539  if (dataset < 0) {
1540  cout << "Improper BinData id for product: "
1541  << iprod << endl;
1542  exit(1);
1543  }
1544 
1545  hid_t filespace = h5table_id[1][bindata_idx + i];
1546  if (filespace < 0) {
1547  cout << "Improper Filespace id for product: "
1548  << iprod << endl;
1549  exit(1);
1550  }
1551 
1552  hid_t datatype = h5table_id[2][bindata_idx + i];
1553  if (datatype < 0) {
1554  cout << "Improper Datatype id for product: "
1555  << iprod << endl;
1556  exit(1);
1557  }
1558 
1559  hid_t dataspace = H5Screate_simple(1, &one, NULL);
1560  if (dataspace < 0) {
1561  cout << "Dataspace cannot be created for product: "
1562  << iprod << endl;
1563  exit(1);
1564  }
1565 
1566  for (int32_t j = 0; j < nbins_to_read; j++) {
1567  binPtr = listOfBins[j];
1568  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1569  &binPtr, NULL, &one, NULL);
1570  if (status < 0) {
1571  cout << "H5Sselect_hyperslab error for product: "
1572  << iprod << endl;
1573  exit(1);
1574  }
1575 
1576  status = H5Dread(dataset, datatype, dataspace, filespace,
1577  H5P_DEFAULT, &sums[2 * k]);
1578  if (status < 0) {
1579  cout << "H5Dread error for product: "
1580  << iprod << endl;
1581  exit(1);
1582  }
1583 
1584  k++;
1585  }
1586 
1587  H5Sclose(dataspace);
1588 
1589  } // if active vdata
1590  } // vdata loop
1591 
1592  return status;
1593 }
1594 
1595 int hdf5_bin::write(const char *product_list, hsize_t nwrite, float *outData,
1596  binListStruct_hdf5* binList) {
1597  // Write BinList DataSet
1598  herr_t status;
1599 
1600  const char* fldname2[] = {"bin_num", "nobs", "nscenes",
1601  "weights", "flags_set"};
1602  binlist_idx = 0;
1603  hsize_t dim = nwrite;
1604  hsize_t unlimited = H5S_UNLIMITED;
1605 
1606  hid_t dataspace = H5Screate_simple(1, &dim, &unlimited);
1607  if (dataspace < 0) {
1608  cout << "Dataspace cannot be created (write)." << endl;
1609  exit(1);
1610  }
1611 
1612  if (binList != NULL) {
1613  if (h5table_id[0][binlist_idx] == -1) {
1614  hid_t type[5] = {
1615  H5T_STD_U32LE,
1616  H5T_NATIVE_SHORT,
1617  H5T_NATIVE_SHORT,
1618  H5T_NATIVE_FLOAT,
1619  H5T_STD_U64LE
1620  };
1621  size_t offset[5] = {
1622  HOFFSET(binListStruct_hdf5, bin_num),
1623  HOFFSET(binListStruct_hdf5, nobs),
1624  HOFFSET(binListStruct_hdf5, nscenes),
1625  HOFFSET(binListStruct_hdf5, weights),
1626  HOFFSET(binListStruct_hdf5, flags_set)
1627  };
1628 
1629  create_compound(grp1, "BinList",
1630  &h5table_id[0][binlist_idx],
1631  &h5table_id[2][binlist_idx],
1632  sizeof (binListStruct_hdf5), 5, fldname2, offset, type,
1633  &h5table_id[1][binlist_idx], dataspace);
1634  } else {
1635  hsize_t newsize = n_data_records + nwrite;
1636  status = H5Dextend(h5table_id[0][binlist_idx], &newsize);
1637  H5Sset_extent_simple(h5table_id[1][binlist_idx], 1, &newsize, NULL);
1638  }
1639  hid_t dataset = h5table_id[0][binlist_idx];
1640  if (dataset < 0) {
1641  cout << "Improper Dataset id for BinList (write)" << endl;
1642  exit(1);
1643  }
1644 
1645  hid_t filespace = h5table_id[1][binlist_idx];
1646  if (filespace < 0) {
1647  cout << "Improper Filespace id for BinList (write)" << endl;
1648  exit(1);
1649  }
1650 
1651  hid_t binlist_tid = h5table_id[2][binlist_idx];
1652  if (binlist_tid < 0) {
1653  cout << "Improper Datatype id for BinList (write)" << endl;
1654  exit(1);
1655  }
1656 
1657  const hsize_t start = n_data_records;
1658  const hsize_t count = nwrite;
1659  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1660  &start, NULL, &count, NULL);
1661  if (status < 0) {
1662  cout << "H5Sselect_hyperslab error for BinList (write)" << endl;
1663  exit(1);
1664  }
1665 
1666  status = H5Dwrite(dataset, binlist_tid, dataspace,
1667  filespace, H5P_DEFAULT, binList);
1668  if (status < 0) {
1669  cout << "Error writing BinList (write)." << endl;
1670  cout << "Dataset id: " << dataset << endl;
1671  cout << "Datatype id: " << binlist_tid << endl;
1672  cout << "Filespace id: " << filespace << endl;
1673  cout << "Start: " << n_data_records << endl;
1674  cout << "Count: " << nwrite << endl;
1675  exit(1);
1676  }
1677  }
1678 
1679  // if no products to write then return
1680  if (product_list == NULL) {
1681  H5Sclose(dataspace);
1682  return 0;
1683  }
1684 
1685  // Write Product Dataset
1686  bindata_idx = 1; // Previous datasets: BinList
1687  char *fldname3[2];
1688  int n = strlen(product_list);
1689  char *buf = (char *) malloc(n + 1);
1690  strcpy(buf, product_list);
1691  char *pch = strtok(buf, ",");
1692 
1693  while (pch != NULL) {
1694 
1695  char ds_name[200];
1696  int i = 0;
1697  while (h5table_id[0][bindata_idx + i] != -1) {
1698  H5Iget_name(h5table_id[0][bindata_idx + i], ds_name, 200);
1699  if (strcmp(pch, &ds_name[21]) == 0)
1700  break;
1701  i++;
1702  }
1703 
1704  if (h5table_id[0][bindata_idx + i] == -1) {
1705 
1706  strcpy(proddata_name[n_datasets++], pch);
1707 
1708  fldname3[0] = (char *) calloc(strlen(pch) + 5, sizeof (char));
1709  fldname3[1] = (char *) calloc(strlen(pch) + 8, sizeof (char));
1710  strcpy(fldname3[0], pch);
1711  strcat(fldname3[0], "_sum");
1712  strcpy(fldname3[1], pch);
1713  strcat(fldname3[1], "_sum_sq");
1714 
1715  hid_t type[2] = {H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT};
1716  size_t offset[2] = {0, 4};
1717  create_compound(grp1, pch,
1718  &h5table_id[0][bindata_idx + i],
1719  &h5table_id[2][bindata_idx + i],
1720  8, 2, fldname3, offset, type,
1721  &h5table_id[1][bindata_idx + i], dataspace);
1722 
1723  free(fldname3[0]);
1724  free(fldname3[1]);
1725  } else {
1726  hsize_t newsize = n_data_records + nwrite;
1727  status = H5Dextend(h5table_id[0][bindata_idx + i], &newsize);
1728  H5Sset_extent_simple(h5table_id[1][bindata_idx + i], 1,
1729  &newsize, NULL);
1730  }
1731 
1732  hid_t dataset = h5table_id[0][bindata_idx + i];
1733  if (dataset < 0) {
1734  cout << "Improper Dataset id for: " << pch << endl;
1735  exit(1);
1736  }
1737 
1738  hid_t filespace = h5table_id[1][bindata_idx + i];
1739  if (filespace < 0) {
1740  cout << "Improper Filespace id for: " << pch << endl;
1741  exit(1);
1742  }
1743 
1744  hid_t datatype = h5table_id[2][bindata_idx + i];
1745  if (datatype < 0) {
1746  cout << "Improper Datatype id for: " << pch << endl;
1747  exit(1);
1748  }
1749 
1750  const hsize_t start = n_data_records;
1751  const hsize_t count = nwrite;
1752  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET,
1753  &start, NULL, &count, NULL);
1754  if (status < 0) {
1755  cout << "H5Sselect_hyperslab error for: " << pch << endl;
1756  exit(1);
1757  }
1758 
1759  status = H5Dwrite(dataset, datatype,
1760  dataspace, filespace, H5P_DEFAULT, outData);
1761  if (status < 0) {
1762  cout << "Error writing: " << pch << endl;
1763  cout << "Dataset id: " << dataset << endl;
1764  cout << "Datatype id: " << datatype << endl;
1765  cout << "Filespace id: " << filespace << endl;
1766  cout << "Start: " << n_data_records << endl;
1767  cout << "Count: " << nwrite << endl;
1768  exit(1);
1769  }
1770 
1771  pch = strtok(NULL, ",");
1772  }
1773  free(buf);
1774 
1775  H5Sclose(dataspace);
1776 
1777  return 0;
1778 }
1779 
1780 int hdf5_bin::writeBinList(int32_t nbins_to_write) {
1781  // Write BinList DataSet
1782  herr_t status;
1783 
1784  const char* fldname2[] = {"bin_num", "nobs", "nscenes",
1785  "weights", "flags_set"};
1786  binlist_idx = 0;
1787  hsize_t dim = nbins_to_write;
1788 
1789  hsize_t unlimited = H5S_UNLIMITED;
1790 
1791  hid_t dataspace = H5Screate_simple(1, &dim, &unlimited);
1792 
1793  if (h5table_id[0][binlist_idx] == -1) {
1794  hid_t type[5] = {
1795  H5T_STD_U32LE,
1796  H5T_NATIVE_SHORT,
1797  H5T_NATIVE_SHORT,
1798  H5T_NATIVE_FLOAT,
1799  H5T_STD_U64LE
1800  };
1801  size_t offset[5] = {
1802  HOFFSET(binListStruct_hdf5, bin_num),
1803  HOFFSET(binListStruct_hdf5, nobs),
1804  HOFFSET(binListStruct_hdf5, nscenes),
1805  HOFFSET(binListStruct_hdf5, weights),
1806  HOFFSET(binListStruct_hdf5, flags_set)
1807  };
1808 
1809  create_compound(grp1, "BinList",
1810  &h5table_id[0][binlist_idx],
1811  &h5table_id[2][binlist_idx],
1812  sizeof (binListStruct_hdf5), 5, fldname2, offset, type,
1813  &h5table_id[1][binlist_idx], dataspace);
1814 
1815  n_datasets++;
1816  } else {
1817  hsize_t newsize = n_data_records + nbins_to_write;
1818  status = H5Dextend(h5table_id[0][binlist_idx], &newsize);
1819  H5Sset_extent_simple(h5table_id[1][binlist_idx], 1, &newsize, NULL);
1820  }
1821  hid_t dataset = h5table_id[0][binlist_idx];
1822  if (dataset < 0) {
1823  cout << "Improper Dataset id for BinList" << endl;
1824  exit(1);
1825  }
1826 
1827  hid_t filespace = h5table_id[1][binlist_idx];
1828  if (filespace < 0) {
1829  cout << "Improper Filespace id for BinList (writeBinList)." << endl;
1830  exit(1);
1831  }
1832 
1833  // cout << H5Sget_simple_extent_npoints(filespace) << endl;
1834  //hsize_t d;
1835  //H5Sget_simple_extent_dims(filespace, &d, NULL);
1836  //cout << "d: " << d << endl;
1837 
1838  hid_t binlist_tid = h5table_id[2][binlist_idx];
1839  if (binlist_tid < 0) {
1840  cout << "Improper Datatype id for BinList (writeBinList)." << endl;
1841  exit(1);
1842  }
1843 
1844  const hsize_t start = n_data_records;
1845  const hsize_t count = nbins_to_write;
1846  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, &start,
1847  NULL, &count, NULL);
1848 
1849  status = H5Dwrite(dataset, binlist_tid, dataspace,
1850  filespace, H5P_DEFAULT, binList);
1851  if (status < 0) {
1852  cout << "Error writing BinList (writeBinList)." << endl;
1853  cout << "Dataset id: " << dataset << endl;
1854  cout << "Datatype id: " << binlist_tid << endl;
1855  cout << "Filespace id: " << filespace << endl;
1856  cout << "Start: " << n_data_records << endl;
1857  cout << "Count: " << nbins_to_write << endl;
1858  exit(1);
1859  }
1860 
1861  H5Sclose(dataspace);
1862 
1863  return 0;
1864 }
1865 
1866 int hdf5_bin::writeSums(float* sums, int32_t nbins_to_write,
1867  const char *prodname) {
1868  int iprod;
1869  bool found = false;
1870  for (iprod = 0; iprod < n_data_prod; iprod++) {
1871  if (strcmp(proddata_name[iprod], prodname) == 0) {
1872  found = true;
1873  break;
1874  }
1875  }
1876  bindata_idx = 1; // Previous Datasets: BinList
1877  hsize_t dim = nbins_to_write;
1878 
1879  hsize_t unlimited = H5S_UNLIMITED;
1880  hid_t dataspace = H5Screate_simple(1, &dim, &unlimited);
1881 
1882  char *fldname3[2];
1883  herr_t status;
1884 
1885  // int i = 0;
1886 
1887  if (found == false) {
1888  strcpy(proddata_name[n_data_prod], prodname);
1889 
1890  fldname3[0] = (char *) calloc(strlen(prodname) + 5, sizeof (char));
1891  fldname3[1] = (char *) calloc(strlen(prodname) + 8, sizeof (char));
1892 
1893  strcpy(fldname3[0], prodname);
1894  strcat(fldname3[0], "_sum");
1895  strcpy(fldname3[1], prodname);
1896  strcat(fldname3[1], "_sum_sq");
1897  hid_t type[2] = {H5T_NATIVE_FLOAT, H5T_NATIVE_FLOAT};
1898  size_t offset[2] = {0, 4};
1899  create_compound(grp1, prodname,
1900  &h5table_id[0][bindata_idx + n_data_prod],
1901  &h5table_id[2][bindata_idx + n_data_prod],
1902  8, 2, fldname3, offset, type,
1903  &h5table_id[1][bindata_idx + n_data_prod], dataspace);
1904 
1905  free(fldname3[0]);
1906  free(fldname3[1]);
1907 
1908  n_data_prod++;
1909  n_datasets++;
1910  } else {
1911  hsize_t newsize = n_data_records + nbins_to_write;
1912  status = H5Dextend(h5table_id[0][bindata_idx + iprod], &newsize);
1913  H5Sset_extent_simple(h5table_id[1][bindata_idx + iprod], 1,
1914  &newsize, NULL);
1915  }
1916  hid_t dataset = h5table_id[0][bindata_idx + iprod];
1917  hid_t filespace = h5table_id[1][bindata_idx + iprod];
1918  hid_t bindata_tid = h5table_id[2][bindata_idx + iprod];
1919  // hsize_t nn1=H5Sget_simple_extent_npoints(filespace);
1920 
1921  const hsize_t start = n_data_records;
1922  const hsize_t count = nbins_to_write;
1923  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, &start,
1924  NULL, &count, NULL);
1925 
1926  status = H5Dwrite(h5table_id[0][bindata_idx + iprod], bindata_tid,
1927  dataspace, filespace, H5P_DEFAULT, sums);
1928  if (status < 0) {
1929  cout << "Error writing product: " << iprod << endl;
1930  cout << "Dataset id: " << dataset << endl;
1931  cout << "Datatype id: " << bindata_tid << endl;
1932  cout << "Filespace id: " << filespace << endl;
1933  cout << "Start: " << n_data_records << endl;
1934  cout << "Count: " << nbins_to_write << endl;
1935  exit(1);
1936  }
1937 
1938  H5Sclose(dataspace);
1939 
1940  return 0;
1941 }
1942 
1943 int hdf5_bin::close() {
1944  herr_t status;
1945  int32_t n_total_bins = 0;
1946  float slat = +90, nlat = -90, elon = -180, wlon = +180;
1947 
1948  // Save old error handler
1949  H5E_auto_t old_func;
1950  void *old_client_data;
1951  H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
1952 
1953  H5Eset_auto(H5E_DEFAULT, NULL, NULL);
1954  hid_t dataset = H5Dopen1(grp1, "BinIndex");
1955 
1956  // Restore previous error handler
1957  H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
1958 
1959  if (dataset == -1) {
1960  int32_t *binnum_data = (int32_t *) calloc(n_data_records, sizeof (int32_t));
1961 
1962  hid_t tid = H5Tcreate(H5T_COMPOUND, sizeof (int32_t));
1963  // Note: Name of field must match original name
1964  status = H5Tinsert(tid, "bin_num", 0, H5T_STD_U32LE);
1965 
1966  status = H5Dread(h5table_id[0][binlist_idx], tid,
1967  H5S_ALL, H5S_ALL, H5P_DEFAULT, binnum_data);
1968 
1969  H5Tclose(tid);
1970  // goto skip;
1971 
1972  for (int32_t i = 0; i < n_data_records - 1; i++) {
1973  if (binnum_data[i] >= binnum_data[i + 1]) {
1974  printf("Improper bin number: %ld at element: %d\n",
1975  (long int) binnum_data[i], (int) i);
1976  }
1977  }
1978 
1979  int32_t *beg = (int32_t *) calloc(nrows, sizeof (int32_t));
1980  int32_t *ext = (int32_t *) calloc(nrows, sizeof (int32_t));
1981 
1982  int32_t *numbin_out = (int32_t *) calloc(nrows, sizeof (int32_t));
1983  int32_t *basebin_out = (int32_t *) calloc(nrows + 1, sizeof (int32_t));
1984 
1985  for (int32_t i = 0; i < nrows; i++) {
1986  float latbin = (i + 0.5) * (180.0 / (nrows)) - 90.0;
1987  numbin_out[i] = (int32_t) (cos(latbin * PI / 180.0) * (2.0 * nrows) + 0.5);
1988  n_total_bins += numbin_out[i];
1989  }
1990 
1991  basebin_out[0] = 1;
1992  for (int32_t i = 1; i <= nrows; i++) {
1993  basebin_out[i] = basebin_out[i - 1] + numbin_out[i - 1];
1994  }
1995 
1996  /* Determine beg and extent values for each row */
1997  /* -------------------------------------------- */
1998  get_beg_ext32(n_data_records, binnum_data, basebin_out, nrows, beg, ext);
1999 
2000  /* Write BinIndex Vdata */
2001  /* -------------------- */
2002  uint8_t *a = (uint8_t *) calloc(36 * nrows, 1);
2003  int32_t i32 = 0;
2004  for (int32_t i = 0; i < nrows; i++) {
2005  double vsize = 180.0 / nrows;
2006  double hsize = 360.0 / numbin_out[i];
2007  memcpy(&a[i * 36], &i, 4);
2008  memcpy(&a[i * 36 + 4], &vsize, 8);
2009  memcpy(&a[i * 36 + 12], &hsize, 8);
2010  memcpy(&a[i * 36 + 20], &basebin_out[i], 4);
2011  memcpy(&a[i * 36 + 24], &beg[i], 4);
2012  memcpy(&a[i * 36 + 28], &ext[i], 4);
2013  memcpy(&a[i * 36 + 32], &numbin_out[i], 4);
2014 
2015  /* Determine NSEW boundries */
2016  /* ------------------------ */
2017  float lon, lat;
2018  if (beg[i] > 0) {
2019  lat = ((i + 0.5) / nrows) * 180.0 - 90.0;
2020  if (lat > nlat)
2021  nlat = lat;
2022  if (lat < slat)
2023  slat = lat;
2024 
2025  lon = 360.0 * (beg[i] - basebin_out[i] + 0.5)
2026  / numbin_out[i] - 180.0;
2027  if (lon < wlon)
2028  wlon = lon;
2029 
2030  lon = 360.0 * (binnum_data[i32 + ext[i] - 1] - basebin_out[i] + 0.5)
2031  / numbin_out[i] - 180.0;
2032  if (lon > elon)
2033  elon = lon;
2034  }
2035  i32 += ext[i];
2036  }
2037 
2038  const char* fldname4[] = {"row_num", "vsize", "hsize", "start_num",
2039  "begin", "extent", "max"};
2040 
2041  hid_t type[7];
2042  type[0] = H5T_STD_I32LE;
2043  type[1] = H5T_NATIVE_DOUBLE;
2044  type[2] = H5T_NATIVE_DOUBLE;
2045  type[3] = H5T_STD_I32LE;
2046  type[4] = H5T_STD_I32LE;
2047  type[5] = H5T_STD_I32LE;
2048  type[6] = H5T_STD_I32LE;
2049 
2050  binindex_idx = n_datasets;
2051  size_t offset[7] = {0, 4, 12, 20, 24, 28, 32};
2052 
2053  hsize_t start[1] = {0};
2054  hsize_t dim = nrows;
2055  hid_t dataspace = H5Screate_simple(1, &dim, NULL);
2056  create_compound(grp1, "BinIndex",
2057  &h5table_id[0][binindex_idx],
2058  &h5table_id[2][binindex_idx],
2059  36, 7, fldname4, offset, type,
2060  &h5table_id[1][binindex_idx], dataspace);
2061 
2062  status = H5Sselect_hyperslab(h5table_id[1][binindex_idx],
2063  H5S_SELECT_SET, start, NULL, &dim, NULL);
2064 
2065  status = H5Dwrite(h5table_id[0][binindex_idx],
2066  h5table_id[2][binindex_idx], dataspace,
2067  h5table_id[1][binindex_idx], H5P_DEFAULT, a);
2068  if (status < 0) {
2069  cout << "Error writing BinIndex." << endl;
2070  exit(1);
2071  }
2072 
2073  H5Sclose(dataspace);
2074 
2075  n_datasets++;
2076 
2077  free(a);
2078 
2079  free(binnum_data);
2080  free(beg);
2081  free(ext);
2082  free(numbin_out);
2083  free(basebin_out);
2084 
2085  // Write Global Attributes
2086  // -----------------------
2087  char buf[50000];
2088 
2089  // Check if metadata already written (l2bin_aquarius)
2090  strcpy(buf, this->meta_l3b.product_name);
2091  if (strcmp(buf, "___") == 0)
2092  goto skip;
2093 
2094  PTB(SetScalarH5A(grp0, "Product Name", H5T_STRING, buf));
2095 
2096  strcpy(buf, this->meta_l3b.sensor_name);
2097  strcat(buf, " Level-3 Binned Data");
2098  PTB(SetScalarH5A(grp0, "Title", H5T_STRING, buf));
2099 
2100  strcpy(buf, this->meta_l3b.sensor);
2101  PTB(SetScalarH5A(grp0, "Sensor", H5T_STRING, buf));
2102 
2103  strcpy(buf, this->meta_l3b.sensor_char);
2104  PTB(SetScalarH5A(grp0, "Sensor Characteristics", H5T_STRING, buf));
2105 
2106  strcpy(buf, this->meta_l3b.mission);
2107  PTB(SetScalarH5A(grp0, "Mission", H5T_STRING, buf));
2108 
2109  strcpy(buf, this->meta_l3b.mission_char);
2110  PTB(SetScalarH5A(grp0, "Mission Characteristics", H5T_STRING, buf));
2111 
2112  strcpy(buf, this->meta_l3b.soft_name);
2113  PTB(SetScalarH5A(grp0, "Software Name", H5T_STRING, buf));
2114 
2115  strcpy(buf, this->meta_l3b.soft_ver);
2116  PTB(SetScalarH5A(grp0, "Software ID", H5T_STRING, buf));
2117 
2118  strcpy(buf, this->meta_l3b.ptime);
2119  PTB(SetScalarH5A(grp0, "Processing Time", H5T_STRING, buf));
2120 
2121  strcpy(buf, this->meta_l3b.proc_con);
2122  PTB(SetScalarH5A(grp0, "Processing Control", H5T_STRING, buf));
2123 
2124  strcpy(buf, this->meta_l3b.flag_names);
2125  PTB(SetScalarH5A(grp0, "L2 Flag Names", H5T_STRING, buf));
2126 
2127  strcpy(buf, this->meta_l3b.infiles);
2128  PTB(SetScalarH5A(grp0, "Input Files", H5T_STRING, buf));
2129 
2130  PTB(SetScalarH5A(grp0, "Start Orbit", H5T_STD_U32LE,
2131  (VOIDP) & this->meta_l3b.start_orb));
2132  PTB(SetScalarH5A(grp0, "End Orbit", H5T_STD_U32LE,
2133  (VOIDP) & this->meta_l3b.end_orb));
2134 
2135  strcpy(buf, ydhmsf(this->meta_l3b.startTime, 'G'));
2136  PTB(SetScalarH5A(grp0, "Start Time", H5T_STRING, buf));
2137 
2138  int16_t syear, sday, eyear, eday;
2139  double msec;
2140  int32_t smsec, emsec;
2141  unix2yds(meta_l3b.startTime, &syear, &sday, &msec);
2142  smsec = (int32_t) msec;
2143  unix2yds(meta_l3b.endTime, &eyear, &eday, &msec);
2144  emsec = (int32_t) msec;
2145 
2146  PTB(SetScalarH5A(grp0, "Start Year", H5T_NATIVE_SHORT, (VOIDP) & syear));
2147  PTB(SetScalarH5A(grp0, "Start Day", H5T_NATIVE_SHORT, (VOIDP) & sday));
2148  PTB(SetScalarH5A(grp0, "Start Millisec", H5T_STD_U32LE, (VOIDP) & smsec));
2149 
2150  strcpy(buf, ydhmsf(this->meta_l3b.endTime, 'G'));
2151  PTB(SetScalarH5A(grp0, "End Time", H5T_STRING, buf));
2152 
2153  PTB(SetScalarH5A(grp0, "End Year", H5T_NATIVE_SHORT, (VOIDP) & eyear));
2154  PTB(SetScalarH5A(grp0, "End Day", H5T_NATIVE_SHORT, (VOIDP) & eday));
2155  PTB(SetScalarH5A(grp0, "End Millisec", H5T_STD_U32LE, (VOIDP) & emsec));
2156 
2157  strcpy(buf, "degrees North");
2158  PTB(SetScalarH5A(grp0, "Latitude Units", H5T_STRING, buf));
2159  strcpy(buf, "degrees East");
2160  PTB(SetScalarH5A(grp0, "Longitude Units", H5T_STRING, buf));
2161 
2162  PTB(SetScalarH5A(grp0, "Northernmost Latitude", H5T_NATIVE_FLOAT, (VOIDP) & nlat));
2163  PTB(SetScalarH5A(grp0, "Southernmost Latitude", H5T_NATIVE_FLOAT, (VOIDP) & slat));
2164  PTB(SetScalarH5A(grp0, "Easternmost Longitude", H5T_NATIVE_FLOAT, (VOIDP) & elon));
2165  PTB(SetScalarH5A(grp0, "Westernmost Longitude", H5T_NATIVE_FLOAT, (VOIDP) & wlon));
2166 
2167  PTB(SetScalarH5A(grp0, "Data Bins", H5T_STD_U32LE, (VOIDP) & n_data_records));
2168  float f32 = 100 * ((float) n_data_records) / n_total_bins;
2169  PTB(SetScalarH5A(grp0, "Percent Data Bins", H5T_NATIVE_FLOAT, (VOIDP) & f32));
2170  } // CREATE
2171 
2172 skip:
2173  for (size_t i = 0; i < MAXNPROD; i++) {
2174  if (h5table_id[0][i] != -1)
2175  H5Dclose(h5table_id[0][i]);
2176  if (h5table_id[1][i] != -1)
2177  H5Sclose(h5table_id[1][i]);
2178  if (h5table_id[2][i] != -1)
2179  H5Tclose(h5table_id[2][i]);
2180  }
2181 
2182  H5Gclose(grp0);
2183  H5Gclose(grp1);
2184 
2185  H5Fclose(h5fid);
2186 
2187  return 0;
2188 }
2189 
2190 // Create Bin File
2191 
2192 int cdf4_bin::create(const char *l3b_filename, int32_t nrows) {
2193  int status;
2194 
2195  if(nrows > MAX_ROWS_32BIT)
2196  is64bit = true;
2197  else
2198  is64bit = false;
2199 
2200  if (n_data_prod < 1) {
2201  cout << "Error - " << __FILE__ << ":" << __LINE__ <<
2202  " - setProductList needs to be set before calling create." << endl;
2203  exit(1);
2204  }
2205 
2206  status = nc_create(l3b_filename, NC_NETCDF4, &ncid);
2207  check_err(status, __LINE__, __FILE__);
2208  status = nc_def_grp(ncid, "level-3_binned_data", &grp1);
2209  check_err(status, __LINE__, __FILE__);
2210 
2211  this->nrows = nrows;
2212  n_data_records = 0;
2213 
2214 
2215  binShape = new l3::L3ShapeIsine(nrows);
2216  totbins = binShape->getNumBins();
2217 
2218 
2219  if(is64bit) {
2220  binList64 = new binListStruct64_cdf4[2 * nrows];
2221  } else {
2222  binList = new binListStruct_cdf4[2 * nrows];
2223  }
2224 
2225  binindex_idx = -1;
2226 
2227  if(is64bit)
2228  defineBinList64_nc(deflate, grp1);
2229  else
2230  defineBinList_nc(deflate, grp1);
2231 
2232  defineBinData_nc(deflate, grp1, n_data_prod, product_array);
2233 
2234  if(is64bit)
2235  defineBinIndex64_nc(deflate, grp1);
2236  else
2237  defineBinIndex_nc(deflate, grp1);
2238 
2239  if (hasQual)
2240  defineQuality_nc(deflate, grp1);
2241 
2242  return 0;
2243 }
2244 
2245 // Open Bin File
2246 
2247 int cdf4_bin::open(const char* l3b_filename) {
2248  access_mode = NC_NOWRITE;
2249 
2250  int status;
2251  int dimid;
2252  status = nc_open(l3b_filename, access_mode, &ncid);
2253  if (status != NC_NOERR) {
2254  cout << l3b_filename << " cannot be opened." << endl;
2255  exit(1);
2256  }
2257  status = nc_inq_ncid(ncid, "level-3_binned_data", &grp1);
2258  status = nc_inq_dimid(grp1, "binIndexDim", &dimid);
2259  status = nc_inq_dimlen(grp1, dimid, (size_t *) & nrows);
2260 
2261  status = nc_inq_dimid(grp1, "binListDim", &dimid);
2262  status = nc_inq_dimlen(grp1, dimid, (size_t *) & n_data_records);
2263 
2264  status = nc_inq_varid(grp1, "BinIndex", &binindex_idx);
2265  status = nc_inq_varid(grp1, "BinList", &binlist_idx);
2266  //status = nc_inq_varid(grp1, pname, bindata_id);
2267 
2268  status = nc_inq_varid(grp1, "qual_l3", &binqual_idx);
2269  if (status == NC_NOERR) {
2270  hasQual = true;
2271  } else {
2272  binqual_idx = -1;
2273  hasQual = false;
2274  }
2275 
2276  // Read metadata
2277  read_l3b_meta_netcdf4(ncid, &meta_l3b);
2278 
2279  int numTables;
2280  char nam_buf[80];
2281 
2282  // determine if the file is 32 or 64 bit bin numbers
2283  is64bit = false;
2284  nc_type xtype;
2285  status = nc_inq_vartype(grp1, binlist_idx, &xtype);
2286  if(status == NC_NOERR) {
2287  int fieldId;
2288  status = nc_inq_compound_fieldindex(grp1, xtype, "bin_num", &fieldId);
2289  if(status == NC_NOERR) {
2290  nc_type fieldType;
2291  status = nc_inq_compound_fieldtype(grp1, xtype, fieldId, &fieldType);
2292  if(status == NC_NOERR) {
2293  if(fieldType == NC_UINT64)
2294  is64bit = true;
2295  }
2296  }
2297  }
2298 
2299  status = nc_inq_varids(grp1, &numTables, NULL);
2300  int *varids = (int *) calloc(numTables, sizeof (int));
2301  status = nc_inq_varids(grp1, &numTables, varids);
2302 
2303  bindata_idx = -1;
2304 
2305  bool first = true;
2306  for (int i = 0; i < numTables; i++) {
2307  status = nc_inq_varname(grp1, varids[i], nam_buf);
2308 
2309  if (strcmp(nam_buf, "BinIndex") == 0)
2310  continue;
2311  if (strcmp(nam_buf, "BinList") == 0)
2312  continue;
2313 
2314  strcpy(proddata_name[n_data_prod++], nam_buf);
2315  // n_datasets++;
2316  if (first) {
2317  bindata_idx = i;
2318  first = false;
2319  }
2320  }
2321  free(varids);
2322 
2323  status = nc_get_att(ncid, NC_GLOBAL, "binning_scheme", nam_buf);
2324  if (status == NC_NOERR) {
2325  strcpy(this->meta_l3b.binning_scheme, nam_buf);
2326  } else {
2327  cout << "Binning Scheme metadata not found" << endl;
2328  exit(1);
2329  }
2330 
2331  binShape = new l3::L3ShapeIsine(nrows);
2332  totbins = binShape->getNumBins();
2333 
2334  if(is64bit)
2335  binList64 = new binListStruct64_cdf4[2 * nrows];
2336  else
2337  binList = new binListStruct_cdf4[2 * nrows];
2338 
2339  return SUCCEED;
2340 }
2341 
2342 // Read BinIndex
2343 
2344 int cdf4_bin::readBinIndex(int row_num_to_read) {
2345  int status;
2346  size_t start = row_num_to_read;
2347 
2348  if(is64bit)
2349  status = nc_get_var1(grp1, binindex_idx, &start, (void *) &binIndex64);
2350  else
2351  status = nc_get_var1(grp1, binindex_idx, &start, (void *) &binIndex);
2352  if (status != NC_NOERR) {
2353  printf("-E- %s %d: %s for %s\n",
2354  __FILE__, __LINE__, nc_strerror(status), "binIndex");
2355  exit(1);
2356  }
2357 
2358  return status;
2359 }
2360 
2361 // Read BinList
2362 
2363 int cdf4_bin::readBinList() {
2364  // stub
2365  return 0;
2366 }
2367 
2368 // Read BinList
2369 
2370 int cdf4_bin::readBinList(int nbins_to_read) {
2371  int status;
2372  size_t n2read = nbins_to_read;
2373 
2374  if (lastBinListPtr == binListPtr && lastNumBins == nbins_to_read) {
2375  binListPtr += nbins_to_read;
2376  return nbins_to_read;
2377  }
2378  lastBinListPtr = binListPtr;
2379  lastNumBins = nbins_to_read;
2380 
2381  if(nbins_to_read > 0) {
2382  if(is64bit)
2383  status = nc_get_vara(grp1, binlist_idx, &binListPtr, &n2read, (void *) binList64);
2384  else
2385  status = nc_get_vara(grp1, binlist_idx, &binListPtr, &n2read, (void *) binList);
2386 
2387  if (status != NC_NOERR) {
2388  printf("-E- %s %d: %s for %s\n",
2389  __FILE__, __LINE__, nc_strerror(status), "binList");
2390  exit(1);
2391  }
2392 
2393  binListPtr += nbins_to_read;
2394  }
2395 
2396  return nbins_to_read;
2397 }
2398 
2399 int cdf4_bin::readBinList(int nbins_to_read, int32_t list_reset_ptr) {
2400  binListPtr = list_reset_ptr;
2401  this->readBinList(nbins_to_read);
2402 
2403  return nbins_to_read;
2404 }
2405 
2406 // Read Bin File Quality Data
2407 
2408 int cdf4_bin::readQual(unsigned char* qual, int32_t nbins_to_read) {
2409  int status = NC_NOERR;
2410  size_t n2read = nbins_to_read;
2411 
2412  if(nbins_to_read > 0) {
2413  status = nc_get_vara(grp1, binqual_idx, &binQualityPtr, &n2read, (void *) qual);
2414  if (status != NC_NOERR) {
2415  printf("-E- %s %d: %s in readQual\n",
2416  __FILE__, __LINE__, nc_strerror(status));
2417  exit(1);
2418  }
2419  binQualityPtr += nbins_to_read;
2420  }
2421 
2422  return status;
2423 }
2424 
2425 int cdf4_bin::readQual(unsigned char* qual, int32_t nbins_to_read,
2426  int32_t row_num_to_read) {
2427 
2428  int status = NC_NOERR;
2429  size_t n2read = nbins_to_read;
2430  size_t start = row_num_to_read;
2431 
2432  if(nbins_to_read > 0) {
2433  status = nc_get_vara(grp1, binqual_idx, &start, &n2read, (void *) qual);
2434  if (status != NC_NOERR) {
2435  printf("-E- %s %d: %s in readQual\n",
2436  __FILE__, __LINE__, nc_strerror(status));
2437  exit(1);
2438  }
2439  }
2440 
2441  binQualityPtr = row_num_to_read + nbins_to_read;
2442 
2443  return status;
2444 }
2445 
2446 // Read Bin File Product Data
2447 
2448 int cdf4_bin::readSums(float* sums, int32_t nbins_to_read, int iprod) {
2449  int status;
2450  size_t n2read = nbins_to_read;
2451 
2452  int k = 0;
2453  for (int32_t i = 0; i < n_data_prod; i++) {
2454  if (active_data_prod[i] == true && (i == iprod || iprod == -1)) {
2455 
2456  status = nc_get_vara(grp1, bindata_idx + i,
2457  (size_t *) & binDataPtr, &n2read,
2458  (void *) &sums[2 * k * nbins_to_read]);
2459  if (status != NC_NOERR) {
2460  printf("-E- %s %d: %s for prod# %d\n",
2461  __FILE__, __LINE__, nc_strerror(status), iprod);
2462  exit(1);
2463  }
2464 
2465  k++;
2466  } // if active vdata
2467  } // vdata loop
2468 
2469  return status;
2470 }
2471 
2472 // Read Bin File Product Data for specified bins
2473 
2474 int cdf4_bin::readSums(float* sums, int32_t* listOfBins,
2475  int32_t nbins_to_read, int iprod) {
2476  int status;
2477  size_t one = 1;
2478 
2479  int k = 0;
2480  size_t binPtr;
2481  for (int32_t i = 0; i < n_data_prod; i++) {
2482  if (active_data_prod[i] == true && (i == iprod || iprod == -1)) {
2483 
2484  for (int32_t j = 0; j < nbins_to_read; j++) {
2485  binPtr = listOfBins[j];
2486  status = nc_get_vara(grp1, bindata_idx + i,
2487  (size_t *) & binPtr, &one, (void *) &sums[2 * k]);
2488  if (status != NC_NOERR) {
2489  printf("-E- %s %d: %s for prod# %d\n",
2490  __FILE__, __LINE__, nc_strerror(status), iprod);
2491  exit(1);
2492  }
2493  k++;
2494  } // j-loop
2495  } // if active vdata
2496  } // vdata loop
2497 
2498  return status;
2499 }
2500 
2501 int cdf4_bin::write(const char *product_list, hsize_t nwrite, float *outData,
2502  binListStruct_cdf4* binList) {
2503  return 0;
2504 }
2505 
2506 int cdf4_bin::writeBinList(int32_t nbins_to_write) {
2507  // Write BinList DataSet
2508  if(is64bit)
2509  writeBinList_nc(grp1, nbins_to_write, (VOIDP) binList64);
2510  else
2511  writeBinList_nc(grp1, nbins_to_write, (VOIDP) binList);
2512 
2513  return 0;
2514 }
2515 
2516 int cdf4_bin::writeQual(uint8_t* qual, int32_t nbins_to_write) {
2517  // Write Quality
2518  writeQuality_nc(grp1, nbins_to_write, qual);
2519 
2520  return 0;
2521 }
2522 
2523 int cdf4_bin::writeSums(float* sums, int32_t nbins_to_write,
2524  const char *prodname) {
2525  int iprod;
2526  bool found = false;
2527 
2528  strcpy(proddata_name[n_data_prod], prodname);
2529  for (iprod = 0; iprod < n_data_prod; iprod++) {
2530  if (strcmp(proddata_name[iprod], prodname) == 0) {
2531  found = true;
2532  break;
2533  }
2534  }
2535  if (found == false)
2536  n_data_prod++;
2537 
2538  writeBinData_nc(grp1, nbins_to_write, iprod, sums);
2539 
2540  return 0;
2541 }
2542 
2543 int cdf4_bin::close() {
2544  int retval = 0;
2545  int status;
2546  int64_t n_total_bins = 0;
2547  float slat = +90, nlat = -90, elon = -180, wlon = +180;
2548  size_t start;
2549  size_t count;
2550 
2551  if (binindex_idx == -1) {
2552  if(n_data_records > 0) {
2553  int64_t *binnum_data = (int64_t *) calloc(n_data_records, sizeof (int64_t));
2554  status = nc_inq_varid(grp1, "BinList", &binlist_idx);
2555  if (status != NC_NOERR) {
2556  cout << "Error looking for BinList in output file" << endl;
2557  exit(1);
2558  }
2559 
2560  if(is64bit) {
2561  binListStruct64_cdf4 *binList0;
2562  binList0 = new binListStruct64_cdf4[n_data_records];
2563  start = 0;
2564  count = n_data_records;
2565  status = nc_get_vara(grp1, binlist_idx, &start, &count, binList0);
2566  if (status != NC_NOERR) {
2567  cout << "Error reading output file binlist records" << endl;
2568  exit(1);
2569  }
2570  for (size_t i = 0; (int) i < n_data_records; i++) {
2571  binnum_data[i] = binList0[i].bin_num;
2572  }
2573  delete[] binList0;
2574  } else {
2575  binListStruct_cdf4 *binList0;
2576  binList0 = new binListStruct_cdf4[n_data_records];
2577  start = 0;
2578  count = n_data_records;
2579  status = nc_get_vara(grp1, binlist_idx, &start, &count, binList0);
2580  if (status != NC_NOERR) {
2581  cout << "Error reading output file binlist records" << endl;
2582  exit(1);
2583  }
2584  for (size_t i = 0; (int) i < n_data_records; i++) {
2585  binnum_data[i] = binList0[i].bin_num;
2586  }
2587  delete[] binList0;
2588  }
2589 
2590  for (int32_t i = 0; i < n_data_records - 1; i++) {
2591  if (binnum_data[i] >= binnum_data[i + 1]) {
2592  printf("Improper bin number: %ld at element: %d\n",
2593  (long int) binnum_data[i], (int) i);
2594  }
2595  }
2596 
2597  int64_t *beg = (int64_t *) calloc(nrows, sizeof (int64_t));
2598  int32_t *ext = (int32_t *) calloc(nrows, sizeof (int32_t));
2599 
2600  int64_t *numbin_out = (int64_t *) calloc(nrows, sizeof (int64_t));
2601  int64_t *basebin_out = (int64_t *) calloc(nrows + 1, sizeof (int64_t));
2602 
2603  if ((nrows % 2) == 0) {
2604  for (int32_t i = 0; i < nrows; i++) {
2605  double latbin = (i + 0.5) * (180.0 / (nrows)) - 90.0;
2606  numbin_out[i] = (int64_t) (cos(latbin * PI / 180.0)
2607  * (2.0 * nrows) + 0.5);
2608  n_total_bins += numbin_out[i];
2609  }
2610  basebin_out[0] = 1;
2611  } else {
2612  int nside = (nrows + 1) / 4;
2613  totbins = 12 * nside * nside;
2614  for (int32_t i = 0; i <= nrows / 2; i++) {
2615  numbin_out[i] = 4 * (i + 1);
2616  if (numbin_out[i] > 4 * nside)
2617  numbin_out[i] = 4 * nside;
2618  numbin_out[nrows - 1 - i] = numbin_out[i];
2619  }
2620  basebin_out[0] = 0;
2621  }
2622 
2623  for (int32_t i = 1; i <= nrows; i++) {
2624  basebin_out[i] = basebin_out[i - 1] + numbin_out[i - 1];
2625  }
2626 
2627  /* Determine beg and extent values for each row */
2628  /* -------------------------------------------- */
2629  get_beg_ext(n_data_records, binnum_data, basebin_out, nrows, beg, ext);
2630 
2631  /* Write BinIndex Vdata */
2632  /* -------------------- */
2633  if(is64bit) {
2634  binIndexStruct64_nc* binIndex0 = new binIndexStruct64_nc[nrows];
2635  for (int32_t i = 0; i < nrows; i++) {
2636  binIndex0[i].start_num = basebin_out[i];
2637  binIndex0[i].begin = beg[i];
2638  binIndex0[i].extent = ext[i];
2639  binIndex0[i].max = numbin_out[i];
2640  }
2641  writeBinIndex_nc(grp1, nrows, (VOIDP) binIndex0);
2642  delete [] binIndex0;
2643  } else {
2644  binIndexStruct_nc* binIndex0 = new binIndexStruct_nc[nrows];
2645  for (int32_t i = 0; i < nrows; i++) {
2646  binIndex0[i].start_num = basebin_out[i];
2647  binIndex0[i].begin = beg[i];
2648  binIndex0[i].extent = ext[i];
2649  binIndex0[i].max = numbin_out[i];
2650  }
2651  writeBinIndex_nc(grp1, nrows, (VOIDP) binIndex0);
2652  delete [] binIndex0;
2653  }
2654 
2655  /* Determine NSEW boundries */
2656  /* ------------------------ */
2657  int32_t i32 = 0;
2658  for (int32_t i = 0; i < nrows; i++) {
2659  float lon, lat;
2660  if (beg[i] > 0) {
2661  lat = ((i + 0.5) / nrows) * 180.0 - 90.0;
2662  if (lat > nlat)
2663  nlat = lat;
2664  if (lat < slat)
2665  slat = lat;
2666 
2667  lon = 360.0 * (beg[i] - basebin_out[i] + 0.5)
2668  / numbin_out[i] - 180.0;
2669  if (lon < wlon)
2670  wlon = lon;
2671 
2672  lon = 360.0 * (binnum_data[i32 + ext[i] - 1] - basebin_out[i] + 0.5)
2673  / numbin_out[i] - 180.0;
2674  if (lon > elon)
2675  elon = lon;
2676  }
2677  i32 += ext[i];
2678  }
2679 
2680  free(binnum_data);
2681  free(beg);
2682  free(ext);
2683  free(numbin_out);
2684  free(basebin_out);
2685 
2686  // Write Global Attributes
2687  // -----------------------
2688  idDS ds_id;
2689  ds_id.fid = ncid;
2690  ds_id.sid = -1;
2691  ds_id.fftype = DS_NCDF; // FMT_L2NCDF
2692 
2693  meta_l3b.north = nlat;
2694  meta_l3b.south = slat;
2695  meta_l3b.east = elon;
2696  meta_l3b.west = wlon;
2697  meta_l3b.data_bins = n_data_records;
2698  meta_l3b.pct_databins = 100 * ((float) n_data_records) / n_total_bins;
2699 
2700  if (nrows == 180) {
2701  meta_l3b.resolution = str2resolution("1deg");
2702  } else if (nrows == 360) {
2703  meta_l3b.resolution = str2resolution("0.5deg");
2704  } else if (nrows == 540) {
2705  meta_l3b.resolution = str2resolution("36km");
2706  } else if (nrows == 720) {
2707  meta_l3b.resolution = str2resolution("0.25deg");
2708  } else if (nrows == 1080) {
2709  meta_l3b.resolution = str2resolution("18km");
2710  } else if (nrows == 2160) {
2711  meta_l3b.resolution = str2resolution("9km");
2712  } else if (nrows == 4320) {
2713  meta_l3b.resolution = str2resolution("4km");
2714  } else if (nrows == 8640) {
2715  meta_l3b.resolution = str2resolution("2km");
2716  } else if (nrows == 17280) {
2717  meta_l3b.resolution = str2resolution("1km");
2718  } else if (nrows == 34560) {
2719  meta_l3b.resolution = str2resolution("hkm");
2720  } else if (nrows == 69120) {
2721  meta_l3b.resolution = str2resolution("qkm");
2722  } else if (nrows == 172800) {
2723  meta_l3b.resolution = str2resolution("hqkm");
2724  } else if (nrows == 345600) {
2725  meta_l3b.resolution = str2resolution("hhkm");
2726  } else {
2727  meta_l3b.resolution = BAD_FLT;
2728  }
2729 
2730  write_l3b_meta_netcdf4(ds_id, &meta_l3b, is64bit);
2731 
2732  } else { // any data?
2733  retval = 110; // no bins were filled
2734  }
2735  } // CREATE
2736 
2737  nc_close(ncid);
2738 
2739  if(is64bit)
2740  delete[] binList64;
2741  else
2742  delete[] binList;
2743 
2744  return retval;
2745 }
2746 
2747 // Check whether bin file has qual field
2748 
2749 bool cdf4_bin::has_qual() {
2750 
2751  if (binqual_idx != -1) {
2752  hasQual = true;
2753  } else {
2754  hasQual = false;
2755  }
2756  return hasQual;
2757 }
2758 
2764 int hdf_bin::query() {
2765  int nchar = 0;
2766  for (size_t i = 0; (int) i < n_data_prod; i++) {
2767  nchar += strlen(proddata_name[i]) + 1;
2768  }
2769  return nchar;
2770 }
2771 
2777 int hdf_bin::query(char* product_list) {
2778  product_list[0] = 0;
2779  for (int32_t i = 0; i < n_data_prod; i++) {
2780  strcat(product_list, proddata_name[i]);
2781  if (i != n_data_prod - 1)
2782  strcat(product_list, ",");
2783  }
2784  return 0;
2785 }
2786 
2787 // Query Bin File Product List
2788 
2789 int hdf_bin::query(char ***prod_array) {
2790  // only copy pointers once
2791  if (product_array[0] == NULL) {
2792  for (int32_t i = 0; i < n_data_prod; i++) {
2793  product_array[i] = proddata_name[i];
2794  }
2795  }
2796  if (prod_array != NULL)
2797  *prod_array = &product_array[0];
2798 
2799  return n_data_prod;
2800 }
2801 
2802 int hdf_bin::get_prodname(int iprod, char *prodname) {
2803  strcpy(prodname, proddata_name[iprod]);
2804  return 0;
2805 }
2806 
2807 void hdf_bin::setProductList(int numProducts, char* prodNames[]) {
2808  if (numProducts > MAXNPROD) {
2809  printf("Error - %s:%d - setProductList - Maximum number of products exceeded",
2810  __FILE__, __LINE__);
2811  exit(1);
2812  }
2813 
2814  n_data_prod = numProducts;
2815  for (int i = 0; i < numProducts; i++) {
2816  if (strlen(prodNames[i]) >= 80) {
2817  printf("Error - %s:%d - setProductList - Product name too long \"%s\"",
2818  __FILE__, __LINE__, prodNames[i]);
2819  exit(1);
2820  }
2821  strcpy(proddata_name[i], prodNames[i]);
2822  product_array[i] = proddata_name[i];
2823  }
2824 }
2825 
2831 const char* hdf_bin::getProdName(int prodIndex) const {
2832  if (prodIndex < 0 || prodIndex >= MAXNPROD)
2833  return NULL;
2834  return proddata_name[prodIndex];
2835 }
2836 
2842 int hdf_bin::getProdIndex(const char *prodname) const {
2843  int iprod = -1;
2844  for (int i = 0; i < n_data_prod; i++) {
2845  if (strcmp(proddata_name[i], prodname) == 0) {
2846  iprod = i;
2847  break;
2848  }
2849  }
2850  return iprod;
2851 }
2852 
2858 const char* hdf_bin::getActiveProdName(int prodIndex) const {
2859  if (prodIndex < 0 || prodIndex >= n_active_prod)
2860  return NULL;
2861  int activeProd = 0;
2862  int i;
2863  for (i = 0; i < n_data_prod; i++) {
2864  if (active_data_prod[i]) {
2865  if (activeProd == prodIndex) {
2866  return proddata_name[i];
2867  }
2868  activeProd++;
2869  }
2870  }
2871  return NULL;
2872 }
2873 
2874 int hdf_bin::copymeta(int32_t nfiles, Hdf::hdf_bin *input_binfile[]) {
2875  strcpy(this->meta_l3b.sensor, input_binfile[0]->meta_l3b.sensor);
2876  strcpy(this->meta_l3b.sensor_name, input_binfile[0]->meta_l3b.sensor_name);
2877  strcpy(this->meta_l3b.data_center, input_binfile[0]->meta_l3b.data_center);
2878  strcpy(this->meta_l3b.mission, input_binfile[0]->meta_l3b.mission);
2879  strcpy(this->meta_l3b.mission_char,
2880  input_binfile[0]->meta_l3b.mission_char);
2881  strcpy(this->meta_l3b.sensor_char, input_binfile[0]->meta_l3b.sensor_char);
2882  strcpy(this->meta_l3b.pversion, input_binfile[0]->meta_l3b.pversion);
2883  strcpy(this->meta_l3b.prod_type, input_binfile[0]->meta_l3b.prod_type);
2884 
2885  int32_t sorbit = input_binfile[0]->meta_l3b.start_orb;
2886  for (int32_t ifile = 1; ifile < nfiles; ifile++) {
2887  int32_t i32 = input_binfile[ifile]->meta_l3b.start_orb;
2888  if (i32 < sorbit)
2889  sorbit = i32;
2890  }
2891  this->meta_l3b.start_orb = sorbit;
2892 
2893  int32_t eorbit = input_binfile[0]->meta_l3b.end_orb;
2894  for (int32_t ifile = 1; ifile < nfiles; ifile++) {
2895  int32_t i32 = input_binfile[ifile]->meta_l3b.end_orb;
2896  if (i32 > eorbit)
2897  eorbit = i32;
2898  }
2899  this->meta_l3b.end_orb = eorbit;
2900 
2901  strcpy(this->meta_l3b.flag_names, input_binfile[0]->meta_l3b.flag_names);
2902 
2903  double stime;
2904  double etime;
2905 
2906  int32_t sfile = 0;
2907  stime = input_binfile[0]->meta_l3b.startTime;
2908  for (int32_t ifile = 1; ifile < nfiles; ifile++) {
2909  if (input_binfile[ifile]->meta_l3b.startTime < stime) {
2910  stime = input_binfile[ifile]->meta_l3b.startTime;
2911  sfile = ifile;
2912  }
2913  }
2914  this->meta_l3b.startTime = input_binfile[sfile]->meta_l3b.startTime;
2915 
2916  int32_t efile = 0;
2917  etime = input_binfile[0]->meta_l3b.endTime;
2918  for (int32_t ifile = 1; ifile < nfiles; ifile++) {
2919  if (input_binfile[ifile]->meta_l3b.endTime > etime) {
2920  etime = input_binfile[ifile]->meta_l3b.endTime;
2921  efile = ifile;
2922  }
2923  }
2924  this->meta_l3b.endTime = input_binfile[efile]->meta_l3b.endTime;
2925 #if(0)
2926  this->meta_l3b.bin_syear = input_binfile[sfile]->meta_l3b.bin_syear;
2927  this->meta_l3b.bin_sday = input_binfile[sfile]->meta_l3b.bin_sday;
2928  this->meta_l3b.bin_eyear = input_binfile[efile]->meta_l3b.bin_eyear;
2929  this->meta_l3b.bin_eday = input_binfile[efile]->meta_l3b.bin_eday;
2930 
2931  this->meta_l3b.syear = input_binfile[sfile]->meta_l3b.syear;
2932  this->meta_l3b.sday = input_binfile[sfile]->meta_l3b.sday;
2933  this->meta_l3b.smsec = input_binfile[sfile]->meta_l3b.smsec;
2934 
2935  this->meta_l3b.eyear = input_binfile[efile]->meta_l3b.eyear;
2936  this->meta_l3b.eday = input_binfile[efile]->meta_l3b.eday;
2937  this->meta_l3b.emsec = input_binfile[efile]->meta_l3b.emsec;
2938 #endif
2939  strcpy(this->meta_l3b.station, input_binfile[0]->meta_l3b.station);
2940  strcpy(this->meta_l3b.units, input_binfile[0]->meta_l3b.units);
2941 
2942  this->meta_l3b.station_lat = input_binfile[0]->meta_l3b.station_lat;
2943  this->meta_l3b.station_lon = input_binfile[0]->meta_l3b.station_lon;
2944 
2945  strcpy(this->meta_l3b.binning_scheme,
2946  input_binfile[sfile]->meta_l3b.binning_scheme);
2947 
2948  strcpy(this->meta_l3b.doi, input_binfile[0]->meta_l3b.doi);
2949  strcpy(this->meta_l3b.keywords, input_binfile[0]->meta_l3b.keywords);
2950 
2951  return 0;
2952 }
2953 
2954 }
char * ydhmsf(double dtime, char zone)
Definition: ydhmsf.c:12
int16 eday
Definition: l1_czcs_hdf.c:17
uint8_t isHDF5
Definition: get_l3m.c:8
Definition: bin_io.cpp:23
char units[MD_ATTRSZ]
Definition: meta_l3b.h:28
char binning_scheme[SM_ATTRSZ]
Definition: meta_l3b.h:48
int j
Definition: decode_rs.h:73
int status
Definition: l1_czcs_hdf.c:32
void check_err(const int stat, const int line, const char *file)
Definition: nc4utils.c:35
char station[SM_ATTRSZ]
Definition: meta_l3b.h:25
int defineBinList64_nc(int32_t deflate, int32_t grpid)
Definition: ncdfbin_utils.c:99
#define FAIL
Definition: ObpgReadGrid.h:18
int32_t read_l3b_meta_hdf5(hid_t grp0, meta_l3bType *meta_l3b)
int defineBinData_nc(int32_t deflate, int32_t grpid, int32_t nprods, char **prodnames)
int16_t * qual
Definition: l2bin.cpp:86
#define NULL
Definition: decode_rs.h:63
int32_t read_l3b_meta_hdf4(int32_t sdfid, meta_l3bType *meta_l3b)
char mission[SM_ATTRSZ]
Definition: meta_l3b.h:21
hdf_bin * openBinObject(const char *binFileName)
Definition: bin_io.cpp:32
char keywords[SM_ATTRSZ]
Definition: meta_l3b.h:55
char sensor_char[SM_ATTRSZ]
Definition: meta_l3b.h:24
int32_t start_orb
Definition: meta_l3b.h:42
int create_compound(hid_t group_id, const char *dataset_name, hid_t *dataset_id, hid_t *type_id, size_t typesize, int32_t n_flds, char const *const fldname[], size_t offset[], hid_t type[], hid_t *filespace, hid_t dataspace)
Definition: bin_util.cpp:262
#define TRUE
Definition: rice.h:165
float * lat
int32 * msec
Definition: l1_czcs_hdf.c:31
int writeBinIndex_nc(int32_t grpid, int32_t n_write, const void *data)
int16 eyear
Definition: l1_czcs_hdf.c:17
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
int syear
Definition: l1_czcs_hdf.c:15
string prodName
Definition: l3mapgen.cpp:55
char flag_names[SM_ATTRSZ]
Definition: meta_l3b.h:37
int write_prodData(int n_elem, int32_t vdata_id_proddata, float *data, binListStruct *binList)
Definition: bin_util.cpp:202
ds_format_t fftype
Definition: dfutils.h:31
int32 smsec
Definition: l1_czcs_hdf.c:16
int64_t get_beg_ext(int32_t n_bins_write, int64_t *binnum_data, int64_t *basebin, int32_t nrows, int64_t *beg, int32_t *ext)
Definition: get_beg_ext.c:83
int write_binList(int n_elem, int32_t vdata_id_binlist, binListStruct *binList)
Definition: bin_util.cpp:163
int create_vdata(int32_t fileid, int32_t vgid, int32_t *vdata_id, const char *vdata_name, const char *class_name, int32_t n_flds, char const *const fldname[], int32_t type[], int32_t noext, int32_t *aid)
Definition: bin_util.cpp:10
int32_t nobs
Definition: atrem_cor.h:93
int writeBinList_nc(int32_t grpid, int32_t nbins_to_write, const void *data)
int sday
Definition: l1_czcs_hdf.c:15
#define PI
Definition: l3_get_org.c:6
float station_lon
Definition: meta_l3b.h:27
int defineQuality_nc(int32_t deflate, int32_t grpid)
#define MAXNPROD
Definition: bin_util.h:20
char sensor[SM_ATTRSZ]
Definition: meta_l3b.h:23
data_t tmp
Definition: decode_rs.h:74
int32_t get_beg_ext32(int32_t n_bins_write, int32_t *binnum_data, int32_t *basebin, int32_t nrows, int32_t *beg, int32_t *ext)
Definition: get_beg_ext.c:5
double endTime
Definition: meta_l3b.h:40
char prod_type[SM_ATTRSZ]
Definition: meta_l3b.h:29
virtual int32_t nprod()
Definition: hdf_bin.h:108
int write_l3b_meta_hdf4(int32_t sd_id, meta_l3bType *meta_l3b)
char data_center[SM_ATTRSZ]
Definition: meta_l3b.h:20
int defineBinIndex_nc(int32_t deflate, int32_t grpid)
meta_l3bType meta_l3b
Definition: hdf_bin.h:131
int32 nrows
int want_verbose
void unix2yds(double usec, short *year, short *day, double *secs)
virtual int open(const char *l3b_filename)=0
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
but the philosophy of the MODIS L1 routines is that the output granule must be if it contains even a single packet of useable data Some of the spacecraft ancillary data in L0 datasets is available only on a cycle that repeates every seconds MOD_PR01 therefore looks backwards up to for such packets If the seconds preceeding the start of an MOD_PR01 run are covered by a different L0 dataset
Definition: MOD_PR01_pr.txt:33
int32_t write_vdata(int vdata_id, int32_t n_recs_to_write, void *data)
Definition: bin_util.cpp:105
@ DS_NCDF
Definition: dfutils.h:20
#define PTB(function)
Definition: passthebuck.h:16
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
int writeQuality_nc(int32_t grpid, int32_t nbins_to_write, const void *data)
int32_t sid
Definition: dfutils.h:30
char doi[SM_ATTRSZ]
Definition: meta_l3b.h:54
int writeBinData_nc(int32_t grpid, int32_t nbins_to_write, int32_t iprod, const void *data)
int32 emsec
Definition: l1_czcs_hdf.c:18
int defineBinList_nc(int32_t deflate, int32_t grpid)
Definition: ncdfbin_utils.c:42
#define MAX_ROWS_32BIT
Definition: bin_io.cpp:17
#define BAD_FLT
Definition: jplaeriallib.h:19
virtual int get_prodname(int iprod, char *prodname)
Definition: bin_io.cpp:2802
double startTime
Definition: meta_l3b.h:39
int32_t fid
Definition: dfutils.h:29
int read_binList(int n_elem, int32_t vdata_id_binlist, binListStruct *binList, l3::L3Shape *shape)
Definition: bin_util.cpp:118
char mission_char[SM_ATTRSZ]
Definition: meta_l3b.h:22
void copy(double **aout, double **ain, int n)
int16_t * nscenes
Definition: l2bin.cpp:86
#define MAXNVDATA
int32_t read_l3b_meta_netcdf4(int ncid, meta_l3bType *meta_l3b)
Definition: dfutils.h:28
float * lon
int defineBinIndex64_nc(int32_t deflate, int32_t grpid)
char pversion[SM_ATTRSZ]
Definition: meta_l3b.h:30
l2prod offset
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
int write_l3b_meta_netcdf4(idDS ds_id, meta_l3bType *meta_l3b, int write64bit)
void radius(double A)
Definition: proj_report.c:132
char sensor_name[SM_ATTRSZ]
Definition: meta_l3b.h:19
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")
int SetScalarH5A(hid_t id, const char *name, hid_t type, const void *value)
Definition: hdf5util.cpp:166
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424
int copy_prodData(int n_elem, int32_t *binsToCopy, char const *const fldname3[], int32_t in_vdata_id_proddata, int32_t out_vdata_id_proddata)
Definition: bin_util.cpp:229
int32_t end_orb
Definition: meta_l3b.h:43
int k
Definition: decode_rs.h:73
double str2resolution(char const *resolutionStr)
Pixel resolution string to meters.
float station_lat
Definition: meta_l3b.h:26
float32 f32
Definition: l2bin.cpp:104
int count
Definition: decode_rs.h:79