OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDF5GMCF.cc
Go to the documentation of this file.
1 // This file is part of the hdf5_handler implementing for the CF-compliant
2 // Copyright (c) 2011-2013 The HDF Group, Inc. and OPeNDAP, Inc.
3 //
4 // This is free software; you can redistribute it and/or modify it under the
5 // terms of the GNU Lesser General Public License as published by the Free
6 // Software Foundation; either version 2.1 of the License, or (at your
7 // option) any later version.
8 //
9 // This software is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 // License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 //
18 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
19 // You can contact The HDF Group, Inc. at 1800 South Oak Street,
20 // Suite 203, Champaign, IL 61820
21 
36 
37 #include "HDF5CF.h"
38 using namespace HDF5CF;
39 
41 
42  newname = var->newname;
43  name = var->name;
44  fullpath = var->fullpath;
45  rank = var->rank;
46  dtype = var->dtype;
49 
50  for (vector<Attribute*>::iterator ira = var->attrs.begin();
51  ira!=var->attrs.end(); ++ira) {
52  Attribute* attr= new Attribute();
53  attr->name = (*ira)->name;
54  attr->newname = (*ira)->newname;
55  attr->dtype =(*ira)->dtype;
56  attr->count =(*ira)->count;
57  attr->strsize = (*ira)->strsize;
58  attr->fstrsize = (*ira)->fstrsize;
59  attr->value =(*ira)->value;
60  attrs.push_back(attr);
61  }
62 
63  for (vector<Dimension*>::iterator ird = var->dims.begin();
64  ird!=var->dims.end(); ++ird) {
65  Dimension *dim = new Dimension((*ird)->size);
66 //cerr <<"dim->name "<< (*ird)->name <<endl;
67 //cerr <<"dim->newname "<< (*ird)->newname <<endl;
68  dim->name = (*ird)->name;
69  dim->newname = (*ird)->newname;
70  dims.push_back(dim);
71  }
72  product_type = General_Product;
73 
74 }
76 
77  fullpath = var->fullpath;
78  rank = var->rank;
81 
82  for (vector<Attribute*>::iterator ira = var->attrs.begin();
83  ira!=var->attrs.end(); ++ira) {
84  Attribute* attr= new Attribute();
85  attr->name = (*ira)->name;
86  attr->newname = (*ira)->newname;
87  attr->dtype =(*ira)->dtype;
88  attr->count =(*ira)->count;
89  attr->strsize = (*ira)->strsize;
90  attr->fstrsize = (*ira)->fstrsize;
91  attr->value =(*ira)->value;
92  attrs.push_back(attr);
93  } // for (vector<Attribute*>::iterator ira = var->attrs.begin();
94 
95  for (vector<Dimension*>::iterator ird = var->dims.begin();
96  ird!=var->dims.end(); ++ird) {
97  Dimension *dim = new Dimension((*ird)->size);
98  dim->name = (*ird)->name;
99  dim->newname = (*ird)->newname;
100  dims.push_back(dim);
101  }
102 }
103 
104 
105 GMFile::GMFile(const char*path, hid_t file_id, H5GCFProduct product_type, GMPattern gproduct_pattern):
106 File(path,file_id), product_type(product_type),gproduct_pattern(gproduct_pattern),iscoard(false)
107 {
108 
109 
110 }
112 {
113 
114  if (!this->cvars.empty()){
115  for (vector<GMCVar *>:: const_iterator i= this->cvars.begin(); i!=this->cvars.end(); ++i) {
116  delete *i;
117  }
118  }
119 
120  if (!this->spvars.empty()){
121  for (vector<GMSPVar *>:: const_iterator i= this->spvars.begin(); i!=this->spvars.end(); ++i) {
122  delete *i;
123  }
124  }
125 
126 }
127 
128 string GMFile::get_CF_string(string s) {
129 
130  if ((General_Product == product_type && OTHERGMS == gproduct_pattern) || s[0] !='/')
131  return File::get_CF_string(s);
132  else {
133  s.erase(0,1);
134  return File::get_CF_string(s);
135  }
136 }
137 
138 void GMFile::Retrieve_H5_Info(const char *path,
139  hid_t file_id, bool include_attr) throw (Exception) {
140 
141  // MeaSure SeaWiFS and Ozone need the attribute info. to build the dimension name list.
142  // GPM needs the attribute info. to obtain the lat/lon.
143  // So set the include_attr to be true for these products.
144  if (product_type == Mea_SeaWiFS_L2 || product_type == Mea_SeaWiFS_L3
145  || GPMS_L3 == product_type || GPMM_L3 == product_type || GPM_L1 == product_type || OBPG_L3 == product_type
146  || Mea_Ozone == product_type || General_Product == product_type)
147  File::Retrieve_H5_Info(path,file_id,true);
148  else
149  File::Retrieve_H5_Info(path,file_id,include_attr);
150 }
151 
153 
155  for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
156  ircv != this->cvars.end(); ++ircv) {
157 
158  //if ((CV_EXIST == (*ircv)->cvartype ) || (CV_MODIFY == (*ircv)->cvartype)
159  // || (CV_FILLINDEX == (*ircv)->cvartype)){
160  if ((*ircv)->cvartype != CV_NONLATLON_MISS){
161  for (vector<Attribute *>::iterator ira = (*ircv)->attrs.begin();
162  ira != (*ircv)->attrs.end(); ++ira) {
163  Retrieve_H5_Attr_Value(*ira,(*ircv)->fullpath);
164  }
165  }
166  }
167  for (vector<GMSPVar *>::iterator irspv = this->spvars.begin();
168  irspv != this->spvars.end(); ++irspv) {
169 
170  for (vector<Attribute *>::iterator ira = (*irspv)->attrs.begin();
171  ira != (*irspv)->attrs.end(); ++ira) {
172  Retrieve_H5_Attr_Value(*ira,(*irspv)->fullpath);
173  Adjust_H5_Attr_Value(*ira);
174  }
175  }
176 }
177 
179 
180  if (product_type == ACOS_L2S) {
181  if (("Type" == attr->name) && (H5VSTRING == attr->dtype)) {
182  string orig_attrvalues(attr->value.begin(),attr->value.end());
183  if (orig_attrvalues != "Signed64") return;
184  string new_attrvalues = "Signed32";
185  // Since the new_attrvalues size is the same as the orig_attrvalues size
186  // No need to adjust the strsize and fstrsize. KY 2011-2-1
187  attr->value.clear();
188  attr->value.resize(new_attrvalues.size());
189  copy(new_attrvalues.begin(),new_attrvalues.end(),attr->value.begin());
190  }
191  } // if (product_type == ACOS_L2S)
192 }
193 
194 void GMFile:: Handle_Unsupported_Dtype(bool include_attr) throw(Exception) {
195 
196  File::Handle_Unsupported_Dtype(include_attr);
197  for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
198  ircv != this->cvars.end(); ++ircv) {
199  if (true == include_attr) {
200  for (vector<Attribute *>::iterator ira = (*ircv)->attrs.begin();
201  ira != (*ircv)->attrs.end(); ++ira) {
202  H5DataType temp_dtype = (*ira)->getType();
203  if (false == HDF5CFUtil::cf_strict_support_type(temp_dtype)) {
204  delete (*ira);
205  (*ircv)->attrs.erase(ira);
206  ira--;
207  }
208  }
209  }
210  H5DataType temp_dtype = (*ircv)->getType();
211  if (false == HDF5CFUtil::cf_strict_support_type(temp_dtype)) {
212 
213  // This may need to be checked carefully in the future,
214  // My current understanding is that the coordinate variable can
215  // be ignored if the corresponding variable is ignored.
216  // Currently we don't find any NASA files in this category.
217  // KY 2012-5-21
218  delete (*ircv);
219  this->cvars.erase(ircv);
220  ircv--;
221  }
222  } // for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
223  for (vector<GMSPVar *>::iterator ircv = this->spvars.begin();
224  ircv != this->spvars.end(); ++ircv) {
225 
226  if (true == include_attr) {
227  for (vector<Attribute *>::iterator ira = (*ircv)->attrs.begin();
228  ira != (*ircv)->attrs.end(); ++ira) {
229  H5DataType temp_dtype = (*ira)->getType();
230  if (false == HDF5CFUtil::cf_strict_support_type(temp_dtype)) {
231  delete (*ira);
232  (*ircv)->attrs.erase(ira);
233  ira--;
234  }
235  }
236  }
237  H5DataType temp_dtype = (*ircv)->getType();
238  if (false == HDF5CFUtil::cf_strict_support_type(temp_dtype)) {
239  delete (*ircv);
240  this->spvars.erase(ircv);
241  ircv--;
242  }
243  }// for (vector<GMSPVar *>::iterator ircv = this->spvars.begin();
244 }
245 
247 
249 
250  if(true == this->unsupported_var_dspace) {
251  for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
252  ircv != this->cvars.end(); ++ircv) {
253  if (true == (*ircv)->unsupported_dspace ) {
254 
255  // This may need to be checked carefully in the future,
256  // My current understanding is that the coordinate variable can
257  // be ignored if the corresponding variable is ignored.
258  // Currently we don't find any NASA files in this category.
259  // KY 2012-5-21
260  delete (*ircv);
261  this->cvars.erase(ircv);
262  ircv--;
263  }
264  } // for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
265 
266  for (vector<GMSPVar *>::iterator ircv = this->spvars.begin();
267  ircv != this->spvars.end(); ++ircv) {
268 
269  if (true == (*ircv)->unsupported_dspace) {
270  delete (*ircv);
271  this->spvars.erase(ircv);
272  ircv--;
273  }
274  }// for (vector<GMSPVar *>::iterator ircv = this->spvars.begin();
275  }// if(true == this->unsupported_dspace)
276 }
277 
279 
280  switch(product_type) {
281  case Mea_SeaWiFS_L2:
282  case Mea_SeaWiFS_L3:
284  break;
285  case Aqu_L3:
287  break;
288  case SMAP:
290  break;
291  case ACOS_L2S:
293  break;
294  case Mea_Ozone:
296  break;
297  case GPMS_L3:
298  case GPMM_L3:
299  case GPM_L1:
301  case OBPG_L3:
303  case General_Product:
305  break;
306  default:
307  throw1("Cannot generate dim. names for unsupported datatype");
308  } // switch(product_type)
309 
310 // Just for debugging
311 #if 0
312 for (vector<Var*>::iterator irv2 = this->vars.begin();
313  irv2 != this->vars.end(); irv2++) {
314  for (vector<Dimension *>::iterator ird = (*irv2)->dims.begin();
315  ird !=(*irv2)->dims.end(); ird++) {
316  cerr<<"Dimension name afet Add_Dim_Name "<<(*ird)->newname <<endl;
317  }
318 }
319 #endif
320 
321 }
322 
324 
326 
327 }
329 
330 //cerr<<"coming to Add_Dim_Name_Mea_SeaWiFS"<<endl;
331 
332  pair<set<string>::iterator,bool> setret;
333  if (Mea_SeaWiFS_L3 == product_type)
334  iscoard = true;
335  for (vector<Var *>::iterator irv = this->vars.begin();
336  irv != this->vars.end(); ++irv) {
338  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
339  ird !=(*irv)->dims.end();++ird) {
340  setret = dimnamelist.insert((*ird)->name);
341  if (true == setret.second)
342  Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
343  }
344  } // for (vector<Var *>::iterator irv = this->vars.begin();
345 
346  if (true == dimnamelist.empty())
347  throw1("This product should have the dimension names, but no dimension names are found");
348 }
349 
350 
352 throw(Exception){
353 
354  Attribute* dimlistattr = NULL;
355  bool has_dimlist = false;
356  bool has_class = false;
357  bool has_reflist = false;
358 
359  for(vector<Attribute *>::iterator ira = var->attrs.begin();
360  ira != var->attrs.end();ira++) {
361  if ("DIMENSION_LIST" == (*ira)->name) {
362  dimlistattr = *ira;
363  has_dimlist = true;
364  }
365  if ("CLASS" == (*ira)->name)
366  has_class = true;
367  if ("REFERENCE_LIST" == (*ira)->name)
368  has_reflist = true;
369 
370  if (true == has_dimlist)
371  break;
372  if (true == has_class && true == has_reflist)
373  break;
374  } // for(vector<Attribute *>::iterator ira = var->attrs.begin(); ...
375 
376  if (true == has_dimlist)
377  Add_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(var,dimlistattr);
378 
379  // Dim name is the same as the variable name for dimscale variable
380  else if(true == has_class && true == has_reflist) {
381  if (var->dims.size() !=1)
382  throw2("dimension scale dataset must be 1 dimension, this is not true for variable ",
383  var->name);
384 
385  // The var name is the object name, however, we would like the dimension name to be full path.
386  // so that the dim name can be served as the key for future handling.
387  (var->dims)[0]->name = var->fullpath;
388  (var->dims)[0]->newname = var->fullpath;
389  pair<set<string>::iterator,bool> setret;
390  setret = dimnamelist.insert((var->dims)[0]->name);
391  if (true == setret.second)
392  Insert_One_NameSizeMap_Element((var->dims)[0]->name,(var->dims)[0]->size);
393  }
394 
395  // No dimension, add fake dim names, this may never happen for MeaSure
396  // but just for coherence and completeness.
397  // For Fake dimesnion
398  else {
399 
400  set<hsize_t> fakedimsize;
401  pair<set<hsize_t>::iterator,bool> setsizeret;
402  for (vector<Dimension *>::iterator ird= var->dims.begin();
403  ird != var->dims.end(); ++ird) {
404  Add_One_FakeDim_Name(*ird);
405  setsizeret = fakedimsize.insert((*ird)->size);
406  if (false == setsizeret.second)
407  Adjust_Duplicate_FakeDim_Name(*ird);
408  }
409 // Just for debugging
410 #if 0
411  for (int i = 0; i < var->dims.size(); ++i) {
412  Add_One_FakeDim_Name((var->dims)[i]);
413  bool gotoMainLoop = false;
414  for (int j =i-1; j>=0 && !gotoMainLoop; --j) {
415  if (((var->dims)[i])->size == ((var->dims)[j])->size){
416  Adjust_Duplicate_FakeDim_Name((var->dims)[i]);
417  gotoMainLoop = true;
418  }
419  }
420  }
421 #endif
422 
423  }
424 }
425 
427 throw (Exception){
428 
429  ssize_t objnamelen = -1;
430  hobj_ref_t rbuf;
431  //hvl_t *vlbuf = NULL;
432  vector<hvl_t> vlbuf;
433 
434  hid_t dset_id = -1;
435  hid_t attr_id = -1;
436  hid_t atype_id = -1;
437  hid_t amemtype_id = -1;
438  hid_t aspace_id = -1;
439  hid_t ref_dset = -1;
440 
441 
442  if(NULL == dimlistattr)
443  throw2("Cannot obtain the dimension list attribute for variable ",var->name);
444 
445  if (0==var->rank)
446  throw2("The number of dimension should NOT be 0 for the variable ",var->name);
447 
448  try {
449 
450  //vlbuf = new hvl_t[var->rank];
451  vlbuf.resize(var->rank);
452 
453  hid_t dset_id = H5Dopen(this->fileid,(var->fullpath).c_str(),H5P_DEFAULT);
454  if (dset_id < 0)
455  throw2("Cannot open the dataset ",var->fullpath);
456 
457  attr_id = H5Aopen(dset_id,(dimlistattr->name).c_str(),H5P_DEFAULT);
458  if (attr_id <0 )
459  throw4("Cannot open the attribute ",dimlistattr->name," of HDF5 dataset ",var->fullpath);
460 
461  atype_id = H5Aget_type(attr_id);
462  if (atype_id <0)
463  throw4("Cannot obtain the datatype of the attribute ",dimlistattr->name," of HDF5 dataset ",var->fullpath);
464 
465  amemtype_id = H5Tget_native_type(atype_id, H5T_DIR_ASCEND);
466 
467  if (amemtype_id < 0)
468  throw2("Cannot obtain the memory datatype for the attribute ",dimlistattr->name);
469 
470 
471  if (H5Aread(attr_id,amemtype_id,&vlbuf[0]) <0)
472  throw2("Cannot obtain the referenced object for the variable ",var->name);
473 
474 
475  vector<char> objname;
476  int vlbuf_index = 0;
477 
478  // The dimension names of variables will be the HDF5 dataset names dereferenced from the DIMENSION_LIST attribute.
479  for (vector<Dimension *>::iterator ird = var->dims.begin();
480  ird != var->dims.end(); ++ird) {
481 
482  rbuf =((hobj_ref_t*)vlbuf[vlbuf_index].p)[0];
483  if ((ref_dset = H5Rdereference(attr_id, H5R_OBJECT, &rbuf)) < 0)
484  throw2("Cannot dereference from the DIMENSION_LIST attribute for the variable ",var->name);
485 
486  if ((objnamelen= H5Iget_name(ref_dset,NULL,0))<=0)
487  throw2("Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute for the variable ",var->name);
488  objname.resize(objnamelen+1);
489  if ((objnamelen= H5Iget_name(ref_dset,&objname[0],objnamelen+1))<=0)
490  throw2("Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute for the variable ",var->name);
491 
492  string objname_str = string(objname.begin(),objname.end());
493  string trim_objname = objname_str.substr(0,objnamelen);
494  (*ird)->name = string(trim_objname.begin(),trim_objname.end());
495 
496  pair<set<string>::iterator,bool> setret;
497  setret = dimnamelist.insert((*ird)->name);
498  if (true == setret.second)
499  Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
500  (*ird)->newname = (*ird)->name;
501  H5Dclose(ref_dset);
502  ref_dset = -1;
503  objname.clear();
504  vlbuf_index++;
505  }// for (vector<Dimension *>::iterator ird = var->dims.begin()
506  if(vlbuf.size()!= 0) {
507 
508  if ((aspace_id = H5Aget_space(attr_id)) < 0)
509  throw2("Cannot get hdf5 dataspace id for the attribute ",dimlistattr->name);
510 
511  if (H5Dvlen_reclaim(amemtype_id,aspace_id,H5P_DEFAULT,(void*)&vlbuf[0])<0)
512  throw2("Cannot successfully clean up the variable length memory for the variable ",var->name);
513 
514  H5Sclose(aspace_id);
515 
516  }
517 
518  H5Tclose(atype_id);
519  H5Tclose(amemtype_id);
520  H5Aclose(attr_id);
521  H5Dclose(dset_id);
522 
523  // if(vlbuf != NULL)
524  // delete[] vlbuf;
525  }
526 
527  catch(...) {
528 
529  if(atype_id != -1)
530  H5Tclose(atype_id);
531 
532  if(amemtype_id != -1)
533  H5Tclose(amemtype_id);
534 
535  if(aspace_id != -1)
536  H5Sclose(aspace_id);
537 
538  if(attr_id != -1)
539  H5Aclose(attr_id);
540 
541  if(dset_id != -1)
542  H5Dclose(dset_id);
543 
544  //if(vlbuf != NULL)
545  // delete[] vlbuf;
546 
547  //throw1("Error in method GMFile::Add_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone");
548  throw;
549  }
550 
551 }
552 
554 
555  iscoard = true;
556  bool use_dimscale = false;
557 
558  for (vector<Group *>::iterator irg = this->groups.begin();
559  irg != this->groups.end(); ++ irg) {
560  if ("/Dimensions" == (*irg)->path) {
561  use_dimscale = true;
562  break;
563  }
564  }
565 
566  if (false == use_dimscale) {
567 
568  bool has_dimlist = false;
569  bool has_class = false;
570  bool has_reflist = false;
571 
572  for (vector<Var *>::iterator irv = this->vars.begin();
573  irv != this->vars.end(); irv++) {
574 
575  for(vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
576  ira != (*irv)->attrs.end();ira++) {
577  if ("DIMENSION_LIST" == (*ira)->name)
578  has_dimlist = true;
579  }
580  if (true == has_dimlist)
581  break;
582  }
583 
584  if (true == has_dimlist) {
585  for (vector<Var *>::iterator irv = this->vars.begin();
586  irv != this->vars.end(); irv++) {
587 
588  for(vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
589  ira != (*irv)->attrs.end();ira++) {
590  if ("CLASS" == (*ira)->name)
591  has_class = true;
592  if ("REFERENCE_LIST" == (*ira)->name)
593  has_reflist = true;
594  if (true == has_class && true == has_reflist)
595  break;
596  }
597 
598  if (true == has_class &&
599  true == has_reflist)
600  break;
601 
602  }
603  if (true == has_class && true == has_reflist)
604  use_dimscale = true;
605  } // if (true == has_dimlist)
606  } // if (false == use_dimscale)
607 
608  if (true == use_dimscale) {
609 
610  pair<set<string>::iterator,bool> setret;
611  for (vector<Var *>::iterator irv = this->vars.begin();
612  irv != this->vars.end(); ++irv) {
614  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
615  ird !=(*irv)->dims.end();++ird) {
616  setret = dimnamelist.insert((*ird)->name);
617  if(true == setret.second)
618  Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
619  }
620  }
621 
622  if (true == dimnamelist.empty())
623  throw1("This product should have the dimension names, but no dimension names are found");
624  } // if (true == use_dimscale)
625 
626  else {
627 
628  // Since the dim. size of each dimension of 2D lat/lon may be the same, so use multimap.
629  multimap<hsize_t,string> ozonedimsize_to_dimname;
630  pair<multimap<hsize_t,string>::iterator,multimap<hsize_t,string>::iterator> mm_er_ret;
631  multimap<hsize_t,string>::iterator irmm;
632 
633  for (vector<Var *>::iterator irv = this->vars.begin();
634  irv != this->vars.end(); ++irv) {
635  bool is_cv = check_cv((*irv)->name);
636  if (true == is_cv) {
637  if ((*irv)->dims.size() != 1)
638  throw3("The coordinate variable", (*irv)->name," must be one dimension for the zonal average product");
639  ozonedimsize_to_dimname.insert(pair<hsize_t,string>(((*irv)->dims)[0]->size,(*irv)->fullpath));
640 #if 0
641  ((*irv)->dims[0])->name = (*irv)->name;
642  ((*irv)->dims[0])->newname = (*irv)->name;
643  pair<set<string>::iterator,bool> setret;
644  setret = dimnamelist.insert(((*irv)->dims[0])->name);
645  if (setret.second)
646  Insert_One_NameSizeMap_Element(((*irv)->dims[0])->name,((*irv)->dims[0])->size);
647 #endif
648  }
649  }// for (vector<Var *>::iterator irv = this->vars.begin(); ...
650 
651  set<hsize_t> fakedimsize;
652  pair<set<hsize_t>::iterator,bool> setsizeret;
653  pair<set<string>::iterator,bool> setret;
654  pair<set<string>::iterator,bool> tempsetret;
655  set<string> tempdimnamelist;
656  bool fakedimflag = false;
657 
658  for (vector<Var *>::iterator irv = this->vars.begin();
659  irv != this->vars.end(); ++irv) {
660 
661  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
662  ird != (*irv)->dims.end(); ++ird) {
663 
664  fakedimflag = true;
665  mm_er_ret = ozonedimsize_to_dimname.equal_range((*ird)->size);
666  for (irmm = mm_er_ret.first; irmm!=mm_er_ret.second;irmm++) {
667  setret = tempdimnamelist.insert(irmm->second);
668  if (true == setret.second) {
669  (*ird)->name = irmm->second;
670  (*ird)->newname = (*ird)->name;
671  setret = dimnamelist.insert((*ird)->name);
672  if(setret.second) Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
673  fakedimflag = false;
674  break;
675  }
676  }
677 
678  if (true == fakedimflag) {
679  Add_One_FakeDim_Name(*ird);
680  setsizeret = fakedimsize.insert((*ird)->size);
681  if (false == setsizeret.second)
683  }
684 
685  } // for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
686  tempdimnamelist.clear();
687  fakedimsize.clear();
688  } // for (vector<Var *>::iterator irv = this->vars.begin();
689  } // else
690 }
691 
692 bool GMFile::check_cv(string & varname) throw(Exception) {
693 
694  const string lat_name ="Latitude";
695  const string time_name ="Time";
696  const string ratio_pressure_name ="MixingRatioPressureLevels";
697  const string profile_pressure_name ="ProfilePressureLevels";
698  const string wave_length_name ="Wavelength";
699 
700  if (lat_name == varname)
701  return true;
702  else if (time_name == varname)
703  return true;
704  else if (ratio_pressure_name == varname)
705  return true;
706  else if (profile_pressure_name == varname)
707  return true;
708  else if (wave_length_name == varname)
709  return true;
710  else
711  return false;
712 }
713 
715 {
716 
717  // This is used to create a dimension name set.
718  pair<set<string>::iterator,bool> setret;
719 
720  // One GPM variable (sunVectorInBodyFrame) misses an element for DimensionNames attributes.
721  // We need to create a fakedim name to fill in. To make the dimension name unique, we use a counter.
722  // int dim_count = 0;
723  // map<string,string> varname_to_fakedim;
724  // map<int,string> gpm_dimsize_to_fakedimname;
725 
726  // We find that GPM has an attribute DimensionNames(nlon,nlat) in this case.
727  // We will use this attribute to specify the dimension names.
728  for (vector<Var *>::iterator irv = this->vars.begin();
729  irv != this->vars.end(); irv++) {
730 
731  bool has_dim_name_attr = false;
732 
733  for (vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
734  ira != (*irv)->attrs.end(); ++ira) {
735 
736  if("DimensionNames" == (*ira)->name) {
737 
738  Retrieve_H5_Attr_Value(*ira,(*irv)->fullpath);
739  string dimname_value((*ira)->value.begin(),(*ira)->value.end());
740 
741  vector<string> ind_elems;
742  char sep=',';
743  HDF5CFUtil::Split(&dimname_value[0],sep,ind_elems);
744 
745  if(ind_elems.size() != (size_t)((*irv)->getRank())) {
746  throw2("The number of dims obtained from the <DimensionNames> attribute is not equal to the rank ",
747  (*irv)->name);
748  }
749 
750  for(unsigned int i = 0; i<ind_elems.size(); ++i) {
751 
752  ((*irv)->dims)[i]->name = ind_elems[i];
753  // Generate a dimension name is the dimension name is missing.
754  // The routine will ensure that the fakeDim name is unique.
755  if(((*irv)->dims)[i]->name==""){
756  Add_One_FakeDim_Name(((*irv)->dims)[i]);
757 // For debugging
758 #if 0
759  string fakedim = "FakeDim";
760  stringstream sdim_count;
761  sdim_count << dim_count;
762  fakedim = fakedim + sdim_count.str();
763  dim_count++;
764  ((*irv)->dims)[i]->name = fakedim;
765  ((*irv)->dims)[i]->newname = fakedim;
766  ind_elems[i] = fakedim;
767 #endif
768  }
769 
770  else {
771  ((*irv)->dims)[i]->newname = ind_elems[i];
772  setret = dimnamelist.insert(((*irv)->dims)[i]->name);
773 
774  if (true == setret.second) {
775  Insert_One_NameSizeMap_Element(((*irv)->dims)[i]->name,
776  ((*irv)->dims)[i]->size);
777  }
778  else {
779  if(dimname_to_dimsize[((*irv)->dims)[i]->name] !=((*irv)->dims)[i]->size)
780  throw5("Dimension ",((*irv)->dims)[i]->name, "has two sizes",
781  ((*irv)->dims)[i]->size,dimname_to_dimsize[((*irv)->dims)[i]->name]);
782 
783  }
784  }
785 
786  }
787  has_dim_name_attr = true;
788  break;
789 
790  }
791  }
792 
793 #if 0
794  if(false == has_dim_name_attr) {
795 
796  throw4( "The variable ", (*irv)->name, " doesn't have the DimensionNames attribute.",
797  "We currently don't support this case. Please report to the NASA data center.");
798  }
799 
800 #endif
801  }
802 
803 }
804 
806 {
807  for (vector<Var *>::iterator irv = this->vars.begin();
808  irv != this->vars.end(); irv++) {
809  if ("l3m_data" == (*irv)->name) {
810  ((*irv)->dims)[0]->name = "lat";
811  ((*irv)->dims)[0]->newname = "lat";
812  ((*irv)->dims)[1]->name = "lon";
813  ((*irv)->dims)[1]->newname = "lon";
814  break;
815  }
816 
817 // For the time being, don't assign dimension names to palette,
818 // we will see if tools can pick up l3m and then make decisions.
819 #if 0
820  if ("palette" == (*irv)->name) {
821 //cerr <<"coming to palette" <<endl;
822  ((*irv)->dims)[0]->name = "paldim0";
823  ((*irv)->dims)[0]->newname = "paldim0";
824  ((*irv)->dims)[1]->name = "paldim1";
825  ((*irv)->dims)[1]->newname = "paldim1";
826  }
827 #endif
828 
829  }
830 }
832 
833  string tempvarname ="";
834  string key = "_lat";
835  string smapdim0 ="YDim";
836  string smapdim1 ="XDim";
837 
838  // Since the dim. size of each dimension of 2D lat/lon may be the same, so use multimap.
839  multimap<hsize_t,string> smapdimsize_to_dimname;
840  pair<multimap<hsize_t,string>::iterator,multimap<hsize_t,string>::iterator> mm_er_ret;
841  multimap<hsize_t,string>::iterator irmm;
842 
843  // Generate dimension names based on the size of "???_lat"(one coordinate variable)
844  for (vector<Var *>::iterator irv = this->vars.begin();
845  irv != this->vars.end(); ++irv) {
846  tempvarname = (*irv)->name;
847  if ((tempvarname.size() > key.size())&&
848  (key == tempvarname.substr(tempvarname.size()-key.size(),key.size()))){
849 //cerr<<"tempvarname " <<tempvarname <<endl;
850  if ((*irv)->dims.size() !=2)
851  throw1("Currently only 2D lat/lon is supported for SMAP");
852  smapdimsize_to_dimname.insert(pair<hsize_t,string>(((*irv)->dims)[0]->size,smapdim0));
853  smapdimsize_to_dimname.insert(pair<hsize_t,string>(((*irv)->dims)[1]->size,smapdim1));
854  break;
855  }
856  }
857 
858  set<hsize_t> fakedimsize;
859  pair<set<hsize_t>::iterator,bool> setsizeret;
860  pair<set<string>::iterator,bool> setret;
861  pair<set<string>::iterator,bool> tempsetret;
862  set<string> tempdimnamelist;
863  bool fakedimflag = false;
864 
865 
866  for (vector<Var *>::iterator irv = this->vars.begin();
867  irv != this->vars.end(); ++irv) {
868 
869  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
870  ird != (*irv)->dims.end(); ++ird) {
871 
872  fakedimflag = true;
873  mm_er_ret = smapdimsize_to_dimname.equal_range((*ird)->size);
874  for (irmm = mm_er_ret.first; irmm!=mm_er_ret.second;irmm++) {
875  setret = tempdimnamelist.insert(irmm->second);
876  if (setret.second) {
877  (*ird)->name = irmm->second;
878  (*ird)->newname = (*ird)->name;
879  setret = dimnamelist.insert((*ird)->name);
880  if(setret.second) Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
881  fakedimflag = false;
882  break;
883  }
884  }
885 
886  if (true == fakedimflag) {
887  Add_One_FakeDim_Name(*ird);
888  setsizeret = fakedimsize.insert((*ird)->size);
889  if (!setsizeret.second)
891  }
892  } // for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
893  tempdimnamelist.clear();
894  fakedimsize.clear();
895  } // for (vector<Var *>::iterator irv = this->vars.begin();
896 }
897 
899 
900  for (vector<Var *>::iterator irv = this->vars.begin();
901  irv != this->vars.end(); ++irv) {
902 
903  set<hsize_t> fakedimsize;
904  pair<set<hsize_t>::iterator,bool> setsizeret;
905  for (vector<Dimension *>::iterator ird= (*irv)->dims.begin();
906  ird != (*irv)->dims.end(); ++ird) {
907  Add_One_FakeDim_Name(*ird);
908  setsizeret = fakedimsize.insert((*ird)->size);
909  if (false == setsizeret.second)
911  }
912  } // for (vector<Var *>::iterator irv = this->vars.begin();
913 }
915 
916  // Check attributes
918 
919  // This general product should follow the HDF5 dimension scale model.
920  if (GENERAL_DIMSCALE == this->gproduct_pattern)
922 
923 }
924 
926 
927  bool has_dimlist = false;
928  bool has_dimscalelist = false;
929 
930  // Check if containing the "DIMENSION_LIST" attribute;
931  for (vector<Var *>::iterator irv = this->vars.begin();
932  irv != this->vars.end(); ++irv) {
933  for(vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
934  ira != (*irv)->attrs.end();ira++) {
935  if ("DIMENSION_LIST" == (*ira)->name) {
936  has_dimlist = true;
937  break;
938  }
939  }
940  if (true == has_dimlist)
941  break;
942  }
943 
944  // Check if containing both the attribute "CLASS" and the attribute "REFERENCE_LIST" for the same variable.
945  // This is the dimension scale.
946  // Actually "REFERENCE_LIST" is not necessary for a dimension scale dataset. If a dimension scale doesn't
947  // have a "REFERENCE_LIST", it is still valid. But no other variables use this dimension scale. We found
948  // such a case in a matched_airs_aqua product. KY 2012-12-03
949  for (vector<Var *>::iterator irv = this->vars.begin();
950  irv != this->vars.end(); ++irv) {
951 
952 
953  for(vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
954  ira != (*irv)->attrs.end();ira++) {
955  if ("CLASS" == (*ira)->name) {
956 
957  Retrieve_H5_Attr_Value(*ira,(*irv)->fullpath);
958  string class_value;
959  class_value.resize((*ira)->value.size());
960  copy((*ira)->value.begin(),(*ira)->value.end(),class_value.begin());
961 
962  // Compare the attribute "CLASS" value with "DIMENSION_SCALE". We only compare the string with the size of
963  // "DIMENSION_SCALE", which is 15.
964  if (0 == class_value.compare(0,15,"DIMENSION_SCALE")) {
965  has_dimscalelist = true;
966  break;
967  }
968  }
969  }
970 
971  if (true == has_dimscalelist)
972  break;
973 
974  }
975 
976  if (true == has_dimlist && true == has_dimscalelist)
977  this->gproduct_pattern = GENERAL_DIMSCALE;
978 
979 }
980 
982 
983  //cerr<<"coming to Add_Dim_Name_Dimscale_General_Product"<<endl;
984  pair<set<string>::iterator,bool> setret;
985  this->iscoard = true;
986 
987  for (vector<Var *>::iterator irv = this->vars.begin();
988  irv != this->vars.end(); ++irv) {
990  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
991  ird !=(*irv)->dims.end();++ird) {
992  setret = dimnamelist.insert((*ird)->name);
993  if (true == setret.second)
994  Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
995  }
996  } // for (vector<Var *>::iterator irv = this->vars.begin();
997 
998  if (true == dimnamelist.empty())
999  throw1("This product should have the dimension names, but no dimension names are found");
1000 
1001 }
1002 
1004 
1005  Attribute* dimlistattr = NULL;
1006  bool has_dimlist = false;
1007  bool has_dimclass = false;
1008 
1009  for(vector<Attribute *>::iterator ira = var->attrs.begin();
1010  ira != var->attrs.end();ira++) {
1011  if ("DIMENSION_LIST" == (*ira)->name) {
1012  dimlistattr = *ira;
1013  has_dimlist = true;
1014  }
1015  if ("CLASS" == (*ira)->name) {
1016 
1017  Retrieve_H5_Attr_Value(*ira,var->fullpath);
1018  string class_value;
1019  class_value.resize((*ira)->value.size());
1020  copy((*ira)->value.begin(),(*ira)->value.end(),class_value.begin());
1021 
1022  // Compare the attribute "CLASS" value with "DIMENSION_SCALE". We only compare the string with the size of
1023  // "DIMENSION_SCALE", which is 15.
1024  if (0 == class_value.compare(0,15,"DIMENSION_SCALE")) {
1025  has_dimclass = true;
1026  break;
1027  }
1028  }
1029 
1030  } // for(vector<Attribute *>::iterator ira = var->attrs.begin(); ...
1031 
1032  // This is a general variable, we need to find the corresponding coordinate variables.
1033  if (true == has_dimlist)
1034  Add_UseDimscale_Var_Dim_Names_General_Product(var,dimlistattr);
1035 
1036  // Dim name is the same as the variable name for dimscale variable
1037  else if(true == has_dimclass) {
1038  if (var->dims.size() !=1)
1039  throw2("Currently dimension scale dataset must be 1 dimension, this is not true for the dataset ",
1040  var->name);
1041 
1042  // The var name is the object name, however, we would like the dimension name to be the full path.
1043  // so that the dim name can be served as the key for future handling.
1044  (var->dims)[0]->name = var->fullpath;
1045  (var->dims)[0]->newname = var->fullpath;
1046  pair<set<string>::iterator,bool> setret;
1047  setret = dimnamelist.insert((var->dims)[0]->name);
1048  if (true == setret.second)
1049  Insert_One_NameSizeMap_Element((var->dims)[0]->name,(var->dims)[0]->size);
1050  }
1051 
1052  // No dimension, add fake dim names, this will rarely happen.
1053  else {
1054 
1055  set<hsize_t> fakedimsize;
1056  pair<set<hsize_t>::iterator,bool> setsizeret;
1057  for (vector<Dimension *>::iterator ird= var->dims.begin();
1058  ird != var->dims.end(); ++ird) {
1059  Add_One_FakeDim_Name(*ird);
1060  setsizeret = fakedimsize.insert((*ird)->size);
1061  // Avoid the same size dimension sharing the same dimension name.
1062  if (false == setsizeret.second)
1063  Adjust_Duplicate_FakeDim_Name(*ird);
1064  }
1065  }
1066 
1067 }
1068 
1070 throw (Exception){
1071 
1072  ssize_t objnamelen = -1;
1073  hobj_ref_t rbuf;
1074  //hvl_t *vlbuf = NULL;
1075  vector<hvl_t> vlbuf;
1076 
1077  hid_t dset_id = -1;
1078  hid_t attr_id = -1;
1079  hid_t atype_id = -1;
1080  hid_t amemtype_id = -1;
1081  hid_t aspace_id = -1;
1082  hid_t ref_dset = -1;
1083 
1084 
1085  if(NULL == dimlistattr)
1086  throw2("Cannot obtain the dimension list attribute for variable ",var->name);
1087 
1088  if (0==var->rank)
1089  throw2("The number of dimension should NOT be 0 for the variable ",var->name);
1090 
1091  try {
1092 
1093  //vlbuf = new hvl_t[var->rank];
1094  vlbuf.resize(var->rank);
1095 
1096  hid_t dset_id = H5Dopen(this->fileid,(var->fullpath).c_str(),H5P_DEFAULT);
1097  if (dset_id < 0)
1098  throw2("Cannot open the dataset ",var->fullpath);
1099 
1100  attr_id = H5Aopen(dset_id,(dimlistattr->name).c_str(),H5P_DEFAULT);
1101  if (attr_id <0 )
1102  throw4("Cannot open the attribute ",dimlistattr->name," of HDF5 dataset ",var->fullpath);
1103 
1104  atype_id = H5Aget_type(attr_id);
1105  if (atype_id <0)
1106  throw4("Cannot obtain the datatype of the attribute ",dimlistattr->name," of HDF5 dataset ",var->fullpath);
1107 
1108  amemtype_id = H5Tget_native_type(atype_id, H5T_DIR_ASCEND);
1109 
1110  if (amemtype_id < 0)
1111  throw2("Cannot obtain the memory datatype for the attribute ",dimlistattr->name);
1112 
1113 
1114  if (H5Aread(attr_id,amemtype_id,&vlbuf[0]) <0)
1115  throw2("Cannot obtain the referenced object for the variable ",var->name);
1116 
1117 
1118  vector<char> objname;
1119  int vlbuf_index = 0;
1120 
1121  // The dimension names of variables will be the HDF5 dataset names dereferenced from the DIMENSION_LIST attribute.
1122  for (vector<Dimension *>::iterator ird = var->dims.begin();
1123  ird != var->dims.end(); ++ird) {
1124 
1125  rbuf =((hobj_ref_t*)vlbuf[vlbuf_index].p)[0];
1126  if ((ref_dset = H5Rdereference(attr_id, H5R_OBJECT, &rbuf)) < 0)
1127  throw2("Cannot dereference from the DIMENSION_LIST attribute for the variable ",var->name);
1128 
1129  if ((objnamelen= H5Iget_name(ref_dset,NULL,0))<=0)
1130  throw2("Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute for the variable ",var->name);
1131  objname.resize(objnamelen+1);
1132  if ((objnamelen= H5Iget_name(ref_dset,&objname[0],objnamelen+1))<=0)
1133  throw2("Cannot obtain the dataset name dereferenced from the DIMENSION_LIST attribute for the variable ",var->name);
1134 
1135  string objname_str = string(objname.begin(),objname.end());
1136  string trim_objname = objname_str.substr(0,objnamelen);
1137  (*ird)->name = string(trim_objname.begin(),trim_objname.end());
1138 
1139  pair<set<string>::iterator,bool> setret;
1140  setret = dimnamelist.insert((*ird)->name);
1141  if (true == setret.second)
1142  Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
1143  (*ird)->newname = (*ird)->name;
1144  H5Dclose(ref_dset);
1145  ref_dset = -1;
1146  objname.clear();
1147  vlbuf_index++;
1148  }// for (vector<Dimension *>::iterator ird = var->dims.begin()
1149  if(vlbuf.size()!= 0) {
1150 
1151  if ((aspace_id = H5Aget_space(attr_id)) < 0)
1152  throw2("Cannot get hdf5 dataspace id for the attribute ",dimlistattr->name);
1153 
1154  if (H5Dvlen_reclaim(amemtype_id,aspace_id,H5P_DEFAULT,(void*)&vlbuf[0])<0)
1155  throw2("Cannot successfully clean up the variable length memory for the variable ",var->name);
1156 
1157  H5Sclose(aspace_id);
1158 
1159  }
1160 
1161  H5Tclose(atype_id);
1162  H5Tclose(amemtype_id);
1163  H5Aclose(attr_id);
1164  H5Dclose(dset_id);
1165 
1166  // if(vlbuf != NULL)
1167  // delete[] vlbuf;
1168  }
1169 
1170  catch(...) {
1171 
1172  if(atype_id != -1)
1173  H5Tclose(atype_id);
1174 
1175  if(amemtype_id != -1)
1176  H5Tclose(amemtype_id);
1177 
1178  if(aspace_id != -1)
1179  H5Sclose(aspace_id);
1180 
1181  if(attr_id != -1)
1182  H5Aclose(attr_id);
1183 
1184  if(dset_id != -1)
1185  H5Dclose(dset_id);
1186 
1187  //if(vlbuf != NULL)
1188  // delete[] vlbuf;
1189 
1190  //throw1("Error in method GMFile::Add_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone");
1191  throw;
1192  }
1193 
1194 }
1195 
1196 
1198 
1199  // No support for coordinate variables for general HDF5 products
1200  // and ACOS_L2S
1201  if (General_Product == this->product_type ||
1202  ACOS_L2S == this->product_type) {
1203  if (GENERAL_DIMSCALE == this->gproduct_pattern)
1205  else
1206  return;
1207  }
1208 
1209  else if (Mea_SeaWiFS_L2 == this->product_type ||
1210  Mea_SeaWiFS_L3 == this->product_type)
1212 
1213  else if (Aqu_L3 == this->product_type)
1214  Handle_CVar_Aqu_L3();
1215  else if (OBPG_L3 == this->product_type)
1217  else if (SMAP == this->product_type)
1218  Handle_CVar_SMAP();
1219  else if (Mea_Ozone == this->product_type)
1221  else if (GPMS_L3 == this->product_type || GPMM_L3 == this->product_type)
1223  else if (GPM_L1 == this->product_type)
1225 }
1226 
1228 
1229 #if 0
1230  // Loop through the variable list to build the coordinates.
1231  for (vector<Var *>::iterator irv = this->vars.begin();
1232  irv != this->vars.end(); ++irv) {
1233  if((*irv)->name=="AlgorithmRuntimeInfo") {
1234  delete(*irv);
1235  this->vars.erase(irv);
1236  break;
1237  }
1238  }
1239 #endif
1240 
1241  // Loop through all variables to check 2-D "Latitude" and "Longitude".
1242  // Create coordinate variables based on 2-D "Latitude" and "Longitude".
1243  // Latitude[Xdim][YDim] Longitude[Xdim][YDim], Latitude <->Xdim, Longitude <->YDim.
1244  // Make sure to build cf dimension names cfdimname = latpath+ the lat dimension name.
1245  // We want to save dimension names of Latitude and Longitude since
1246  // the Fake coordinate variables of these two dimensions should not be generated.
1247  // So we need to remember these dimension names.
1248  string ll_dim0,ll_dim1;
1249  for (vector<Var *>::iterator irv = this->vars.begin();
1250  irv != this->vars.end(); ++irv) {
1251  if((*irv)->rank == 2 && (*irv)->name == "Latitude") {
1252  GMCVar* GMcvar = new GMCVar(*irv);
1253  size_t lat_pos = (*irv)->fullpath.rfind("Latitude");
1254  string lat_path = (*irv)->fullpath.substr(0,lat_pos);
1255  GMcvar->cfdimname = lat_path + ((*irv)->dims)[0]->name;
1256  ll_dim0 = ((*irv)->dims)[0]->name;
1257  GMcvar->cvartype = CV_EXIST;
1258  GMcvar->product_type = product_type;
1259  this->cvars.push_back(GMcvar);
1260  delete(*irv);
1261  this->vars.erase(irv);
1262  irv--;
1263  }
1264  if((*irv)->rank == 2 && (*irv)->name == "Longitude") {
1265  GMCVar* GMcvar = new GMCVar(*irv);
1266  size_t lon_pos = (*irv)->fullpath.rfind("Longitude");
1267  string lon_path = (*irv)->fullpath.substr(0,lon_pos);
1268  GMcvar->cfdimname = lon_path + ((*irv)->dims)[1]->name;
1269  ll_dim1 = ((*irv)->dims)[1]->name;
1270  GMcvar->cvartype = CV_EXIST;
1271  GMcvar->product_type = product_type;
1272  this->cvars.push_back(GMcvar);
1273  delete(*irv);
1274  this->vars.erase(irv);
1275  irv--;
1276  }
1277  }// for (vector<Var *>::iterator irv = this->vars.begin();...
1278 
1279 #if 0
1280  // Loop through all variables and create a dim set.
1281  set<string> cvdimset;
1282  pair<set<string>::iterator,bool> setret;
1283  for (vector<Var *>::iterator irv = this->vars.begin();
1284  irv != this->vars.end(); ++irv) {
1285  for(vector<Dimension *>::iterator ird = (*irv)->dims.begin();
1286  ird != (*irv)->dims.end(); ++ird) {
1287  setret = cvdimset.insert((*ird)->name);
1288 cerr<<"var name is "<<(*irv)->fullpath <<endl;
1289  if (true == setret.second) {
1290 cerr<<"dim name is "<<(*ird)->name <<endl;
1291  Insert_One_NameSizeMap_Element((*ird)->name,(*ird)->size);
1292  }
1293  }
1294  }// for (vector<Var *>::iterator irv = this->vars.begin();...
1295 #endif
1296 
1297  // For each dimension, create a coordinate variable.
1298  // Here we just need to loop through the map dimname_to_dimsize,
1299  // use the name and the size to create coordinate variables.
1300  for (map<string,hsize_t>::const_iterator itd = dimname_to_dimsize.begin();
1301  itd!=dimname_to_dimsize.end();++itd) {
1302  if((itd->first) != ll_dim0 && (itd->first) != ll_dim1) {
1303  GMCVar*GMcvar = new GMCVar();
1304  Create_Missing_CV(GMcvar,itd->first);
1305  this->cvars.push_back(GMcvar);
1306  }
1307  }//for (map<string,hsize_t>::iterator itd = dimname_to_dimsize.begin(); ...
1308 
1309 
1310 
1311 }
1312 
1314 
1315  iscoard = true;
1316  //map<string,hsize_t>::iterator itd;
1317 
1318  // Here we just need to loop through the map dimname_to_dimsize,
1319  // use the name and the size to create coordinate variables.
1320  for (map<string,hsize_t>::const_iterator itd = dimname_to_dimsize.begin();
1321  itd!=dimname_to_dimsize.end();++itd) {
1322 
1323  GMCVar*GMcvar = new GMCVar();
1324  if("nlon" == itd->first || "nlat" == itd->first
1325  || "lnH" == itd->first || "ltH" == itd->first
1326  || "lnL" == itd->first || "ltL" == itd->first) {
1327  GMcvar->name = itd->first;
1328  GMcvar->newname = GMcvar->name;
1329  GMcvar->fullpath = GMcvar->name;
1330  GMcvar->rank = 1;
1331  GMcvar->dtype = H5FLOAT32;
1332  Dimension* gmcvar_dim = new Dimension(itd->second);
1333  gmcvar_dim->name = GMcvar->name;
1334  gmcvar_dim->newname = gmcvar_dim->name;
1335  GMcvar->dims.push_back(gmcvar_dim);
1336  GMcvar->cfdimname = gmcvar_dim->name;
1337  if ("nlat" ==GMcvar->name || "ltH" == GMcvar->name
1338  || "ltL" == GMcvar->name)
1339  GMcvar->cvartype = CV_LAT_MISS;
1340  else if ("nlon" == GMcvar->name || "lnH" == GMcvar->name
1341  || "lnL" == GMcvar->name)
1342  GMcvar->cvartype = CV_LON_MISS;
1343  GMcvar->product_type = product_type;
1344  }
1345  else if (("nlayer" == itd->first && 28 == itd->second) ||
1346  ("hgt" == itd->first && 5 == itd->second) ||
1347  ("nalt" == itd->first && 5 == itd->second)){
1348  GMcvar->name = itd->first;
1349  GMcvar->newname = GMcvar->name;
1350  GMcvar->fullpath = GMcvar->name;
1351  GMcvar->rank = 1;
1352  GMcvar->dtype = H5FLOAT32;
1353  Dimension* gmcvar_dim = new Dimension(itd->second);
1354  gmcvar_dim->name = GMcvar->name;
1355  gmcvar_dim->newname = gmcvar_dim->name;
1356  GMcvar->dims.push_back(gmcvar_dim);
1357  GMcvar->cfdimname = gmcvar_dim->name;
1358  GMcvar->cvartype = CV_SPECIAL;
1359  GMcvar->product_type = product_type;
1360  }
1361  else
1362  Create_Missing_CV(GMcvar,itd->first);
1363  this->cvars.push_back(GMcvar);
1364  }//for (map<string,hsize_t>::iterator itd = dimname_to_dimsize.begin(); ...
1365 
1366 }
1367 
1369 
1370  pair<set<string>::iterator,bool> setret;
1371  set<string>tempdimnamelist = dimnamelist;
1372 
1373  for (set<string>::iterator irs = dimnamelist.begin();
1374  irs != dimnamelist.end();++irs) {
1375  for (vector<Var *>::iterator irv = this->vars.begin();
1376  irv != this->vars.end(); ++irv) {
1377  if ((*irs)== (*irv)->fullpath) {
1378 
1379  if (!iscoard && (("/natrack" == (*irs))
1380  || "/nxtrack" == (*irs)))
1381  continue;
1382 
1383  if((*irv)->dims.size()!=1)
1384  throw3("Coard coordinate variable",(*irv)->name, "is not 1D");
1385  // Create Coordinate variables.
1386  tempdimnamelist.erase(*irs);
1387  GMCVar* GMcvar = new GMCVar(*irv);
1388  GMcvar->cfdimname = *irs;
1389  GMcvar->cvartype = CV_EXIST;
1390  GMcvar->product_type = product_type;
1391  this->cvars.push_back(GMcvar);
1392  delete(*irv);
1393  this->vars.erase(irv);
1394  irv--;
1395  } // if ((*irs)== (*irv)->fullpath)
1396  else if(false == iscoard) {
1397  // 2-D lat/lon, natrack maps to lat, nxtrack maps to lon.
1398 
1399  if ((((*irs) =="/natrack") && ((*irv)->fullpath == "/latitude"))
1400  ||(((*irs) =="/nxtrack") && ((*irv)->fullpath == "/longitude"))) {
1401  tempdimnamelist.erase(*irs);
1402  GMCVar* GMcvar = new GMCVar(*irv);
1403  GMcvar->cfdimname = *irs;
1404  GMcvar->cvartype = CV_EXIST;
1405  GMcvar->product_type = product_type;
1406  this->cvars.push_back(GMcvar);
1407  delete(*irv);
1408  this->vars.erase(irv);
1409  irv--;
1410  }
1411  }// else if(false == iscoard)
1412  } // for (vector<Var *>::iterator irv = this->vars.begin() ...
1413  } // for (set<string>::iterator irs = dimnamelist.begin() ...
1414 
1415  // Creating the missing "third-dimension" according to the dimension names.
1416  // This may never happen for the current MeaSure SeaWiFS, but put it here for code coherence and completeness.
1417  // KY 12-30-2011
1418  for (set<string>::iterator irs = tempdimnamelist.begin();
1419  irs != tempdimnamelist.end();++irs) {
1420  GMCVar*GMcvar = new GMCVar();
1421  Create_Missing_CV(GMcvar,*irs);
1422  this->cvars.push_back(GMcvar);
1423  }
1424 }
1425 
1427 
1428  pair<set<string>::iterator,bool> setret;
1429  set<string>tempdimnamelist = dimnamelist;
1430  string tempvarname;
1431  string key0 = "_lat";
1432  string key1 = "_lon";
1433  string smapdim0 ="YDim";
1434  string smapdim1 ="XDim";
1435 
1436  bool foundkey0 = false;
1437  bool foundkey1 = false;
1438 
1439  set<string> itset;
1440 
1441  for (vector<Var *>::iterator irv = this->vars.begin();
1442  irv != this->vars.end(); ++irv) {
1443 
1444  tempvarname = (*irv)->name;
1445 
1446  if ((tempvarname.size() > key0.size())&&
1447  (key0 == tempvarname.substr(tempvarname.size()-key0.size(),key0.size()))){
1448  foundkey0 = true;
1449  if (dimnamelist.find(smapdim0)== dimnamelist.end())
1450  throw5("variable ",tempvarname," must have dimension ",smapdim0," , but not found ");
1451 
1452  tempdimnamelist.erase(smapdim0);
1453  GMCVar* GMcvar = new GMCVar(*irv);
1454  GMcvar->newname = GMcvar->name; // Remove the path, just use the variable name
1455  GMcvar->cfdimname = smapdim0;
1456  GMcvar->cvartype = CV_EXIST;
1457  GMcvar->product_type = product_type;
1458  this->cvars.push_back(GMcvar);
1459  delete(*irv);
1460  this->vars.erase(irv);
1461  irv--;
1462  }// if ((tempvarname.size() > key0.size())&& ...
1463 
1464  else if ((tempvarname.size() > key1.size())&&
1465  (key1 == tempvarname.substr(tempvarname.size()-key1.size(),key1.size()))){
1466  foundkey1 = true;
1467  if (dimnamelist.find(smapdim1)== dimnamelist.end())
1468  throw5("variable ",tempvarname," must have dimension ",smapdim1," , but not found ");
1469 
1470  tempdimnamelist.erase(smapdim1);
1471 
1472  GMCVar* GMcvar = new GMCVar(*irv);
1473  GMcvar->newname = GMcvar->name;
1474  GMcvar->cfdimname = smapdim1;
1475  GMcvar->cvartype = CV_EXIST;
1476  GMcvar->product_type = product_type;
1477  this->cvars.push_back(GMcvar);
1478  delete(*irv);
1479  this->vars.erase(irv);
1480  irv--;
1481  }// else if ((tempvarname.size() > key1.size())&& ...
1482  if (true == foundkey0 && true == foundkey1)
1483  break;
1484 
1485  } // for (vector<Var *>::iterator irv = this->vars.begin(); ...
1486 
1487  for (set<string>::iterator irs = tempdimnamelist.begin();
1488  irs != tempdimnamelist.end();++irs) {
1489 
1490  GMCVar*GMcvar = new GMCVar();
1491  Create_Missing_CV(GMcvar,*irs);
1492  this->cvars.push_back(GMcvar);
1493  }
1494 
1495 }
1496 
1498 
1499  iscoard = true;
1500  for (vector<Var *>::iterator irv = this->vars.begin();
1501  irv != this->vars.end(); ++irv) {
1502 
1503  if ( "l3m_data" == (*irv)->name) {
1504  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
1505  ird != (*irv)->dims.end(); ++ird) {
1506  GMCVar*GMcvar = new GMCVar();
1507  GMcvar->name = (*ird)->name;
1508  GMcvar->newname = GMcvar->name;
1509  GMcvar->fullpath = GMcvar->name;
1510  GMcvar->rank = 1;
1511  GMcvar->dtype = H5FLOAT32;
1512  Dimension* gmcvar_dim = new Dimension((*ird)->size);
1513  gmcvar_dim->name = GMcvar->name;
1514  gmcvar_dim->newname = gmcvar_dim->name;
1515  GMcvar->dims.push_back(gmcvar_dim);
1516  GMcvar->cfdimname = gmcvar_dim->name;
1517  if ("lat" ==GMcvar->name ) GMcvar->cvartype = CV_LAT_MISS;
1518  if ("lon" == GMcvar->name ) GMcvar->cvartype = CV_LON_MISS;
1519  GMcvar->product_type = product_type;
1520  this->cvars.push_back(GMcvar);
1521  } // for (vector<Dimension *>::iterator ird = (*irv)->dims.begin(); ...
1522  } // if ( "l3m_data" == (*irv)->name)
1523  }//for (vector<Var *>::iterator irv = this->vars.begin(); ...
1524 
1525 }
1526 
1528 
1529  pair<set<string>::iterator,bool> setret;
1530  set<string>tempdimnamelist = dimnamelist;
1531 
1532  if(false == iscoard)
1533  throw1("Measure Ozone level 3 zonal average product must follow COARDS conventions");
1534 
1535  for (set<string>::iterator irs = dimnamelist.begin();
1536  irs != dimnamelist.end();++irs) {
1537  for (vector<Var *>::iterator irv = this->vars.begin();
1538  irv != this->vars.end(); ++irv) {
1539  if ((*irs)== (*irv)->fullpath) {
1540 
1541  if((*irv)->dims.size()!=1)
1542  throw3("Coard coordinate variable",(*irv)->name, "is not 1D");
1543 
1544  // Create Coordinate variables.
1545  tempdimnamelist.erase(*irs);
1546  GMCVar* GMcvar = new GMCVar(*irv);
1547  GMcvar->cfdimname = *irs;
1548  GMcvar->cvartype = CV_EXIST;
1549  GMcvar->product_type = product_type;
1550  this->cvars.push_back(GMcvar);
1551  delete(*irv);
1552  this->vars.erase(irv);
1553  irv--;
1554  } // if ((*irs)== (*irv)->fullpath)
1555  } // for (vector<Var *>::iterator irv = this->vars.begin();
1556  } // for (set<string>::iterator irs = dimnamelist.begin();
1557 
1558  // Wait for the final product to see if the following statement is true. Now comment out.
1559  //if(false == tempdimnamelist.empty()) throw1("Measure Ozone level 3 new data shouldnot have missing dimensions");
1560  for (set<string>::iterator irs = tempdimnamelist.begin();
1561  irs != tempdimnamelist.end();irs++) {
1562 
1563  GMCVar*GMcvar = new GMCVar();
1564  Create_Missing_CV(GMcvar,*irs);
1565  this->cvars.push_back(GMcvar);
1566  }
1567 }
1568 
1569 
1571  pair<set<string>::iterator,bool> setret;
1572  set<string>tempdimnamelist = dimnamelist;
1573 
1574  if(false == iscoard)
1575  throw1("Currently products that use HDF5 dimension scales must follow COARDS conventions");
1576 
1577  for (set<string>::iterator irs = dimnamelist.begin();
1578  irs != dimnamelist.end();++irs) {
1579  for (vector<Var *>::iterator irv = this->vars.begin();
1580  irv != this->vars.end(); ++irv) {
1581 
1582  // This is the dimension scale dataset; it should be changed to a coordinate variable.
1583  if ((*irs)== (*irv)->fullpath) {
1584 
1585  if((*irv)->dims.size()!=1)
1586  throw3("COARDS coordinate variable",(*irv)->name, "is not 1D");
1587 
1588  // Create Coordinate variables.
1589  tempdimnamelist.erase(*irs);
1590  GMCVar* GMcvar = new GMCVar(*irv);
1591  GMcvar->cfdimname = *irs;
1592 
1593  // Check if this is just a netCDF-4 dimension.
1594  bool is_netcdf_dimension = Is_netCDF_Dimension(*irv);
1595  if (true == is_netcdf_dimension)
1596  GMcvar->cvartype = CV_FILLINDEX;
1597  else
1598  GMcvar->cvartype = CV_EXIST;
1599 
1600  GMcvar->product_type = product_type;
1601  this->cvars.push_back(GMcvar);
1602  delete(*irv);
1603  this->vars.erase(irv);
1604  irv--;
1605  } // if ((*irs)== (*irv)->fullpath)
1606  } // for (vector<Var *>::iterator irv = this->vars.begin();
1607  } // for (set<string>::iterator irs = dimnamelist.begin();
1608 
1609  // Wait for the final product to see if the following statement is true. Now comment out.
1610  //if(false == tempdimnamelist.empty()) throw1("Measure Ozone level 3 new data shouldnot have missing dimensions");
1611  for (set<string>::iterator irs = tempdimnamelist.begin();
1612  irs != tempdimnamelist.end();irs++) {
1613 
1614  GMCVar*GMcvar = new GMCVar();
1615  Create_Missing_CV(GMcvar,*irs);
1616  this->cvars.push_back(GMcvar);
1617  }
1618 
1619 }
1620 
1622 
1623  if (GENERAL_DIMSCALE == this->gproduct_pattern)
1625  // Change the CV Type of the corresponding CVs of lat and lon from CV_FILLINDEX to CV_LATMISS or CV_LONMISS
1626  for (vector<Var *>::iterator irv = this->vars.begin();
1627  irv != this->vars.end(); ++irv) {
1628 
1629  // Here I try to avoid using the dimension name row and column to find the lat/lon dimension size.
1630  // So I am looking for a 2-D floating-point array or a 2-D array under the group geophsical_data.
1631  // This may be subject to change if OBPG level 3 change its arrangement of variables.
1632  // KY 2014-09-29
1633 
1634  if((*irv)->rank == 2) {
1635 
1636  if(((*irv)->fullpath.find("/geophsical_data") == 0) || ((*irv)->dtype == H5FLOAT32)) {
1637 
1638  size_t lat_size = (*irv)->getDimensions()[0]->size;
1639  string lat_name = (*irv)->getDimensions()[0]->name;
1640  size_t lon_size = (*irv)->getDimensions()[1]->size;
1641  string lon_name = (*irv)->getDimensions()[1]->name;
1642  size_t temp_size = 0;
1643  string temp_name;
1644  H5DataType ll_dtype = (*irv)->dtype;
1645 
1646 //cerr<<"lat_name is "<<lat_name <<endl;
1647 //cerr<<"lon_name is "<<lon_name <<endl;
1648  // We always assume that longitude size is greater than latitude size.
1649  if(lat_size >lon_size) {
1650  temp_size = lon_size;
1651  temp_name = lon_name;
1652  lon_size = lat_size;
1653  lon_name = lat_name;
1654  lat_size = temp_size;
1655  lat_name = temp_name;
1656  }
1657  for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
1658  ircv != this->cvars.end(); ++ircv) {
1659  if((*ircv)->cvartype == CV_FILLINDEX) {
1660  if((*ircv)->getDimensions()[0]->size == lat_size &&
1661  (*ircv)->getDimensions()[0]->name == lat_name) {
1662  (*ircv)->cvartype = CV_LAT_MISS;
1663  (*ircv)->dtype = ll_dtype;
1664  for (vector<Attribute *>::iterator ira = (*ircv)->attrs.begin();
1665  ira != (*ircv)->attrs.end(); ++ira) {
1666  if ((*ira)->name == "NAME") {
1667  delete (*ira);
1668  (*ircv)->attrs.erase(ira);
1669  break;
1670  }
1671  }
1672  }
1673  else if((*ircv)->getDimensions()[0]->size == lon_size &&
1674  (*ircv)->getDimensions()[0]->name == lon_name) {
1675  (*ircv)->cvartype = CV_LON_MISS;
1676  (*ircv)->dtype = ll_dtype;
1677  for (vector<Attribute *>::iterator ira = (*ircv)->attrs.begin();
1678  ira != (*ircv)->attrs.end(); ++ira) {
1679  if ((*ira)->name == "NAME") {
1680  delete (*ira);
1681  (*ircv)->attrs.erase(ira);
1682  break;
1683  }
1684  }
1685  }
1686 
1687  }
1688  }
1689  break;
1690 
1691  } // if(((*irv)->fullpath.find("/geophsical_data") == 0) || ((*irv)->dtype == H5FLOAT32))
1692  } // if((*irv)->rank == 2)
1693  } // for (vector<Var *>::iterator irv = this->vars.begin();
1694 
1695 }
1696 
1698  if (ACOS_L2S == product_type)
1700  else if(GPM_L1 == product_type) {
1701  // Loop through the variable list to build the coordinates.
1702  for (vector<Var *>::iterator irv = this->vars.begin();
1703  irv != this->vars.end(); ++irv) {
1704  if((*irv)->name=="AlgorithmRuntimeInfo") {
1705  delete(*irv);
1706  this->vars.erase(irv);
1707  break;
1708  }
1709  }
1710  }
1711 
1712  else if(GPMM_L3 == product_type || GPMS_L3 == product_type) {
1713 
1714  for (vector<Var *>::iterator irv = this->vars.begin();
1715  irv != this->vars.end(); ++irv) {
1716  if((*irv)->name=="InputFileNames") {
1717  delete(*irv);
1718  this->vars.erase(irv);
1719  irv--;
1720  }
1721  else if((*irv)->name=="InputAlgorithmVersions") {
1722  delete(*irv);
1723  this->vars.erase(irv);
1724  irv--;
1725  }
1726  else if((*irv)->name=="InputGenerationDateTimes") {
1727  delete(*irv);
1728  this->vars.erase(irv);
1729  irv--;
1730  }
1731 
1732  }
1733 
1734  }
1735 
1736 }
1737 
1739 
1740  //The ACOS only have 64-bit variables. So we will not handle attributes yet.
1741  for (vector<Var *>::iterator irv = this->vars.begin();
1742  irv != this->vars.end(); ++irv) {
1743  if (H5INT64 == (*irv)->getType()) {
1744 
1745  // First: Time Part of soundingid
1746  GMSPVar * spvar = new GMSPVar(*irv);
1747  spvar->name = (*irv)->name +"_Time";
1748  spvar->newname = (*irv)->newname+"_Time";
1749  spvar->dtype = H5INT32;
1750  spvar->otype = (*irv)->getType();
1751  spvar->sdbit = 1;
1752 
1753  // 2 digit hour, 2 digit min, 2 digit seconds
1754  spvar->numofdbits = 6;
1755  this->spvars.push_back(spvar);
1756 
1757  // Second: Date Part of soundingid
1758  GMSPVar * spvar2 = new GMSPVar(*irv);
1759  spvar2->name = (*irv)->name +"_Date";
1760  spvar2->newname = (*irv)->newname+"_Date";
1761  spvar2->dtype = H5INT32;
1762  spvar2->otype = (*irv)->getType();
1763  spvar2->sdbit = 7;
1764 
1765  // 4 digit year, 2 digit month, 2 digit day
1766  spvar2->numofdbits = 8;
1767  this->spvars.push_back(spvar2);
1768 
1769  delete(*irv);
1770  this->vars.erase(irv);
1771  irv--;
1772  } // if (H5INT64 == (*irv)->getType())
1773  } // for (vector<Var *>::iterator irv = this->vars.begin(); ...
1774 }
1775 
1776 
1778 
1779  if(Mea_Ozone == product_type)
1781 
1782  if(GPMS_L3 == product_type || GPMM_L3 == product_type)
1784 
1785 // Just for debugging
1786 #if 0
1787 for (vector<Var*>::iterator irv2 = this->vars.begin();
1788  irv2 != this->vars.end(); irv2++) {
1789  for (vector<Dimension *>::iterator ird = (*irv2)->dims.begin();
1790  ird !=(*irv2)->dims.end(); ird++) {
1791  cerr<<"Dimension name afet Adjust_Obj_Name "<<(*ird)->newname <<endl;
1792  }
1793 }
1794 #endif
1795 
1796 
1797 }
1798 
1800 
1801 //cerr<<"number of group is "<<this->groups.size() <<endl;
1802  string objnewname;
1803  // In this definition, root group is not considered as a group.
1804  if(this->groups.size() <= 1) {
1805  for (vector<Var *>::iterator irv = this->vars.begin();
1806  irv != this->vars.end(); ++irv) {
1807  objnewname = HDF5CFUtil::obtain_string_after_lastslash((*irv)->newname);
1808  if (objnewname !="")
1809  (*irv)->newname = objnewname;
1810  }
1811  }
1812  else {
1813  for (vector<Var *>::iterator irv = this->vars.begin();
1814  irv != this->vars.end(); ++irv) {
1815 //cerr<<"(*irv)->newname is "<<(*irv)->newname <<endl;
1816  size_t grid_group_path_pos = ((*irv)->newname.substr(1)).find_first_of("/");
1817  objnewname = ((*irv)->newname).substr(grid_group_path_pos+2);
1818  (*irv)->newname = objnewname;
1819  }
1820 
1821 
1822  }
1823 }
1824 
1826 
1827  string objnewname;
1828  for (vector<Var *>::iterator irv = this->vars.begin();
1829  irv != this->vars.end(); ++irv) {
1830  objnewname = HDF5CFUtil::obtain_string_after_lastslash((*irv)->newname);
1831  if (objnewname !="")
1832  (*irv)->newname = objnewname;
1833 
1834 #if 0
1835 //Just for debugging
1836 for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
1837  ird !=(*irv)->dims.end();++ird) {
1838  cerr<<"Ozone dim. name "<<(*ird)->name <<endl;
1839  cerr<<"Ozone dim. new name "<<(*ird)->newname <<endl;
1840 }
1841 #endif
1842 
1843  }
1844 
1845  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
1846  irv != this->cvars.end(); ++irv) {
1847  objnewname = HDF5CFUtil::obtain_string_after_lastslash((*irv)->newname);
1848  if (objnewname !="")
1849  (*irv)->newname = objnewname;
1850 #if 0
1851  //Just for debugging
1852 for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
1853  ird !=(*irv)->dims.end();++ird) {
1854  cerr<<"Ozone CV dim. name "<<(*ird)->name <<endl;
1855  cerr<<"Ozone CV dim. new name "<<(*ird)->newname <<endl;
1856 }
1857 #endif
1858  }
1859 }
1860 void GMFile::Flatten_Obj_Name(bool include_attr) throw(Exception){
1861 
1862  File::Flatten_Obj_Name(include_attr);
1863 
1864  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
1865  irv != this->cvars.end(); ++irv) {
1866  (*irv)->newname = get_CF_string((*irv)->newname);
1867 
1868  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
1869  ird != (*irv)->dims.end(); ++ird) {
1870  (*ird)->newname = get_CF_string((*ird)->newname);
1871  }
1872 
1873 
1874 
1875  if (true == include_attr) {
1876  for (vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
1877  ira != (*irv)->attrs.end(); ++ira)
1878  (*ira)->newname = get_CF_string((*ira)->newname);
1879 
1880  }
1881 
1882  }
1883 
1884  for (vector<GMSPVar *>::iterator irv = this->spvars.begin();
1885  irv != this->spvars.end(); ++irv) {
1886  (*irv)->newname = get_CF_string((*irv)->newname);
1887 
1888  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
1889  ird != (*irv)->dims.end(); ++ird)
1890  (*ird)->newname = get_CF_string((*ird)->newname);
1891 
1892  if (true == include_attr) {
1893  for (vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
1894  ira != (*irv)->attrs.end(); ++ira)
1895  (*ira)->newname = get_CF_string((*ira)->newname);
1896 
1897  }
1898  }
1899 
1900 // Just for debugging
1901 #if 0
1902 for (vector<Var*>::iterator irv2 = this->vars.begin();
1903  irv2 != this->vars.end(); irv2++) {
1904  for (vector<Dimension *>::iterator ird = (*irv2)->dims.begin();
1905  ird !=(*irv2)->dims.end(); ird++) {
1906  cerr<<"Dimension name afet Flatten_Obj_Name "<<(*ird)->newname <<endl;
1907  }
1908 }
1909 #endif
1910 
1911 
1912 }
1913 
1914 void GMFile::Handle_Obj_NameClashing(bool include_attr) throw(Exception) {
1915 
1916  // objnameset will be filled with all object names that we are going to check the name clashing.
1917  // For example, we want to see if there are any name clashings for all variable names in this file.
1918  // objnameset will include all variable names. If a name clashing occurs, we can figure out from the set operation immediately.
1919 
1920  set<string>objnameset;
1921  Handle_GMCVar_NameClashing(objnameset);
1922  Handle_GMSPVar_NameClashing(objnameset);
1923  File::Handle_GeneralObj_NameClashing(include_attr,objnameset);
1924  if (true == include_attr) {
1925  Handle_GMCVar_AttrNameClashing();
1926  Handle_GMSPVar_AttrNameClashing();
1927  }
1928  // Moving to h5gmcfdap.cc, right after Adjust_Dim_Name
1929  //Handle_DimNameClashing();
1930 }
1931 
1932 void GMFile::Handle_GMCVar_NameClashing(set<string> &objnameset ) throw(Exception) {
1933 
1934  GMHandle_General_NameClashing(objnameset,this->cvars);
1935 }
1936 
1937 void GMFile::Handle_GMSPVar_NameClashing(set<string> &objnameset ) throw(Exception) {
1938 
1939  GMHandle_General_NameClashing(objnameset,this->spvars);
1940 }
1941 
1942 
1944 
1945  set<string> objnameset;
1946 
1947  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
1948  irv != this->cvars.end(); ++irv) {
1949  Handle_General_NameClashing(objnameset,(*irv)->attrs);
1950  objnameset.clear();
1951  }
1952 }
1954 
1955  set<string> objnameset;
1956 
1957  for (vector<GMSPVar *>::iterator irv = this->spvars.begin();
1958  irv != this->spvars.end(); ++irv) {
1959  Handle_General_NameClashing(objnameset,(*irv)->attrs);
1960  objnameset.clear();
1961  }
1962 }
1963 
1964 //class T must have member string newname
1965 template<class T> void
1966 GMFile::GMHandle_General_NameClashing(set <string>&objnameset, vector<T*>& objvec) throw(Exception){
1967 
1968  pair<set<string>::iterator,bool> setret;
1969  set<string>::iterator iss;
1970 
1971  vector<string> clashnamelist;
1972  vector<string>::iterator ivs;
1973 
1974  map<int,int> cl_to_ol;
1975  int ol_index = 0;
1976  int cl_index = 0;
1977 
1978  typename vector<T*>::iterator irv;
1979  //for (vector<T*>::iterator irv = objvec.begin();
1980 
1981  for (irv = objvec.begin();
1982  irv != objvec.end(); ++irv) {
1983 
1984  setret = objnameset.insert((*irv)->newname);
1985  if (false == setret.second ) {
1986  clashnamelist.insert(clashnamelist.end(),(*irv)->newname);
1987  cl_to_ol[cl_index] = ol_index;
1988  cl_index++;
1989  }
1990  ol_index++;
1991  }
1992 
1993 
1994  // Now change the clashed elements to unique elements;
1995  // Generate the set which has the same size as the original vector.
1996 
1997  for (ivs=clashnamelist.begin(); ivs!=clashnamelist.end(); ++ivs) {
1998  int clash_index = 1;
1999  string temp_clashname = *ivs +'_';
2000  HDF5CFUtil::gen_unique_name(temp_clashname,objnameset,clash_index);
2001  *ivs = temp_clashname;
2002  }
2003 
2004 
2005  // Now go back to the original vector, make it unique.
2006  for (unsigned int i =0; i <clashnamelist.size(); i++)
2007  objvec[cl_to_ol[i]]->newname = clashnamelist[i];
2008 
2009 }
2010 
2012 
2013 //cerr<<"coming to DimNameClashing "<<endl;
2014 
2015  // ACOS L2S product doesn't need the dimension name clashing check based on our current understanding. KY 2012-5-16
2016  if (ACOS_L2S == product_type) return;
2017 
2018  map<string,string>dimname_to_dimnewname;
2019  pair<map<string,string>::iterator,bool>mapret;
2020  set<string> dimnameset;
2021  vector<Dimension*>vdims;
2022  set<string> dimnewnameset;
2023  pair<set<string>::iterator,bool> setret;
2024 
2025  // First: Generate the dimset/dimvar based on coordinate variables.
2026  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
2027  irv !=this->cvars.end(); ++irv) {
2028  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2029  ird !=(*irv)->dims.end();++ird) {
2030  //setret = dimnameset.insert((*ird)->newname);
2031  setret = dimnameset.insert((*ird)->name);
2032  if (true == setret.second)
2033  vdims.push_back(*ird);
2034  }
2035  }
2036 
2037  // For some cases, dimension names are provided but there are no corresponding coordinate
2038  // variables. For now, we will assume no such cases.
2039  // Actually, we find such a case in our fake testsuite. So we need to fix it.
2040  for(vector<Var *>::iterator irv= this->vars.begin();
2041  irv != this->vars.end();++irv) {
2042  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2043  ird !=(*irv)->dims.end();++ird) {
2044  //setret = dimnameset.insert((*ird)->newname);
2045  setret = dimnameset.insert((*ird)->name);
2046  if (setret.second) vdims.push_back(*ird);
2047  }
2048  }
2049 
2050  // For some cases, dimension names are provided but there are no corresponding coordinate
2051  // variables. For now, we will assume no such cases.
2052  GMHandle_General_NameClashing(dimnewnameset,vdims);
2053 
2054  // Third: Make dimname_to_dimnewname map
2055  for (vector<Dimension*>::iterator ird = vdims.begin();ird!=vdims.end();++ird) {
2056  mapret = dimname_to_dimnewname.insert(pair<string,string>((*ird)->name,(*ird)->newname));
2057  if (false == mapret.second)
2058  throw4("The dimension name ",(*ird)->name," should map to ",
2059  (*ird)->newname);
2060  }
2061 
2062  // Fourth: Change the original dimension new names to the unique dimension new names
2063  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
2064  irv !=this->cvars.end(); ++irv)
2065  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2066  ird!=(*irv)->dims.end();++ird)
2067  (*ird)->newname = dimname_to_dimnewname[(*ird)->name];
2068 
2069  for (vector<Var *>::iterator irv = this->vars.begin();
2070  irv != this->vars.end(); ++irv)
2071  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2072  ird !=(*irv)->dims.end();++ird)
2073  (*ird)->newname = dimname_to_dimnewname[(*ird)->name];
2074 
2075 }
2076 
2077 
2079 
2080 #if 0
2081  // Just for debugging
2082 for (vector<Var*>::iterator irv2 = this->vars.begin();
2083  irv2 != this->vars.end(); irv2++) {
2084  for (vector<Dimension *>::iterator ird = (*irv2)->dims.begin();
2085  ird !=(*irv2)->dims.end(); ird++) {
2086  cerr<<"Dimension new name "<<(*ird)->newname <<endl;
2087  }
2088 }
2089 #endif
2090 
2091  // Only need for COARD conventions.
2092  if( true == iscoard) {
2093  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
2094  irv !=this->cvars.end(); ++irv) {
2095  if ((*irv)->dims.size()!=1)
2096  throw3("Coard coordinate variable ",(*irv)->name, "is not 1D");
2097  if ((*irv)->newname != (((*irv)->dims)[0]->newname)) {
2098  ((*irv)->dims)[0]->newname = (*irv)->newname;
2099 
2100  // For all variables that have this dimension,the dimension newname should also change.
2101  for (vector<Var*>::iterator irv2 = this->vars.begin();
2102  irv2 != this->vars.end(); ++irv2) {
2103  for (vector<Dimension *>::iterator ird = (*irv2)->dims.begin();
2104  ird !=(*irv2)->dims.end(); ++ird) {
2105  // This is the key, the dimension name of this dimension
2106  // should be equal to the dimension name of the coordinate variable.
2107  // Then the dimension name matches and the dimension name should be changed to
2108  // the new dimension name.
2109  if ((*ird)->name == ((*irv)->dims)[0]->name)
2110  (*ird)->newname = ((*irv)->dims)[0]->newname;
2111  }
2112  }
2113  } // if ((*irv)->newname != (((*irv)->dims)[0]->newname))
2114  }// for (vector<GMCVar *>::iterator irv = this->cvars.begin(); ...
2115  } // if( true == iscoard)
2116 
2117 // Just for debugging
2118 #if 0
2119 for (vector<Var*>::iterator irv2 = this->vars.begin();
2120  irv2 != this->vars.end(); irv2++) {
2121  for (vector<Dimension *>::iterator ird = (*irv2)->dims.begin();
2122  ird !=(*irv2)->dims.end(); ird++) {
2123  cerr<<"Dimension name afet Adjust_Dim_Name "<<(*ird)->newname <<endl;
2124  }
2125 }
2126 #endif
2127 
2128 
2129 }
2130 
2131 void
2133 
2134  if (General_Product == product_type || true == add_path) {
2135  File::Add_Supplement_Attrs(add_path);
2136 
2137  // Adding variable original name(origname) and full path(fullpath)
2138  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
2139  irv != this->cvars.end(); ++irv) {
2140  if (((*irv)->cvartype == CV_EXIST) || ((*irv)->cvartype == CV_MODIFY)) {
2141  Attribute * attr = new Attribute();
2142  const string varname = (*irv)->name;
2143  const string attrname = "origname";
2144  Add_Str_Attr(attr,attrname,varname);
2145  (*irv)->attrs.push_back(attr);
2146  }
2147  }
2148 
2149  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
2150  irv != this->cvars.end(); ++irv) {
2151  if (((*irv)->cvartype == CV_EXIST) || ((*irv)->cvartype == CV_MODIFY)) {
2152  Attribute * attr = new Attribute();
2153  const string varname = (*irv)->fullpath;
2154  const string attrname = "fullnamepath";
2155  Add_Str_Attr(attr,attrname,varname);
2156  (*irv)->attrs.push_back(attr);
2157  }
2158  }
2159 
2160  for (vector<GMSPVar *>::iterator irv = this->spvars.begin();
2161  irv != this->spvars.end(); ++irv) {
2162  Attribute * attr = new Attribute();
2163  const string varname = (*irv)->name;
2164  const string attrname = "origname";
2165  Add_Str_Attr(attr,attrname,varname);
2166  (*irv)->attrs.push_back(attr);
2167  }
2168 
2169  for (vector<GMSPVar *>::iterator irv = this->spvars.begin();
2170  irv != this->spvars.end(); ++irv) {
2171  Attribute * attr = new Attribute();
2172  const string varname = (*irv)->fullpath;
2173  const string attrname = "fullnamepath";
2174  Add_Str_Attr(attr,attrname,varname);
2175  (*irv)->attrs.push_back(attr);
2176  }
2177  } // if (General_Product == product_type || true == add_path)
2178 
2179  if(GPM_L1 == product_type || GPMS_L3 == product_type || GPMM_L3 == product_type)
2180  Add_GPM_Attrs();
2181  else if (Aqu_L3 == product_type)
2182  Add_Aqu_Attrs();
2183  else if (Mea_SeaWiFS_L2 == product_type || Mea_SeaWiFS_L3 == product_type)
2184  Add_SeaWiFS_Attrs();
2185 
2186 }
2187 
2188 void
2190 
2191  vector<HDF5CF::Var *>::const_iterator it_v;
2192  vector<HDF5CF::Attribute *>::const_iterator ira;
2193  const string attr_name_be_replaced = "CodeMissingValue";
2194  const string attr_new_name = "_FillValue";
2195  const string attr_cor_fill_value = "-9999.9";
2196  const string attr2_name_be_replaced = "Units";
2197  const string attr2_new_name ="units";
2198 
2199  // Need to convert String type CodeMissingValue to the corresponding _FilLValue
2200  // Create a function at HDF5CF.cc. use strtod,strtof,strtol etc. function to convert
2201  // string to the corresponding type.
2202  for (it_v = vars.begin(); it_v != vars.end(); ++it_v) {
2203  for(ira = (*it_v)->attrs.begin(); ira!= (*it_v)->attrs.end();ira++) {
2204  if((attr_name_be_replaced == (*ira)->name)) {
2205  if((*ira)->dtype == H5FSTRING)
2206  Change_Attr_One_Str_to_Others((*ira),(*it_v));
2207  (*ira)->name = attr_new_name;
2208  (*ira)->newname = attr_new_name;
2209  }
2210  }
2211 
2212  }
2213 
2214 
2215  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
2216  irv != this->cvars.end(); ++irv) {
2217 
2218  for(ira = (*irv)->attrs.begin(); ira!= (*irv)->attrs.end();ira++) {
2219 
2220  if(attr_name_be_replaced == (*ira)->name) {
2221  if((*ira)->dtype == H5FSTRING)
2222  Change_Attr_One_Str_to_Others((*ira),(*irv));
2223  (*ira)->name = attr_new_name;
2224  (*ira)->newname = attr_new_name;
2225  break;
2226  }
2227  }
2228 
2229  if(product_type == GPM_L1) {
2230  if ((*irv)->cvartype == CV_EXIST) {
2231 
2232  for(ira = (*irv)->attrs.begin(); ira!= (*irv)->attrs.end();ira++) {
2233 
2234  if(attr2_name_be_replaced == (*ira)->name) {
2235 
2236  if((*irv)->name.find("Latitude") !=string::npos) {
2237 
2238  string unit_value = "degrees_north";
2239  (*ira)->value.clear();
2240  Add_Str_Attr(*ira,attr2_new_name,unit_value);
2241  //(*ira)->value.resize(unit_value.size());
2242  //copy(unit_value.begin(),unit_value.end(),(*ira)->value.begin());
2243  }
2244 
2245  else if((*irv)->name.find("Longitude") !=string::npos) {
2246 
2247  string unit_value = "degrees_east";
2248  (*ira)->value.clear();
2249  Add_Str_Attr(*ira,attr2_new_name,unit_value);
2250  //(*ira)->value.resize(unit_value.size());
2251  //copy(unit_value.begin(),unit_value.end(),(*ira)->value.begin());
2252  }
2253  }
2254  }
2255  }
2256 
2257  else if ((*irv)->cvartype == CV_NONLATLON_MISS) {
2258 
2259  string comment;
2260  const string attrname = "comment";
2261  Attribute*attr = new Attribute();
2262 
2263  {
2264  if((*irv)->name == "nchannel1")
2265  comment = "Number of Swath S1 channels (10V 10H 19V 19H 23V 37V 37H 89V 89H).";
2266  else if((*irv)->name == "nchannel2")
2267  comment = "Number of Swath S2 channels (166V 166H 183+/-3V 183+/-8V).";
2268  else if((*irv)->name == "nchan1")
2269  comment = "Number of channels in Swath 1.";
2270  else if((*irv)->name == "nchan2")
2271  comment = "Number of channels in Swath 2.";
2272  else if((*irv)->name == "VH")
2273  comment = "Number of polarizations.";
2274  else if((*irv)->name == "GMIxyz")
2275  comment = "x, y, z components in GMI instrument coordinate system.";
2276  else if((*irv)->name == "LNL")
2277  comment = "Linear and non-linear.";
2278  else if((*irv)->name == "nscan")
2279  comment = "Number of scans in the granule.";
2280  else if((*irv)->name == "nscan1")
2281  comment = "Typical number of Swath S1 scans in the granule.";
2282  else if((*irv)->name == "nscan2")
2283  comment = "Typical number of Swath S2 scans in the granule.";
2284  else if((*irv)->name == "npixelev")
2285  comment = "Number of earth view pixels in one scan.";
2286  else if((*irv)->name == "npixelht")
2287  comment = "Number of hot load pixels in one scan.";
2288  else if((*irv)->name == "npixelcs")
2289  comment = "Number of cold sky pixels in one scan.";
2290  else if((*irv)->name == "npixelfr")
2291  comment = "Number of full rotation earth view pixels in one scan.";
2292  else if((*irv)->name == "nfreq1")
2293  comment = "Number of frequencies in Swath 1.";
2294  else if((*irv)->name == "nfreq2")
2295  comment = "Number of frequencies in Swath 2.";
2296  else if((*irv)->name == "npix1")
2297  comment = "Number of pixels in Swath 1.";
2298  else if((*irv)->name == "npix2")
2299  comment = "Number of pixels in Swath 2.";
2300  else if((*irv)->name == "npix3")
2301  comment = "Number of pixels in Swath 3.";
2302  else if((*irv)->name == "npix4")
2303  comment = "Number of pixels in Swath 4.";
2304  else if((*irv)->name == "ncolds1")
2305  comment = "Maximum number of cold samples in Swath 1.";
2306  else if((*irv)->name == "ncolds2")
2307  comment = "Maximum number of cold samples in Swath 2.";
2308  else if((*irv)->name == "nhots1")
2309  comment = "Maximum number of hot samples in Swath 1.";
2310  else if((*irv)->name == "nhots2")
2311  comment = "Maximum number of hot samples in Swath 2.";
2312  else if((*irv)->name == "ntherm")
2313  comment = "Number of hot load thermisters.";
2314  else if((*irv)->name == "ntach")
2315  comment = "Number of tachometer readings.";
2316  else if((*irv)->name == "nsamt"){
2317  comment = "Number of sample types. ";
2318  comment = +"The types are: total science GSDR, earthview,hot load, cold sky.";
2319  }
2320  else if((*irv)->name == "nndiode")
2321  comment = "Number of noise diodes.";
2322  else if((*irv)->name == "n7")
2323  comment = "Number seven.";
2324  else if((*irv)->name == "nray")
2325  comment = "Number of angle bins in each NS scan.";
2326  else if((*irv)->name == "nrayMS")
2327  comment = "Number of angle bins in each MS scan.";
2328  else if((*irv)->name == "nrayHS")
2329  comment = "Number of angle bins in each HS scan.";
2330  else if((*irv)->name == "nbin")
2331  comment = "Number of range bins in each NS and MS ray. Bin interval is 125m.";
2332  else if((*irv)->name == "nbinHS")
2333  comment = "Number of range bins in each HS ray. Bin interval is 250m.";
2334  else if((*irv)->name == "nbinSZP")
2335  comment = "Number of range bins for sigmaZeroProfile.";
2336  else if((*irv)->name == "nbinSZPHS")
2337  comment = "Number of range bins for sigmaZeroProfile in each HS scan.";
2338  else if((*irv)->name == "nNP")
2339  comment = "Number of NP kinds.";
2340  else if((*irv)->name == "nearFar")
2341  comment = "Near reference, Far reference.";
2342  else if((*irv)->name == "foreBack")
2343  comment = "Forward, Backward.";
2344  else if((*irv)->name == "method")
2345  comment = "Number of SRT methods.";
2346  else if((*irv)->name == "nNode")
2347  comment = "Number of binNode.";
2348  else if((*irv)->name == "nDSD")
2349  comment = "Number of DSD parameters. Parameters are N0 and D0";
2350  else if((*irv)->name == "LS")
2351  comment = "Liquid, solid.";
2352  }
2353 
2354  if(""==comment)
2355  delete attr;
2356  else {
2357  Add_Str_Attr(attr,attrname,comment);
2358  (*irv)->attrs.push_back(attr);
2359  }
2360 
2361  }
2362  }
2363 
2364  if(product_type == GPMS_L3 || product_type == GPMM_L3) {
2365  if ((*irv)->cvartype == CV_NONLATLON_MISS) {
2366 
2367  string comment;
2368  const string attrname = "comment";
2369  Attribute*attr = new Attribute();
2370 
2371  {
2372  if((*irv)->name == "chn")
2373  comment = "Number of channels:Ku,Ka,KaHS,DPR.";
2374  else if((*irv)->name == "inst")
2375  comment = "Number of instruments:Ku,Ka,KaHS.";
2376  else if((*irv)->name == "tim")
2377  comment = "Number of hours(local time).";
2378  else if((*irv)->name == "ang"){
2379  comment = "Number of angles.The meaning of ang is different for each channel.";
2380  comment +=
2381  "For Ku channel all indices are used with the meaning 0,1,2,..6 =angle bins 24,";
2382  comment +=
2383  "(20,28),(16,32),(12,36),(8,40),(3,44),and (0,48).";
2384  comment +=
2385  "For Ka channel 4 indices are used with the meaning 0,1,2,3 = angle bins 12,(8,16),";
2386  comment +=
2387  "(4,20),and (0,24). For KaHS channel 4 indices are used with the meaning 0,1,2,3 =";
2388  comment += "angle bins(11,2),(7,16),(3,20),and (0.23).";
2389 
2390  }
2391  else if((*irv)->name == "rt")
2392  comment = "Number of rain types: stratiform, convective,all.";
2393  else if((*irv)->name == "st")
2394  comment = "Number of surface types:ocean,land,all.";
2395  else if((*irv)->name == "bin"){
2396  comment = "Number of bins in histogram. The thresholds are different for different";
2397  comment +=" variables. see the file specification for this algorithm.";
2398  }
2399  else if((*irv)->name == "nvar") {
2400  comment = "Number of phase bins. Bins are counts of phase less than 100, ";
2401  comment +="counts of phase greater than or equal to 100 and less than 200, ";
2402  comment +="counts of phase greater than or equal to 200.";
2403  }
2404  else if((*irv)->name == "AD")
2405  comment = "Ascending or descending half of the orbit.";
2406  }
2407 
2408  if(""==comment)
2409  delete attr;
2410  else {
2411  Add_Str_Attr(attr,attrname,comment);
2412  (*irv)->attrs.push_back(attr);
2413  }
2414 
2415  }
2416  }
2417 
2418 
2419  if ((*irv)->cvartype == CV_SPECIAL) {
2420  if((*irv)->name == "nlayer" || (*irv)->name == "hgt"
2421  || (*irv)->name == "nalt") {
2422  Attribute*attr = new Attribute();
2423  string unit_value = "km";
2424  Add_Str_Attr(attr,attr2_new_name,unit_value);
2425  (*irv)->attrs.push_back(attr);
2426 
2427  Attribute*attr1 = new Attribute();
2428  string attr1_axis="axis";
2429  string attr1_value = "Z";
2430  Add_Str_Attr(attr1,attr1_axis,attr1_value);
2431  (*irv)->attrs.push_back(attr1);
2432 
2433  Attribute*attr2 = new Attribute();
2434  string attr2_positive="positive";
2435  string attr2_value = "up";
2436  Add_Str_Attr(attr2,attr2_positive,attr2_value);
2437  (*irv)->attrs.push_back(attr2);
2438 
2439  }
2440  if((*irv)->name == "hgt" || (*irv)->name == "nalt"){
2441  Attribute*attr1 = new Attribute();
2442  string comment ="Number of heights above the earth ellipsoid";
2443  Add_Str_Attr(attr1,"comment",comment);
2444  (*irv)->attrs.push_back(attr1);
2445  }
2446 
2447  }
2448 
2449  }
2450 
2451 
2452 
2453 
2454 // Old code, leave it for the time being
2455 #if 0
2456  const string fill_value_attr_name = "_FillValue";
2457  vector<HDF5CF::Var *>::const_iterator it_v;
2458  vector<HDF5CF::Attribute *>::const_iterator ira;
2459 
2460  for (it_v = vars.begin();
2461  it_v != vars.end(); ++it_v) {
2462 
2463  bool has_fillvalue = false;
2464  for(ira = (*it_v)->attrs.begin(); ira!= (*it_v)->attrs.end();ira++) {
2465  if (fill_value_attr_name == (*ira)->name){
2466  has_fillvalue = true;
2467  break;
2468  }
2469 
2470  }
2471 
2472  // Add the fill value
2473  if (has_fillvalue != true ) {
2474 
2475  if(H5FLOAT32 == (*it_v)->dtype) {
2476  Attribute* attr = new Attribute();
2477  float _FillValue = -9999.9;
2478  Add_One_Float_Attr(attr,fill_value_attr_name,_FillValue);
2479  (*it_v)->attrs.push_back(attr);
2480  }
2481  }
2482  }// for (it_v = vars.begin(); ...
2483 #endif
2484 
2485 }
2486 
2487 void
2489 
2490  vector<HDF5CF::Var *>::const_iterator it_v;
2491  vector<HDF5CF::Attribute *>::const_iterator ira;
2492 
2493  const string orig_longname_attr_name = "Parameter";
2494  const string longname_attr_name ="long_name";
2495  string longname_value;
2496 
2497 
2498  const string orig_units_attr_name = "Units";
2499  const string units_attr_name = "units";
2500  string units_value;
2501 
2502  // const string orig_valid_min_attr_name = "Data Minimum";
2503  const string orig_valid_min_attr_name = "Data Minimum";
2504  const string valid_min_attr_name = "valid_min";
2505  float valid_min_value;
2506 
2507  const string orig_valid_max_attr_name = "Data Maximum";
2508  const string valid_max_attr_name = "valid_max";
2509  float valid_max_value;
2510 
2511  // The fill value is -32767.0. However, No _FillValue attribute is added.
2512  // So add it here. KY 2012-2-16
2513 
2514  const string fill_value_attr_name = "_FillValue";
2515  float _FillValue = -32767.0;
2516 
2517 
2518 
2519  for (ira = this->root_attrs.begin(); ira != this->root_attrs.end(); ++ira) {
2520  if (orig_longname_attr_name == (*ira)->name) {
2521  Retrieve_H5_Attr_Value(*ira,"/");
2522  longname_value.resize((*ira)->value.size());
2523  copy((*ira)->value.begin(),(*ira)->value.end(),longname_value.begin());
2524 
2525  }
2526  else if (orig_units_attr_name == (*ira)->name) {
2527  Retrieve_H5_Attr_Value(*ira,"/");
2528  units_value.resize((*ira)->value.size());
2529  copy((*ira)->value.begin(),(*ira)->value.end(),units_value.begin());
2530 
2531  }
2532  else if (orig_valid_min_attr_name == (*ira)->name) {
2533  Retrieve_H5_Attr_Value(*ira,"/");
2534  memcpy(&valid_min_value,(void*)(&((*ira)->value[0])),(*ira)->value.size());
2535  }
2536 
2537  else if (orig_valid_max_attr_name == (*ira)->name) {
2538  Retrieve_H5_Attr_Value(*ira,"/");
2539  memcpy(&valid_max_value,(void*)(&((*ira)->value[0])),(*ira)->value.size());
2540  }
2541 
2542  }// for (ira = this->root_attrs.begin(); ira != this->root_attrs.end(); ++ira)
2543 
2544  // Level 3 variable name is l3m_data
2545  for (it_v = vars.begin();
2546  it_v != vars.end(); ++it_v) {
2547  if ("l3m_data" == (*it_v)->name) {
2548 
2549  // 1. Add the long_name attribute
2550  Attribute * attr = new Attribute();
2551  Add_Str_Attr(attr,longname_attr_name,longname_value);
2552  (*it_v)->attrs.push_back(attr);
2553 
2554  // 2. Add the units attribute
2555  attr = new Attribute();
2556  Add_Str_Attr(attr,units_attr_name,units_value);
2557  (*it_v)->attrs.push_back(attr);
2558 
2559  // 3. Add the valid_min attribute
2560  attr = new Attribute();
2561  Add_One_Float_Attr(attr,valid_min_attr_name,valid_min_value);
2562  (*it_v)->attrs.push_back(attr);
2563 
2564  // 4. Add the valid_max attribute
2565  attr = new Attribute();
2566  Add_One_Float_Attr(attr,valid_max_attr_name,valid_max_value);
2567  (*it_v)->attrs.push_back(attr);
2568 
2569  // 5. Add the _FillValue attribute
2570  attr = new Attribute();
2571  Add_One_Float_Attr(attr,fill_value_attr_name,_FillValue);
2572  (*it_v)->attrs.push_back(attr);
2573 
2574  break;
2575  }
2576  } // for (it_v = vars.begin(); ...
2577 }
2578 
2579 void
2581 
2582  // The fill value is -999.0. However, No _FillValue attribute is added.
2583  // So add it here. KY 2012-2-16
2584  const string fill_value_attr_name = "_FillValue";
2585  float _FillValue = -999.0;
2586  const string valid_range_attr_name = "valid_range";
2587  vector<HDF5CF::Var *>::const_iterator it_v;
2588  vector<HDF5CF::Attribute *>::const_iterator ira;
2589 
2590 
2591  for (it_v = vars.begin();
2592  it_v != vars.end(); ++it_v) {
2593  if (H5FLOAT32 == (*it_v)->dtype) {
2594  bool has_fillvalue = false;
2595  bool has_validrange = false;
2596  for(ira = (*it_v)->attrs.begin(); ira!= (*it_v)->attrs.end();ira++) {
2597  if (fill_value_attr_name == (*ira)->name){
2598  has_fillvalue = true;
2599  break;
2600  }
2601 
2602  else if(valid_range_attr_name == (*ira)->name) {
2603  has_validrange = true;
2604  break;
2605  }
2606 
2607  }
2608  // Add the fill value
2609  if (has_fillvalue != true && has_validrange != true ) {
2610  Attribute* attr = new Attribute();
2611  Add_One_Float_Attr(attr,fill_value_attr_name,_FillValue);
2612  (*it_v)->attrs.push_back(attr);
2613  }
2614  }// if (H5FLOAT32 == (*it_v)->dtype)
2615  }// for (it_v = vars.begin(); ...
2616 }
2617 
2619 
2620  string co_attrname = "coordinates";
2621  string co_attrvalue="";
2622  string unit_attrname = "units";
2623  string nonll_unit_attrvalue ="level";
2624  string lat_unit_attrvalue ="degrees_north";
2625  string lon_unit_attrvalue ="degrees_east";
2626 
2627  for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
2628  ircv != this->cvars.end(); ++ircv) {
2629 //cerr<<"CV name is "<<(*ircv)->name << " cv type is "<<(*ircv)->cvartype <<endl;
2630 
2631  if ((*ircv)->cvartype == CV_NONLATLON_MISS) {
2632  Attribute * attr = new Attribute();
2633  Add_Str_Attr(attr,unit_attrname,nonll_unit_attrvalue);
2634  (*ircv)->attrs.push_back(attr);
2635  }
2636 
2637  else if ((*ircv)->cvartype == CV_LAT_MISS) {
2638 //cerr<<"Should add new attribute "<<endl;
2639  Attribute * attr = new Attribute();
2640 // float temp = -999.9;
2641 // Add_One_Float_Attr(attr,unit_attrname,temp);
2642  Add_Str_Attr(attr,unit_attrname,lat_unit_attrvalue);
2643  (*ircv)->attrs.push_back(attr);
2644 //cerr<<"After adding new attribute "<<endl;
2645  }
2646 
2647  else if ((*ircv)->cvartype == CV_LON_MISS) {
2648  Attribute * attr = new Attribute();
2649  Add_Str_Attr(attr,unit_attrname,lon_unit_attrvalue);
2650  (*ircv)->attrs.push_back(attr);
2651  }
2652  } // for (vector<GMCVar *>::iterator ircv = this->cvars.begin(); ...
2653 
2654  if(product_type == Mea_SeaWiFS_L2)
2655  return;
2656 
2657  else if(product_type == GPM_L1) {
2659  return;
2660  }
2661  else if (true == iscoard)
2662  return;
2663 
2664  for (vector<Var *>::iterator irv = this->vars.begin();
2665  irv != this->vars.end(); ++irv) {
2666  bool coor_attr_keep_exist = false;
2667 
2668  for (vector<Attribute *>:: iterator ira =(*irv)->attrs.begin();
2669  ira !=(*irv)->attrs.end();++ira) {
2670  if (((*ira)->newname == "coordinates")) {
2671  if (product_type == SMAP) {
2672  coor_attr_keep_exist = true;
2673  break;
2674  }
2675  else {
2676  delete (*ira);
2677  (*irv)->attrs.erase(ira);
2678  ira --;
2679  }
2680  }
2681  }// for (vector<Attribute *>:: iterator ira =(*irv)->attrs.begin(); ...
2682 
2683  if (true == coor_attr_keep_exist)
2684  continue;
2685 
2686  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
2687  ird != (*irv)->dims.end(); ++ ird) {
2688  for (vector<GMCVar *>::iterator ircv = this->cvars.begin();
2689  ircv != this->cvars.end(); ++ircv) {
2690  if ((*ird)->name == (*ircv)->cfdimname)
2691  co_attrvalue = (co_attrvalue.empty())
2692  ?(*ircv)->newname:co_attrvalue + " "+(*ircv)->newname;
2693  }
2694  }
2695 
2696  if (false == co_attrvalue.empty()) {
2697  Attribute * attr = new Attribute();
2698  Add_Str_Attr(attr,co_attrname,co_attrvalue);
2699  (*irv)->attrs.push_back(attr);
2700  }
2701 
2702  co_attrvalue.clear();
2703  } // for (vector<Var *>::iterator irv = this->vars.begin(); ...
2704 }
2705 
2707 
2708  // Build a map from CFdimname to 2-D lat/lon variable name, should be something like: aa_list[cfdimname]=s1_latitude .
2709  // Loop all variables
2710  // Inner loop: for all dims of a var
2711  // if(dimname matches the dim(not cfdim) name of one of 2-D lat/lon,
2712  // check if the variable's full path contains the path of one of 2-D lat/lon,
2713  // yes, build its cfdimname = path+ dimname, check this cfdimname with the cfdimname of the corresponding 2-D lat/lon
2714  // If matched, save this latitude variable name as one of the coordinate variable.
2715  // else this is a 3rd-cv, just use the dimension name(or the corresponding cv name maybe through a map).
2716 
2717  // Prepare 1) 2-D CVar(lat,lon) corresponding dimension name set.
2718  // 2) cfdim name to cvar name map(don't need to use a map, just a holder. It should be fine.
2719 
2720 
2721  // "coordinates" attribute name and value. We only need to provide this atttribute for variables that have 2-D lat/lon
2722  string co_attrname = "coordinates";
2723  string co_attrvalue="";
2724 
2725  // 2-D cv dimname set.
2726  set<string> cvar_2d_dimset;
2727 
2728  pair<map<string,string>::iterator,bool>mapret;
2729 
2730  // Hold the mapping from cfdimname to 2-D cvar name. Something like nscan->lat, npixel->lon
2731  map<string,string>cfdimname_to_cvar2dname;
2732 
2733  // Loop through cv variables to build 2-D cv dimname set and the mapping from cfdimname to 2-D cvar name.
2734  for (vector<GMCVar *>::iterator irv = this->cvars.begin();
2735  irv != this->cvars.end(); ++irv) {
2736  //This CVar must be 2-D array.
2737  if((*irv)->rank == 2) {
2738 //cerr<<"2-D cv name is "<<(*irv)->name <<endl;
2739 //cerr<<"2-D cv new name is "<<(*irv)->newname <<endl;
2740 //cerr<<"(*irv)->cfdimname is "<<(*irv)->cfdimname <<endl;
2741  for(vector<Dimension *>::iterator ird = (*irv)->dims.begin();
2742  ird != (*irv)->dims.end(); ++ird) {
2743  cvar_2d_dimset.insert((*ird)->name);
2744  }
2745  mapret = cfdimname_to_cvar2dname.insert(pair<string,string>((*irv)->cfdimname,(*irv)->newname));
2746  if (false == mapret.second)
2747  throw4("The cf dimension name ",(*irv)->cfdimname," should map to 2-D coordinate variable",
2748  (*irv)->newname);
2749  }
2750  }
2751 
2752 
2753  // Loop through the variable list to build the coordinates.
2754  for (vector<Var *>::iterator irv = this->vars.begin();
2755  irv != this->vars.end(); ++irv) {
2756 
2757  // Only apply to >2D variables.
2758  if((*irv)->rank >=2) {
2759 
2760  // The variable dimension names must be found in the 2D cvar dim. nameset.
2761  // The flag must be at least 2.
2762  short have_2d_dimnames_flag = 0;
2763  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
2764  ird !=(*irv)->dims.end();++ird) {
2765  if (cvar_2d_dimset.find((*ird)->name)!=cvar_2d_dimset.end())
2766  have_2d_dimnames_flag++;
2767  }
2768 
2769  // Final candidates to have 2-D CVar coordinates.
2770  if(have_2d_dimnames_flag >=2) {
2771 //cerr<<"var name "<<(*irv)->name <<" has 2-D CVar coordinates "<<endl;
2772 
2773  // Obtain the variable path
2774  string var_path;
2775  if((*irv)->fullpath.size() > (*irv)->name.size())
2776  var_path=(*irv)->fullpath.substr(0,(*irv)->fullpath.size()-(*irv)->name.size());
2777  else
2778  throw4("The variable full path ",(*irv)->fullpath," doesn't contain the variable name ",
2779  (*irv)->name);
2780 
2781  // A flag to identify if this variable really needs the 2-D coordinate variables.
2782  short cv_2d_flag = 0;
2783 
2784  // 2-D coordinate variable names for the potential variable candidate
2785  vector<string> cv_2d_names;
2786 
2787  // Dimension names of the 2-D coordinate variables.
2788  set<string> cv_2d_dimnames;
2789 
2790  // Loop through the map from dim. name to coordinate name.
2791  for(map<string,string>::const_iterator itm = cfdimname_to_cvar2dname.begin();
2792  itm != cfdimname_to_cvar2dname.end();++itm) {
2793  // Obtain the dimension name from the cfdimname.
2794  string reduced_dimname = HDF5CFUtil::obtain_string_after_lastslash(itm->first);
2795 //cerr<<"reduced_dimname is "<<reduced_dimname <<endl;
2796  string cfdim_path;
2797  if(itm->first.size() <= reduced_dimname.size())
2798  throw2("The cf dim. name of this dimension is not right.",itm->first);
2799  else
2800  cfdim_path= itm->first.substr(0,itm->first.size() - reduced_dimname.size());
2801  // cfdim_path will not be NULL only when the cfdim name is for the 2-D cv var.
2802 
2803 //cerr<<"var_path is "<<var_path <<endl;
2804 //cerr<<"cfdim_path is "<<cfdim_path <<endl;
2805  // Find the correct path,
2806  // Note:
2807  // var_path doesn't have to be the same as cfdim_path
2808  // consider the variable /a1/a2/foo and the latitude /a1/latitude(cfdimpath is /a1)
2809  // If there is no /a1/a2/latitude, the /a1/latitude can be used as the coordinate of /a1/a2/foo.
2810  //
2811  if(var_path == cfdim_path) {
2812  for (vector<Dimension*>::iterator ird = (*irv)->dims.begin();
2813  ird!=(*irv)->dims.end();++ird) {
2814  if(reduced_dimname == (*ird)->name) {
2815  cv_2d_flag++;
2816  cv_2d_names.push_back(itm->second);
2817  cv_2d_dimnames.insert((*ird)->name);
2818  }
2819  }
2820  }
2821 
2822  }
2823 
2824  // Note:
2825  // var_path doesn't have to be the same as cfdim_path
2826  // consider the variable /a1/a2/foo and the latitude /a1/latitude(cfdimpath is /a1)
2827  // If there is no /a1/a2/latitude, the /a1/latitude can be used as the coordinate of /a1/a2/foo.
2828  // The variable has 2 coordinates(dimensions) if the flag is 2
2829  // But we want to check if var_path is the same as cfdim_path first. So we check cfdimname_to_cvarname again.
2830  if(cv_2d_flag !=2) {
2831  cv_2d_flag = 0;
2832  // Loop through the map from dim. name to coordinate name.
2833  for(map<string,string>::const_iterator itm = cfdimname_to_cvar2dname.begin();
2834  itm != cfdimname_to_cvar2dname.end();++itm) {
2835  // Obtain the dimension name from the cfdimname.
2836  string reduced_dimname = HDF5CFUtil::obtain_string_after_lastslash(itm->first);
2837  string cfdim_path;
2838  if(itm->first.size() <= reduced_dimname.size())
2839  throw2("The cf dim. name of this dimension is not right.",itm->first);
2840  else
2841  cfdim_path= itm->first.substr(0,itm->first.size() - reduced_dimname.size());
2842  // cfdim_path will not be NULL only when the cfdim name is for the 2-D cv var.
2843 
2844  // Find the correct path,
2845  // Note:
2846  // var_path doesn't have to be the same as cfdim_path
2847  // consider the variable /a1/a2/foo and the latitude /a1/latitude(cfdimpath is /a1)
2848  // If there is no /a1/a2/latitude, the /a1/latitude can be used as the coordinate of /a1/a2/foo.
2849  //
2850  if(var_path.find(cfdim_path)!=string::npos) {
2851  for (vector<Dimension*>::iterator ird = (*irv)->dims.begin();
2852  ird!=(*irv)->dims.end();++ird) {
2853  if(reduced_dimname == (*ird)->name) {
2854  cv_2d_flag++;
2855  cv_2d_names.push_back(itm->second);
2856  cv_2d_dimnames.insert((*ird)->name);
2857  }
2858  }
2859  }
2860 
2861  }
2862  }
2863  if(2 == cv_2d_flag) {
2864 
2865  // Add latitude and longitude to the 'coordinates' attribute.
2866  co_attrvalue = cv_2d_names[0] + " " + cv_2d_names[1];
2867  if((*irv)->rank >2) {
2868  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
2869  ird !=(*irv)->dims.end();++ird) {
2870 
2871  // Add 3rd-dimension to the 'coordinates' attribute.
2872  if(cv_2d_dimnames.find((*ird)->name) == cv_2d_dimnames.end())
2873  co_attrvalue = co_attrvalue + " " +(*ird)->newname;
2874  }
2875  }
2876  Attribute * attr = new Attribute();
2877  Add_Str_Attr(attr,co_attrname,co_attrvalue);
2878  (*irv)->attrs.push_back(attr);
2879 
2880  }
2881  }
2882 
2883  }
2884 
2885  }
2886 }
2887 // #endif
2888 
2889 void GMFile:: Create_Missing_CV(GMCVar *GMcvar, const string& dimname) throw(Exception) {
2890 
2891  GMcvar->name = dimname;
2892  GMcvar->newname = GMcvar->name;
2893  GMcvar->fullpath = GMcvar->name;
2894  GMcvar->rank = 1;
2895  GMcvar->dtype = H5INT32;
2896  hsize_t gmcvar_dimsize = dimname_to_dimsize[dimname];
2897  Dimension* gmcvar_dim = new Dimension(gmcvar_dimsize);
2898  gmcvar_dim->name = dimname;
2899  gmcvar_dim->newname = dimname;
2900  GMcvar->dims.push_back(gmcvar_dim);
2901  GMcvar->cfdimname = dimname;
2902  GMcvar->cvartype = CV_NONLATLON_MISS;
2903  GMcvar->product_type = product_type;
2904 }
2905 
2906  // Check if this is just a netCDF-4 dimension. We need to check the dimension scale dataset attribute "NAME",
2907  // the value should start with "This is a netCDF dimension but not a netCDF variable".
2909 
2910  string netcdf_dim_mark = "This is a netCDF dimension but not a netCDF variable";
2911 
2912  bool is_only_dimension = false;
2913 
2914  for(vector<Attribute *>::iterator ira = var->attrs.begin();
2915  ira != var->attrs.end();ira++) {
2916 
2917  if ("NAME" == (*ira)->name) {
2918 
2919  Retrieve_H5_Attr_Value(*ira,var->fullpath);
2920  string name_value;
2921  name_value.resize((*ira)->value.size());
2922  copy((*ira)->value.begin(),(*ira)->value.end(),name_value.begin());
2923 
2924  // Compare the attribute "NAME" value with the string netcdf_dim_mark. We only compare the string with the size of netcdf_dim_mark
2925  if (0 == name_value.compare(0,netcdf_dim_mark.size(),netcdf_dim_mark))
2926  is_only_dimension = true;
2927 
2928  break;
2929  }
2930  } // for(vector<Attribute *>::iterator ira = var->attrs.begin(); ...
2931 
2932  return is_only_dimension;
2933 }
2934 
2935 void
2937 
2938 }
2939 
2940 
2941 
2942 
2943 
2944 
2945 
2946 
void Adjust_H5_Attr_Value(Attribute *attr)
Adjust attribute values for general HDF5 products.
Definition: HDF5GMCF.cc:178
Definition: HDF5CF.h:60
void Flatten_Obj_Name(bool include_attr)
Flatten the object name for general NASA HDF5 products.
Definition: HDF5GMCF.cc:1860
#define comment
Definition: lex.hdfeos.cc:606
void Retrieve_H5_Attr_Value(Attribute *attr, string)
Definition: HDF5CF.cc:614
#define throw5(a1, a2, a3, a4, a5)
Definition: HDFSP.cc:84
void Handle_GMSPVar_AttrNameClashing()
Definition: HDF5GMCF.cc:1953
vector< Dimension * > dims
Definition: HDF5CF.h:320
std::string newname
Definition: HDF5CF.h:310
void Handle_SpVar()
Handle special variables for general NASA HDF5 products.
Definition: HDF5GMCF.cc:1697
void Create_Missing_CV(GMCVar *, const string &)
Definition: HDF5GMCF.cc:2889
size_t fstrsize
Definition: HDF5CF.h:236
This class represents one HDF5 dataset(CF variable)
Definition: HDF5CF.h:251
void Handle_Coor_Attr()
Handle "coordinates" attributes for general HDF5 products.
Definition: HDF5GMCF.cc:2618
void Handle_CVar()
Handle coordinate variables for general NASA HDF5 products.
Definition: HDF5GMCF.cc:1197
void Adjust_GPM_L3_Obj_Name()
Definition: HDF5GMCF.cc:1799
void Add_GPM_Attrs()
Definition: HDF5GMCF.cc:2189
void Handle_DimNameClashing()
Handle dimension name clashing. Since COARDS requires the change of cv names, So we need to handle di...
Definition: HDF5GMCF.cc:2011
void Handle_GPM_l1_Coor_Attr()
Definition: HDF5GMCF.cc:2706
void Add_Dim_Name()
Add dimension name.
Definition: HDF5GMCF.cc:278
void Handle_GeneralObj_NameClashing(bool, set< string > &objnameset)
Definition: HDF5CF.cc:1016
std::string name
Definition: HDF5CF.h:311
void Add_Dim_Name_Dimscale_General_Product()
Definition: HDF5GMCF.cc:981
void Add_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(Var *, Attribute *)
Definition: HDF5GMCF.cc:426
bool check_cv(string &varname)
Definition: HDF5GMCF.cc:692
virtual void Retrieve_H5_Info(const char *path, hid_t file_id, bool include_attr)
Retrieve DDS information from the HDF5 file. The reason to separate reading DDS from DAS is: DAP need...
Definition: HDF5CF.cc:83
void Handle_CVar_Dimscale_General_Product()
Definition: HDF5GMCF.cc:1570
vector< size_t > strsize
Definition: HDF5CF.h:235
vector< char > value
Definition: HDF5CF.h:237
void Handle_Obj_NameClashing(bool)
Handle object name clashing for general NASA HDF5 products.
Definition: HDF5GMCF.cc:1914
GMPattern
Definition: HDF5CF.h:55
void GMHandle_General_NameClashing(set< string > &objnameset, vector< T * > &objvec)
Definition: HDF5GMCF.cc:1966
This class is a derived class of Var. It represents a special general HDF5 product(currently ACOS) ...
Definition: HDF5CF.h:355
void Add_Dim_Name_ACOS_L2S()
Definition: HDF5GMCF.cc:898
void Handle_CVar_Aqu_L3()
Definition: HDF5GMCF.cc:1497
void Add_One_FakeDim_Name(Dimension *dim)
Definition: HDF5CF.cc:1077
This class is a derived class of CVar. It represents a coordinate variable for general HDF5 files...
Definition: HDF5CF.h:386
virtual void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes.
Definition: HDF5CF.cc:776
set< string > dimnamelist
Definition: HDF5CF.h:652
void Handle_SpVar_Attr()
Handle special variable attributes for general NASA HDF5 products.
Definition: HDF5GMCF.cc:2936
int rank
Definition: HDF5CF.h:314
string newname
Definition: HDF5CF.h:232
virtual ~GMFile()
Definition: HDF5GMCF.cc:111
void Add_Dim_Name_GPM()
Definition: HDF5GMCF.cc:714
void Add_Dim_Name_Mea_SeaWiFS()
Definition: HDF5GMCF.cc:328
virtual void Retrieve_H5_Supported_Attr_Values()
Retrieve attribute values for the supported HDF5 datatypes.
Definition: HDF5CF.cc:588
H5DataType
Definition: HDF5CFUtil.h:54
static void gen_unique_name(std::string &str, std::set< std::string > &namelist, int &clash_index)
Definition: HDF5CFUtil.cc:191
void Handle_CVar_OBPG_L3()
Definition: HDF5GMCF.cc:1621
virtual void Add_Supplement_Attrs(bool)
Add supplemental attributes such as fullpath and original name.
Definition: HDF5CF.cc:1322
bool unsupported_dspace
Definition: HDF5CF.h:316
This class retrieves all information from an HDF5 file.
Definition: HDF5CF.h:506
vector< Var * > vars
Var vectors.
Definition: HDF5CF.h:639
virtual string get_CF_string(string)
Definition: HDF5CF.cc:1026
void Add_Str_Attr(Attribute *attr, const string &attrname, const string &strvalue)
Definition: HDF5CF.cc:1163
void Adjust_Duplicate_FakeDim_Name(Dimension *dim)
Definition: HDF5CF.cc:1130
H5GCFProduct
#define NULL
Definition: wcsUtil.h:65
virtual void Handle_Unsupported_Dspace()
Handle unsupported HDF5 dataspaces for datasets.
Definition: HDF5CF.cc:850
void Add_Aqu_Attrs()
Definition: HDF5GMCF.cc:2488
void Adjust_Mea_Ozone_Obj_Name()
Definition: HDF5GMCF.cc:1825
void Handle_CVar_GPM_L3()
Definition: HDF5GMCF.cc:1313
void Handle_CVar_GPM_L1()
Definition: HDF5GMCF.cc:1227
void Retrieve_H5_Supported_Attr_Values()
Retrieve attribute values for the supported HDF5 datatypes for general HDF5 products.
Definition: HDF5GMCF.cc:152
#define throw1(a1)
The followings are convenient functions to throw exceptions with different.
Definition: HDFSP.cc:80
void Add_SeaWiFS_Attrs()
Definition: HDF5GMCF.cc:2580
void Adjust_Dim_Name()
Adjust dimension name for general NASA HDF5 products.
Definition: HDF5GMCF.cc:2078
void Change_Attr_One_Str_to_Others(Attribute *attr, Var *var)
Definition: HDF5CF.cc:1187
void Add_Dim_Name_Aqu_L3()
Definition: HDF5GMCF.cc:805
H5DataType dtype
Definition: HDF5CF.h:233
void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes for general HDF5 products.
Definition: HDF5GMCF.cc:194
hsize_t count
Definition: HDF5CF.h:234
H5DataType dtype
Definition: HDF5CF.h:313
void Handle_UseDimscale_Var_Dim_Names_Mea_SeaWiFS_Ozone(Var *)
Definition: HDF5GMCF.cc:351
GMFile(const char *path, hid_t file_id, H5GCFProduct product, GMPattern gproduct_pattern)
Definition: HDF5GMCF.cc:105
static std::string obtain_string_after_lastslash(const std::string s)
Definition: HDF5CFUtil.cc:115
void Add_Dim_Name_Mea_Ozonel3z()
Definition: HDF5GMCF.cc:553
map< string, hsize_t > dimname_to_dimsize
Definition: HDF5CF.h:653
vector< Attribute * > attrs
Definition: HDF5CF.h:319
This class represents one attribute.
Definition: HDF5CF.h:184
static void Split(const char *s, int len, char sep, std::vector< std::string > &names)
From a string separated by a separator to a list of string, for example, split "ab,c" to {"ab","c"}.
Definition: HDF5CFUtil.cc:212
void Handle_Unsupported_Dspace()
Handle unsupported HDF5 dataspaces for general HDF5 products.
Definition: HDF5GMCF.cc:246
string newname
Definition: HDF5CF.h:171
void Handle_CVar_SMAP()
Definition: HDF5GMCF.cc:1426
bool Is_netCDF_Dimension(Var *var)
Definition: HDF5GMCF.cc:2908
void Check_General_Product_Pattern()
Definition: HDF5GMCF.cc:925
void Add_One_Float_Attr(Attribute *attr, const string &attrname, float float_value)
Definition: HDF5CF.cc:1177
#define throw3(a1, a2, a3)
Definition: HDFSP.cc:82
void Handle_CVar_Mea_Ozone()
Definition: HDF5GMCF.cc:1527
void Handle_SpVar_ACOS()
Definition: HDF5GMCF.cc:1738
void Handle_GMCVar_NameClashing(set< string > &)
Definition: HDF5GMCF.cc:1932
std::string fullpath
Definition: HDF5CF.h:312
void Handle_GMSPVar_NameClashing(set< string > &)
Definition: HDF5GMCF.cc:1937
void Handle_UseDimscale_Var_Dim_Names_General_Product(Var *)
Definition: HDF5GMCF.cc:1003
bool unsupported_attr_dtype
Definition: HDF5CF.h:315
#define throw2(a1, a2)
Definition: HDFSP.cc:81
void Adjust_Obj_Name()
Adjust object names based on different general NASA HDF5 products.
Definition: HDF5GMCF.cc:1777
This class repersents one dimension of an HDF5 dataset(variable).
Definition: HDF5CF.h:145
void Handle_CVar_Mea_SeaWiFS()
Definition: HDF5GMCF.cc:1368
void Add_Dim_Name_General_Product()
Definition: HDF5GMCF.cc:914
void Insert_One_NameSizeMap_Element(string name, hsize_t size)
Definition: HDF5CF.cc:1044
void Handle_GMCVar_AttrNameClashing()
Definition: HDF5GMCF.cc:1943
bool unsupported_var_dspace
Definition: HDF5CF.h:650
static bool cf_strict_support_type(H5DataType dtype)
Definition: HDF5CFUtil.cc:106
string get_CF_string(string s)
Definition: HDF5GMCF.cc:128
void Add_UseDimscale_Var_Dim_Names_General_Product(Var *, Attribute *)
Definition: HDF5GMCF.cc:1069
#define throw4(a1, a2, a3, a4)
Definition: HDFSP.cc:83
virtual void Flatten_Obj_Name(bool)
Flatten the object name.
Definition: HDF5CF.cc:866
void Add_Supplement_Attrs(bool)
Add supplemental attributes such as fullpath and original name for general NASA HDF5 products...
Definition: HDF5GMCF.cc:2132
vector< Group * > groups
Non-root group vectors.
Definition: HDF5CF.h:645
This class specifies the core engineering of mapping HDF5 to DAP by following CF. ...
void Handle_General_NameClashing(set< string > &objnameset, vector< T * > &objvec)
Definition: HDF5CF.cc:971
void Retrieve_H5_Info(const char *path, hid_t file_id, bool include_attr)
Retrieve DDS information from the HDF5 file; real implementation for general HDF5 products...
Definition: HDF5GMCF.cc:138
vector< Attribute * > root_attrs
Root attribute vectors.
Definition: HDF5CF.h:642
void Add_Dim_Name_OBPG_L3()
Definition: HDF5GMCF.cc:323
void Add_Dim_Name_SMAP()
Definition: HDF5GMCF.cc:831