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