bes  Updated for version 3.20.6
heos5cfdap.cc
Go to the documentation of this file.
1 // This file is part of hdf5_handler: an HDF5 file handler for the OPeNDAP
2 // data server.
3 
4 // Copyright (c) 2011-2016 The HDF Group, Inc. and OPeNDAP, Inc.
5 //
6 // This is free software; you can redistribute it and/or modify it under the
7 // terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 2.1 of the License, or (at your
9 // option) any later version.
10 //
11 // This software is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
21 // You can contact The HDF Group, Inc. at 1800 South Oak Street,
22 // Suite 203, Champaign, IL 61820
23 
32 
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 #include <iostream>
38 #include <sstream>
39 
40 #include <BESLog.h>
41 #include <BESDebug.h>
42 
43 #include "parser.h"
44 #include "heos5cfdap.h"
45 #include "h5cfdaputil.h"
46 #include "HDF5CFByte.h"
47 #include "HDF5CFUInt16.h"
48 #include "HDF5CFInt16.h"
49 #include "HDF5CFUInt32.h"
50 #include "HDF5CFInt32.h"
51 #include "HDF5CFFloat32.h"
52 #include "HDF5CFFloat64.h"
53 #include "HDF5CFStr.h"
54 #include "HDF5CFArray.h"
55 #include "HDFEOS5CFMissLLArray.h"
58 #include "HDF5RequestHandler.h"
59 
60 #include "he5dds.tab.hh"
61 #include "HE5Parser.h"
62 #include "HE5Checker.h"
63 #include "he5das.tab.hh"
64 
65 struct yy_buffer_state;
66 
67 yy_buffer_state *he5dds_scan_string(const char *str);
68 int he5ddsparse(HE5Parser *he5parser);
69 int he5dasparse(libdap::parser_arg *arg);
70 int he5ddslex_destroy();
71 int he5daslex_destroy();
72 
74 yy_buffer_state *he5das_scan_string(const char *str);
75 
76 using namespace HDF5CF;
77 
78 // Map EOS5 to DAP DDS
79 void map_eos5_cfdds(DDS &dds, hid_t file_id, const string & filename) {
80 
81  BESDEBUG("h5","Coming to HDF-EOS5 products DDS mapping function map_eos5_cfdds "<<endl);
82 
83 
84  string st_str ="";
85  string core_str="";
86  string arch_str="";
87  string xml_str ="";
88  string subset_str="";
89  string product_str="";
90  string other_str ="";
91  bool st_only = true;
92 
93  // Read ECS metadata: merge them into one C++ string
94  read_ecs_metadata(file_id,st_str,core_str,arch_str,xml_str, subset_str,product_str,other_str,st_only);
95  if(""==st_str) {
96  string msg =
97  "unable to obtain the HDF-EOS5 struct metadata ";
98  throw InternalErr(__FILE__, __LINE__, msg);
99  }
100 
101  bool is_check_nameclashing = HDF5RequestHandler::get_check_name_clashing();
102 
103  EOS5File *f = NULL;
104 
105  try {
106  f = new EOS5File(filename.c_str(),file_id);
107  }
108  catch(...) {
109  throw InternalErr(__FILE__,__LINE__,"Cannot allocate the file object.");
110  }
111 
112  bool include_attr = false;
113 
114  // This first "try-catch" block will use the parsed info
115  try {
116 
117  // Parse the structmetadata
118  HE5Parser p;
119  HE5Checker c;
120  he5dds_scan_string(st_str.c_str());
121  he5ddsparse(&p);
122  he5ddslex_destroy();
123 
124  // Retrieve ProjParams from StructMetadata
125  p.add_projparams(st_str);
126 #if 0
127  //p.print();
128 #endif
129 
130  // Check if the HDF-EOS5 grid has the valid parameters, projection codes.
131  if (c.check_grids_unknown_parameters(&p)) {
132  throw InternalErr("Unknown HDF-EOS5 grid paramters found in the file");
133  }
134 
135  if (c.check_grids_missing_projcode(&p)) {
136  throw InternalErr("The HDF-EOS5 is missing project code ");
137  }
138 
139  // We gradually add the support of different projection codes
140  if (c.check_grids_support_projcode(&p)) {
141  throw InternalErr("The current project code is not supported");
142  }
143 
144  // HDF-EOS5 provides default pixel and origin values if they are not defined.
145  c.set_grids_missing_pixreg_orig(&p);
146 
147  // Check if this multi-grid file shares the same grid.
148  bool grids_mllcv = c.check_grids_multi_latlon_coord_vars(&p);
149 
150  // Retrieve all HDF5 info(Not the values)
151  f->Retrieve_H5_Info(filename.c_str(),file_id,include_attr);
152 
153  // Adjust EOS5 Dimension names/sizes based on the parsed results
154  f->Adjust_EOS5Dim_Info(&p);
155 
156  // Translate the parsed output to HDF-EOS5 grids/swaths/zonal.
157  // Several maps related to dimension and coordiantes are set up here.
158  f->Add_EOS5File_Info(&p, grids_mllcv);
159 
160  // Add the dimension names
161  f->Add_Dim_Name(&p);
162  }
163  catch (HDF5CF::Exception &e){
164  if(f!=NULL)
165  delete f;
166  throw InternalErr(e.what());
167  }
168  catch(...) {
169  if(f!=NULL)
170  delete f;
171  throw;
172  }
173 
174  // The parsed struct will no longer be in this "try-catch" block.
175  try {
176 
177  // NASA Aura files need special handlings. So first check if this file is an Aura file.
179 
180  // Adjust the variable name
182 
183  // Handle coordinate variables
184  f->Handle_CVar();
185 
186  // Adjust variable and dimension names again based on the handling of coordinate variables.
188 
189 
190  // We need to use the CV units to distinguish lat/lon from th 3rd CV when
191  // memory cache is turned on.
192  if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
193  (HDF5RequestHandler::get_srdata_mem_cache() != NULL)){
194 
195  // Handle unsupported datatypes including the attributes
196  f->Handle_Unsupported_Dtype(true);
197 
198  // Handle unsupported dataspaces including the attributes
199  f->Handle_Unsupported_Dspace(true);
200 
201  // We need to retrieve coordinate variable attributes for memory cache use.
203 
204  }
205  else {
206 
207  // Handle unsupported datatypes
208  f->Handle_Unsupported_Dtype(include_attr);
209 
210  // Handle unsupported dataspaces
211  f->Handle_Unsupported_Dspace(include_attr);
212 
213  }
214 
215 
216  // Need to retrieve the units of CV when memory cache is turned on.
217  // The units of CV will be used to distinguish whether this CV is
218  // latitude/longitude or a third-dimension CV.
219  // isLatLon() will use the units value.
220  if((HDF5RequestHandler::get_lrdata_mem_cache() != NULL) ||
221  (HDF5RequestHandler::get_srdata_mem_cache() != NULL))
222  f->Adjust_Attr_Info();
223 
224  // May need to adjust the object names for special objects. Currently no operations
225  // are done in this routine.
226  f->Adjust_Obj_Name();
227 
228  // Flatten the object name
229  f->Flatten_Obj_Name(include_attr);
230 
231  // Handle name clashing
232  if(true == is_check_nameclashing)
233  f->Handle_Obj_NameClashing(include_attr);
234 
235  // Check if this should follow COARDS, yes, set the COARDS flag.
236  f->Set_COARDS_Status();
237 
238  // For COARDS, the dimension name needs to be changed.
239  f->Adjust_Dim_Name();
240  if(true == is_check_nameclashing)
242 
243  // We need to turn off the very long string in the TES file to avoid
244  // the choking of netCDF Java tools. So this special variable routine
245  // is listed at last. We may need to turn off this if netCDF can handle
246  // long string better.
247  f->Handle_SpVar();
248  }
249  catch (HDF5CF::Exception &e){
250  if(f != NULL)
251  delete f;
252  throw InternalErr(e.what());
253  }
254 
255  // Generate EOS5 DDS
256  try {
257  gen_eos5_cfdds(dds,f);
258  }
259  catch(...) {
260  if (f!=NULL)
261  delete f;
262  throw;
263  }
264 
265  if (f!=NULL)
266  delete f;
267 }
268 
269 // Map EOS5 to DAP DAS
270 void map_eos5_cfdas(DAS &das, hid_t file_id, const string &filename) {
271 
272  BESDEBUG("h5","Coming to HDF-EOS5 products DAS mapping function map_eos5_cfdas "<<endl);
273  string st_str ="";
274  string core_str="";
275  string arch_str="";
276  string xml_str ="";
277  string subset_str="";
278  string product_str="";
279  string other_str ="";
280  bool st_only = true;
281 
282  read_ecs_metadata(file_id,st_str,core_str,arch_str,xml_str, subset_str,product_str,other_str,st_only);
283  if(""==st_str) {
284  string msg =
285  "unable to obtain the HDF-EOS5 struct metadata ";
286  throw InternalErr(__FILE__, __LINE__, msg);
287  }
288 
289  bool is_check_nameclashing = HDF5RequestHandler::get_check_name_clashing();
290 
291  bool is_add_path_attrs = HDF5RequestHandler::get_add_path_attrs();
292 
293  EOS5File *f = NULL;
294  try {
295  f = new EOS5File(filename.c_str(),file_id);
296  }
297  catch(...) {
298  throw InternalErr(__FILE__,__LINE__,"Cannot allocate the file object.");
299  }
300  bool include_attr = true;
301 
302  // The first "try-catch" block will use the parsed info.
303  try {
304 
305  HE5Parser p;
306  HE5Checker c;
307  he5dds_scan_string(st_str.c_str());
308 
309  he5ddsparse(&p);
310  he5ddslex_destroy();
311  p.add_projparams(st_str);
312 #if 0
313  //p.print();
314  // cerr<<"main loop p.za_list.size() = "<<p.za_list.size() <<endl;
315 #endif
316 
317  if (c.check_grids_unknown_parameters(&p)) {
318  throw InternalErr("Unknown HDF-EOS5 grid paramters found in the file");
319  }
320 
321  if (c.check_grids_missing_projcode(&p)) {
322  throw InternalErr("The HDF-EOS5 is missing project code ");
323  }
324  if (c.check_grids_support_projcode(&p)) {
325  throw InternalErr("The current project code is not supported");
326  }
327  c.set_grids_missing_pixreg_orig(&p);
328 
329  bool grids_mllcv = c.check_grids_multi_latlon_coord_vars(&p);
330 
331  f->Retrieve_H5_Info(filename.c_str(),file_id,include_attr);
332  f->Adjust_EOS5Dim_Info(&p);
333  f->Add_EOS5File_Info(&p, grids_mllcv);
334  f->Add_Dim_Name(&p);
335  }
336  catch (HDF5CF::Exception &e){
337  if(f != NULL)
338  delete f;
339  throw InternalErr(e.what());
340  }
341  catch(...) {
342  if(f != NULL)
343  delete f;
344  throw;
345  }
346 
347  try {
350  f->Handle_CVar();
352  f->Handle_Unsupported_Dtype(include_attr);
353 
354  // Remove unsupported dataspace
355  f->Handle_Unsupported_Dspace(include_attr);
356 
357  // Need to retrieve the attribute values.
359 
360 
361  // Handle other unsupported objects,
362  // currently it mainly generates the info. for the
363  // unsupported objects other than datatype, dataspace,links and named datatype
364  // This function needs to be called after retrieving supported attributes.
365  f->Handle_Unsupported_Others(include_attr);
366 
367  // Add/adjust CF attributes
368  f->Adjust_Attr_Info();
369  f->Adjust_Obj_Name();
370  f->Flatten_Obj_Name(include_attr);
371  if (true == is_check_nameclashing)
372  f->Handle_Obj_NameClashing(include_attr);
373  f->Set_COARDS_Status();
374 
375 #if 0
376  //f->Adjust_Dim_Name();
377  //if(true == is_check_nameclashing)
378  // f->Handle_DimNameClashing();
379 #endif
380 
381  // Add supplemental attributes
382  f->Add_Supplement_Attrs(is_add_path_attrs);
383 
384  // Handle coordinate attributes
385  f->Handle_Coor_Attr();
386  f->Handle_SpVar_Attr();
387  }
388  catch (HDF5CF::Exception &e){
389  if(f != NULL)
390  delete f;
391  throw InternalErr(e.what());
392  }
393 
394  // Generate DAS for the EOS5
395  try {
396  gen_eos5_cfdas(das,file_id,f);
397  }
398  catch(...) {
399  if (f != NULL)
400  delete f;
401  throw;
402  }
403 
404  if( f != NULL)
405  delete f;
406 
407 }
408 
409 // Generate DDS for the EOS5
410 void gen_eos5_cfdds(DDS &dds, HDF5CF::EOS5File *f) {
411 
412  BESDEBUG("h5","Coming to HDF-EOS5 products DDS generation function gen_eos5_cfdds "<<endl);
413  const vector<HDF5CF::Var *>& vars = f->getVars();
414  const vector<HDF5CF::EOS5CVar *>& cvars = f->getCVars();
415  const string filename = f->getPath();
416  const hid_t file_id = f->getFileID();
417 
418  // Read Variable info.
419  vector<HDF5CF::Var *>::const_iterator it_v;
420  vector<HDF5CF::EOS5CVar *>::const_iterator it_cv;
421 
422  for (it_v = vars.begin(); it_v !=vars.end();++it_v) {
423  BESDEBUG("h5","variable full path= "<< (*it_v)->getFullPath() <<endl);
424  gen_dap_onevar_dds(dds,*it_v,file_id,filename);
425  }
426 
427  for (it_cv = cvars.begin(); it_cv !=cvars.end();++it_cv) {
428  BESDEBUG("h5","variable full path= "<< (*it_cv)->getFullPath() <<endl);
429  gen_dap_oneeos5cvar_dds(dds,*it_cv,file_id,filename);
430 
431  }
432 
433  // We need to provide grid_mapping info. for multiple grids.
434  // Here cv_lat_miss_index represents the missing latitude(HDF-EOS grid without the latitude field) cv index
435  // This index is used to create the grid_mapping variable for different grids.
436  unsigned short cv_lat_miss_index = 1;
437  for (it_cv = cvars.begin(); it_cv !=cvars.end();++it_cv) {
438  if((*it_cv)->getCVType() == CV_LAT_MISS) {
439  if((*it_cv)->getProjCode() != HE5_GCTP_GEO) {
440  // Here we need to add grid_mapping variables for each grid
441  // For projections other than sinusoidal since attribute values for LAMAZ and PS
442  // are different for each grid.
443  gen_dap_oneeos5cf_dds(dds,*it_cv);
444  add_cf_grid_mapinfo_var(dds,(*it_cv)->getProjCode(),cv_lat_miss_index);
445  cv_lat_miss_index++;
446  }
447  }
448  }
449 }
450 
451 void gen_dap_oneeos5cf_dds(DDS &dds,const HDF5CF::EOS5CVar* cvar) {
452 
453  BESDEBUG("h5","Coming to gen_dap_oneeos5cf_dds() "<<endl);
454 
455  float cv_point_lower = cvar->getPointLower();
456  float cv_point_upper = cvar->getPointUpper();
457  float cv_point_left = cvar->getPointLeft();
458  float cv_point_right = cvar->getPointRight();
459  EOS5GridPCType cv_proj_code = cvar->getProjCode();
460  const vector<HDF5CF::Dimension *>& dims = cvar->getDimensions();
461  if(dims.size() !=2)
462  throw InternalErr(__FILE__,__LINE__,"Currently we only support the 2-D CF coordinate projection system.");
463  add_cf_grid_cvs(dds,cv_proj_code,cv_point_lower,cv_point_upper,cv_point_left,cv_point_right,dims);
464 
465 }
466 
467 void gen_dap_oneeos5cf_das(DAS &das,const vector<HDF5CF::Var*>& vars, const HDF5CF::EOS5CVar* cvar,const unsigned short g_suffix) {
468 
469  BESDEBUG("h5","Coming to gen_dap_oneeos5cf_das() "<<endl);
470 #if 0
471  float cv_point_lower = cvar->getPointLower();
472  float cv_point_upper = cvar->getPointUpper();
473  float cv_point_left = cvar->getPointLeft();
474  float cv_point_right = cvar->getPointRight();
475 #endif
476  EOS5GridPCType cv_proj_code = cvar->getProjCode();
477  const vector<HDF5CF::Dimension *>& dims = cvar->getDimensions();
478 
479 #if 0
480 cerr<<"cv_point_lower is "<<cv_point_lower <<endl;
481 cerr<<"cvar name is "<<cvar->getName() <<endl;
482 for(vector<HDF5CF::Dimension*>::const_iterator it_d = dims.begin(); it_d != dims.end(); ++it_d)
483  cerr<<"dim name das is "<<(*it_d)->getNewName() <<endl;
484 #endif
485 
486  if(dims.size() !=2)
487  throw InternalErr(__FILE__,__LINE__,"Currently we only support the 2-D CF coordinate projection system.");
488 #if 0
489  add_cf_grid_cv_attrs(das,vars,cv_proj_code,cv_point_lower,cv_point_upper,cv_point_left,cv_point_right,dims,cvar->getParams(),g_suffix);
490 #endif
491  add_cf_grid_cv_attrs(das,vars,cv_proj_code,dims,cvar->getParams(),g_suffix);
492 
493 }
494 
495 //For EOS5, generate the ignored object info. for the CF option
496 void gen_eos5_cf_ignored_obj_info(DAS &das, HDF5CF::EOS5File *f) {
497 
498  BESDEBUG("h5","Coming to gen_eos5_cf_ignored_obj_info() "<<endl);
499  AttrTable *at = das.get_table("Ignored_Object_Info");
500  if (NULL == at)
501  at = das.add_table("Ignored_Object_Info", new AttrTable);
502 
503  at->append_attr("Message","String",f->Get_Ignored_Msg());
504 
505 
506 }
507 
508 // Generate DDS for EOS5 coordinate variables
509 void gen_dap_oneeos5cvar_dds(DDS &dds,const HDF5CF::EOS5CVar* cvar, const hid_t file_id, const string & filename) {
510 
511  BESDEBUG("h5","Coming to gen_dap_oneeos5cvar_dds() "<<endl);
512  BaseType *bt = NULL;
513 
514  // TODO: need to handle 64-bit integer for DAP4 CF
515  if(cvar->getType()==H5INT64 || cvar->getType() == H5UINT64)
516  return;
517  switch(cvar->getType()) {
518 #define HANDLE_CASE(tid,type) \
519  case tid: \
520  bt = new (type)(cvar->getNewName(),cvar->getFullPath()); \
521  break;
522 
523  HANDLE_CASE(H5FLOAT32, HDF5CFFloat32);
524  HANDLE_CASE(H5FLOAT64, HDF5CFFloat64);
525  HANDLE_CASE(H5CHAR,HDF5CFInt16);
526  HANDLE_CASE(H5UCHAR, HDF5CFByte);
527  HANDLE_CASE(H5INT16, HDF5CFInt16);
528  HANDLE_CASE(H5UINT16, HDF5CFUInt16);
529  HANDLE_CASE(H5INT32, HDF5CFInt32);
530  HANDLE_CASE(H5UINT32, HDF5CFUInt32);
531  HANDLE_CASE(H5FSTRING, Str);
532  HANDLE_CASE(H5VSTRING, Str);
533  default:
534  throw InternalErr(__FILE__,__LINE__,"unsupported data type.");
535 #undef HANDLE_CASE
536  }
537 
538  if (bt) {
539 
540  const vector<HDF5CF::Dimension *>& dims = cvar->getDimensions();
541  vector <HDF5CF::Dimension*>:: const_iterator it_d;
542  vector <size_t> dimsizes;
543  dimsizes.resize(cvar->getRank());
544  for(int i = 0; i <cvar->getRank();i++)
545  dimsizes[i] = (dims[i])->getSize();
546 
547 
548  if(dims.size() == 0)
549  throw InternalErr(__FILE__,__LINE__,"the coordinate variables cannot be scalar.");
550  switch(cvar->getCVType()) {
551 
552  case CV_EXIST:
553  {
554 
555 #if 0
556 for(vector<HDF5CF::Attribute *>::const_iterator it_ra = cvar->getAttributes().begin();
557  it_ra != cvar->getAttributes().end(); ++it_ra) {
558 cerr<<"cvar attribute name is "<<(*it_ra)->getNewName() <<endl;
559 cerr<<"cvar attribute value type is "<<(*it_ra)->getType() <<endl;
560 }
561 cerr<<"cvar new name exist at he s5cfdap.cc is "<<cvar->getNewName() <<endl;
562 #endif
563  bool is_latlon = cvar->isLatLon();
564  HDF5CFArray *ar = NULL;
565  try {
566  ar = new HDF5CFArray (
567  cvar->getRank(),
568  file_id,
569  filename,
570  cvar->getType(),
571  dimsizes,
572  cvar->getFullPath(),
573  cvar->getTotalElems(),
574  CV_EXIST,
575  is_latlon,
576  cvar->getCompRatio(),
577  cvar->getNewName(),
578  bt);
579  }
580  catch (...) {
581  delete bt;
582  throw InternalErr(__FILE__,__LINE__,"unable to allocate memory for HDF5CFArray.");
583  }
584 
585  for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
586  if (""==(*it_d)->getNewName())
587  ar->append_dim((*it_d)->getSize());
588  else
589  ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
590  }
591 
592  dds.add_var(ar);
593  delete bt;
594  delete ar;
595  }
596  break;
597 
598  case CV_LAT_MISS:
599  case CV_LON_MISS:
600  {
601 
602  HDFEOS5CFMissLLArray *ar = NULL;
603  try {
604 #if 0
605 cerr<<"cvar zone here is "<<cvar->getZone() <<endl;
606 cerr<<"cvar Sphere here is "<<cvar->getSphere() <<endl;
607 cerr<<"cvar getParams here 1 is "<<cvar->getParams()[0]<<endl;
608 #endif
609  ar = new HDFEOS5CFMissLLArray (
610  cvar->getRank(),
611  filename,
612  file_id,
613  cvar->getFullPath(),
614  cvar->getCVType(),
615  cvar->getPointLower(),
616  cvar->getPointUpper(),
617  cvar->getPointLeft(),
618  cvar->getPointRight(),
619  cvar->getPixelReg(),
620  cvar->getOrigin(),
621  cvar->getProjCode(),
622  cvar->getParams(),
623  cvar->getZone(),
624  cvar->getSphere(),
625  cvar->getXDimSize(),
626  cvar->getYDimSize(),
627  cvar->getNewName(),
628  bt);
629  }
630  catch (...) {
631  delete bt;
632  throw InternalErr(__FILE__,__LINE__,"unable to allocate memory for HDFEOS5CFMissLLArray.");
633  }
634 
635  for(it_d = dims.begin(); it_d != dims.end(); ++it_d) {
636  if (""==(*it_d)->getNewName())
637  ar->append_dim((*it_d)->getSize());
638  else
639  ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
640  }
641 
642  dds.add_var(ar);
643  delete bt;
644  delete ar;
645  }
646  break;
647 
648  case CV_NONLATLON_MISS:
649  {
650 
651  if (cvar->getRank() !=1) {
652  delete bt;
653  throw InternalErr(__FILE__, __LINE__, "The rank of missing Z dimension field must be 1");
654  }
655  int nelem = (cvar->getDimensions()[0])->getSize();
656 
657  HDFEOS5CFMissNonLLCVArray *ar = NULL;
658  try {
659  ar = new HDFEOS5CFMissNonLLCVArray(
660  cvar->getRank(),
661  nelem,
662  cvar->getNewName(),
663  bt);
664  }
665  catch (...) {
666  delete bt;
667  throw InternalErr(__FILE__,__LINE__,"unable to allocate memory for HDFEOS5CFMissNonLLCVArray.");
668  }
669 
670 
671  for(it_d = dims.begin(); it_d != dims.end(); it_d++) {
672  if (""==(*it_d)->getNewName())
673  ar->append_dim((*it_d)->getSize());
674  else
675  ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
676  }
677  dds.add_var(ar);
678  delete bt;
679  delete ar;
680 
681 
682  }
683  break;
684  case CV_SPECIAL:
685  // Currently only support Aura TES files. May need to revise when having more
686  // special products KY 2012-2-3
687  {
688 
689  if (cvar->getRank() !=1) {
690  delete bt;
691  throw InternalErr(__FILE__, __LINE__, "The rank of missing Z dimension field must be 1");
692  }
693  int nelem = (cvar->getDimensions()[0])->getSize();
694  HDFEOS5CFSpecialCVArray *ar = NULL;
695 
696  try {
697  ar = new HDFEOS5CFSpecialCVArray(
698  cvar->getRank(),
699  filename,
700  file_id,
701  cvar->getType(),
702  nelem,
703  cvar->getFullPath(),
704  cvar->getNewName(),
705  bt);
706  }
707  catch (...) {
708  delete bt;
709  throw InternalErr(__FILE__,__LINE__,"unable to allocate memory for HDF5CFArray.");
710  }
711 
712 
713  for(it_d = dims.begin(); it_d != dims.end(); ++it_d){
714  if (""==(*it_d)->getNewName())
715  ar->append_dim((*it_d)->getSize());
716  else
717  ar->append_dim((*it_d)->getSize(), (*it_d)->getNewName());
718  }
719  dds.add_var(ar);
720  delete bt;
721  delete ar;
722  }
723  break;
724  case CV_MODIFY:
725  default:
726  delete bt;
727  throw InternalErr(__FILE__,__LINE__,"Unsupported coordinate variable type.");
728  }
729 
730  }
731 
732 }
733 
734 // Generate EOS5 DAS
735 void gen_eos5_cfdas(DAS &das, hid_t file_id, HDF5CF::EOS5File *f) {
736 
737  BESDEBUG("h5","Coming to HDF-EOS5 products DAS generation function gen_eos5_cfdas "<<endl);
738 
739  // First check if this is for generating the ignored object info.
740  if(true == f->Get_IgnoredInfo_Flag()) {
741  gen_eos5_cf_ignored_obj_info(das, f);
742  return;
743  }
744 
745  const vector<HDF5CF::Var *>& vars = f->getVars();
746  const vector<HDF5CF::EOS5CVar *>& cvars = f->getCVars();
747  const vector<HDF5CF::Group *>& grps = f->getGroups();
748  const vector<HDF5CF::Attribute *>& root_attrs = f->getAttributes();
749 
750  vector<HDF5CF::Var *>::const_iterator it_v;
751  vector<HDF5CF::EOS5CVar *>::const_iterator it_cv;
752  vector<HDF5CF::Group *>::const_iterator it_g;
753  vector<HDF5CF::Attribute *>::const_iterator it_ra;
754 
755  // Handling the file attributes(attributes under the root group)
756  // The table name is "HDF_GLOBAL".
757  if (false == root_attrs.empty()) {
758  AttrTable *at = das.get_table(FILE_ATTR_TABLE_NAME);
759  if (NULL == at)
760  at = das.add_table(FILE_ATTR_TABLE_NAME, new AttrTable);
761 
762  for (it_ra = root_attrs.begin(); it_ra != root_attrs.end(); it_ra++) {
763  gen_dap_oneobj_das(at,*it_ra,NULL);
764  }
765  }
766 
767  if (false == grps.empty()) {
768  for (it_g = grps.begin();
769  it_g != grps.end(); ++it_g) {
770  AttrTable *at = das.get_table((*it_g)->getNewName());
771  if (NULL == at)
772  at = das.add_table((*it_g)->getNewName(), new AttrTable);
773 
774  for (it_ra = (*it_g)->getAttributes().begin();
775  it_ra != (*it_g)->getAttributes().end(); ++it_ra) {
776  //gen_dap_oneobj_das(at,*it_ra,NULL);
777  // TODO: ADDING a BES KEY
778  if((*it_ra)->getNewName()=="Conventions" &&((*it_g)->getNewName() == "HDFEOS_ADDITIONAL_FILE_ATTRIBUTES")
779  && (true==HDF5RequestHandler::get_eos5_rm_convention_attr_path())) {
780  AttrTable *at_das = das.get_table(FILE_ATTR_TABLE_NAME);
781  if (NULL == at_das)
782  at_das = das.add_table(FILE_ATTR_TABLE_NAME, new AttrTable);
783  gen_dap_oneobj_das(at_das,*it_ra,NULL);
784  }
785  else
786  gen_dap_oneobj_das(at,*it_ra,NULL);
787  }
788  }
789  }
790 
791  for (it_v = vars.begin();
792  it_v != vars.end(); ++it_v) {
793  if (false == ((*it_v)->getAttributes().empty())) {
794 
795  // TODO: Need to handle 64-bit int support for DAP4 CF.
796  if(H5INT64 == (*it_v)->getType() || H5UINT64 == (*it_v)->getType()){
797  continue;
798  }
799 
800  AttrTable *at = das.get_table((*it_v)->getNewName());
801  if (NULL == at)
802  at = das.add_table((*it_v)->getNewName(), new AttrTable);
803 
804  for (it_ra = (*it_v)->getAttributes().begin();
805  it_ra != (*it_v)->getAttributes().end(); ++it_ra) {
806  gen_dap_oneobj_das(at,*it_ra,*it_v);
807  }
808  }
809  }
810 
811  for (it_cv = cvars.begin(); it_cv !=cvars.end();it_cv++) {
812 
813  if (false == ((*it_cv)->getAttributes().empty())) {
814 
815  // TODO: Need to handle 64-bit int support for DAP4 CF.
816  if(H5INT64 == (*it_cv)->getType() || H5UINT64 == (*it_cv)->getType()){
817  continue;
818  }
819 
820  AttrTable *at = das.get_table((*it_cv)->getNewName());
821  if (NULL == at)
822  at = das.add_table((*it_cv)->getNewName(), new AttrTable);
823 
824 
825  for (it_ra = (*it_cv)->getAttributes().begin();
826  it_ra != (*it_cv)->getAttributes().end(); ++it_ra) {
827  gen_dap_oneobj_das(at,*it_ra,*it_cv);
828  }
829  }
830  }
831 
832  // Add CF 1-D projection variables
833  unsigned short cv_lat_miss_index = 1;
834  // This code block will add grid_mapping attribute info. to corresponding variables.
835  for (it_cv = cvars.begin(); it_cv !=cvars.end();++it_cv) {
836  if((*it_cv)->getCVType() == CV_LAT_MISS) {
837  if((*it_cv)->getProjCode() != HE5_GCTP_GEO) {
838  gen_dap_oneeos5cf_das(das,vars,*it_cv,cv_lat_miss_index);
839  cv_lat_miss_index++;
840  }
841  }
842  }
843 
844  for (it_cv = cvars.begin(); it_cv !=cvars.end();++it_cv) {
845  if((*it_cv)->getProjCode() == HE5_GCTP_LAMAZ) {
846  if((*it_cv)->getCVType() == CV_LAT_MISS || (*it_cv)->getCVType() == CV_LON_MISS) {
847  AttrTable *at = das.get_table((*it_cv)->getNewName());
848  if (NULL == at)
849  at = das.add_table((*it_cv)->getNewName(), new AttrTable);
850  if((*it_cv)->getCVType() == CV_LAT_MISS)
851  add_ll_valid_range(at,true);
852  else
853  add_ll_valid_range(at,false);
854  }
855  }
856  }
857 
858 
859  bool disable_ecsmetadata = HDF5RequestHandler::get_disable_ecsmeta();
860 
861  if(disable_ecsmetadata == false) {
862 
863  // To keep the backward compatiablity with the old handler,
864  // we parse the special ECS metadata to DAP attributes
865 
866  string st_str ="";
867  string core_str="";
868  string arch_str="";
869  string xml_str ="";
870  string subset_str="";
871  string product_str="";
872  string other_str ="";
873  bool st_only = false;
874 
875  read_ecs_metadata(file_id, st_str, core_str, arch_str, xml_str,
876  subset_str, product_str, other_str, st_only);
877 
878 #if 0
879 if(st_str!="") "h5","Final structmetadata "<<st_str <<endl;
880 if(core_str!="") "h5","Final coremetadata "<<core_str <<endl;
881 if(arch_str!="") "h5","Final archivedmetadata "<<arch_str <<endl;
882 if(xml_str!="") "h5","Final xmlmetadata "<<xml_str <<endl;
883 if(subset_str!="") "h5","Final subsetmetadata "<<subset_str <<endl;
884 if(product_str!="") "h5","Final productmetadata "<<product_str <<endl;
885 if(other_str!="") "h5","Final othermetadata "<<other_str <<endl;
886 
887 #endif
888  if(st_str != ""){
889 
890 #if 0
891  string check_disable_smetadata_key ="H5.DisableStructMetaAttr";
892  bool is_check_disable_smetadata = false;
893  is_check_disable_smetadata = HDF5CFDAPUtil::check_beskeys(check_disable_smetadata_key);
894 #endif
895  bool is_check_disable_smetadata = HDF5RequestHandler::get_disable_structmeta();
896 
897  if (false == is_check_disable_smetadata) {
898 
899  AttrTable *at = das.get_table("StructMetadata");
900  if (NULL == at)
901  at = das.add_table("StructMetadata", new AttrTable);
902  parser_arg arg(at);
903 
904  he5das_scan_string((const char*) st_str.c_str());
905  if (he5dasparse(&arg) != 0
906  || false == arg.status()){
907 
908  (*BESLog::TheLog())<< "HDF-EOS5 parse error while processing a "
909  << "StructMetadata " << " HDFEOS attribute" << endl;
910  }
911 
912  he5daslex_destroy();
913 
914  }
915  }
916 
917  if(core_str != ""){
918  AttrTable *at = das.get_table("CoreMetadata");
919  if (NULL == at)
920  at = das.add_table("CoreMetadata", new AttrTable);
921  parser_arg arg(at);
922  he5das_scan_string((const char*) core_str.c_str());
923  if (he5dasparse(&arg) != 0
924  || false == arg.status()){
925 
926  (*BESLog::TheLog())<< "HDF-EOS5 parse error while processing a "
927  << "CoreMetadata " << " HDFEOS attribute" << endl;
928  }
929 
930  he5daslex_destroy();
931  }
932  if(arch_str != ""){
933  AttrTable *at = das.get_table("ArchiveMetadata");
934  if (NULL == at)
935  at = das.add_table("ArchiveMetadata", new AttrTable);
936  parser_arg arg(at);
937  he5das_scan_string((const char*) arch_str.c_str());
938  if (he5dasparse(&arg) != 0
939  || false == arg.status()){
940 
941  (*BESLog::TheLog())<< "HDF-EOS5 parse error while processing a "
942  << "ArchiveMetadata " << " HDFEOS attribute" << endl;
943  }
944  he5daslex_destroy();
945  }
946 
947  // XML attribute includes double quote("), this will choke netCDF Java library.
948  // So we replace double_quote(") with &quote.This is currently the OPeNDAP way.
949  // XML attribute cannot parsed. So just pass the string.
950  if(xml_str != ""){
951  AttrTable *at = das.get_table("XMLMetadata");
952  if (NULL == at)
953  at = das.add_table("XMLMetadata", new AttrTable);
954  HDF5CFDAPUtil::replace_double_quote(xml_str);
955  at->append_attr("Contents","String",xml_str);
956  }
957 
958  // SubsetMetadata and ProductMetadata exist in HDF-EOS2 files.
959  // So far we haven't found any metadata in NASA HDF-EOS5 files,
960  // but will keep an eye on it. KY 2012-3-6
961  if(subset_str != ""){
962  AttrTable *at = das.get_table("SubsetMetadata");
963  if (NULL == at)
964  at = das.add_table("SubsetMetadata", new AttrTable);
965  parser_arg arg(at);
966  he5das_scan_string((const char*) subset_str.c_str());
967  if (he5dasparse(&arg) != 0
968  || false == arg.status()) {
969 
970  (*BESLog::TheLog())<< "HDF-EOS5 parse error while processing a "
971  << "SubsetMetadata " << " HDFEOS attribute" << endl;
972  }
973  he5daslex_destroy();
974  }
975  if(product_str != ""){
976  AttrTable *at = das.get_table("ProductMetadata");
977  if (NULL == at)
978  at = das.add_table("ProductMetadata", new AttrTable);
979  parser_arg arg(at);
980  he5das_scan_string((const char*) product_str.c_str());
981  if (he5dasparse(&arg) != 0
982  || false == arg.status()){
983  (*BESLog::TheLog())<< "HDF-EOS5 parse error while processing a "
984  << "ProductMetadata " << " HDFEOS attribute" << endl;
985  }
986  he5daslex_destroy();
987  }
988 
989  // All other metadata under "HDF-EOS Information" will not be
990  // parsed since we don't know how to parse them.
991  // We will simply pass a string to the DAS.
992  if (other_str != ""){
993  AttrTable *at = das.get_table("OtherMetadata");
994  if (NULL == at)
995  at = das.add_table("OtherMetadata", new AttrTable);
996  at->append_attr("Contents","String",other_str);
997  }
998 
999  }
1000  // CHECK ALL UNLIMITED DIMENSIONS from the coordinate variables based on the names.
1001  if(f->HaveUnlimitedDim() == true) {
1002 
1003  AttrTable *at = das.get_table("DODS_EXTRA");
1004  if (NULL == at)
1005  at = das.add_table("DODS_EXTRA", new AttrTable);
1006  string unlimited_names;
1007 
1008  for (it_cv = cvars.begin();
1009  it_cv != cvars.end(); it_cv++) {
1010 #if 0
1011  bool has_unlimited_dim = false;
1012 #endif
1013  // Check unlimited dimension names.
1014  for (vector<Dimension*>::const_iterator ird = (*it_cv)->getDimensions().begin();
1015  ird != (*it_cv)->getDimensions().end(); ++ird) {
1016 
1017  // Currently we only check one unlimited dimension, which is the most
1018  // common case. When receiving the conventions from JG, will add
1019  // the support of multi-unlimited dimension. KY 2016-02-09
1020  if((*ird)->HaveUnlimitedDim() == true) {
1021 
1022  if(unlimited_names=="") {
1023  unlimited_names = (*ird)->getNewName();
1024  at->append_attr("Unlimited_Dimension","String",unlimited_names);
1025  }
1026  else {
1027  if(unlimited_names.rfind((*ird)->getNewName()) == string::npos) {
1028  unlimited_names = unlimited_names+" "+(*ird)->getNewName();
1029  at->append_attr("Unlimited_Dimension","String",(*ird)->getNewName());
1030  }
1031  }
1032  }
1033 
1034  }
1035 
1036 #if 0
1037  //if(true == has_unlimited_dim)
1038  // break;
1039 #endif
1040  }
1041 #if 0
1042  //if(unlimited_names!="")
1043  // at->append_attr("Unlimited_Dimension","String",unlimited_names);
1044 #endif
1045  }
1046 
1047 }
1048 
1049 // Read ECS metadata
1050 void read_ecs_metadata(hid_t s_file_id,
1051  string &total_strmeta_value,
1052  string &total_coremeta_value,
1053  string &total_archmeta_value,
1054  string &total_xmlmeta_value,
1055  string &total_submeta_value,
1056  string &total_prometa_value,
1057  string &total_othermeta_value,
1058  bool s_st_only) {
1059 
1060  BESDEBUG("h5","Coming to read_ecs_metadata() "<<endl);
1061  string ecs_group = "/HDFEOS INFORMATION";
1062  hid_t ecs_grp_id = -1;
1063  if ((ecs_grp_id = H5Gopen(s_file_id, ecs_group.c_str(),H5P_DEFAULT))<0) {
1064  string msg =
1065  "h5_ecs_meta: unable to open the HDF5 group ";
1066  msg +=ecs_group;
1067  throw InternalErr(__FILE__, __LINE__, msg);
1068  }
1069 
1070  H5G_info_t g_info;
1071  hsize_t nelems = 0;
1072 
1073  if (H5Gget_info(ecs_grp_id,&g_info) <0) {
1074  string msg =
1075  "h5_ecs_meta: unable to obtain the HDF5 group info. for ";
1076  msg +=ecs_group;
1077  H5Gclose(ecs_grp_id);
1078  throw InternalErr(__FILE__, __LINE__, msg);
1079  }
1080 
1081  nelems = g_info.nlinks;
1082 
1083  ssize_t oname_size = 0;
1084 #if 0
1085  int cur_archmeta_suffix = 0;
1086  int cur_coremeta_suffix = 0;
1087  int cur_strmeta_suffix = 0;
1088  int cur_xmlmeta_suffix = 0;
1089 #endif
1090 
1091  int archmeta_num = -1;
1092  int coremeta_num = -1;
1093  int xmlmeta_num = -1;
1094  int strmeta_num = -1;
1095  int submeta_num = -1;
1096  int prometa_num = -1;
1097 
1098  // Initalize the total number for different metadata.
1099  int archmeta_num_total = 0;
1100  int coremeta_num_total = 0;
1101  int xmlmeta_num_total = 0;
1102  int strmeta_num_total = 0;
1103  int submeta_num_total = 0;
1104  int prometa_num_total = 0;
1105  int othermeta_num_total = 0;
1106 
1107  bool archmeta_no_suffix = true;
1108  bool coremeta_no_suffix = true;
1109  bool strmeta_no_suffix = true;
1110  bool xmlmeta_no_suffix = true;
1111  bool submeta_no_suffix = true;
1112  bool prometa_no_suffix = true;
1113 
1114  // Define a vector of string to hold all dataset names.
1115  vector<string> s_oname(nelems);
1116 
1117  // Define an EOSMetadata array that can describe the metadata type for each object
1118  // We initialize the value to OtherMeta.
1119  EOS5Metadata metatype[nelems];
1120 
1121  for (unsigned int i =0; i<nelems; i++)
1122  metatype[i] = OtherMeta;
1123 
1124  for (hsize_t i = 0; i < nelems; i++) {
1125 
1126  // Query the length of the object name.
1127  oname_size =
1128  H5Lget_name_by_idx(ecs_grp_id,".",H5_INDEX_NAME,H5_ITER_NATIVE,i,NULL,
1129  0, H5P_DEFAULT);
1130  if (oname_size <= 0) {
1131  string msg = "hdf5 object name error from: ";
1132  msg += ecs_group;
1133  H5Gclose(ecs_grp_id);
1134  throw InternalErr(__FILE__, __LINE__, msg);
1135  }
1136 
1137  // Obtain the name of the object.
1138  vector<char> oname(oname_size + 1);
1139  if (H5Lget_name_by_idx(ecs_grp_id,".",H5_INDEX_NAME,H5_ITER_NATIVE,i,&oname[0],
1140  (size_t)(oname_size+1), H5P_DEFAULT)<0){
1141  string msg = "hdf5 object name error from: ";
1142  msg += ecs_group;
1143  H5Gclose(ecs_grp_id);
1144  throw InternalErr(__FILE__, __LINE__, msg);
1145  }
1146 
1147  // Check if this object is an HDF5 dataset, not, throw an error.
1148  // First, check if it is the hard link or the soft link
1149  H5L_info_t linfo;
1150  if (H5Lget_info(ecs_grp_id,&oname[0],&linfo,H5P_DEFAULT)<0) {
1151  string msg = "hdf5 link name error from: ";
1152  msg += ecs_group;
1153  H5Gclose(ecs_grp_id);
1154  throw InternalErr(__FILE__, __LINE__, msg);
1155  }
1156 
1157  // This is the soft link.
1158  if (linfo.type == H5L_TYPE_SOFT){
1159  string msg = "hdf5 link name error from: ";
1160  msg += ecs_group;
1161  H5Gclose(ecs_grp_id);
1162  throw InternalErr(__FILE__, __LINE__, msg);
1163  }
1164 
1165  // Obtain the object type
1166  H5O_info_t oinfo;
1167  if (H5Oget_info_by_idx(ecs_grp_id, ".", H5_INDEX_NAME, H5_ITER_NATIVE,
1168  i, &oinfo, H5P_DEFAULT)<0) {
1169  string msg = "Cannot obtain the object info ";
1170  msg += ecs_group;
1171  H5Gclose(ecs_grp_id);
1172  throw InternalErr(__FILE__, __LINE__, msg);
1173  }
1174 
1175  if(oinfo.type != H5O_TYPE_DATASET) {
1176  string msg = "hdf5 link name error from: ";
1177  msg += ecs_group;
1178  H5Gclose(ecs_grp_id);
1179  throw InternalErr(__FILE__, __LINE__, msg);
1180  }
1181 
1182  // We want to remove the last '\0' character added by C .
1183  string s_one_oname(oname.begin(),oname.end()-1);
1184  s_oname[i] = s_one_oname;
1185 
1186  // Calculate how many elements we have for each category(StructMetadata, CoreMetadata, etc.)
1187  if (((s_one_oname.find("StructMetadata"))==0) ||
1188  ((s_one_oname.find("structmetadata"))==0)){
1189 
1190  metatype[i] = StructMeta;
1191 
1192  // Do we have suffix for the metadata?
1193  // If this metadata doesn't have any suffix, it should only come to this loop once.
1194  // That's why, when checking the first time, no_suffix is always true.
1195  // If we have already found that it doesn't have any suffix,
1196  // it should not go into this loop. throw an error.
1197  if (false == strmeta_no_suffix) {
1198  string msg = "StructMetadata/structmetadata without suffix should only appear once. ";
1199  H5Gclose(ecs_grp_id);
1200  throw InternalErr(__FILE__, __LINE__, msg);
1201  }
1202 
1203  else if(strmeta_num_total >0)
1204  strmeta_num_total++;
1205  else { // either no suffix or the first time to loop the one having the suffix.
1206  if ((0 == s_one_oname.compare("StructMetadata"))||
1207  (0 == s_one_oname.compare("structmetadata")))
1208  strmeta_no_suffix = false;
1209  else strmeta_num_total++;
1210  }
1211 #if 0
1212 "h5","strmeta_num_total= "<<strmeta_num_total <<endl;
1213 if(strmeta_no_suffix) "h5","structmeta data has the suffix" <<endl;
1214 else "h5","structmeta data doesn't have the suffix" <<endl;
1215 #endif
1216  }
1217 
1218  if(false == s_st_only) {
1219 
1220  if ((0 == (s_one_oname.find("CoreMetadata"))) ||
1221  (0 == (s_one_oname.find("coremetadata")))){
1222 
1223  metatype[i] = CoreMeta;
1224 
1225  // Do we have suffix for the metadata?
1226  // When checking the first time, no_suffix is always true.
1227  // If we have already found that it doesn't have any suffix,
1228  // it should not go into this loop anyway. throw an error.
1229  if (false == coremeta_no_suffix) {
1230  string msg = "CoreMetadata/coremetadata without suffix should only appear once. ";
1231  H5Gclose(ecs_grp_id);
1232  throw InternalErr(__FILE__, __LINE__, msg);
1233  }
1234 
1235  else if(coremeta_num_total >0)
1236  coremeta_num_total++;
1237  else { // either no suffix or the first time to loop the one having the suffix.
1238  // If no suffix is true, it should be out of the loop. In case it comes
1239  // to the loop again, we set "coremeta_no_suffix" be false so an error
1240  // can be thrown. This is counter-intutitive. Hopefully people can understand it.
1241  if ((0 == s_one_oname.compare("CoreMetadata")) ||
1242  (0 == s_one_oname.compare("coremetadata")))
1243  coremeta_no_suffix = false;
1244  else coremeta_num_total++;
1245  }
1246 #if 0
1247 "h5","coremeta_num_total= "<<coremeta_num_total <<endl;
1248 if(coremeta_no_suffix) "h5","coreuctmeta data has the suffix" <<endl;
1249 else "h5","coremeta data doesn't have the suffix" <<endl;
1250 #endif
1251  }
1252 
1253  // OMI has the metadata name as "ArchiveMetadata.0"
1254  else if ((0 == (s_one_oname.find("ArchivedMetadata"))) ||
1255  (0 == (s_one_oname.find("archivedmetadata"))) ||
1256  (0 == (s_one_oname.find("ArchiveMetadata"))) ||
1257  (0 == (s_one_oname.find("archivemetadata")))){
1258 
1259  metatype[i] = ArchivedMeta;
1260  // Do we have suffix for the metadata?
1261  // When checking the first time, no_suffix is always true.
1262  // If we have already found that it doesn't have any suffix,
1263  // it should not go into this loop anyway. throw an error.
1264  if (false == archmeta_no_suffix) {
1265  string msg = "archivedmetadata/ArchivedMetadata without suffix should only appear once. ";
1266  H5Gclose(ecs_grp_id);
1267  throw InternalErr(__FILE__, __LINE__, msg);
1268  }
1269 
1270  else if(archmeta_num_total >0)
1271  archmeta_num_total++;
1272  else { // either no suffix or the first time to loop the one having the suffix.
1273  if ((0 == s_one_oname.compare("ArchivedMetadata"))||
1274  (0 == s_one_oname.compare("archivedmetadata")) ||
1275  (0 == s_one_oname.compare("archivemetadata")) ||
1276  (0 == s_one_oname.compare("ArchiveMetadata")))
1277  archmeta_no_suffix = false;
1278  else
1279  archmeta_num_total++;
1280  }
1281 #if 0
1282 "h5","archmeta_num_total= "<<archmeta_num_total <<endl;
1283 if(archmeta_no_suffix) "h5","archuctmeta data has the suffix" <<endl;
1284 else "h5","archmeta data doesn't have the suffix" <<endl;
1285 #endif
1286 
1287  }
1288 
1289  else if (((s_one_oname.find("SubsetMetadata"))==0) ||
1290  ((s_one_oname.find("subsetmetadata"))==0)){
1291 
1292  metatype[i] = SubsetMeta;
1293  // Do we have suffix for the metadata?
1294  // When checking the first time, no_suffix is always true.
1295  // If we have already found that it doesn't have any suffix,
1296  // it should not go into this loop anyway. throw an error.
1297  if (false == submeta_no_suffix) {
1298  H5Gclose(ecs_grp_id);
1299  string msg = "submetadata/SubMetadata without suffix should only appear once. ";
1300  throw InternalErr(__FILE__, __LINE__, msg);
1301  }
1302 
1303  else if(submeta_num_total >0)
1304  submeta_num_total++;
1305  else { // either no suffix or the first time to loop the one having the suffix.
1306  if ((0 == s_one_oname.compare("SubsetMetadata"))||
1307  (0 == s_one_oname.compare("subsetmetadata")))
1308  submeta_no_suffix = false;
1309  else submeta_num_total++;
1310  }
1311 #if 0
1312 "h5","submeta_num_total= "<<submeta_num_total <<endl;
1313 if(submeta_no_suffix) "h5","subuctmeta data has the suffix" <<endl;
1314 else "h5","submeta data doesn't have the suffix" <<endl;
1315 #endif
1316 
1317  }
1318 
1319  else if ((0 == (s_one_oname.find("XmlMetadata"))) ||
1320  (0 == (s_one_oname.find("xmlmetadata")))){
1321 
1322  metatype[i] = XMLMeta;
1323 
1324  // Do we have suffix for the metadata?
1325  // When checking the first time, no_suffix is always true.
1326  // If we have already found that it doesn't have any suffix,
1327  // it should not go into this loop anyway. throw an error.
1328  if (false == xmlmeta_no_suffix) {
1329  H5Gclose(ecs_grp_id);
1330  string msg = "xmlmetadata/Xmlmetadata without suffix should only appear once. ";
1331  throw InternalErr(__FILE__, __LINE__, msg);
1332  }
1333 
1334  else if(xmlmeta_num_total >0)
1335  xmlmeta_num_total++;
1336  else { // either no suffix or the first time to loop the one having the suffix.
1337  if ((0 == s_one_oname.compare("XmlMetadata"))||
1338  (0 == s_one_oname.compare("xmlmetadata")))
1339  xmlmeta_no_suffix = false;
1340  else xmlmeta_num_total++;
1341  }
1342 #if 0
1343 "h5","xmlmeta_num_total= "<<xmlmeta_num_total <<endl;
1344 if(xmlmeta_no_suffix) "h5","xmluctmeta data doesn't have the suffix" <<endl;
1345 else "h5","xmlmeta data has the suffix" <<endl;
1346 #endif
1347 
1348  }
1349 
1350  else if ((0 == (s_one_oname.find("ProductMetadata"))) ||
1351  (0 == (s_one_oname.find("productmetadata")))){
1352 
1353  metatype[i] = ProductMeta;
1354  // Do we have suffix for the metadata?
1355  // When checking the first time, no_suffix is always true.
1356  // If we have already found that it doesn't have any suffix,
1357  // it should not go into this loop anyway. throw an error.
1358  if (!prometa_no_suffix) {
1359  H5Gclose(ecs_grp_id);
1360  string msg = "productmetadata/ProductMetadata without suffix should only appear once. ";
1361  throw InternalErr(__FILE__, __LINE__, msg);
1362  }
1363 
1364  else if(prometa_num_total >0) prometa_num_total++;
1365  else { // either no suffix or the first time to loop the one having the suffix.
1366  if ((0 == s_one_oname.compare("ProductMetadata"))||
1367  (0 == s_one_oname.compare("productmetadata")))
1368  prometa_no_suffix = false;
1369  else prometa_num_total++;
1370  }
1371 
1372  }
1373 
1374  // All other metadata will be merged to one string, no need to check the name.
1375  else othermeta_num_total++;
1376  }
1377 
1378  oname.clear();
1379  s_one_oname.clear();
1380  }
1381 
1382  // Define a vector of string to hold StructMetadata.
1383  // StructMetadata must exist for a valid HDF-EOS5 file.
1384  vector<string> strmeta_value;
1385  if (strmeta_num_total <= 0) {
1386  string msg = "hdf5 object name error from: ";
1387  H5Gclose(ecs_grp_id);
1388  throw InternalErr(__FILE__, __LINE__, msg);
1389  }
1390  else {
1391  strmeta_value.resize(strmeta_num_total);
1392  for (int i = 0; i < strmeta_num_total; i++)
1393  strmeta_value[i]="";
1394  }
1395 
1396  // All other metadata are optional.
1397  // Define a vector of string to hold archivedmetadata.
1398  vector<string> archmeta_value;
1399  if (archmeta_num_total >0) {
1400  archmeta_value.resize(archmeta_num_total);
1401  for (int i = 0; i < archmeta_num_total; i++)
1402  archmeta_value[i]="";
1403  }
1404 
1405  // Define a vector of string to hold coremetadata.
1406  vector<string> coremeta_value;
1407  if (coremeta_num_total >0) {
1408  coremeta_value.resize(coremeta_num_total);
1409  for (int i = 0; i < coremeta_num_total; i++)
1410  coremeta_value[i]="";
1411  }
1412 
1413  // Define a vector of string to hold xmlmetadata.
1414  vector<string> xmlmeta_value;
1415  if (xmlmeta_num_total >0) {
1416  xmlmeta_value.resize(xmlmeta_num_total);
1417  for (int i = 0; i < xmlmeta_num_total; i++)
1418  xmlmeta_value[i]="";
1419  }
1420 
1421  // Define a vector of string to hold subsetmetadata.
1422  vector<string> submeta_value;
1423  if (submeta_num_total >0) {
1424  submeta_value.resize(submeta_num_total);
1425  for (int i = 0; i < submeta_num_total; i++)
1426  submeta_value[i]="";
1427  }
1428 
1429  // Define a vector of string to hold productmetadata.
1430  vector<string> prometa_value;
1431  if (prometa_num_total >0) {
1432  prometa_value.resize(prometa_num_total);
1433  for (int i = 0; i < prometa_num_total; i++)
1434  prometa_value[i]="";
1435  }
1436 
1437  // For all other metadata, we don't need to calculate the value, just append them.
1438 
1439  // Now we want to retrieve the metadata value and combine them into one string.
1440  // Here we have to remember the location of every element of the metadata if
1441  // this metadata has a suffix.
1442  for (hsize_t i = 0; i < nelems; i++) {
1443 
1444  // DDS parser only needs to parse the struct Metadata. So check
1445  // if st_only flag is true, will only read StructMetadata string.
1446  // Struct Metadata is generated by the HDF-EOS5 library, so the
1447  // name "StructMetadata.??" won't change for real struct metadata.
1448  //However, we still assume that somebody may not use the HDF-EOS5
1449  // library to add StructMetadata, the name may be "structmetadata".
1450  if (true == s_st_only &&
1451  (((s_oname[i].find("StructMetadata"))!=0) &&
1452  ((s_oname[i].find("structmetadata"))!=0))){
1453  continue;
1454  }
1455 
1456  // Open the dataset, dataspace, datatype, number of elements etc. for this metadata
1457  hid_t s_dset_id = -1;
1458  hid_t s_space_id = -1;
1459  hid_t s_ty_id = -1;
1460  hssize_t s_nelms = -1;
1461  size_t dtype_size = -1;
1462 
1463  if ((s_dset_id = H5Dopen(ecs_grp_id,s_oname[i].c_str(),H5P_DEFAULT))<0){
1464  string msg = "Cannot open HDF5 dataset ";
1465  msg += s_oname[i];
1466  H5Gclose(ecs_grp_id);
1467  throw InternalErr(__FILE__, __LINE__, msg);
1468  }
1469 
1470  if ((s_space_id = H5Dget_space(s_dset_id))<0) {
1471  string msg = "Cannot open the data space of HDF5 dataset ";
1472  msg += s_oname[i];
1473  H5Dclose(s_dset_id);
1474  H5Gclose(ecs_grp_id);
1475  throw InternalErr(__FILE__, __LINE__, msg);
1476  }
1477 
1478  if ((s_ty_id = H5Dget_type(s_dset_id)) < 0) {
1479  string msg = "Cannot get the data type of HDF5 dataset ";
1480  msg += s_oname[i];
1481  H5Sclose(s_space_id);
1482  H5Dclose(s_dset_id);
1483  H5Gclose(ecs_grp_id);
1484  throw InternalErr(__FILE__, __LINE__, msg);
1485  }
1486  if ((s_nelms = H5Sget_simple_extent_npoints(s_space_id))<0) {
1487  string msg = "Cannot get the number of points of HDF5 dataset ";
1488  msg += s_oname[i];
1489  H5Tclose(s_ty_id);
1490  H5Sclose(s_space_id);
1491  H5Dclose(s_dset_id);
1492  H5Gclose(ecs_grp_id);
1493  throw InternalErr(__FILE__, __LINE__, msg);
1494  }
1495  if ((dtype_size = H5Tget_size(s_ty_id))==0) {
1496 
1497  string msg = "Cannot get the data type size of HDF5 dataset ";
1498  msg += s_oname[i];
1499  H5Tclose(s_ty_id);
1500  H5Sclose(s_space_id);
1501  H5Dclose(s_dset_id);
1502  H5Gclose(ecs_grp_id);
1503  throw InternalErr(__FILE__, __LINE__, msg);
1504  }
1505 
1506  // Obtain the real value of the metadata
1507  vector<char> s_buf(dtype_size*s_nelms +1);
1508 
1509  if ((H5Dread(s_dset_id,s_ty_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,&s_buf[0]))<0) {
1510 
1511  string msg = "Cannot read HDF5 dataset ";
1512  msg += s_oname[i];
1513  H5Tclose(s_ty_id);
1514  H5Sclose(s_space_id);
1515  H5Dclose(s_dset_id);
1516  H5Gclose(ecs_grp_id);
1517  throw InternalErr(__FILE__, __LINE__, msg);
1518  }
1519 
1520  // Now we can safely close datatype, data space and dataset IDs.
1521  H5Tclose(s_ty_id);
1522  H5Sclose(s_space_id);
1523  H5Dclose(s_dset_id);
1524 
1525 
1526  // Convert from the vector<char> to a C++ string.
1527  string tempstr(s_buf.begin(),s_buf.end());
1528  s_buf.clear();
1529  size_t temp_null_pos = tempstr.find_first_of('\0');
1530 
1531  // temp_null_pos returns the position of NULL,which is the last character of the string.
1532  // so the length of string before null is EQUAL to
1533  // temp_null_pos since pos starts at 0.
1534  string finstr = tempstr.substr(0,temp_null_pos);
1535 
1536  // For the DDS parser, only return StructMetadata
1537  if (StructMeta == metatype[i]) {
1538 
1539  // Now obtain the corresponding value in integer type for the suffix. '0' to 0 etc.
1540  try {
1541  strmeta_num = get_metadata_num(s_oname[i]);
1542  }
1543  catch(...) {
1544  H5Gclose(ecs_grp_id);
1545  throw InternalErr(__FILE__,__LINE__,"Obtain structmetadata suffix error.");
1546 
1547  }
1548  // This is probably not necessary, since structmetadata may always have a suffix.
1549  // Leave here just in case the rules change or a special non-HDF-EOS5 library generated file.
1550  // when strmeta_num is -1, it means no suffix for this metadata. So the total structmetadata
1551  // is this string only.
1552  if (-1 == strmeta_num)
1553  total_strmeta_value = finstr;
1554  // strmeta_value at this point should be empty before assigning any values.
1555  else if (strmeta_value[strmeta_num]!="") {
1556  string msg = "The structmeta value array at this index should be empty string ";
1557  H5Gclose(ecs_grp_id);
1558  throw InternalErr(__FILE__, __LINE__, msg);
1559  }
1560  // assign the string vector to this value.
1561  else
1562  strmeta_value[strmeta_num] = finstr;
1563  }
1564 
1565  // DAS parser needs all metadata.
1566  if (false == s_st_only &&
1567  (metatype[i] != StructMeta)) {
1568 
1569  switch (metatype[i]) {
1570 
1571  case CoreMeta:
1572  {
1573  if (coremeta_num_total < 0) {
1574  string msg = "There may be no coremetadata or coremetadata is not counted ";
1575  H5Gclose(ecs_grp_id);
1576  throw InternalErr(__FILE__, __LINE__, msg);
1577 
1578  }
1579 
1580  try {
1581  coremeta_num = get_metadata_num(s_oname[i]);
1582  }
1583  catch(...) {
1584  H5Gclose(ecs_grp_id);
1585  throw InternalErr(__FILE__,__LINE__,"Obtain coremetadata suffix error.");
1586 
1587  }
1588 
1589  // when coremeta_num is -1, it means no suffix for this metadata. So the total coremetadata
1590  // is this string only. Similar cases apply for the rest metadata.
1591  if ( -1 == coremeta_num )
1592  total_coremeta_value = finstr;
1593  else if (coremeta_value[coremeta_num]!="") {
1594  string msg = "The coremeta value array at this index should be empty string ";
1595  H5Gclose(ecs_grp_id);
1596  throw InternalErr(__FILE__, __LINE__, msg);
1597  }
1598 
1599  // assign the string vector to this value.
1600  else
1601  coremeta_value[coremeta_num] = finstr;
1602  }
1603  break;
1604 
1605  case ArchivedMeta:
1606  {
1607  if (archmeta_num_total < 0) {
1608  string msg = "There may be no archivemetadata or archivemetadata is not counted ";
1609  H5Gclose(ecs_grp_id);
1610  throw InternalErr(__FILE__, __LINE__, msg);
1611  }
1612  try {
1613  archmeta_num = get_metadata_num(s_oname[i]);
1614  }
1615  catch(...) {
1616  H5Gclose(ecs_grp_id);
1617  throw InternalErr(__FILE__,__LINE__,"Obtain archivemetadata suffix error.");
1618  }
1619  if (-1 == archmeta_num )
1620  total_archmeta_value = finstr;
1621  else if (archmeta_value[archmeta_num]!="") {
1622  string msg = "The archivemeta value array at this index should be empty string ";
1623  H5Gclose(ecs_grp_id);
1624  throw InternalErr(__FILE__, __LINE__, msg);
1625 
1626  }
1627  // assign the string vector to this value.
1628  else
1629  archmeta_value[archmeta_num] = finstr;
1630  }
1631  break;
1632  case SubsetMeta:
1633  {
1634  if (submeta_num_total < 0) {
1635  string msg = "The subsetemeta value array at this index should be empty string ";
1636  H5Gclose(ecs_grp_id);
1637  throw InternalErr(__FILE__, __LINE__, msg);
1638  }
1639  try {
1640  submeta_num = get_metadata_num(s_oname[i]);
1641  }
1642  catch(...) {
1643  H5Gclose(ecs_grp_id);
1644  throw InternalErr(__FILE__,__LINE__,"Obtain subsetmetadata suffix error.");
1645  }
1646  if (-1 == submeta_num )
1647  total_submeta_value = finstr;
1648  else if (submeta_value[submeta_num]!="") {
1649  string msg = "The submeta value array at this index should be empty string ";
1650  H5Gclose(ecs_grp_id);
1651  throw InternalErr(__FILE__, __LINE__, msg);
1652  }
1653  // assign the string vector to this value.
1654  else
1655  submeta_value[submeta_num] = finstr;
1656  }
1657  break;
1658  case ProductMeta:
1659  {
1660  if (prometa_num_total < 0) {
1661  string msg = "There may be no productmetadata or productmetadata is not counted ";
1662  H5Gclose(ecs_grp_id);
1663  throw InternalErr(__FILE__, __LINE__, msg);
1664  }
1665  try {
1666  prometa_num = get_metadata_num(s_oname[i]);
1667  }
1668  catch(...) {
1669  H5Gclose(ecs_grp_id);
1670  throw InternalErr(__FILE__,__LINE__,"Obtain productmetadata suffix error.");
1671  }
1672  if (prometa_num == -1)
1673  total_prometa_value = finstr;
1674  else if (prometa_value[prometa_num]!="") {
1675  string msg = "The productmeta value array at this index should be empty string ";
1676  H5Gclose(ecs_grp_id);
1677  throw InternalErr(__FILE__, __LINE__, msg);
1678  }
1679  // assign the string vector to this value.
1680  else
1681  prometa_value[prometa_num] = finstr;
1682  }
1683  break;
1684  case XMLMeta:
1685  {
1686  if (xmlmeta_num_total < 0) {
1687  string msg = "There may be no xmlmetadata or xmlmetadata is not counted ";
1688  H5Gclose(ecs_grp_id);
1689  throw InternalErr(__FILE__, __LINE__, msg);
1690  }
1691  try {
1692  xmlmeta_num = get_metadata_num(s_oname[i]);
1693  }
1694  catch(...) {
1695  H5Gclose(ecs_grp_id);
1696  throw InternalErr(__FILE__,__LINE__,"Obtain XMLmetadata suffix error.");
1697  }
1698  if (-1 == xmlmeta_num )
1699  total_xmlmeta_value = finstr;
1700  else if (xmlmeta_value[xmlmeta_num]!="") {
1701  string msg = "The xmlmeta value array at this index should be empty string ";
1702  H5Gclose(ecs_grp_id);
1703  throw InternalErr(__FILE__, __LINE__, msg);
1704  }
1705  // assign the string vector to this value.
1706  else
1707  xmlmeta_value[xmlmeta_num] = finstr;
1708  }
1709  break;
1710  case OtherMeta:
1711  {
1712  if (othermeta_num_total < 0) {
1713  string msg = "There may be no othermetadata or other metadata is not counted ";
1714  H5Gclose(ecs_grp_id);
1715  throw InternalErr(__FILE__, __LINE__, msg);
1716  }
1717  total_othermeta_value = total_othermeta_value + finstr;
1718  }
1719  break;
1720  default :
1721  {
1722  string msg = "Unsupported metadata type ";
1723  H5Gclose(ecs_grp_id);
1724  throw InternalErr(__FILE__, __LINE__, msg);
1725  }
1726  }
1727  }
1728  tempstr.clear();
1729  finstr.clear();
1730  }
1731 
1732  // Now we need to handle the concatenation of the metadata
1733  // first StructMetadata
1734  if (strmeta_num_total > 0) {
1735  // The no suffix one has been taken care.
1736  if (strmeta_num != -1) {
1737  for (int i = 0; i <strmeta_num_total; i++)
1738  total_strmeta_value +=strmeta_value[i];
1739  }
1740  }
1741 
1742  // For the DAS handler
1743  if ( false == s_st_only) {
1744 
1745  if (coremeta_num_total >0) {
1746  if (coremeta_num != -1) {
1747  for(int i = 0; i <coremeta_num_total; i++)
1748  total_coremeta_value +=coremeta_value[i];
1749  }
1750  }
1751 
1752  if (archmeta_num_total >0) {
1753  if (archmeta_num != -1) {
1754  for(int i = 0; i <archmeta_num_total; i++)
1755  total_archmeta_value +=archmeta_value[i];
1756  }
1757  }
1758 
1759  if (submeta_num_total >0) {
1760  if (submeta_num != -1) {
1761  for(int i = 0; i <submeta_num_total; i++)
1762  total_submeta_value +=submeta_value[i];
1763  }
1764  }
1765 
1766  if (xmlmeta_num_total >0) {
1767  if (xmlmeta_num != -1) {
1768  for(int i = 0; i <xmlmeta_num_total; i++)
1769  total_xmlmeta_value +=xmlmeta_value[i];
1770  }
1771  }
1772 
1773  if (prometa_num_total >0) {
1774  if (prometa_num != -1) {
1775  for(int i = 0; i <prometa_num_total; i++)
1776  total_prometa_value +=prometa_value[i];
1777  }
1778  }
1779  }
1780  H5Gclose(ecs_grp_id);
1781 }
1782 
1783 // Helper function for read_ecs_metadata. Get the number after metadata.
1784 int get_metadata_num(const string & meta_str) {
1785 
1786  // The normal metadata names should be like coremetadata.0, coremetadata.1 etc.
1787  // We just find a not so nice coremetadata names such as coremetadata.0, coremetadata.0.1 for a HIRDLS-MLS-Aura-L3
1788  // We need to handle them. Here we assume no more than two dots in a name series. KY 2012-11-08
1789  size_t dot_pos = meta_str.find(".");
1790  if (dot_pos == string::npos) // No dot
1791  return -1;
1792  else if (meta_str.find_first_of(".") == meta_str.find_last_of(".")) { // One dot
1793  string num_str = meta_str.substr(dot_pos+1);
1794  stringstream ssnum(num_str);
1795  int num;
1796  ssnum >> num;
1797  if (ssnum.fail())
1798  throw InternalErr(__FILE__,__LINE__,"Suffix after dots is not a number.");
1799  return num;
1800  }
1801  else { // Two dots
1802  string str_after_first_dot = meta_str.substr(dot_pos+1);
1803  if (str_after_first_dot.find_first_of(".") != str_after_first_dot.find_last_of("."))
1804  throw InternalErr(__FILE__,__LINE__,"Currently don't support metadata names containing more than two dots.");
1805  // Here we don't check if names are like coremetadata.0 coremetadata.0.0 etc., Having ".0 .0.0" is,if not mistaken,
1806  // is insane.
1807  // Instead we hope that the data producers will produce data like coremetadata.0 coremetadata.0.1 coremeatadata.0.2
1808  // KY 2012-11-08
1809  size_t second_dot_pos = str_after_first_dot.find(".");
1810  string num_str = str_after_first_dot.substr(second_dot_pos+1);
1811  stringstream ssnum(num_str);
1812  int num;
1813  ssnum >> num;
1814  return num;
1815  }
1816 
1817 }
1818 
1819 
1820 
1821 
1822 
heos5cfdap.h
Map and generate DDS and DAS for the CF option for HDF-EOS5 products.
HDF5CF::EOS5File::Handle_Unsupported_Others
void Handle_Unsupported_Others(bool)
Handle other unmapped objects/attributes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:356
HDFEOS5CFSpecialCVArray.h
This class specifies the retrieval of special coordinate variable values for HDF-EOS5 products.
HDF5CF::File::getGroups
const std::vector< Group * > & getGroups() const
Public interface to obtain all the group info.
Definition: HDF5CF.h:670
HDF5CFStr.h
This class provides a way to map HDF5 Str to DAP Str for the CF option.
HDF5CF::EOS5File::getCVars
const std::vector< EOS5CVar * > & getCVars() const
Obtain coordinate variables for HDF-EOS5 products.
Definition: HDF5CF.h:1183
HDF5CF::Var::getRank
int getRank() const
Get the dimension rank of this variable.
Definition: HDF5CF.h:295
HDF5CF::EOS5File::Handle_Unsupported_Dtype
void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:204
HDF5CF::EOS5File::Adjust_EOS5Dim_Info
void Adjust_EOS5Dim_Info(HE5Parser *strmeta_info)
Adjust HDF-EOS5 dimension information.
Definition: HDFEOS5CF.cc:535
HE5Checker
Definition: HE5Checker.h:41
HDF5CFInt16.h
This class provides a way to map HDF5 int16 to DAP int16 for the CF option.
HDF5CFUInt32.h
This class provides a way to map HDF5 unsigned 32-bit integer to DAP uint32 for the CF option.
HDF5CF::EOS5File::Adjust_Dim_Name
void Adjust_Dim_Name()
Adjust the dimension name for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3636
HDF5CF::File::getAttributes
const std::vector< Attribute * > & getAttributes() const
Public interface to obtain information of all attributes under the root group.
Definition: HDF5CF.h:664
HE5Parser.h
A class for parsing NASA HDF-EOS5 StructMetadata.
HDF5CF::EOS5File::Check_Aura_Product_Status
void Check_Aura_Product_Status()
Check if the HDF-EOS5 file is an Aura file. Special CF operations need to be used.
Definition: HDFEOS5CF.cc:1712
HDF5CF::EOS5CVar
This class is a derived class of CVar. It represents a coordinate variable for HDF-EOS5 files.
Definition: HDF5CF.h:438
HDF5CFByte
Definition: HDF5CFByte.h:43
HDF5CF::File::getFileID
hid_t getFileID() const
Obtain the HDF5 file ID.
Definition: HDF5CF.h:646
HE5Checker.h
A class for parsing NASA HDF-EOS5 StructMetadata.
HDF5CF::Var::getType
H5DataType getType() const
Get the data type of this variable(Not HDF5 datatype id)
Definition: HDF5CF.h:301
HDF5CF::EOS5File::Adjust_Var_Dim_NewName_Before_Flattening
void Adjust_Var_Dim_NewName_Before_Flattening()
Adjust variable dimension names before the flattening for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:3030
HDF5CF::EOS5File::Handle_CVar
void Handle_CVar()
Handle coordinate variable for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:1764
HDF5CF::EOS5File::Add_Dim_Name
void Add_Dim_Name(HE5Parser *)
Add the dimension name for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:1316
HDF5CF::EOS5File::Handle_SpVar
void Handle_SpVar()
Handle special variables for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:3965
HDF5CFUInt16.h
This class provides a way to map HDF5 unsigned 16-bit integer to DAP uint16 for the CF option.
HDF5CF::Var::getNewName
const std::string & getNewName() const
Get the new name of this variable.
Definition: HDF5CF.h:277
HDF5CF::File::HaveUnlimitedDim
bool HaveUnlimitedDim() const
Has unlimited dimensions.
Definition: HDF5CF.h:676
HDFEOS5CFMissNonLLCVArray.h
This class specifies the retrieval of the missing lat/lon values for HDFEOS5 products.
HDF5CFFloat64
Definition: HDF5CFFloat64.h:41
HDF5CFInt16
Definition: HDF5CFInt16.h:40
HDF5CFByte.h
This class provides a way to map HDF5 byte to DAP byte for the CF option.
HDF5CFFloat32
Definition: HDF5CFFloat32.h:42
HDF5CFUInt32
Definition: HDF5CFUInt32.h:42
HDF5CF::EOS5File::Handle_Obj_NameClashing
void Handle_Obj_NameClashing(bool)
Handle the object name clashing for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3230
HDF5CF::EOS5File::Adjust_Var_NewName_After_Parsing
void Adjust_Var_NewName_After_Parsing()
Adjust variable names for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:1224
HDFEOS5CFMissLLArray
Definition: HDFEOS5CFMissLLArray.h:45
HDF5CF::Var::getName
const std::string & getName() const
Get the original name of this variable.
Definition: HDF5CF.h:271
HDF5RequestHandler.h
include the entry functions to execute the handlers
HDF5CFArray.h
This class includes the methods to read data array into DAP buffer from an HDF5 dataset for the CF op...
HDF5CF::EOS5File::Set_COARDS_Status
void Set_COARDS_Status()
Set COARDS flag.
Definition: HDFEOS5CF.cc:3380
HDF5CF::EOS5File::Get_IgnoredInfo_Flag
bool Get_IgnoredInfo_Flag()
Obtain the flag to see if ignored objects should be generated.
Definition: HDF5CF.h:1266
HDFEOS5CFSpecialCVArray
Definition: HDFEOS5CFSpecialCVArray.h:44
HDF5CFInt32
Definition: HDF5CFInt32.h:41
HDF5CF::EOS5File::Adjust_Attr_Info
void Adjust_Attr_Info()
Adjust the attribute info for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3403
HDFEOS5CFMissLLArray.h
This class specifies the retrieval of the missing lat/lon values for HDF-EOS5 products.
HDF5CF::EOS5File::Handle_DimNameClashing
void Handle_DimNameClashing()
Definition: HDFEOS5CF.cc:3315
HDF5CF::CVar::getCVType
CVType getCVType() const
Get the coordinate variable type of this variable.
Definition: HDF5CF.h:360
HE5Parser
Definition: HE5Parser.h:49
h5cfdaputil.h
Helper functions for generating DAS attributes and a function to check BES Key.
HDF5CF::Var::getCompRatio
int getCompRatio() const
Get the compression ratio of this dataset.
Definition: HDF5CF.h:318
HDF5CFInt32.h
This class provides a way to map HDF5 32-bit integer to DAP Int32 for the CF option.
HDF5CF::EOS5File
This class is a derived class of File. It includes methods applied to HDF-EOS5 files only.
Definition: HDF5CF.h:1171
HDF5CF::EOS5File::Handle_Unsupported_Dspace
void Handle_Unsupported_Dspace(bool)
Handle unsupported HDF5 dataspaces for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:297
HDF5CF::EOS5File::Retrieve_H5_CVar_Supported_Attr_Values
void Retrieve_H5_CVar_Supported_Attr_Values()
Retrieve coordinate variable attributes.
Definition: HDFEOS5CF.cc:166
HDF5CFArray
Definition: HDF5CFArray.h:47
HDF5CF::File::getVars
const std::vector< Var * > & getVars() const
Public interface to obtain information of all variables.
Definition: HDF5CF.h:658
HDF5CF::EOS5File::Adjust_Obj_Name
void Adjust_Obj_Name()
This method is a no-op operation. Leave here since the method in the base class is pure virtual.
Definition: HDFEOS5CF.cc:4123
HDF5CFFloat64.h
This class provides a way to map HDF5 64-bit floating-point(double) to DAP 64-bit floating-point for ...
HDF5CF::EOS5File::Retrieve_H5_Supported_Attr_Values
void Retrieve_H5_Supported_Attr_Values()
Retrieve attribute values for the supported HDF5 datatypes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:182
HDFEOS5CFMissNonLLCVArray
Definition: HDFEOS5CFMissNonLLCVArray.h:44
HDF5CFFloat32.h
This class provides a way to map HDF5 float to DAP float for the CF option.
HDF5CF::EOS5File::Get_Ignored_Msg
const std::string & Get_Ignored_Msg()
Obtain the message that contains the ignored object info.
Definition: HDF5CF.h:1271
HDF5CF::EOS5File::Handle_Coor_Attr
void Handle_Coor_Attr()
Handle the coordinates attribute for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3751
HDF5CF::EOS5File::Handle_SpVar_Attr
void Handle_SpVar_Attr()
Handle special variables for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:4087
HDF5CF::Exception
Definition: HDF5CF.h:70
HDF5CF::EOS5File::Retrieve_H5_Info
void Retrieve_H5_Info(const char *path, hid_t file_id, bool include_attr)
Retrieve DDS information from the HDF5 file; a real implementation for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:159
HDF5CF::File::getPath
const std::string & getPath() const
Obtain the path of the file.
Definition: HDF5CF.h:652
HDF5CFUInt16
Definition: HDF5CFUInt16.h:40
HDF5CF::Var::getDimensions
const std::vector< Dimension * > & getDimensions() const
Get the list of the dimensions.
Definition: HDF5CF.h:312
HDF5CF::EOS5File::Add_EOS5File_Info
void Add_EOS5File_Info(HE5Parser *, bool)
Add HDF-EOS5 dimension and coordinate variable related info. to EOS5Grid,EOS5Swath etc.
Definition: HDFEOS5CF.cc:837
HDF5CF::EOS5File::Flatten_Obj_Name
void Flatten_Obj_Name(bool include_attr)
Flatten the object name for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:3208
he5das_scan_string
yy_buffer_state * he5das_scan_string(const char *str)
Buffer state for NASA EOS metadata scanner.
HDF5CF::EOS5File::Add_Supplement_Attrs
void Add_Supplement_Attrs(bool)
Add the supplemental attributes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3666
HDF5CF::Var::getFullPath
const std::string & getFullPath() const
Get the full path of this variable.
Definition: HDF5CF.h:283