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 
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:360
This class is a derived class of CVar. It represents a coordinate variable for HDF-EOS5 files.
Definition: HDF5CF.h:438
This class is a derived class of File. It includes methods applied to HDF-EOS5 files only.
Definition: HDF5CF.h:1171
void Add_EOS5File_Info(HE5Parser *, bool)
Add HDF-EOS5 dimension and coordinate variable related info. to EOS5Grid,EOS5Swath etc.
Definition: HDFEOS5CF.cc:837
void Set_COARDS_Status()
Set COARDS flag.
Definition: HDFEOS5CF.cc:3380
void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:204
void Adjust_Var_Dim_NewName_Before_Flattening()
Adjust variable dimension names before the flattening for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:3030
void Adjust_Attr_Info()
Adjust the attribute info for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3403
bool Get_IgnoredInfo_Flag()
Obtain the flag to see if ignored objects should be generated.
Definition: HDF5CF.h:1266
void Handle_Obj_NameClashing(bool)
Handle the object name clashing for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3230
void Retrieve_H5_CVar_Supported_Attr_Values()
Retrieve coordinate variable attributes.
Definition: HDFEOS5CF.cc:166
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
void Handle_SpVar()
Handle special variables for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:3965
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
const std::vector< EOS5CVar * > & getCVars() const
Obtain coordinate variables for HDF-EOS5 products.
Definition: HDF5CF.h:1183
void Handle_DimNameClashing()
Definition: HDFEOS5CF.cc:3315
void Handle_CVar()
Handle coordinate variable for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:1764
const std::string & Get_Ignored_Msg()
Obtain the message that contains the ignored object info.
Definition: HDF5CF.h:1271
void Handle_SpVar_Attr()
Handle special variables for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:4087
void Retrieve_H5_Supported_Attr_Values()
Retrieve attribute values for the supported HDF5 datatypes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:182
void Handle_Coor_Attr()
Handle the coordinates attribute for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3751
void Adjust_Var_NewName_After_Parsing()
Adjust variable names for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:1224
void Add_Supplement_Attrs(bool)
Add the supplemental attributes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3666
void Add_Dim_Name(HE5Parser *)
Add the dimension name for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:1316
void Handle_Unsupported_Others(bool)
Handle other unmapped objects/attributes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:356
void Flatten_Obj_Name(bool include_attr)
Flatten the object name for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:3208
void Adjust_Dim_Name()
Adjust the dimension name for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3636
void Handle_Unsupported_Dspace(bool)
Handle unsupported HDF5 dataspaces for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:297
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
void Adjust_EOS5Dim_Info(HE5Parser *strmeta_info)
Adjust HDF-EOS5 dimension information.
Definition: HDFEOS5CF.cc:535
bool HaveUnlimitedDim() const
Has unlimited dimensions.
Definition: HDF5CF.h:676
const std::string & getPath() const
Obtain the path of the file.
Definition: HDF5CF.h:652
hid_t getFileID() const
Obtain the HDF5 file ID.
Definition: HDF5CF.h:646
const std::vector< Attribute * > & getAttributes() const
Public interface to obtain information of all attributes under the root group.
Definition: HDF5CF.h:664
const std::vector< Var * > & getVars() const
Public interface to obtain information of all variables.
Definition: HDF5CF.h:658
const std::vector< Group * > & getGroups() const
Public interface to obtain all the group info.
Definition: HDF5CF.h:670
int getRank() const
Get the dimension rank of this variable.
Definition: HDF5CF.h:295
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:301
const std::vector< Dimension * > & getDimensions() const
Get the list of the dimensions.
Definition: HDF5CF.h:312
int getCompRatio() const
Get the compression ratio of this dataset.
Definition: HDF5CF.h:318
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.