OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDFEOS5CF.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  dim->name = (*ird)->name;
67  dim->newname = (*ird)->newname;
68  dims.push_back(dim);
69  }
70 
71 }
72 
73 //This method will effectively remove any dimnames like
74 // ???/XDim or ???/YDim from the dimension name set.
75 // Use this function in caution.
76 void
78 
79 
80  // If I put both "XDim" and "YDim" into one for loop, Mac g++ compiler
81  // gives segmentation fault, which doesn't make sense.
82  // I simply split them into two loops. It doesn't affect performance much.
83  // KY 2012-2-14
84  for (set<string>::iterator it = this->vardimnames.begin();
85  it != this->vardimnames.end(); ++it) {
86  string xydimname_candidate = HDF5CFUtil::obtain_string_after_lastslash(*it);
87  if ("XDim" == xydimname_candidate) {
88  this->vardimnames.erase(*it);
89  break;
90  }
91  }
92 
93  for (set<string>::iterator it = this->vardimnames.begin();
94  it != this->vardimnames.end(); ++it) {
95  string xydimname_candidate = HDF5CFUtil::obtain_string_after_lastslash(*it);
96  if ("YDim" == xydimname_candidate) {
97  this->vardimnames.erase(*it);
98  break;
99  }
100  }
101 
102 }
103 
104 
106 {
107  for (vector<EOS5CVar *>:: const_iterator i= this->cvars.begin(); i!=this->cvars.end(); ++i)
108  delete *i;
109 
110  for (vector<EOS5CFGrid *>:: const_iterator i= this->eos5cfgrids.begin(); i!=this->eos5cfgrids.end(); ++i)
111  delete *i;
112 
113  for (vector<EOS5CFSwath *>:: const_iterator i= this->eos5cfswaths.begin(); i!=this->eos5cfswaths.end(); ++i)
114  delete *i;
115 
116  for (vector<EOS5CFZa *>:: const_iterator i= this->eos5cfzas.begin(); i!=this->eos5cfzas.end(); ++i)
117  delete *i;
118 
119 }
120 
121 string EOS5File::get_CF_string(string s) {
122 
123  if (s[0] !='/')
124  return File::get_CF_string(s);
125  else {
126  s.erase(0,1);
127  return File::get_CF_string(s);
128  }
129 }
130 
131 void EOS5File::Retrieve_H5_Info(const char *path,
132  hid_t file_id, bool include_attr) throw (Exception) {
133  // Since we need to check the attribute info in order to determine if the file is augmented to netCDF-4,
134  // we need to retrieve the attribute info also.
135  File::Retrieve_H5_Info(path,file_id,true);
136 }
137 
139 
141  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
142  ircv != this->cvars.end(); ++ircv) {
143  if ((CV_EXIST == (*ircv)->cvartype ) || (CV_MODIFY == (*ircv)->cvartype)){
144  for (vector<Attribute *>::iterator ira = (*ircv)->attrs.begin();
145  ira != (*ircv)->attrs.end(); ++ira)
146  Retrieve_H5_Attr_Value(*ira,(*ircv)->fullpath);
147 
148  }
149  }
150 }
151 
153 
154 }
155 
156 void EOS5File:: Handle_Unsupported_Dtype(bool include_attr) throw(Exception) {
157 
158  File::Handle_Unsupported_Dtype(include_attr);
159  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
160  ircv != this->cvars.end(); ++ircv) {
161  if (true == include_attr) {
162  for (vector<Attribute *>::iterator ira = (*ircv)->attrs.begin();
163  ira != (*ircv)->attrs.end(); ++ira) {
164  H5DataType temp_dtype = (*ira)->getType();
165  if (false == HDF5CFUtil::cf_strict_support_type(temp_dtype)) {
166  delete (*ira);
167  (*ircv)->attrs.erase(ira);
168  ira--;
169  }
170  }
171  }
172 
173  H5DataType temp_dtype = (*ircv)->getType();
174  if (!HDF5CFUtil::cf_strict_support_type(temp_dtype)) {
175  delete (*ircv);
176  this->cvars.erase(ircv);
177  ircv--;
178  }
179 
180  }
181 }
182 
184 
186 
187  if (true == this->unsupported_var_dspace) {
188  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
189  ircv != this->cvars.end(); ++ircv) {
190  if (true == (*ircv)->unsupported_dspace) {
191  delete (*ircv);
192  this->cvars.erase(ircv);
193  ircv--;
194  }
195  }
196  }
197 }
199 
200  // Condense redundant XDim, YDim in the grid/swath/za dimension list
201 
202  for (unsigned int i = 0; i <strmeta_info->swath_list.size();++i) {
203  HE5Swath& he5s = strmeta_info->swath_list.at(i);
204 
205  Adjust_EOS5Dim_List(he5s.dim_list);
206  for (unsigned int j = 0; j<he5s.geo_var_list.size(); ++j) {
207  Adjust_EOS5VarDim_Info((he5s.geo_var_list)[j].dim_list,he5s.dim_list,he5s.name,SWATH);
208  }
209  for (unsigned int j = 0; j<he5s.data_var_list.size(); ++j) {
210  Adjust_EOS5VarDim_Info((he5s.data_var_list)[j].dim_list,he5s.dim_list,he5s.name,SWATH);
211  }
212  }
213 
214  for (unsigned int i = 0; i <strmeta_info->grid_list.size();++i) {
215 
216  HE5Grid& he5g = strmeta_info->grid_list.at(i);
217 //cerr<<"grid name is "<<he5g.name <<endl;
218 
219  Adjust_EOS5Dim_List(he5g.dim_list);
220  for (unsigned int j = 0; j<he5g.data_var_list.size(); ++j) {
221  Adjust_EOS5VarDim_Info((he5g.data_var_list)[j].dim_list,he5g.dim_list,he5g.name,GRID);
222  }
223  }
224 
225  for (unsigned int i = 0; i <strmeta_info->za_list.size();++i) {
226  HE5Za& he5z = strmeta_info->za_list.at(i);
227 
228  Adjust_EOS5Dim_List(he5z.dim_list);
229  for (unsigned int j = 0; j<he5z.data_var_list.size(); ++j) {
230  Adjust_EOS5VarDim_Info((he5z.data_var_list)[j].dim_list,he5z.dim_list,he5z.name,ZA);
231  }
232  }
233 }
234 
235 void EOS5File::Adjust_EOS5Dim_List(vector<HE5Dim>& groupdimlist) throw(Exception){
236 
237  Remove_NegativeSizeDims(groupdimlist);
238 
239  // Condense redundant XDim, YDim in the grid/swath/za dimension list
240  Condense_EOS5Dim_List(groupdimlist);
241 
242 }
243 
244 void EOS5File::Remove_NegativeSizeDims(vector<HE5Dim>& groupdimlist) throw(Exception){
245 
246  vector <HE5Dim>:: iterator id;
247  // We find one product has dimension with name: Unlimited, size: -1; this dimension
248  // will not be used by any variables. The "Unlimited" dimension is useful for extended
249  // datasets when data is written. It is not useful for data accessing as far as I know.
250  // So we will remove it from the list.
251  // This algoritm will also remove any dimension with size <=0. KY 2011-1-14
252  for (id = groupdimlist.begin(); id != groupdimlist.end(); ++id) {
253  if ((*id).size <= 0) {
254  groupdimlist.erase(id);
255  id --;
256  }
257  }
258 }
259 
260 void EOS5File::Condense_EOS5Dim_List(vector<HE5Dim>& groupdimlist) throw(Exception){
261 
262  set<int>xdimsizes;
263  set<int>ydimsizes;
264  pair<set<int>::iterator,bool> setret;
265  vector <HE5Dim>:: iterator id;
266 
267  for (id = groupdimlist.begin(); id != groupdimlist.end(); ++id) {
268  if ("XDim" == (*id).name || "Xdim" == (*id).name) {
269  setret = xdimsizes.insert((*id).size);
270  if (false == setret.second) {
271  groupdimlist.erase(id);
272  id--;
273  }
274  else if ("Xdim" == (*id).name) (*id).name = "XDim";
275 
276  }
277  }
278 
279  for (id = groupdimlist.begin(); id != groupdimlist.end(); ++id) {
280  if ("YDim" == (*id).name || "Ydim" ==(*id).name) {
281  setret = ydimsizes.insert((*id).size);
282  if (false == setret.second) {
283  groupdimlist.erase(id);
284  id--;
285  }
286  else if ("Ydim" == (*id).name)
287  (*id).name = "YDim";
288  }
289  }
290 }
291 
292 
293 void EOS5File::Adjust_EOS5VarDim_Info(vector<HE5Dim>& vardimlist, vector<HE5Dim>& groupdimlist,const string & eos5_obj_name,EOS5Type eos5type) throw(Exception){
294 
295 
296  set<string> dimnamelist;
297  pair<set<string>::iterator,bool> setret;
298 
299  // For EOS5 Grids: Dimension names XDim and YDim are predefined.
300  // Even the data producers make a mistake to define "xdim", "ydim" etc in the grid
301  // dimension name list, the variable will still pick up "XDim" and "YDim" as their
302  // dimension names So we assume that 'xdim", "ydim" etc will never appear in the
303  // variable name list.
304  for (unsigned int i = 0; i <vardimlist.size(); ++i) {
305 
306  HE5Dim& he5d = vardimlist.at(i);
307  bool dim_in_groupdimlist = false;
308  for (unsigned int j = 0; j <groupdimlist.size();++j) {
309  HE5Dim he5gd = groupdimlist.at(j);
310  if (he5gd.name == he5d.name) {
311  he5d.size = he5gd.size;
312  dim_in_groupdimlist = true;
313  break;
314  }
315  }
316 
317  if (false == dim_in_groupdimlist)
318  throw2("The EOS5 group dimension name list doesn't include the dimension ",he5d.name);
319 
320  // Some variables have data like float foo[nlevel= 10][nlevel= 10],need to make the dimname unique
321  // to ensure the coordinate variables to be generated correctly.
322  //
323  setret = dimnamelist.insert(he5d.name);
324  if (false == setret.second) {
325  int clash_index =1;
326  string temp_clashname=he5d.name+'_';
327  HDF5CFUtil::gen_unique_name(temp_clashname,dimnamelist,clash_index);
328 
329  string ori_dimname = he5d.name;
330 
331  he5d.name = temp_clashname;
332 //cerr<<"HDF5 dim. name is "<<he5d.name <<endl;
333  // We have to add this dim. to this dim. list if this dim doesn't exist in the dim. list.
334  bool dim_exist = false;
335  for (unsigned int j = 0; j <groupdimlist.size();++j) {
336  if (he5d.name == groupdimlist[j].name &&
337  he5d.size == groupdimlist[j].size ) {
338  dim_exist = true;
339  break;
340  }
341  }
342 
343  if (false == dim_exist) {
344  ori_dimname = eos5_obj_name + "/" + ori_dimname;
345  string dup_dimname = eos5_obj_name + "/" + he5d.name;
346  if (GRID == eos5type){
347  ori_dimname = "/GRIDS/"+ori_dimname;
348  dup_dimname = "/GRIDS/"+dup_dimname;
349  }
350  else if (SWATH == eos5type){
351  ori_dimname = "/SWATHS/"+ori_dimname;
352  dup_dimname = "/SWATHS/"+dup_dimname;
353  }
354  else if (ZA == eos5type) {
355  ori_dimname = "/ZAS/" + ori_dimname;
356  dup_dimname = "/ZAS/"+dup_dimname;
357  }
358 
359  dimname_to_dupdimnamelist.insert(pair<string,string>(ori_dimname,dup_dimname));
360  groupdimlist.push_back(he5d);
361  }
362 
363  // cerr<<"groupdimlist size= "<<groupdimlist.size() <<endl;
364  }//if(false == setret.second)
365  }// for (unsigned int i = 0; i <vardimlist.size(); ++i)
366 
367 }
368 
369 void EOS5File::Add_EOS5File_Info(HE5Parser * strmeta_info, bool grids_mllcv) throw(Exception) {
370 
371  string fslash_str="/";
372  string grid_str ="/GRIDS/";
373  string swath_str="/SWATHS/";
374  string za_str = "/ZAS/";
375  // cerr<<"coming to Add_EOSFile_Info "<<endl;
376 
377  // Assign the original number of grids. These number will be useful
378  // to generate the final DAP object names for grids/swaths/zas that don't have coordinate
379  // variables. For example, OMI level 2G product has latitude and longitude with 3-D arrays.
380  // There is no way to make the lat/lon become CF coordinate variables. To still follow the
381  // HDF-EOS5 object name conventions, the original number of grid is expected.
382  // Since this happens only for grids, we just keep the original number for grids now.
383  this->orig_num_grids = strmeta_info->grid_list.size();
384 
385  //
386  for(unsigned int i=0; i < strmeta_info->grid_list.size(); i++) {
387  HE5Grid he5g = strmeta_info->grid_list.at(i);
388  EOS5CFGrid * eos5grid = new EOS5CFGrid();
389  eos5grid->name = he5g.name;
390  eos5grid->dimnames.resize(he5g.dim_list.size());
391 
392  for (unsigned int j=0; j <he5g.dim_list.size(); j++) {
393 
394  HE5Dim he5d = he5g.dim_list.at(j);
395  if ("XDim" == he5d.name)
396  eos5grid->xdimsize = he5d.size;
397  if ("YDim" == he5d.name)
398  eos5grid->ydimsize = he5d.size;
399 
400  // Here we add the grid name connecting with "/" to
401  // adjust the dim names to assure the uniqueness of
402  // the dimension names for multiple grids.
403  // For single grid, we don't have to do that.
404  // However, considering the rare case that one
405  // can have one grid, one swath and one za, the dimnames
406  // without using the group names may cause the name clashings.
407  // so still add the group path.
408  string unique_dimname=
409  grid_str +he5g.name + fslash_str + he5d.name;
410 
411  (eos5grid->dimnames)[j] = unique_dimname;
412 
413  pair<map<hsize_t,string>::iterator,bool>mapret1;
414  mapret1 = eos5grid->dimsizes_to_dimnames.insert(pair<hsize_t,string>((hsize_t)he5d.size,unique_dimname));
415 
416  // Create the dimname to dimsize map. This will be used to create the missing coordinate
417  // variables. Based on our understanding, dimension names should be unique for
418  // grid/swath/zonal average. We will throw an error if we find the same dimension name used.
419  pair<map<string,hsize_t>::iterator,bool>mapret2;
420  mapret2 = eos5grid->dimnames_to_dimsizes.insert(pair<string,hsize_t>(unique_dimname,(hsize_t)he5d.size));
421  if (false == mapret2.second)
422  throw5("The dimension name ",unique_dimname, " with the dimension size ", he5d.size, "is not unique");
423  } // for (int j=0; j <he5g.dim_list.size(); j++)
424 
425  // Check if having Latitude/Longitude.
426  EOS5SwathGrid_Set_LatLon_Flags(eos5grid,he5g.data_var_list);
427 
428 
429  // Using map for possible the third-D CVs.
430  map<string,string> dnames_to_1dvnames;
431  EOS5Handle_nonlatlon_dimcvars(he5g.data_var_list,GRID,he5g.name,dnames_to_1dvnames);
432  eos5grid->dnames_to_1dvnames = dnames_to_1dvnames;
433  eos5grid->point_lower = he5g.point_lower;
434  eos5grid->point_upper = he5g.point_upper;
435  eos5grid->point_left = he5g.point_left;
436  eos5grid->point_right = he5g.point_right;
437 
438  eos5grid->eos5_pixelreg = he5g.pixelregistration;
439  eos5grid->eos5_origin = he5g.gridorigin;
440  eos5grid->eos5_projcode = he5g.projection;
441  this->eos5cfgrids.push_back(eos5grid);
442 
443  }// for(int i=0; i < strmeta_info->grid_list.size(); i++)
444 
445  this->grids_multi_latloncvs = grids_mllcv;
446 
447  // Second Swath
448  for (unsigned int i=0; i < strmeta_info->swath_list.size(); i++) {
449 
450  HE5Swath he5s = strmeta_info->swath_list.at(i);
451  EOS5CFSwath * eos5swath = new EOS5CFSwath();
452  eos5swath->name = he5s.name;
453  eos5swath->dimnames.resize(he5s.dim_list.size());
454 
455  for (unsigned int j=0; j <he5s.dim_list.size(); j++) {
456 
457  HE5Dim he5d = he5s.dim_list.at(j);
458 
459  // Here we add the swath name connecting with "/" to
460  // adjust the dim names to assure the uniqueness of
461  // the dimension names for multiple swaths.
462  // For single swath, we don't have to do that.
463  // However, considering the rare case that one
464  // can have one grid, one swath and one za, the dimnames
465  // without using the group names may cause the name clashings.
466  // so still add the group path.
467  string unique_dimname=
468  swath_str + he5s.name + fslash_str + he5d.name;
469  (eos5swath->dimnames)[j] = unique_dimname;
470 
471  // Create the dimsize to dimname map for those variables missing dimension names.
472  // Note: For different dimnames sharing the same dimsizes, we only pick up the first one.
473  pair<map<hsize_t,string>::iterator,bool>mapret1;
474  mapret1 = eos5swath->dimsizes_to_dimnames.insert(pair<hsize_t,string>((hsize_t)he5d.size,unique_dimname));
475 
476  // Create the dimname to dimsize map. This will be used to create the missing coordinate
477  // variables. Based on our understanding, dimension names should be unique for
478  // grid/swath/zonal average. We will throw an error if we find the same dimension name used.
479  pair<map<string,hsize_t>::iterator,bool>mapret2;
480  mapret2 = eos5swath->dimnames_to_dimsizes.insert(pair<string,hsize_t>(unique_dimname,(hsize_t)he5d.size));
481  if (false == mapret2.second)
482  throw5("The dimension name ",unique_dimname, " with the dimension size ", he5d.size, "is not unique");
483 
484  } // for (int j=0; j <he5s.dim_list.size(); j++)
485 
486  // Check if having Latitude/Longitude.
487  EOS5SwathGrid_Set_LatLon_Flags(eos5swath,he5s.geo_var_list);
488 
489  // Using map for possible the third-D CVs.
490  map<string,string> dnames_to_geo1dvnames;
491  EOS5Handle_nonlatlon_dimcvars(he5s.geo_var_list,SWATH,he5s.name,dnames_to_geo1dvnames);
492  eos5swath->dnames_to_geo1dvnames = dnames_to_geo1dvnames;
493  this->eos5cfswaths.push_back(eos5swath);
494  } // for (int i=0; i < strmeta_info->swath_list.size(); i++)
495 
496  // Third Zonal average
497  for(unsigned int i=0; i < strmeta_info->za_list.size(); i++) {
498 
499  HE5Za he5z = strmeta_info->za_list.at(i);
500 
501  EOS5CFZa * eos5za = new EOS5CFZa();
502  eos5za->name = he5z.name;
503  eos5za->dimnames.resize(he5z.dim_list.size());
504 
505  for (unsigned int j=0; j <he5z.dim_list.size(); j++) {
506 
507  HE5Dim he5d = he5z.dim_list.at(j);
508 
509  // Here we add the grid name connecting with "/" to
510  // adjust the dim names to assure the uniqueness of
511  // the dimension names for multiple grids.
512  // For single grid, we don't have to do that.
513  string unique_dimname =
514  za_str + he5z.name + fslash_str + he5d.name;
515  (eos5za->dimnames)[j] = unique_dimname;
516  pair<map<hsize_t,string>::iterator,bool>mapret1;
517  mapret1 = eos5za->dimsizes_to_dimnames.insert(pair<hsize_t,string>((hsize_t)he5d.size,unique_dimname));
518 
519  // Create the dimname to dimsize map. This will be used to create the missing coordinate
520  // variables. Based on our understanding, dimension names should be unique for
521  // grid/swath/zonal average. We will throw an error if we find the same dimension name used.
522  pair<map<string,hsize_t>::iterator,bool>mapret2;
523  mapret2 = eos5za->dimnames_to_dimsizes.insert(pair<string,hsize_t>(unique_dimname,(hsize_t)he5d.size));
524  if (false == mapret2.second)
525  throw5("The dimension name ",unique_dimname, " with the dimension size ", he5d.size, "is not unique");
526 
527  } // for (int j=0; j <he5z.dim_list.size(); j++)
528 
529  // Using map for possible the third-D CVs.
530  map<string,string> dnames_to_1dvnames;
531  EOS5Handle_nonlatlon_dimcvars(he5z.data_var_list,ZA,he5z.name,dnames_to_1dvnames);
532  eos5za->dnames_to_1dvnames = dnames_to_1dvnames;
533  this->eos5cfzas.push_back(eos5za);
534  } // for(int i=0; i < strmeta_info->za_list.size(); i++)
535 
536 // Debugging info
537 #if 0
538 for (vector<EOS5CFGrid *>::iterator irg = this->eos5cfgrids.begin();
539  irg != this->eos5cfgrids.end(); ++irg) {
540 
541 cerr<<"grid name "<<(*irg)->name <<endl;
542 cerr<<"eos5_pixelreg"<<(*irg)->eos5_pixelreg <<endl;
543 cerr<<"eos5_origin"<<(*irg)->eos5_pixelreg <<endl;
544 cerr<<"point_lower "<<(*irg)->point_lower <<endl;
545 cerr<<"xdimsize "<<(*irg)->xdimsize <<endl;
546 
547 if((*irg)->has_g2dlatlon) cerr<<"has g2dlatlon"<<endl;
548 if((*irg)->has_2dlatlon) cerr<<"has 2dlatlon"<<endl;
549 if((*irg)->has_1dlatlon) cerr<<"has 1dlatlon"<<endl;
550 if((*irg)->has_nolatlon) cerr<<"has no latlon" <<endl;
551 if(this->grids_multi_latloncvs) cerr<<"having multiple lat/lon from structmeta" <<endl;
552 else cerr<<"no multiple lat/lon from structmeta" <<endl;
553 
554 
555 // Dimension names
556 cerr <<"number of dimensions "<<(*irg)->dimnames.size() <<endl;
557 for (vector<string>::iterator irv = (*irg)->dimnames.begin();
558  irv != (*irg)->dimnames.end(); ++irv)
559  cerr<<"dim names" <<*irv <<endl;
560 
561 // mapping size to name
562 for (map<hsize_t,string>::iterator im1 = (*irg)->dimsizes_to_dimnames.begin();
563  im1 !=(*irg)->dimsizes_to_dimnames.end();++im1) {
564  cerr<<"size to name "<< (int)((*im1).first) <<"=> "<<(*im1).second <<endl;
565 }
566 
567 // mapping dime names to 1d varname
568 for (map<string,string>::iterator im2 = (*irg)->dnames_to_1dvnames.begin();
569  im2 !=(*irg)->dnames_to_1dvnames.end();++im2) {
570 cerr<<"dimanme to 1d var name "<< (*im2).first <<"=> "<<(*im2).second <<endl;
571 }
572 }
573 
574 //Swath
575 for (vector<EOS5CFSwath *>::iterator irg = this->eos5cfswaths.begin();
576  irg != this->eos5cfswaths.end(); ++irg) {
577 
578 cerr<<"swath name "<<(*irg)->name <<endl;
579 if((*irg)->has_nolatlon) cerr<<"has no latlon" <<endl;
580 if((*irg)->has_1dlatlon) cerr<<"has 1dlatlon"<<endl;
581 if((*irg)->has_2dlatlon) cerr<<"has 2dlatlon"<<endl;
582 
583 // Dimension names
584 for (vector<string>::iterator irv = (*irg)->dimnames.begin();
585  irv != (*irg)->dimnames.end(); ++irv)
586 cerr<<"dim names" <<*irv <<endl;
587 
588 // mapping size to name
589 for (map<hsize_t,string>::iterator im1 = (*irg)->dimsizes_to_dimnames.begin();
590  im1 !=(*irg)->dimsizes_to_dimnames.end();++im1) {
591 cerr<<"size to name "<< (int)((*im1).first) <<"=> "<<(*im1).second <<endl;
592 }
593 
594 // mapping dime names to 1d varname
595 for (map<string,string>::iterator im2 = (*irg)->dnames_to_geo1dvnames.begin();
596  im2 !=(*irg)->dnames_to_geo1dvnames.end();++im2) {
597 cerr<<"dimname to 1d varname "<< (*im2).first <<"=> "<<(*im2).second <<endl;
598 }
599 }
600 
601 for (vector<EOS5CFZa *>::iterator irg = this->eos5cfzas.begin();
602  irg != this->eos5cfzas.end(); ++irg) {
603 
604 cerr<<"za name now"<<(*irg)->name <<endl;
605 
606 // Dimension names
607 for (vector<string>::iterator irv = (*irg)->dimnames.begin();
608  irv != (*irg)->dimnames.end(); ++irv)
609 cerr<<"dim names" <<*irv <<endl;
610 
611 // mapping size to name
612 for (map<hsize_t,string>::iterator im1 = (*irg)->dimsizes_to_dimnames.begin();
613  im1 !=(*irg)->dimsizes_to_dimnames.end();++im1) {
614 cerr<<"size to name "<< (int)((*im1).first) <<"=> "<<(*im1).second <<endl;
615 }
616 
617 // mapping dime names to 1d varname
618 for (map<string,string>::iterator im2 = (*irg)->dnames_to_1dvnames.begin();
619  im2 !=(*irg)->dnames_to_1dvnames.end();++im2) {
620 cerr<<"dimname to 1d varname "<< (*im2).first <<"=> "<<(*im2).second <<endl;
621 }
622 }
623 #endif
624 
625 }
626 
627 template<class T>
628 void EOS5File::EOS5SwathGrid_Set_LatLon_Flags(T* eos5gridswath,vector<HE5Var> &eos5varlist) throw (Exception){
629 
630  bool find_lat = false;
631  bool find_lon = false;
632  bool has_1dlat = false;
633  bool has_1dlon = false;
634  bool has_2dlat = false;
635  string lat_xdimname;
636  string lat_ydimname;
637  string lon_xdimname;
638  string lon_ydimname;
639  bool has_2dlon = false;
640  bool has_g2dlat = false;
641  bool has_g2dlon = false;
642 
643  for (unsigned int i = 0; i < eos5varlist.size(); ++i) {
644  HE5Var he5v = eos5varlist.at(i);
645  if ("Latitude" == he5v.name) {
646  find_lat = true;
647  int num_dims = he5v.dim_list.size();
648  if ( 1 == num_dims)
649  has_1dlat = true;
650  else if (2 == num_dims) {
651  lat_ydimname = (he5v.dim_list)[0].name;
652  lat_xdimname = (he5v.dim_list)[1].name;
653  has_2dlat = true;
654  }
655  else if (num_dims >2)
656  has_g2dlat = true;
657  else
658  throw1("The number of dimension should not be 0 for grids or swaths");
659  }// if ("Latitude" == he5v.name)
660 
661  if ("Longitude" == he5v.name) {
662  find_lon = true;
663  int num_dims = he5v.dim_list.size();
664  if ( 1 == num_dims)
665  has_1dlon = true;
666  else if (2 == num_dims) {
667  lon_ydimname = (he5v.dim_list)[0].name;
668  lon_xdimname = (he5v.dim_list)[1].name;
669  has_2dlon = true;
670  }
671  else if (num_dims >2)
672  has_g2dlon = true;
673  else
674  throw1("The number of dimension should not be 0 for grids or swaths");
675  } // if ("Longitude" == he5v.name)
676 
677  if (true == find_lat && true == find_lon) {
678  if (true == has_1dlat && true == has_1dlon)
679  eos5gridswath->has_1dlatlon = true;
680 
681  // Make sure we have lat[YDIM][XDIM] and lon[YDIM][XDIM]
682  if (true == has_2dlat && true == has_2dlon &&
683  lat_ydimname == lon_ydimname &&
684  lat_xdimname == lon_xdimname)
685  eos5gridswath->has_2dlatlon = true;
686 
687  if (true == has_g2dlat && true == has_g2dlon)
688  eos5gridswath->has_g2dlatlon = true;
689 
690  eos5gridswath->has_nolatlon = false;
691  break;
692  } // if (true == find_lat && true == find_lon)
693  }// for (unsigned int i = 0; i < eos5varlist.size(); ++i)
694 }
695 
696 
697 void EOS5File::EOS5Handle_nonlatlon_dimcvars(vector<HE5Var> & eos5varlist,
698  EOS5Type eos5type,
699  string groupname,
700  map<string,string>& dnamesgeo1dvnames) throw(Exception){
701 
702  set<string> nocvdimnames;
703  string grid_str = "/GRIDS/";
704  string xdim_str ="XDim";
705  string ydim_str ="YDim";
706  string fslash_str ="/";
707  string eos5typestr;
708 
709  if (GRID==eos5type) {
710  string xdimname = grid_str + groupname + fslash_str + xdim_str;
711  nocvdimnames.insert(xdimname);
712  string ydimname = grid_str + groupname + fslash_str + ydim_str;
713  nocvdimnames.insert(ydimname);
714  eos5typestr = "/GRIDS/";
715  }
716  else if (SWATH == eos5type)
717  eos5typestr = "/SWATHS/";
718  else if (ZA == eos5type)
719  eos5typestr = "/ZAS/";
720  else
721  throw1("Unsupported HDF-EOS5 type, this type is not swath, grid or zonal average");
722 
723  pair<map<string,string>::iterator,bool>mapret;
724  for(unsigned int i=0; i < eos5varlist.size(); ++i) {
725  HE5Var he5v = eos5varlist.at(i);
726  if (1 == he5v.dim_list.size()) {
727  HE5Dim he5d = he5v.dim_list.at(0);
728  string dimname;
729  dimname = eos5typestr + groupname + fslash_str + he5d.name;
730  string varname; // using the new var name format
731  varname = eos5typestr + groupname + fslash_str + he5v.name;
732  mapret = dnamesgeo1dvnames.insert(pair<string,string>(dimname,varname));
733 
734  // If another geo field already shares the same dimname, we need to
735  // disqualify this geofield as the coordinate variable since it is not
736  // unique anymore.
737  if (false == mapret.second )
738  nocvdimnames.insert(dimname);
739  }
740  }
741 
742  // Manage the coordinate variables. We only want to leave fields that uniquely hold
743  // the dimension name to be the possible cv candidate.
744  set<string>:: iterator itset;
745  for ( itset = nocvdimnames.begin(); itset!=nocvdimnames.end();++itset)
746  dnamesgeo1dvnames.erase(*itset);
747 }
748 
750 
751  for (vector<Var *>::iterator irv = this->vars.begin();
752  irv != this->vars.end(); ++irv) {
753  Obtain_Var_NewName(*irv);
754  }
755 }
756 
758 
759  string fslash_str="/";
760  string eos5typestr="";
761 
762  EOS5Type vartype = Get_Var_EOS5_Type(var);
763 
764  // Actually the newname is used to check if the we have the existing
765  // third dimension coordinate variable. To avoid the check of
766  // fullpath again, we will make newname to have the path and remove
767  // the grid and grid name before passing to DDS downstream. KY 2012-1-20
768  switch (vartype) {
769  case GRID:
770  {
771  eos5typestr = "/GRIDS/";
772  string eos5_groupname = Obtain_Var_EOS5Type_GroupName(var,vartype);
773 // var->newname = ((1 == num_grids)?var->name:
774 // eos5typestr + eos5_groupname + fslash_str + var->name);
775  var->newname = eos5typestr + eos5_groupname + fslash_str + var->name;
776  }
777  break;
778 
779  case SWATH:
780  {
781  eos5typestr = "/SWATHS/";
782  string eos5_groupname = Obtain_Var_EOS5Type_GroupName(var,vartype);
783 // var->newname = ((1 == num_swaths)?var->name:
784  // eos5typestr + eos5_groupname + fslash_str + var->name);
785  var->newname = eos5typestr + eos5_groupname + fslash_str + var->name;
786 //cerr <<"var newname "<<var->newname <<endl;
787  }
788  break;
789  case ZA:
790  {
791  eos5typestr = "/ZAS/";
792  string eos5_groupname = Obtain_Var_EOS5Type_GroupName(var,vartype);
793  // var->newname = ((1 == num_zas)?var->name:
794  // eos5typestr + eos5_groupname + fslash_str + var->name);
795  var->newname = eos5typestr + eos5_groupname + fslash_str + var->name;
796  }
797  break;
798  case OTHERVARS: {
799  string eos5infopath = "/HDFEOS INFORMATION";
800  if (var->fullpath.size() > eos5infopath.size()){
801  if (eos5infopath == var->fullpath.substr(0,eos5infopath.size()))
802  var->newname = var->name;
803  }
804  else var->newname = var->fullpath;
805  }
806  break;
807  default:
808  throw1("Non-supported EOS type");
809  } // switch(vartype)
810 }
811 
813 
814  string EOS5GRIDPATH ="/HDFEOS/GRIDS";
815  string EOS5SWATHPATH ="/HDFEOS/SWATHS";
816  string EOS5ZAPATH ="/HDFEOS/ZAS";
817 
818  if (var->fullpath.size() >= EOS5GRIDPATH.size()) {
819  if (EOS5GRIDPATH ==
820  var->fullpath.substr(0,EOS5GRIDPATH.size()))
821  return GRID;
822  }
823  if (var->fullpath.size() >=EOS5SWATHPATH.size()) {
824  if (EOS5SWATHPATH ==
825  var->fullpath.substr(0,EOS5SWATHPATH.size()))
826  return SWATH;
827  }
828  if (var->fullpath.size() >=EOS5ZAPATH.size()) {
829  if (EOS5ZAPATH ==
830  var->fullpath.substr(0,EOS5ZAPATH.size()))
831  return ZA;
832  }
833  return OTHERVARS;
834 
835 }
836 
837 
838 void EOS5File::Add_Dim_Name( HE5Parser *strmeta_info) throw(Exception){
839 
840  for (vector<Var *>::iterator irv = this->vars.begin();
841  irv != this->vars.end(); ++irv) {
842  Obtain_Var_Dims(*irv,strmeta_info);
843 #if 0
844 for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
845  ird != (*irv)->dims.end();++ird) {
846 cerr<<"dim name right after change "<<(*ird)->newname <<endl;
847 }
848 #endif
849 
850  }
851 }
852 
853 // CHECK if finding the same variables from the parser.
854 bool EOS5File::Obtain_Var_Dims(Var *var,HE5Parser * strmeta_info) throw(Exception){
855 
856  string varname_from_parser ="";
857  EOS5Type vartype = Get_Var_EOS5_Type(var);
858 
859  if (GRID == vartype) {
860  int num_grids = strmeta_info->grid_list.size();
861  for (int i = 0; i < num_grids; ++i) {
862  HE5Grid he5g = strmeta_info->grid_list.at(i);
863  if (he5g.name == Obtain_Var_EOS5Type_GroupName(var,vartype)){
864  EOS5CFGrid *eos5cfgrid = (this->eos5cfgrids)[i];
865  bool var_is_parsed = Set_Var_Dims(eos5cfgrid,var,he5g.data_var_list,he5g.name,num_grids,GRID);
866  if (false == var_is_parsed){
867  map<hsize_t,string> dimsizes_to_dimnames = eos5cfgrid->dimsizes_to_dimnames;
868  // Check if this swath includes data fields(variables) that don't have any dimension names.
869  // This rarely happens. But we do find one NASA Aura product that has this problem. Although
870  // this has been fixed, we should anticipiate that the similar problem may happen in the future.
871  // So check here to avoid the potential problems. KY 2012-1-9
872  Set_NonParse_Var_Dims(eos5cfgrid,var,dimsizes_to_dimnames,num_grids,vartype);
873  }
874  }
875  }// for (unsigned int i = 0; i < num_grids; ++i)
876  }// if (GRID == vartype)
877  else if (SWATH == vartype) {
878  int num_swaths = strmeta_info->swath_list.size();
879  for (int i = 0; i < num_swaths; ++i) {
880 
881  HE5Swath he5s = strmeta_info->swath_list.at(i);
882 
883  if (he5s.name == Obtain_Var_EOS5Type_GroupName(var,vartype)){
884 
885  EOS5CFSwath *eos5cfswath = (this->eos5cfswaths)[i];
886 
887  bool var_is_parsed = true;
888  int swath_fieldtype_flag = Check_EOS5Swath_FieldType(var);
889  if (1 == swath_fieldtype_flag)
890  var_is_parsed = Set_Var_Dims(eos5cfswath,var,he5s.geo_var_list,he5s.name,num_swaths,SWATH);
891  else if ( 0 == swath_fieldtype_flag)
892  var_is_parsed = Set_Var_Dims(eos5cfswath,var,he5s.data_var_list,he5s.name,num_swaths,SWATH);
893  else // Neither Geo nor Data(For example, added by the augmentation tool)
894  var_is_parsed = false;
895 
896  if (false == var_is_parsed){
897  map<hsize_t,string> dimsizes_to_dimnames = eos5cfswath->dimsizes_to_dimnames;
898  Set_NonParse_Var_Dims(eos5cfswath,var,dimsizes_to_dimnames,num_swaths,vartype);
899  }
900  } // if (he5s.name == Obtain_Var_EOS5Type_GroupName(var,vartype))
901  }// for (unsigned int i = 0; i < num_swaths; ++i)
902  } // else if (SWATH == vartype)
903 
904  else if (ZA == vartype) {
905 
906  int num_zas = strmeta_info->za_list.size();
907  for ( int i = 0; i < num_zas; ++i) {
908  HE5Za he5z = strmeta_info->za_list.at(i);
909  if (he5z.name == Obtain_Var_EOS5Type_GroupName(var,vartype)){
910  EOS5CFZa *eos5cfza = (this->eos5cfzas)[i];
911  bool var_is_parsed = Set_Var_Dims(eos5cfza,var,he5z.data_var_list,he5z.name,num_zas,ZA);
912  if (false == var_is_parsed){
913  map<hsize_t,string> dimsizes_to_dimnames = eos5cfza->dimsizes_to_dimnames;
914  Set_NonParse_Var_Dims(eos5cfza,var,dimsizes_to_dimnames,num_zas,vartype);
915  }
916  }
917  }
918  }
919  return false;
920 }
921 
922 template <class T>
923 bool EOS5File::Set_Var_Dims(T* eos5data, Var *var, vector<HE5Var> &he5var,
924  const string& groupname,int num_groups, EOS5Type eos5type) throw(Exception) {
925 
926  bool is_parsed = false;
927  string eos5typestr = "";
928  string fslash_str="/";
929 
930 //cerr<<"coming to Set_Var_Dims "<<endl;
931 
932  if (GRID == eos5type)
933  eos5typestr = "/GRIDS/";
934  else if (SWATH == eos5type)
935  eos5typestr = "/SWATHS/";
936  else if (ZA == eos5type)
937  eos5typestr = "/ZAS/";
938  else
939  throw1("Unsupported HDF-EOS5 type, this type is not swath, grid or zonal average");
940 
941  for (unsigned int i = 0; i < he5var.size(); i++) {
942 
943  HE5Var he5v = he5var.at(i);
944 
945  if (he5v.name == var->name) {
946 
947  if (he5v.dim_list.size() != var->dims.size())
948  throw2("Number of dimensions don't match with the structmetadata for variable ",
949  var->name);
950  is_parsed = true;
951 
952  // Some variables have the same dim. names shared. For examples, we
953  // see variables that have int foo[nlevels][nlevels]. To generate the CVs,
954  // we have to make the dimension name unique for one variable. So we will
955  // change the dimension names. The variable for the same example will be
956  // int foo[nlevels][nlevels_1]. Note this is not required by CF conventions.
957  // This is simply due to the mising of the third coordinate variable for some
958  // NASA products. Another way is to totally ignore this kind of variables which
959  // we will wait for users' responses.
960 
961  // Here is the killer, if different dim. names share the same size,
962  // Currently there are no ways to know which dimension name is corresponding to
963  // which size. HDF-EOS model gives too much freedom to users. The DimList in
964  // the StructMetadata doesn't reflect the order at all. See two example files
965  // CH4 in TES-Aura_L3-CH4_r0000010410_F01_07.he5 and NO2DayColumn in
966  // HIRDLS-Aura_L3SCOL_v06-00-00-c02_2005d022-2008d077.he5.
967  // Fortunately it seems that it doesn't matter for us to make the mapping from
968  // dimension names to coordinate variables.
969  // KY 2012-1-10
970 
971  // Dimension list of some OMI level 2 products doesn't include all dimension name and size
972  // pairs. For example, Latitude[1644][60]. We have no way to find the dimension name of
973  // the dimension with the size of 1644. The dimension name list of the variable also
974  // includes the wrong dimension name. In this case, a dimension with the dimension size =1
975  // is allocated in the latitude's dimension list. The latest version still has this bug.
976  // To serve this kind of files, we create a fakedim name for the unmatched size.
977  // KY 2012-1-13
978 
979  set<hsize_t> dimsize_have_name_set;
980  pair<set<hsize_t>::iterator,bool> setret1;
981  set<string> thisvar_dimname_set;
982  pair<set<string>::iterator,bool> setret2;
983 
984  for (unsigned int j=0; j<he5v.dim_list.size();j++) {
985  HE5Dim he5d = he5v.dim_list.at(j);
986  for (vector<Dimension *>::iterator ird = var->dims.begin();
987  ird != var->dims.end(); ++ird) {
988  if ((hsize_t)(he5d.size) == (*ird)->size) {
989  // This will assure that the same size dims be assigned to different dims
990  if (""==(*ird)->name) {
991  string dimname_candidate = eos5typestr + groupname + fslash_str + he5d.name;
992  setret2 = thisvar_dimname_set.insert(dimname_candidate);
993  if (true == setret2.second) {
994  (*ird)->name = dimname_candidate;
995  // Should check in the future if the newname may cause potential inconsistency. KY:2012-3-9
996  (*ird)->newname = (num_groups == 1)? he5d.name :(*ird)->name;
997  eos5data->vardimnames.insert((*ird)->name);
998  }
999  }
1000  }
1001  }
1002  } // for (unsigned int j=0; j<he5v.dim_list.size();j++)
1003 
1004  // We have to go through the dimension list of this variable again to assure that every dimension has a name.
1005  for (vector<Dimension *>::iterator ird = var->dims.begin();
1006  ird != var->dims.end(); ++ird) {
1007  if ("" == (*ird)->name)
1008  Create_Unique_DimName(eos5data, thisvar_dimname_set,*ird, num_groups, eos5type);
1009  }
1010  } // if (he5v.name == var->name)
1011  } // for (unsigned int i = 0; i < he5var.size(); i++)
1012  return is_parsed;
1013 }
1014 
1015 template<class T>
1016 void EOS5File::Create_Unique_DimName(T*eos5data,set<string>& thisvar_dimname_set,
1017  Dimension *dim,int num_groups, EOS5Type eos5type) throw(Exception){
1018 
1019 //cerr <<"NO DIMNAME dim size = "<<(int)(dim->size) <<endl;
1020 
1021  map<hsize_t,string>:: iterator itmap1;
1022  map<string,hsize_t>:: iterator itmap2;
1023  pair<set<string>::iterator,bool> setret2;
1024  itmap1 = (eos5data->dimsizes_to_dimnames).find(dim->size);
1025 
1026  // Even if we find this dimension matches the dimsizes_to_dimnames map, we have to check if the dimension
1027  // name has been used for this size. This is to make sure each dimension has a unique name in a variable.
1028  // For example, float foo[100][100] can be float foo[nlevels = 100][nlevels_1 = 100].
1029  // Step 1: Check if there is a dimension name that matches the size
1030 
1031  if (itmap1 != (eos5data->dimsizes_to_dimnames).end()) {
1032  string dimname_candidate = (eos5data->dimsizes_to_dimnames)[dim->size];
1033 
1034  // First check local var dimname set
1035  setret2 = thisvar_dimname_set.insert(dimname_candidate);
1036 
1037  if (false == setret2.second) {
1038 
1039  // Will see if other dimension names have this size
1040  bool match_some_dimname = Check_All_DimNames(eos5data,dimname_candidate,dim->size);
1041 
1042  if (false == match_some_dimname) {
1043 
1044  // dimname_candidate is updated.
1045  Get_Unique_Name(eos5data->vardimnames,dimname_candidate);
1046  thisvar_dimname_set.insert(dimname_candidate);
1047 
1048  // Finally generate a new dimension(new dim. name with a size);Update all information
1049  Insert_One_NameSizeMap_Element2(eos5data->dimnames_to_dimsizes,dimname_candidate,dim->size);
1050  eos5data->dimsizes_to_dimnames.insert(pair<hsize_t,string>(dim->size,dimname_candidate));
1051  eos5data->dimnames.push_back(dimname_candidate);
1052  }
1053  }
1054 
1055  // The final dimname_candidate(may be updated) should be assigned to the name of this dimension
1056  dim->name = dimname_candidate;
1057  if (num_groups > 1)
1058  dim->newname = dim->name;
1059  else {
1060  string dname = HDF5CFUtil::obtain_string_after_lastslash(dim->name);
1061  if (""==dname)
1062  throw3("The dimension name ", dim->name, " of the variable is not right");
1063  else dim->newname = dname;
1064  }
1065  }
1066 
1067  else { // No dimension names match or close to march this dimension name, we will create a fakedim.
1068  // Check Add_One_FakeDim_Name in HDF5CF.cc Fakedimname must be as a string reference.
1069  // cerr <<"NO DIMNAME dim size = "<<(int)(dim->size) <<endl;
1070  string Fakedimname = Create_Unique_FakeDimName(eos5data,eos5type);
1071  thisvar_dimname_set.insert(Fakedimname);
1072 
1073  // Finally generate a new dimension(new dim. name with a size);Update all information
1074  Insert_One_NameSizeMap_Element2(eos5data->dimnames_to_dimsizes,Fakedimname,dim->size);
1075  eos5data->dimsizes_to_dimnames.insert(pair<hsize_t,string>(dim->size,Fakedimname));
1076  eos5data->dimnames.push_back(Fakedimname);
1077  dim->name = Fakedimname;
1078  if (num_groups > 1)
1079  dim->newname = dim->name;
1080  else {
1081  string dname = HDF5CFUtil::obtain_string_after_lastslash(dim->name);
1082  if (""==dname)
1083  throw3("The dimension name ", dim->name, " of the variable is not right");
1084  else
1085  dim->newname = dname;
1086  }
1087  }
1088 }
1089 
1090 
1091 
1092 template<class T>
1093 bool EOS5File::Check_All_DimNames(T* eos5data,string& dimname,hsize_t dimsize) {
1094 
1095  bool ret_flag = false;
1096  for (map<string,hsize_t>::iterator im =eos5data->dimnames_to_dimsizes.begin();
1097  im !=eos5data->dimnames_to_dimsizes.end();++im) {
1098  // cerr<<"name to size"<< (*im).first <<"=> "<<(int)((*im).second) <<endl;
1099  // dimname must not be the same one since the same one is rejected.
1100  if (dimsize == (*im).second && dimname !=(*im).first) {
1101  dimname = (*im).first;
1102  ret_flag = true;
1103  break;
1104  }
1105  }
1106  return ret_flag;
1107 }
1108 
1109 
1110 void EOS5File::Get_Unique_Name(set<string> & nameset,string& dimname_candidate) throw(Exception){
1111 
1112  int clash_index =1;
1113  string temp_clashname=dimname_candidate+'_';
1114  HDF5CFUtil::gen_unique_name(temp_clashname,nameset,clash_index);
1115  dimname_candidate = temp_clashname;
1116 }
1117 
1118 template<class T>
1119 string EOS5File::Create_Unique_FakeDimName(T*eos5data, EOS5Type eos5type) throw(Exception) {
1120 
1121  string fslash_str = "/";
1122  string eos5typestr;
1123  if (GRID==eos5type)
1124  eos5typestr = "/GRIDS/";
1125  else if (SWATH == eos5type)
1126  eos5typestr = "/SWATHS/";
1127  else if (ZA == eos5type)
1128  eos5typestr = "/ZAS/";
1129  else
1130  throw1("Unsupported HDF-EOS5 type, this type is not swath, grid or zonal average");
1131 
1132  stringstream sfakedimindex;
1133  sfakedimindex << eos5data->addeddimindex;
1134  string fakedimstr = "FakeDim";
1135  string added_dimname = eos5typestr + eos5data->name + fslash_str + fakedimstr + sfakedimindex.str();
1136 
1137  pair<set<string>::iterator,bool> setret;
1138  setret = eos5data->vardimnames.insert(added_dimname);
1139  if (false == setret.second)
1140  Get_Unique_Name(eos5data->vardimnames,added_dimname);
1141  eos5data->addeddimindex = eos5data->addeddimindex + 1;
1142  return added_dimname;
1143 }
1144 
1145 
1147 
1148  string EOS5GRIDPATH ="/HDFEOS/GRIDS";
1149  string EOS5SWATHPATH ="/HDFEOS/SWATHS";
1150  string EOS5ZAPATH ="/HDFEOS/ZAS";
1151  size_t eostypename_start_pos;
1152  size_t eostypename_end_pos;
1153  string groupname;
1154 
1155  // The fullpath is like "HDFEOS/GRIDS/Temp/Data Fields/etc
1156  // To get "Temp", we obtain the position of "T" and the position of "p"
1157  // and then generate a substr.
1158 
1159  if (GRID == eos5type)
1160  eostypename_start_pos = EOS5GRIDPATH.size()+1;
1161  else if (SWATH == eos5type)
1162  eostypename_start_pos = EOS5SWATHPATH.size()+1;
1163  else if (ZA == eos5type)
1164  eostypename_start_pos = EOS5ZAPATH.size()+1;
1165  else
1166  throw2("Non supported eos5 type for var ",var->fullpath);
1167 
1168  eostypename_end_pos = var->fullpath.find('/',eostypename_start_pos)-1;
1169  groupname = var->fullpath.substr(eostypename_start_pos,eostypename_end_pos-eostypename_start_pos+1);
1170 
1171  return groupname;
1172 }
1173 
1175 
1176  string geofield_relative_path = "/Geolocation Fields/"+var->name;
1177  string datafield_relative_path = "/Data Fields/" + var->name;
1178 
1179  int tempflag = -1;
1180 
1181  if (var->fullpath.size() > datafield_relative_path.size()) {
1182  size_t field_pos_in_full_path = var->fullpath.size()-datafield_relative_path.size();
1183  if (var->fullpath.rfind(datafield_relative_path,field_pos_in_full_path) !=string::npos)
1184  tempflag = 0;
1185  }
1186 
1187  if (tempflag != 0 && (var->fullpath.size() > geofield_relative_path.size())) {
1188  size_t field_pos_in_full_path = var->fullpath.size()-geofield_relative_path.size();
1189 //cerr<<"field_pos_in_full_path= "<<(int)field_pos_in_full_path <<endl;
1190  if (var->fullpath.rfind(geofield_relative_path,field_pos_in_full_path) !=string::npos)
1191  tempflag = 1;
1192  }
1193  return tempflag;
1194 }
1195 
1196 
1197 
1198 // An error will be thrown if we find a dimension size that doesn't match any dimension name
1199 // in this EOS5 group.
1200 template<class T>
1201 void EOS5File::Set_NonParse_Var_Dims(T*eos5data, Var* var,
1202  map<hsize_t,string>& dimsizes_to_dimnames,
1203  int num_groups, EOS5Type eos5type) throw(Exception){
1204 
1205  map<hsize_t,string>::iterator itmap;
1206  set<string> thisvar_dimname_set;
1207 
1208  for (vector<Dimension *>::iterator ird = var->dims.begin();
1209  ird != var->dims.end(); ++ird) {
1210  if ("" == (*ird)->name)
1211  Create_Unique_DimName(eos5data, thisvar_dimname_set,*ird, num_groups, eos5type);
1212  else
1213  throw5("The dimension name ", (*ird)->name, " of the variable ",var->name," is not right");
1214  }
1215 }
1216 
1217 
1219 
1220  // Aura files will put an attribute called InStrumentName under /HDFEOS/ADDITIONAL/FILE_ATTRIBUTES
1221  // We just need to check that attribute.
1222  string eos5_fattr_group_name ="/HDFEOS/ADDITIONAL/FILE_ATTRIBUTES";
1223  string instrument_attr_name = "InstrumentName";
1224 
1225  // Check if this file is an aura file
1226  for (vector<Group *>::iterator irg = this->groups.begin();
1227  irg != this->groups.end(); ++irg) {
1228  if (eos5_fattr_group_name ==(*irg)->path){
1229  for (vector<Attribute *>::iterator ira = (*irg)->attrs.begin();
1230  ira != (*irg)->attrs.end(); ++ira) {
1231  if (instrument_attr_name == (*ira)->name) {
1232  Retrieve_H5_Attr_Value(*ira,(*irg)->path);
1233  string attr_value((*ira)->value.begin(),(*ira)->value.end());
1234  if ("OMI" == attr_value) {
1235  this->isaura = true;
1236  this->aura_name = OMI;
1237  }
1238  else if ("MLS Aura" == attr_value) {
1239  this->isaura = true;
1240  this->aura_name = MLS;
1241  }
1242  else if ("TES" == attr_value) {
1243  this->isaura = true;
1244  this->aura_name = TES;
1245  }
1246  else if ("HIRDLS" == attr_value) {
1247  this->isaura = true;
1248  this->aura_name = HIRDLS;
1249  }
1250  break;
1251  }
1252  }
1253  }
1254  }
1255 
1256  // Assign EOS5 to CF MAP values for Aura files
1257  if (true == this->isaura) {
1258  eos5_to_cf_attr_map["FillValue"] = "_FillValue";
1259  eos5_to_cf_attr_map["MissingValue"] = "missing_value";
1260  eos5_to_cf_attr_map["Units"] = "units";
1261  eos5_to_cf_attr_map["Offset"] = "add_offset";
1262  eos5_to_cf_attr_map["ScaleFactor"] = "scale_factor";
1263  eos5_to_cf_attr_map["ValidRange"] = "valid_range";
1264  eos5_to_cf_attr_map["Title"] = "title";
1265  }
1266 
1267 }
1268 
1270 
1271  bool is_augmented = Check_Augmentation_Status();
1272 
1273 #if 0
1274 if(is_augmented) cerr <<"The file is augmented "<<endl;
1275 else cerr<<"The file is not augmented "<<endl;
1276 #endif
1277 
1278  if (this->eos5cfgrids.size() > 0)
1279  Handle_Grid_CVar(is_augmented);
1280  if (this->eos5cfswaths.size() >0)
1281  Handle_Swath_CVar(is_augmented);
1282  if (this->eos5cfzas.size() >0)
1283  Handle_Za_CVar(is_augmented);
1284 
1285 #if 0
1286 for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
1287  irv != this->cvars.end(); irv++) {
1288 cerr <<"EOS5CVar name "<<(*irv)->name <<endl;
1289 cerr <<"EOS5CVar dimension name "<< (*irv)->cfdimname <<endl;
1290 cerr <<"EOS5CVar new name "<<(*irv)->newname <<endl;
1291 }
1292 #endif
1293 
1294 }
1295 void EOS5File::Handle_Grid_CVar(bool is_augmented) throw(Exception){
1296 
1297 
1298  if (true == is_augmented) {
1299 //cerr<<"IS Augmented "<<endl;
1300  // Create latitude/longitude based on the first XDim and YDim
1301  Handle_Augmented_Grid_CVar();
1302  }
1303  else {
1304  // cerr<<"before this->eos5cfgrids.size() = " << this->eos5cfgrids.size() << endl;
1305  Remove_MultiDim_LatLon_EOS5CFGrid();
1306  // cerr<<"this->eos5cfgrids.size() = " << this->eos5cfgrids.size() << endl;
1307  // If the grid size is 0, it must be a Grid file that cannot be handled
1308  // with the CF option, simply return with handling any coordinate variables.
1309  if (0 == this->eos5cfgrids.size()) return;
1310  if (1 == this->eos5cfgrids.size())
1311  Handle_Single_Nonaugment_Grid_CVar((this->eos5cfgrids)[0]);
1312  else
1313  Handle_Multi_Nonaugment_Grid_CVar();
1314  }
1315 }
1316 
1318 
1319  bool aug_status = false;
1320  int num_aug_eos5grp = 0;
1321 
1322  for (vector <EOS5CFGrid *>::iterator irg = this->eos5cfgrids.begin();
1323  irg != this->eos5cfgrids.end(); ++irg) {
1324  for (vector<Var *>::iterator irv = this->vars.begin();
1325  irv != this->vars.end(); ++irv) {
1326  bool is_augmented = Check_Augmented_Var_Candidate(*irg,*irv,GRID);
1327  if (true == is_augmented) {
1328  num_aug_eos5grp ++;
1329  break;
1330  }
1331  }
1332  }
1333 
1334  for (vector <EOS5CFSwath *>::iterator irg = this->eos5cfswaths.begin();
1335  irg != this->eos5cfswaths.end(); ++irg) {
1336  for (vector<Var *>::iterator irv = this->vars.begin();
1337  irv != this->vars.end(); ++irv) {
1338  bool is_augmented = Check_Augmented_Var_Candidate(*irg,*irv,SWATH);
1339  if (true == is_augmented) {
1340  num_aug_eos5grp ++;
1341  break;
1342  }
1343 
1344  }
1345  }
1346 
1347  for (vector <EOS5CFZa *>::iterator irg = this->eos5cfzas.begin();
1348  irg != this->eos5cfzas.end(); ++irg) {
1349  for (vector<Var *>::iterator irv = this->vars.begin();
1350  irv != this->vars.end(); ++irv) {
1351  bool is_augmented = Check_Augmented_Var_Candidate(*irg,*irv,ZA);
1352  if (true == is_augmented) {
1353  num_aug_eos5grp ++;
1354  break;
1355  }
1356  }
1357  }
1358 
1359  int total_num_eos5grp = this->eos5cfgrids.size() + this->eos5cfswaths.size() + this->eos5cfzas.size();
1360 //cerr<< "total_num_eos5grp "<<total_num_eos5grp <<endl;
1361 //cerr <<"num_aug_eos5grp "<< num_aug_eos5grp <<endl;
1362 
1363  if (num_aug_eos5grp == total_num_eos5grp)
1364  aug_status = true;
1365  return aug_status;
1366 
1367 }
1368 
1369 // This method is not used. Still keep it now since it may be useful in the future. KY 2012-3-09
1371 
1372  // We will check whether the attribute "CLASS" and the attribute "REFERENCE_LIST" exist.
1373  // For the attribute "CLASS", we would like to check if the value is "DIMENSION_SCALE".
1374  bool has_dimscale_class = false;
1375  bool has_reflist = false;
1376  for (vector<Attribute *>::iterator ira = var->attrs.begin();
1377  ira != var->attrs.end(); ++ira) {
1378  if ("CLASS" == (*ira)->name) {
1379  Retrieve_H5_Attr_Value(*ira,var->fullpath);
1380  string class_value((*ira)->value.begin(),(*ira)->value.end());
1381  if ("DIMENSION_SCALE"==class_value)
1382  has_dimscale_class = true;
1383  }
1384 
1385  if ("REFERENCE_LIST" == (*ira)->name)
1386  has_reflist = true;
1387  if (true == has_reflist && true == has_dimscale_class)
1388  break;
1389  }
1390 
1391  if (true == has_reflist && true == has_dimscale_class)
1392  return true;
1393  else
1394  return false;
1395 
1396 }
1397 
1398 template <class T>
1399 bool EOS5File::Check_Augmented_Var_Candidate(T *eos5data, Var *var, EOS5Type eos5type) throw(Exception) {
1400 
1401  bool augmented_var = false;
1402 
1403  string EOS5DATAPATH = "";
1404  if (GRID == eos5type)
1405  EOS5DATAPATH = "/HDFEOS/GRIDS/";
1406  else if (ZA == eos5type)
1407  EOS5DATAPATH = "/HDFEOS/ZAS/";
1408  else if (SWATH == eos5type)
1409  EOS5DATAPATH ="/HDFEOS/SWATHS/";
1410  else throw1("Non supported EOS5 type");
1411 
1412  string fslash_str ="/";
1413  string THIS_EOS5DATAPATH = EOS5DATAPATH + eos5data->name + fslash_str;
1414 
1415  // Match the EOS5 type
1416  if (eos5type == Get_Var_EOS5_Type(var)) {
1417  string var_eos5data_name = Obtain_Var_EOS5Type_GroupName(var,eos5type);
1418  // Match the EOS5 group name
1419  if (var_eos5data_name == eos5data->name) {
1420  if (var->fullpath.size() > THIS_EOS5DATAPATH.size()){
1421  // Obtain the var name from the full path
1422  string var_path_after_eos5dataname = var->fullpath.substr(THIS_EOS5DATAPATH.size());
1423  // Match the variable name
1424  if (var_path_after_eos5dataname == var->name)
1425  augmented_var = true;
1426  }
1427  }
1428  }
1429 
1430  return augmented_var;
1431 
1432 }
1433 
1434 
1436  for (vector <EOS5CFGrid *>::iterator irv = this->eos5cfgrids.begin();
1437  irv !=this->eos5cfgrids.end();++irv)
1439 }
1440 
1441 
1442 template <class T>
1443 void EOS5File::Handle_Single_Augment_CVar(T* cfeos5data, EOS5Type eos5type) throw(Exception) {
1444 
1445  set<string> tempvardimnamelist;
1446  tempvardimnamelist = cfeos5data->vardimnames;
1447  set <string>::iterator its;
1448 //cerr <<"coming to Single Augment Grid "<<endl;
1449  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
1450  for (vector<Var *>::iterator irv = this->vars.begin();
1451  irv != this->vars.end(); ++irv) {
1452 
1453  bool is_augmented = Check_Augmented_Var_Candidate(cfeos5data,*irv,eos5type);
1454 
1455  if (true == is_augmented) {
1456 
1457  // Since we have already checked if this file is augmented or not, we can safely
1458  // compare the dimension name with the var name now.
1459 //cerr<<"dimension name "<<*its <<endl;
1460  string tempdimname = HDF5CFUtil::obtain_string_after_lastslash(*its);
1461 //cerr<<"tempdimname "<<tempdimname <<endl;
1462  if (tempdimname == (*irv)->name) {
1463 
1464  //Find it, create a coordinate variable.
1465  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
1466 
1467  // Still keep the original dimension name to avoid the nameclashing when
1468  // one grid and one swath and one za occur in the same file
1469  EOS5cvar->cfdimname = *its;
1470  EOS5cvar->cvartype = CV_EXIST;
1471  EOS5cvar->eos_type = eos5type;
1472 
1473  // Save this cv to the cv vector
1474  this->cvars.push_back(EOS5cvar);
1475 
1476  // Remove this var from the var vector since it becomes a cv.
1477  delete(*irv);
1478  this->vars.erase(irv);
1479  irv--;
1480  }
1481  } // if (true == is_augmented)
1482  } // for (vector<Var *>::iterator irv = this->vars.begin();....
1483  } // for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
1484 
1485  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
1486  irv != this->cvars.end(); ++irv) {
1487  its = tempvardimnamelist.find((*irv)->cfdimname);
1488  if (its != tempvardimnamelist.end())
1489  tempvardimnamelist.erase(its);
1490  }
1491 
1492  if (false == tempvardimnamelist.empty())
1493  throw1("Augmented files still need to provide more coordinate variables");
1494 }
1495 
1496 
1498 
1499  for (vector <EOS5CFGrid *>::iterator irg = this->eos5cfgrids.begin();
1500  irg != this->eos5cfgrids.end(); ++irg) {
1501 
1502  // If number of dimension latitude/longitude is >=2, no cooridnate variables will be generated.
1503  // We will simply remove this grid from the vector eos5cfgrids.
1504  // In the future, we may consider supporting 2D latlon. KY 2012-1-17
1505  // I just find that new OMI level 3 data provide 2D lat/lon for geographic projection data.
1506  // The 2D lat/lon can be condensed to 1D lat/lon, which is the same calculated by the calculation of
1507  // the projection. So I don't remove this OMI grid from the grid list. KY 2012-2-9
1508  // However, I do remove the "Longitude" and "Latitude" fields since "Latitude" and "Longitude"
1509  // can be calculated.
1510 
1511  if (true == (*irg)->has_2dlatlon) {
1512 
1513  if ((true == this->isaura) && (OMI == this->aura_name) &&
1514  (HE5_GCTP_GEO == (*irg)->eos5_projcode))
1515 
1516  {// We need to remove the redundant latitude and longitude fields
1517 
1518  string EOS5GRIDPATH ="/HDFEOS/GRIDS/";
1519  string fslash_str ="/";
1520  string THIS_EOS5GRIDPATH = EOS5GRIDPATH + (*irg)->name + fslash_str;
1521  int catch_latlon = 0;
1522 
1523  for (vector<Var *>::iterator irv = this->vars.begin();
1524  (irv != this->vars.end()) && (catch_latlon!=2); ++irv) {
1525  if (GRID == Get_Var_EOS5_Type(*irv) &&
1526  ((*irv)->fullpath.size() > THIS_EOS5GRIDPATH.size())) {
1527 
1528  string var_grid_name = Obtain_Var_EOS5Type_GroupName(*irv,GRID);
1529  if ((var_grid_name == (*irg)->name)) {
1530  if(("Longitude" == (*irv)->name) || ("Latitude" == (*irv)->name)) {
1531  catch_latlon++;
1532  // Remove this var from the var vector since it becomes a cv.
1533  delete(*irv);
1534  this->vars.erase(irv);
1535  irv--;
1536  }
1537  }
1538  }
1539  } // for (vector<Var *>::iterator irv = this->vars.begin() ...
1540  if (2 == catch_latlon) {
1541  // cerr <<"coming to the catch "<<endl;
1542  (*irg)->has_nolatlon = true;
1543  (*irg)->has_2dlatlon = false;
1544  }
1545  } // if ((true == this->isaura) ...
1546  else {// remove this grid from the eos5cfgrids list.
1547  delete (*irg);
1548  this->eos5cfgrids.erase(irg);
1549  irg--;
1550  }
1551  } // if (true == (*irg) ...
1552 
1553  if (true == (*irg)->has_g2dlatlon) {
1554  delete (*irg);
1555  this->eos5cfgrids.erase(irg);
1556  irg--;
1557  }
1558  } // for (vector <EOS5CFGrid *>::iterator irg = this->eos5cfgrids.begin() ...
1559 }
1560 
1562 
1563  set<string> tempvardimnamelist;
1564  tempvardimnamelist = cfgrid->vardimnames;
1565 
1566  // Handle Latitude and longitude
1567  bool use_own_latlon = false;
1568  if (true == cfgrid->has_1dlatlon)
1569  use_own_latlon = Handle_Single_Nonaugment_Grid_CVar_OwnLatLon(cfgrid, tempvardimnamelist);
1570 #if 0
1571 if(use_own_latlon) cerr <<"using 1D latlon"<<endl;
1572 else cerr <<"use_own_latlon is false "<<endl;
1573 #endif
1574 
1575  if (false == use_own_latlon) {
1576  bool use_eos5_latlon = false;
1577  use_eos5_latlon = Handle_Single_Nonaugment_Grid_CVar_EOS5LatLon(cfgrid,tempvardimnamelist);
1578 
1579  // If we cannot obtain lat/lon from the HDF-EOS5 library, no need to create other CVs. Simply return.
1580  if (false == use_eos5_latlon)
1581  return;
1582  }
1583 
1584  // Else handling non-latlon grids
1585 //cerr <<"tempvardim set size "<<tempvardimnamelist.size() <<endl;
1586  Handle_NonLatLon_Grid_CVar(cfgrid,tempvardimnamelist);
1587 
1588 }
1589 
1590 
1591 bool EOS5File::Handle_Single_Nonaugment_Grid_CVar_OwnLatLon(EOS5CFGrid *cfgrid, set<string>& tempvardimnamelist) throw(Exception) {
1592 
1593  set <string>::iterator its;
1594  string EOS5GRIDPATH ="/HDFEOS/GRIDS/";
1595  string fslash_str ="/";
1596  string THIS_EOS5GRIDPATH = EOS5GRIDPATH + cfgrid->name + fslash_str;
1597 //cerr<<"coming to Handle_Single_Nonaugment_Grid_CVar_OwnLatLon " <<endl;
1598 
1599  // Handle latitude and longitude
1600  bool find_latydim = false;
1601  bool find_lonxdim = false;
1602 
1603  for (vector<Var *>::iterator irv = this->vars.begin();
1604  irv != this->vars.end(); ++irv) {
1605  if (GRID == Get_Var_EOS5_Type(*irv) &&
1606  ((*irv)->fullpath.size() > THIS_EOS5GRIDPATH.size())) {
1607 
1608  string var_grid_name = Obtain_Var_EOS5Type_GroupName(*irv,GRID);
1609  if ((var_grid_name == cfgrid->name) && ((*irv)->name == "Latitude")) {
1610 
1611  string tempdimname = (((*irv)->dims)[0])->name;
1612 
1613  if ("YDim" == HDF5CFUtil::obtain_string_after_lastslash(tempdimname)) {
1614  //Find it, create a coordinate variable.
1615  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
1616 
1617  // Still keep the original dimension name to avoid the nameclashing when
1618  // one grid and one swath and one za occur in the same file
1619  EOS5cvar->cfdimname = tempdimname;
1620  EOS5cvar->cvartype = CV_EXIST;
1621  EOS5cvar->eos_type = GRID;
1622 
1623  // Save this cv to the cv vector
1624  this->cvars.push_back(EOS5cvar);
1625 
1626  // Remove this var from the var vector since it becomes a cv.
1627  delete(*irv);
1628  this->vars.erase(irv);
1629 
1630  // No need to remove back the iterator since it will go out of the loop.
1631  find_latydim = true;
1632  break;
1633  } // if ("YDim" == HDF5CFUtil::obtain_string_after_lastslash(tempdimname))
1634  } // if ((var_grid_name == cfgrid->name) && ((*irv)->name == "Latitude"))
1635  } // if (GRID == Get_Var_EOS5_Type(*irv) ...
1636  } // for (vector<Var *>::iterator irv = this->vars.begin() ...
1637 
1638  for (vector<Var *>::iterator irv = this->vars.begin();
1639  irv != this->vars.end(); ++irv) {
1640 
1641  if (GRID == Get_Var_EOS5_Type(*irv) &&
1642  ((*irv)->fullpath.size() > THIS_EOS5GRIDPATH.size())) {
1643 
1644  string var_grid_name = Obtain_Var_EOS5Type_GroupName(*irv,GRID);
1645 
1646  if ((var_grid_name == cfgrid->name) && ((*irv)->name == "Longitude")) {
1647 
1648  string tempdimname = (((*irv)->dims)[0])->name;
1649 
1650  if ("XDim" == HDF5CFUtil::obtain_string_after_lastslash(tempdimname)) {
1651  //Find it, create a coordinate variable.
1652  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
1653 
1654  // Still keep the original dimension name to avoid the nameclashing when
1655  // one grid and one swath and one za occur in the same file
1656  EOS5cvar->cfdimname = tempdimname;
1657  EOS5cvar->cvartype = CV_EXIST;
1658  EOS5cvar->eos_type = GRID;
1659 
1660  // Save this cv to the cv vector
1661  this->cvars.push_back(EOS5cvar);
1662 
1663  // Remove this var from the var vector since it becomes a cv.
1664  delete(*irv);
1665  this->vars.erase(irv);
1666  find_lonxdim = true;
1667  break;
1668  } // if ("XDim" == HDF5CFUtil::obtain_string_after_lastslash(tempdimname))
1669  } // if ((var_grid_name == cfgrid->name) && ((*irv)->name == "Longitude"))
1670  } // if (GRID == Get_Var_EOS5_Type(*irv) ...
1671  }// for (vector<Var *>::iterator irv = this->vars.begin(); ...
1672 
1673 
1674 
1675  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
1676  irv != this->cvars.end(); ++irv) {
1677  its = tempvardimnamelist.find((*irv)->cfdimname);
1678  if (its != tempvardimnamelist.end()) tempvardimnamelist.erase(its);
1679 
1680  }
1681 
1682 #if 0
1683 for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
1684  cerr <<"tempvardim "<<*its <<endl;
1685 #endif
1686 
1687  return(find_latydim == true && find_lonxdim == true);
1688 }
1689 
1690 bool EOS5File::Handle_Single_Nonaugment_Grid_CVar_EOS5LatLon(EOS5CFGrid *cfgrid, set<string>& tempvardimnamelist) throw(Exception) {
1691 
1692  // Handle latitude and longitude
1693  bool find_ydim = false;
1694  bool find_xdim = false;
1695  set <string>::iterator its;
1696 
1697 
1698 #if 0
1699 for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
1700 cerr<<"dim names "<<(*its) <<endl;
1701 #endif
1702 
1703 
1704  //for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
1705  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ) {
1706  if ("YDim" == HDF5CFUtil::obtain_string_after_lastslash(*its)) {
1707 //cerr<<"coming to YDim "<<endl;
1708 
1709  // Create EOS5 Latitude CV
1710  EOS5CVar *EOS5cvar = new EOS5CVar();
1711  EOS5cvar->name = "lat";
1712  Create_Added_Var_NewName_FullPath(GRID,cfgrid->name,EOS5cvar->name,EOS5cvar->newname,EOS5cvar->fullpath);
1713  EOS5cvar->rank = 1;
1714  EOS5cvar->dtype = H5FLOAT32;
1715  Dimension* eos5cvar_dim = new Dimension((hsize_t)cfgrid->ydimsize);
1716  eos5cvar_dim->name = *its;
1717  eos5cvar_dim->newname = (this->eos5cfgrids.size() == 1) ? "YDim":(*its);
1718  EOS5cvar->dims.push_back(eos5cvar_dim);
1719  EOS5cvar->cfdimname = eos5cvar_dim->name;
1720  EOS5cvar->cvartype = CV_LAT_MISS;
1721  EOS5cvar->eos_type = GRID;
1722  EOS5cvar->xdimsize = cfgrid->xdimsize;
1723  EOS5cvar->ydimsize = cfgrid->ydimsize;
1724 
1725  //Special parameters for EOS5 Grid
1726  EOS5cvar->point_lower = cfgrid->point_lower;
1727  EOS5cvar->point_upper = cfgrid->point_upper;
1728  EOS5cvar->point_left = cfgrid->point_left;
1729  EOS5cvar->point_right = cfgrid->point_right;
1730  EOS5cvar->eos5_pixelreg = cfgrid->eos5_pixelreg;
1731  EOS5cvar->eos5_origin = cfgrid->eos5_origin;
1732  EOS5cvar->eos5_projcode = cfgrid->eos5_projcode;
1733 
1734  // Save this cv to the cv vector
1735  this->cvars.push_back(EOS5cvar);
1736  // erase the dimension name from the dimension name set
1737 
1738  // This is the right way to make its platform-independent.
1739  tempvardimnamelist.erase(its++);
1740  find_ydim = true;
1741 // cerr<<"end of YDim " <<endl;
1742 
1743  } // if ("YDim" == HDF5CFUtil::obtain_string_after_lastslash(*its))
1744 
1745  else if ("XDim" == HDF5CFUtil::obtain_string_after_lastslash(*its)) {
1746 // cerr<<"coming to XDim" <<endl;
1747 
1748  // Create EOS5 Latitude CV
1749  EOS5CVar *EOS5cvar = new EOS5CVar();
1750  EOS5cvar->name = "lon";
1751  Create_Added_Var_NewName_FullPath(GRID,cfgrid->name,EOS5cvar->name,EOS5cvar->newname,EOS5cvar->fullpath);
1752  //EOS5cvar->newname = EOS5cvar->name;
1753  //EOS5cvar->fullpath = EOS5cvar->name;
1754  EOS5cvar->rank = 1;
1755  EOS5cvar->dtype = H5FLOAT32;
1756  Dimension* eos5cvar_dim = new Dimension((hsize_t)cfgrid->xdimsize);
1757  //eos5cvar_dim->name = EOS5cvar->name;
1758  eos5cvar_dim->name = *its;
1759  eos5cvar_dim->newname = (this->eos5cfgrids.size() == 1) ? "XDim":(*its);
1760  EOS5cvar->dims.push_back(eos5cvar_dim);
1761  EOS5cvar->cfdimname = eos5cvar_dim->name;
1762  EOS5cvar->cvartype = CV_LON_MISS;
1763  EOS5cvar->eos_type = GRID;
1764  EOS5cvar->xdimsize = cfgrid->xdimsize;
1765  EOS5cvar->ydimsize = cfgrid->ydimsize;
1766 
1767 
1768  //Special parameters for EOS5 Grid
1769  EOS5cvar->point_lower = cfgrid->point_lower;
1770  EOS5cvar->point_upper = cfgrid->point_upper;
1771  EOS5cvar->point_left = cfgrid->point_left;
1772  EOS5cvar->point_right = cfgrid->point_right;
1773  EOS5cvar->eos5_pixelreg = cfgrid->eos5_pixelreg;
1774  EOS5cvar->eos5_origin = cfgrid->eos5_origin;
1775  EOS5cvar->eos5_projcode = cfgrid->eos5_projcode;
1776 
1777  // Save this cv to the cv vector
1778  this->cvars.push_back(EOS5cvar);
1779 
1780  // erase the dimension name from the dimension name set,platform independent way.
1781  tempvardimnamelist.erase(its++);
1782  find_xdim = true;
1783 // cerr<<"end of XDim" <<endl;
1784 
1785  } // else if ("XDim" == HDF5CFUtil::obtain_string_after_lastslash(*its))
1786  else
1787  ++its;
1788  if (true == find_xdim && true == find_ydim)
1789  break;
1790  } // for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
1791 
1792  return ( true == find_xdim && true == find_ydim);
1793 }
1794 
1795 void EOS5File::Handle_NonLatLon_Grid_CVar(EOS5CFGrid *cfgrid, set<string>& tempvardimnamelist) throw(Exception) {
1796 
1797  // First check if we have existing coordinate variable
1798  set <string>::iterator its;
1799  int num_dimnames = tempvardimnamelist.size();
1800  bool has_dimnames = true;
1801 
1802  //cerr<<"num_dimnames "<<num_dimnames <<endl;
1803  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
1804  if (cfgrid->dnames_to_1dvnames.find(*its) !=cfgrid->dnames_to_1dvnames.end()){
1805  for (vector<Var *>::iterator irv = this->vars.begin();
1806  has_dimnames && (irv != this->vars.end()); ++irv) {
1807  // We need to check if this var is a grid and use "newname"
1808  // of var to check the dnames_to_1dvnames since it is
1809  // possible to have name clashings for the "name" of a var.
1810  if (GRID == Get_Var_EOS5_Type(*irv) &&
1811  (*irv)->newname == (cfgrid->dnames_to_1dvnames)[*its]) {
1812 
1813  //Find it, create a coordinate variable.
1814  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
1815 
1816  // Still keep the original dimension name to avoid the nameclashing when
1817  // one grid and one swath and one za occur in the same file
1818  EOS5cvar->cfdimname = *its;
1819  EOS5cvar->cvartype = CV_EXIST;
1820  EOS5cvar->eos_type = GRID;
1821 
1822  // Save this cv to the cv vector
1823  this->cvars.push_back(EOS5cvar);
1824 
1825  // Remove this var from the var vector since it becomes a cv.
1826  delete(*irv);
1827  this->vars.erase(irv);
1828  irv--;
1829  num_dimnames--;
1830  if (0 == num_dimnames)
1831  has_dimnames = false;
1832  } // if (GRID == Get_Var_EOS5_Type(*irv) ...
1833  } // for (vector<Var *>::iterator irv = this->vars.begin(); ...
1834  } // if (cfgrid->dnames_to_1dvnames.find(*its) !=cfgrid->dnames_to_1dvnames.end())
1835  } // for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
1836 
1837 // cerr<<"before EOS5CVar in handle_nonlatlon "<<endl;
1838  // Remove the dimension name that finds the cooresponding variables from the tempvardimlist.
1839  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
1840  irv != this->cvars.end(); ++irv) {
1841  its = tempvardimnamelist.find((*irv)->cfdimname);
1842  if (its != tempvardimnamelist.end())
1843  tempvardimnamelist.erase(its);
1844  }
1845 
1846  // Second: Some dimension names still need to find CVs, create the missing CVs
1847  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
1848 
1849  EOS5CVar *EOS5cvar = new EOS5CVar();
1850  Create_Missing_CV(cfgrid,EOS5cvar,*its,GRID,this->eos5cfgrids.size());
1851  this->cvars.push_back(EOS5cvar);
1852 
1853  }
1854 // cerr<<" end of handle_nonlatlon "<<endl;
1855 }
1856 
1857 
1859 
1860  //cerr <<"coming to Handle_Multi_nonaugment_Grid_CVar "<<endl;
1861 
1862  // If the multiple grids don't share the same lat/lon according to the parameters
1863  // We then assume that each single grid has its own lat/lon, just loop through each grid.
1864  if (true == this->grids_multi_latloncvs) {
1865  for (vector <EOS5CFGrid *>::iterator irv = this->eos5cfgrids.begin();
1866  irv !=this->eos5cfgrids.end();++irv)
1868  }
1869 
1870  // We would like to check if lat/lon pairs provide for all grids
1871  // If lat/lon pairs are provided for all grids, then we ASSUME that
1872  // all grids share the same lat/lon values. This is what happened with
1873  // Aura grids. We only apply this to Aura files.They provide a lat/lon pair for each grid. We will observe
1874  // if this assumption is true for the future products.
1875  // If lat/lon pairs are not provided for all grids, we assume that each grid
1876  // may still have its unique lat/lon.
1877  else {
1878  int num_1dlatlon_pairs = 0;
1879  for (vector <EOS5CFGrid *>::iterator irv = this->eos5cfgrids.begin();
1880  irv !=this->eos5cfgrids.end() ;++irv)
1881  if (true == (*irv)->has_1dlatlon)
1882  num_1dlatlon_pairs ++;
1883 
1884  bool use_eos5_latlon = false;
1885  if (( 0 == num_1dlatlon_pairs) ||
1886  ((num_1dlatlon_pairs == (int)(this->eos5cfgrids.size())) && (true == this->isaura))) {
1887  set<string> tempvardimnamelist = ((this->eos5cfgrids)[0])->vardimnames;
1888  if ( 0 == num_1dlatlon_pairs) {
1889  use_eos5_latlon =
1890  Handle_Single_Nonaugment_Grid_CVar_EOS5LatLon((this->eos5cfgrids)[0],tempvardimnamelist);
1891 
1892  if (false == use_eos5_latlon)
1893  return;
1894  }
1895 
1896  else {
1897  // One lat/lon for all grids
1898  bool use_own_latlon = false;
1899  use_own_latlon =
1900  Handle_Single_Nonaugment_Grid_CVar_OwnLatLon((this->eos5cfgrids)[0],tempvardimnamelist);
1901  if (false == use_own_latlon) {
1902  use_eos5_latlon = Handle_Single_Nonaugment_Grid_CVar_EOS5LatLon((this->eos5cfgrids)[0],tempvardimnamelist);
1903  if (false == use_eos5_latlon)
1904  return;
1905  }
1906  }
1907 
1908  // We need to handle the first grid differently since it will include "XDim" and "YDim".
1909  Handle_NonLatLon_Grid_CVar((this->eos5cfgrids)[0],tempvardimnamelist);
1910 
1911  // Updating the dimension name sets for other grids
1912  for (unsigned j = 1; j < this->eos5cfgrids.size(); j++ )
1913  (this->eos5cfgrids)[j]->Update_Dimnamelist();
1914 
1915  // Adjusting the dimension names for all vars under these EOS5 Grids
1916  Adjust_EOS5GridDimNames((this->eos5cfgrids)[0]);
1917 
1918  // Now we can safely handle the rest grids
1919  for (unsigned j = 1; j < this->eos5cfgrids.size(); j++ ) {
1920  tempvardimnamelist = (this->eos5cfgrids)[j]->vardimnames;
1921  Handle_NonLatLon_Grid_CVar((this->eos5cfgrids)[j],tempvardimnamelist);
1922  tempvardimnamelist.clear();
1923  }
1924 //cerr <<"end of NONLATLON "<<endl;
1925  }// if (( 0 == num_1dlatlon_pairs) || .....
1926  // No unique lat/lon, just loop through.
1927  else {
1928 
1929  this->grids_multi_latloncvs = true;
1930  for (vector <EOS5CFGrid *>::iterator irv = this->eos5cfgrids.begin();
1931  irv !=this->eos5cfgrids.end();++irv)
1933  }
1934  }
1935 }
1936 
1938 
1939  string xdimname;
1940  string ydimname;
1941  bool find_xdim = false;
1942  bool find_ydim = false;
1943 
1944  for (set<string>::iterator it = cfgrid->vardimnames.begin();
1945  it != cfgrid->vardimnames.end(); ++it) {
1946  string xydimname_candidate = HDF5CFUtil::obtain_string_after_lastslash(*it);
1947  if ("XDim" == xydimname_candidate) {
1948  find_xdim = true;
1949  xdimname = *it;
1950  }
1951  else if ("YDim" == xydimname_candidate) {
1952  find_ydim = true;
1953  ydimname = *it;
1954  }
1955  if (find_xdim && find_ydim) break;
1956  } // for (set<string>::iterator it = cfgrid->vardimnames.begin() ...
1957 
1958  if (false == find_xdim || false == find_ydim)
1959  throw2("Cannot find Dimension name that includes XDim or YDim in the grid ",cfgrid->name);
1960 
1961  for (vector <Var *>::iterator irv = this->vars.begin();
1962  irv !=this->vars.end();++irv) {
1963  if (GRID == Get_Var_EOS5_Type(*irv)){
1964  for (vector <Dimension *>::iterator id = (*irv)->dims.begin();
1965  id != (*irv)->dims.end(); ++id) {
1966  string xydimname_candidate = HDF5CFUtil::obtain_string_after_lastslash((*id)->name);
1967  if ("XDim" == xydimname_candidate) (*id)->name = xdimname;
1968  else if("YDim" == xydimname_candidate) (*id)->name = ydimname;
1969 //cerr<<"dim name before the final "<<(*id)->name <<endl;
1970  }
1971  }
1972  }
1973 }
1974 
1975 void EOS5File::Handle_Swath_CVar(bool isaugmented) throw(Exception){
1976 
1977  // In this version, we will not use the augmented option for coordinate variables of swath
1978  // since MLS products don't use the recent version of the augmentation tool to allocate their
1979  // coordinate variables.
1980  for (vector <EOS5CFSwath *>::iterator irs = this->eos5cfswaths.begin();
1981  irs !=this->eos5cfswaths.end();++irs) {
1982  if ((*irs)->has_1dlatlon)
1983  Handle_Single_1DLatLon_Swath_CVar(*irs,isaugmented);
1984 
1985  else if((*irs)->has_2dlatlon)
1986  Handle_Single_2DLatLon_Swath_CVar(*irs,isaugmented);
1987 
1988  // If number of dimension latitude/longitude is >2 or no lat/lon,
1989  // no cooridnate variables will be generated.
1990  // We will simply remove this swath from the vector eos5cfswaths.
1991  // In the future, we may consider supporting non "Latitude", "Longitude" naming swaths.
1992  // KY 2011-1-20
1993  else {
1994  delete (*irs);
1995  this->eos5cfswaths.erase(irs);
1996  irs--;
1997  }
1998 //cerr<<"eos5 cf swath name "<<(*irs)->name <<endl;
1999  } // for (vector <EOS5CFSwath *>::iterator irs = this->eos5cfswaths.begin();
2000 }
2001 
2002 void EOS5File::Handle_Single_1DLatLon_Swath_CVar(EOS5CFSwath *cfswath, bool is_augmented) throw(Exception){
2003 
2004  // For 1DLatLon, we will use latitude as the coordinate variable
2005  set <string>::iterator its;
2006  set <string> tempvardimnamelist = cfswath->vardimnames;
2007  string EOS5SWATHPATH ="/HDFEOS/SWATHS/";
2008  string fslash_str ="/";
2009  string THIS_EOS5SWATHPATH = EOS5SWATHPATH + cfswath->name + fslash_str;
2010  bool find_lat = false;
2011 #if 0
2012 for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
2013 cerr<<"Dimension name befor latitude " << *its << endl;
2014 #endif
2015 
2016  // Find latitude and assign to the coordinate variable
2017  // (*irv)->fullpath.size() > THIS_EOS5SWATHPATH.size() is necessary to handle the augmented variables.
2018  for (vector<Var *>::iterator irv = this->vars.begin();
2019  irv != this->vars.end(); ++irv) {
2020  if (SWATH == Get_Var_EOS5_Type(*irv) &&
2021  ((*irv)->fullpath.size() > THIS_EOS5SWATHPATH.size())) {
2022 
2023  string var_swath_name = Obtain_Var_EOS5Type_GroupName(*irv,SWATH);
2024  if ((var_swath_name == cfswath->name) && ((*irv)->name == "Latitude")) {
2025 
2026  //Find it, create a coordinate variable.
2027  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
2028 
2029  // Still keep the original dimension name to avoid the nameclashing when
2030  // one grid and one swath and one za occur in the same file
2031  EOS5cvar->cfdimname = ((*irv)->dims)[0]->name;
2032  EOS5cvar->cvartype = CV_EXIST;
2033  EOS5cvar->eos_type = SWATH;
2034 
2035  // Save this cv to the cv vector
2036  this->cvars.push_back(EOS5cvar);
2037 
2038  // Remove this var from the var vector since it becomes a cv.
2039  delete(*irv);
2040  this->vars.erase(irv);
2041  irv--;
2042  find_lat = true;
2043  break;
2044  } // if ((var_swath_name == cfswath->name) && ...
2045  } // if (SWATH == Get_Var_EOS5_Type(*irv) &&
2046  } // for (vector<Var *>::iterator irv = this->vars.begin() ...
2047 
2048  // Finish this variable, remove it from the list.
2049 
2050  bool find_lat_dim = false;
2051  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end();++its ) {
2052 
2053  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2054  irv != this->cvars.end(); ++irv) {
2055  if (((*irv)->name == "Latitude") && (*irv)->cfdimname == (*its)) {
2056  tempvardimnamelist.erase(its);
2057  find_lat_dim = true;
2058  break;
2059  }
2060  }
2061 
2062  if(true == find_lat_dim)
2063  break;
2064  }
2065 
2066 #if 0
2067 for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
2068 cerr<<"Dimension name afte latitude " << *its << endl;
2069 #endif
2070 
2071  Handle_NonLatLon_Swath_CVar(cfswath,tempvardimnamelist);
2072 
2073  // Remove the added variables during the augmentation process
2074  if (true == is_augmented) {
2075  for (vector<Var *>::iterator irv = this->vars.begin();
2076  irv != this->vars.end(); ++irv) {
2077 
2078  if (SWATH == Get_Var_EOS5_Type(*irv)) {
2079 #if 0
2080  string my_swath_short_path = (*irv)->fullpath.substr(EOS5SWATHPATH.size());
2081  size_t first_fslash_pos = my_swath_short_path.find_first_of("/");
2082  string my_swath_name = my_swath_short_path.substr(0,first_fslash_pos);
2083 #endif
2084  // Need to find the swath for this variable
2085  string my_swath_name = Obtain_Var_EOS5Type_GroupName(*irv,SWATH);
2086 
2087  if (my_swath_name == cfswath->name) {
2088  string var_path_after_swathname = (*irv)->fullpath.substr(THIS_EOS5SWATHPATH.size());
2089  if (var_path_after_swathname == (*irv)->name) {
2090  delete(*irv);
2091  this->vars.erase(irv);
2092  irv--;
2093  }
2094  }
2095  }
2096  }
2097  } // if (true == is_augmented)
2098 }
2099 
2100 void EOS5File::Handle_Single_2DLatLon_Swath_CVar(EOS5CFSwath *cfswath, bool is_augmented) throw(Exception){
2101 
2102  // For 2DLatLon, we will use both latitude and longitude as the coordinate variables
2103  set <string>::iterator its;
2104  set <string> tempvardimnamelist = cfswath->vardimnames;
2105  string EOS5SWATHPATH ="/HDFEOS/SWATHS/";
2106  string fslash_str ="/";
2107  string THIS_EOS5SWATHPATH = EOS5SWATHPATH + cfswath->name + fslash_str;
2108  bool find_lat = false;
2109  bool find_lon = false;
2110 
2111 #if 0
2112 for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
2113 cerr<<"Dimension name befor latitude " << *its << endl;
2114 #endif
2115 
2116  // Find latitude and assign to the coordinate variable
2117  for (vector<Var *>::iterator irv = this->vars.begin();
2118  irv != this->vars.end(); ++irv) {
2119  if (SWATH == Get_Var_EOS5_Type(*irv) &&
2120  ((*irv)->fullpath.size() > THIS_EOS5SWATHPATH.size())) {
2121  string var_swath_name = Obtain_Var_EOS5Type_GroupName(*irv,SWATH);
2122  if ( (var_swath_name == cfswath->name) && ((*irv)->name == "Latitude")) {
2123 
2124  //Find it, create a coordinate variable.
2125  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
2126 
2127  // Still keep the original dimension name to avoid the nameclashing when
2128  // one grid and one swath and one za occur in the same file
2129  EOS5cvar->cfdimname = ((*irv)->dims)[0]->name;
2130  EOS5cvar->cvartype = CV_EXIST;
2131  EOS5cvar->eos_type = SWATH;
2132  EOS5cvar->is_2dlatlon = true;
2133 
2134  // Save this cv to the cv vector
2135  this->cvars.push_back(EOS5cvar);
2136 
2137  // Remove this var from the var vector since it becomes a cv.
2138  delete(*irv);
2139  this->vars.erase(irv);
2140  irv--;
2141  find_lat = true;
2142  } // if ( (var_swath_name == cfswath->name) && ...
2143  else if ( (var_swath_name == cfswath->name) && ((*irv)->name == "Longitude")) {
2144 
2145  //Find it, create a coordinate variable.
2146  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
2147 
2148  // Still keep the original dimension name to avoid the nameclashing when
2149  // one grid and one swath and one za occur in the same file
2150  EOS5cvar->cfdimname = ((*irv)->dims)[1]->name;
2151  EOS5cvar->cvartype = CV_EXIST;
2152  EOS5cvar->eos_type = SWATH;
2153  EOS5cvar->is_2dlatlon = true;
2154 
2155  // Save this cv to the cv vector
2156  this->cvars.push_back(EOS5cvar);
2157 
2158  // Remove this var from the var vector since it becomes a cv.
2159  delete(*irv);
2160  this->vars.erase(irv);
2161  irv--;
2162  find_lon = true;
2163 
2164  } // else if ( (var_swath_name == cfswath->name) && ...
2165  } // if (SWATH == Get_Var_EOS5_Type(*irv) && ...
2166 
2167  if (true == find_lat && true == find_lon) break;
2168  } // for (vector<Var *>::iterator irv = this->vars.begin();
2169 
2170 
2171 
2172  // Remove the dim. of latitude
2173  find_lat = false;
2174  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
2175  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2176  irv != this->cvars.end(); ++irv) {
2177  if (((*irv)->name == "Latitude") && (*irv)->cfdimname == (*its)) {
2178  tempvardimnamelist.erase(its);
2179  find_lat = true;
2180  break;
2181  }
2182  }
2183 
2184  if(true == find_lat)
2185  break;
2186  }
2187 
2188  // Remove the dim. of longitude
2189  find_lon = false;
2190  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
2191 
2192  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2193  irv != this->cvars.end(); ++irv) {
2194 
2195  if (((*irv)->name == "Longitude") && (*irv)->cfdimname == (*its)) {
2196  tempvardimnamelist.erase(its);
2197  find_lon = true;
2198  break;
2199  }
2200  }
2201 
2202  if(true == find_lon)
2203  break;
2204 
2205  }
2206 
2207 #if 0
2208 for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its)
2209 cerr<<"Dimension name afte latitude " << *its << endl;
2210 #endif
2211 
2212  Handle_NonLatLon_Swath_CVar(cfswath,tempvardimnamelist);
2213 
2214  // Remove the added variables during the augmentation process
2215  // For Swath, we don't want to keep the augmented files. This is because
2216  // some aura files assign the dimensional scale as zero.
2217  // We will actively check the new NASA HDF-EOS5 products and will
2218  // revise the following section as needed. KY 2012-03-09
2219  if (true == is_augmented) {
2220  for (vector<Var *>::iterator irv = this->vars.begin();
2221  irv != this->vars.end(); ++irv) {
2222 
2223  if (SWATH == Get_Var_EOS5_Type(*irv)) {
2224 
2225  string my_swath_name = Obtain_Var_EOS5Type_GroupName(*irv,SWATH);
2226  if (my_swath_name == cfswath->name) {
2227  string var_path_after_swathname = (*irv)->fullpath.substr(THIS_EOS5SWATHPATH.size());
2228  if (var_path_after_swathname == (*irv)->name) {
2229  delete(*irv);
2230  this->vars.erase(irv);
2231  irv--;
2232  }
2233  }
2234  }
2235  }
2236  }
2237 }
2238 
2239 void EOS5File::Handle_NonLatLon_Swath_CVar(EOS5CFSwath *cfswath, set<string>& tempvardimnamelist) throw(Exception) {
2240 
2241  // First check if we have existing coordinate variable
2242  set <string>::iterator its;
2243  int num_dimnames = tempvardimnamelist.size();
2244  bool has_dimnames = true;
2245  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
2246  if (cfswath->dnames_to_geo1dvnames.find(*its) !=cfswath->dnames_to_geo1dvnames.end()){
2247  for (vector<Var *>::iterator irv = this->vars.begin();
2248  has_dimnames && (irv != this->vars.end()); ++irv) {
2249 
2250  // We need to check if this var is a swath and use "newname"
2251  // of var to check the dnames_to_1dvnames since it is
2252  // possible to have name clashings for the "name" of a var.
2253  if (SWATH == Get_Var_EOS5_Type(*irv) &&
2254  (*irv)->newname == (cfswath->dnames_to_geo1dvnames)[*its]) {
2255 
2256  //Find it, create a coordinate variable.
2257  EOS5CVar *EOS5cvar = new EOS5CVar(*irv);
2258 
2259  // Still keep the original dimension name to avoid the nameclashing when
2260  // one grid and one swath and one za occur in the same file
2261  EOS5cvar->cfdimname = *its;
2262  EOS5cvar->cvartype = CV_EXIST;
2263  EOS5cvar->eos_type = SWATH;
2264 
2265  // Save this cv to the cv vector
2266  this->cvars.push_back(EOS5cvar);
2267 
2268  // Remove this var from the var vector since it becomes a cv.
2269  delete(*irv);
2270  this->vars.erase(irv);
2271  irv--;
2272  num_dimnames--;
2273  if (0 == num_dimnames)
2274  has_dimnames = false;
2275  } // if (SWATH == Get_Var_EOS5_Type(*irv) && ...)
2276  } // for (vector<Var *>::iterator irv = this->vars.begin(); ...
2277  } // if (cfswath->dnames_to_geo1dvnames.find(*its) ....
2278  } // for (its = tempvardimnamelist.begin()...
2279 
2280  // Remove the dimension name that finds the cooresponding variables from the tempvardimlist.
2281  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2282  irv != this->cvars.end(); ++irv) {
2283  its = tempvardimnamelist.find((*irv)->cfdimname);
2284  if (its != tempvardimnamelist.end())
2285  tempvardimnamelist.erase(its);
2286  }
2287 
2288  // Check if some attributes have CV information for some special products
2289  // Currently TES needs to be handled carefully
2290  Handle_Special_NonLatLon_Swath_CVar(cfswath, tempvardimnamelist);
2291 
2292  // Remove the dimension name that finds the cooresponding variables from the tempvardimlist.
2293  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2294  irv != this->cvars.end(); ++irv) {
2295  its = tempvardimnamelist.find((*irv)->cfdimname);
2296  if (its != tempvardimnamelist.end())
2297  tempvardimnamelist.erase(its);
2298  }
2299 
2300  // Second: Some dimension names still need to find CVs, create the missing CVs
2301  for (its = tempvardimnamelist.begin(); its != tempvardimnamelist.end(); ++its) {
2302 
2303  EOS5CVar *EOS5cvar = new EOS5CVar();
2304  Create_Missing_CV(cfswath,EOS5cvar,*its,SWATH,this->eos5cfswaths.size());
2305  this->cvars.push_back(EOS5cvar);
2306 
2307  }
2308 }
2309 
2310 
2311 void EOS5File::Handle_Special_NonLatLon_Swath_CVar(EOS5CFSwath *cfswath, set<string>& tempvardimnamelist) throw(Exception) {
2312 
2313  // We have no choice but hard-code this one.
2314  // TES swath puts "Pressure" as the VerticalCoordinate but doesn't provide "Pressure" values.
2315  // Moreover, the number of pressure level(66) is one less than the total number of corresponding dimension size(67)
2316  // most probably due to the missing pressure level on the ground. To make the handler visualize some
2317  // TES variables and to follow the general physical sense. We have to add a pressure level by linear interpolation.
2318  // KY 2012-1-27
2319  if (true == this->isaura && TES == this->aura_name) {
2320 
2321  string eos5_swath_group_name ="/HDFEOS/SWATHS/" + cfswath->name;
2322  string eos5_vc_attr_name = "VerticalCoordinate";
2323  string eos5_pre_attr_name = "Pressure";
2324  bool has_vc_attr = false;
2325  Group *vc_group = NULL;
2326 
2327  // 1. Check if having the "VerticalCoordinate" attribute in this swath and the attribute is "Pressure".
2328  for (vector<Group *>::iterator irg = this->groups.begin();
2329  irg != this->groups.end(); ++irg) {
2330  if (eos5_swath_group_name ==(*irg)->path){
2331  for (vector<Attribute *>::iterator ira = (*irg)->attrs.begin();
2332  ira != (*irg)->attrs.end(); ++ira) {
2333  if (eos5_vc_attr_name == (*ira)->name) {
2334  Retrieve_H5_Attr_Value(*ira,(*irg)->path);
2335  string attr_value((*ira)->value.begin(),(*ira)->value.end());
2336  if (eos5_pre_attr_name == attr_value) {
2337  has_vc_attr = true;
2338  vc_group = *irg;
2339  break;
2340  }
2341  }
2342  } // for (vector<Attribute *>:: iterator ira =(*irg)->attrs.begin(); ...
2343  if (true == has_vc_attr)
2344  break;
2345  } // if (eos5_swath_group_name ==(*irg)->path)
2346  } // for (vector<Group *>::iterator irg = this->groups.begin(); ...
2347 
2348 
2349  // 2. Check if having the "Pressure" attribute and if the attribute size is 1 less than
2350  // the dimension size of "nLevels". If yes,
2351  // add one pressure value by using the nearest neighbor value. This value should be the first value
2352  // of the "Pressure" attribute.
2353  // Another special part of the TES file is that dimension name nLevels is used twice in some variables
2354  // float foo[...][nLevels][nLevels]. To make the variable visualized by tools, the dimension name
2355  // needs to be changed and the coordinate variable needs to separately created. Note this is not
2356  // against CF conventions. However, the popular tools are not happy with the duplicate dimension names
2357  // in a variable.
2358  // Though may not cover 100% cases, searching the string after the last forward slash and see if
2359  // it contains nLevels should catch 99% memebers of the "nLevels" family. We will then create the
2360  // corresponding coordinate variables.
2361 
2362  // 2.1. Check if we have the dimension name called "nLevels" for this swath
2363  if (true == has_vc_attr) {
2364  string dimname_candidate = "/SWATHS/"+cfswath->name + "/nLevels";
2365  set<string>:: iterator it;
2366  for (it = tempvardimnamelist.begin(); it!=tempvardimnamelist.end();++it) {
2367  if ((*it).find(dimname_candidate) != string::npos) {
2368  hsize_t dimsize_candidate = 0;
2369  if ((cfswath->dimnames_to_dimsizes).find(*it) !=
2370  (cfswath->dimnames_to_dimsizes).end())
2371  dimsize_candidate = cfswath->dimnames_to_dimsizes[*it];
2372  else throw2("Cannot find the dimension size of the dimension name ",*it);
2373 
2374  // Note: we don't have to use two loops to create the coordinate variables.
2375  // However, there are only 3-4 attributes for this group and so far TES has only
2376  // one additional nLevels.
2377  // So essentially the following loop doesn't hurt the performance.
2378  // KY 2012-2-1
2379  for (vector<Attribute *>::iterator ira = vc_group->attrs.begin();
2380  ira != vc_group->attrs.end(); ++ira) {
2381  if ((eos5_pre_attr_name == (*ira)->name) && ((*ira)->count == (dimsize_candidate-1))) {
2382 
2383  // Should change the attr_value from char type to float type when reading the data
2384  // Here just adding a coordinate variable by using this name.
2385  EOS5CVar *EOS5cvar = new EOS5CVar();
2386  string reduced_dimname = HDF5CFUtil::obtain_string_after_lastslash(*it);
2387  string orig_dimname = "nLevels";
2388  if ("nLevels" == reduced_dimname)
2389  EOS5cvar->name = eos5_pre_attr_name + "_CV";
2390  else // the dimname will be ..._CV_1 etc.
2391  EOS5cvar->name = eos5_pre_attr_name +"_CV"+ reduced_dimname.substr(orig_dimname.size());
2392  Create_Added_Var_NewName_FullPath(SWATH,cfswath->name,EOS5cvar->name,EOS5cvar->newname,EOS5cvar->fullpath);
2393  EOS5cvar->rank = 1;
2394  EOS5cvar->dtype = (*ira)->dtype;
2395  Dimension *eos5cvar_dim = new Dimension(dimsize_candidate);
2396  eos5cvar_dim->name = *it;
2397  if (1 == this->eos5cfswaths.size())
2398  eos5cvar_dim->newname = reduced_dimname;
2399  else
2400  eos5cvar_dim->newname = eos5cvar_dim->name;
2401 
2402  EOS5cvar->dims.push_back(eos5cvar_dim);
2403  EOS5cvar->cvartype = CV_SPECIAL;
2404  EOS5cvar->cfdimname = eos5cvar_dim->name;
2405  EOS5cvar->eos_type = SWATH;
2406 
2407  // Save this cv to the cv vector
2408  this->cvars.push_back(EOS5cvar);
2409  }// if ((eos5_pre_attr_name == (*ira)->name) && ...
2410  }// for (vector<Attribute *>::iterator ira = vc_group->attrs.begin();
2411  } // if ((*it).find(dimname_candidate) != string::npos)
2412  } // for (it = tempvardimnamelist.begin(); ...
2413  } // if (true == has_vc_attr) ...
2414  } // if (true == this->isaura && ...
2415 }
2416 
2417 
2418 
2419 void EOS5File::Handle_Za_CVar(bool isaugmented) throw(Exception){
2420 
2421  // We are not supporting non-augmented zonal average HDF-EOS5 product now. KY:2012-1-20
2422  if(false == isaugmented)
2423  return;
2424 
2425  for (vector <EOS5CFZa *>::iterator irv = this->eos5cfzas.begin();
2426  irv !=this->eos5cfzas.end();++irv)
2427  Handle_Single_Augment_CVar(*irv,ZA);
2428 
2429 }
2430 
2432 
2433  int num_grids =this->eos5cfgrids.size();
2434  int num_swaths = this->eos5cfswaths.size();
2435  int num_zas = this->eos5cfzas.size();
2436 
2437  bool mixed_eos5typefile = false;
2438 
2439  // Check if this file mixes grid,swath and zonal average
2440  if (((num_grids > 0) && (num_swaths > 0)) ||
2441  ((num_grids > 0) && (num_zas > 0)) ||
2442  ((num_swaths >0) && (num_zas > 0)))
2443  mixed_eos5typefile = true;
2444 
2445  // This file doesn't mix swath, grid and zonal average
2446  for (vector<Var *>::iterator irv = this->vars.begin();
2447  irv != this->vars.end(); ++irv)
2448  Adjust_Per_Var_Dim_NewName_Before_Flattening(*irv,mixed_eos5typefile,num_grids,num_swaths,num_zas);
2449 
2450 
2451  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2452  irv != this->cvars.end(); ++irv)
2453  Adjust_Per_Var_Dim_NewName_Before_Flattening(*irv,mixed_eos5typefile,num_grids,num_swaths,num_zas);
2454 #if 0
2455 for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2456  irv != this->cvars.end(); ++irv) {
2457  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
2458  ird !=(*irv)->dims.end(); ++ird) {
2459 cerr<<"eos5svar dimension new name "<<(*ird)->newname <<endl;
2460  }
2461 }
2462 #endif
2463 
2465 
2466 }
2467 
2468 template <class T>
2469 void EOS5File::Adjust_Per_Var_Dim_NewName_Before_Flattening(T* var,bool mixed_eos5type,int num_grids,int num_swaths,int num_zas)
2470 throw(Exception) {
2471 
2472  string eos5typestr;
2473  EOS5Type vartype = Get_Var_EOS5_Type(var);
2474  switch (vartype) {
2475 
2476  case GRID:
2477  {
2478  eos5typestr = "/GRIDS/";
2479  if (false == mixed_eos5type) {
2480  if (0 == num_grids)
2481  var->newname = ((1 == this->orig_num_grids)?var->name:
2482  var->newname.substr(eos5typestr.size()));
2483  else
2484  var->newname = ((1 == num_grids)?var->name:
2485  var->newname.substr(eos5typestr.size()));
2486  // Dimension newname is unlike Var newname, when num_grids is equal to 1, the
2487  // newname is Dimension name already. So we don't need to do anything with
2488  // the dimension newname when the num_grids is 1. The main reason we handle
2489  // the var newname and the dimension newname differently is that the variable name is
2490  // more critical for users to pick up the meanings of that variable. So we would like
2491  // to work hard to keep the original form. However, the dimension name is mainly used to
2492  // generate the coordinate variables. So the different usage makes us relax the dimension
2493  // name a little bit. This is an example of end-user priority driven implementation.
2494  // KY 2012-1-24
2495  // Just receive a user request: the dimension name is also very important.
2496  // So a bunch of code has been updated. For number of grid/swath/za = 1, I still maintain
2497  // the newname to be the same as the last part of the dim name. Hopefully this
2498  // will handle the current HDF-EOS5 products. Improvement for complicate HDF-EOS5 products
2499  // will be supported as demanded in the future. KY 2012-1-26
2500  if (num_grids > 1) {
2501  for (vector<Dimension *> ::iterator ird = var->dims.begin();
2502  ird !=var->dims.end();ird++) {
2503  if((*ird)->newname.size() <= eos5typestr.size())
2504  throw5("The size of the dimension new name ",(*ird)->newname, "of variable ",var->newname,
2505  " is too small");
2506  (*ird)->newname = (*ird)->newname.substr(eos5typestr.size());
2507  }
2508  }
2509  } // if(false == mixed_eos5type)
2510  else {
2511  // No need to set the dimension newname for the reason listed above.
2512  var->newname = ((1 == num_grids)?(eos5typestr + var->name):
2513  var->newname);
2514  }
2515  }
2516  break;
2517 
2518  case SWATH:
2519  {
2520  eos5typestr = "/SWATHS/";
2521  if (false == mixed_eos5type) {
2522  var->newname = ((1 == num_swaths)?var->name:
2523  var->newname.substr(eos5typestr.size()));
2524 //cerr<<"var->newname "<<var->newname <<endl;
2525  if (num_swaths > 1) {
2526  for (vector<Dimension *> ::iterator ird = var->dims.begin();
2527  ird !=var->dims.end();ird++) {
2528  if((*ird)->newname.size() <= eos5typestr.size())
2529  throw5("The size of the dimension new name ",(*ird)->newname, "of variable ",var->newname,
2530  " is too small");
2531  (*ird)->newname = (*ird)->newname.substr(eos5typestr.size());
2532  }
2533  }
2534  }
2535  else {
2536  var->newname = ((1 == num_swaths)?(eos5typestr + var->name):
2537  var->newname);
2538  }
2539  }
2540  break;
2541 
2542  case ZA:
2543  {
2544  eos5typestr = "/ZAS/";
2545  if (false == mixed_eos5type) {
2546  var->newname = ((1 == num_zas)?var->name:
2547  var->newname.substr(eos5typestr.size()));
2548  if (num_zas > 1) {
2549  for (vector<Dimension *> ::iterator ird = var->dims.begin();
2550  ird !=var->dims.end();ird++) {
2551  if((*ird)->newname.size() <= eos5typestr.size())
2552  throw5("The size of the dimension new name ",(*ird)->newname, "of variable ",var->newname,
2553  " is too small");
2554  (*ird)->newname = (*ird)->newname.substr(eos5typestr.size());
2555  }
2556  }
2557  }
2558  else {
2559  var->newname = ((1 == num_zas)?(eos5typestr + var->name):
2560  var->newname);
2561  }
2562  }
2563  break;
2564  case OTHERVARS:
2565  break;
2566  default:
2567  throw1("Non-supported EOS type");
2568  } // switch(vartype)
2569 
2570 }
2571 
2573 
2574  // Remove the EOS5 type string("GRIDS") and the GRID Name from
2575  // the variable newname and the dimension newname
2576  // This case won't happen for the current version, but may occur
2577  // if curviliner grid exists in the file. KY 2012-1-26
2578  if ((this->eos5cfgrids.size() > 1) &&
2579  (0 == this->eos5cfswaths.size()) &&
2580  (0 == this->eos5cfzas.size()) &&
2581  (false == this->grids_multi_latloncvs)){
2582 
2583  // We would like to condense the dimension name and the coordinate variable name for lat/lon.
2584  string lat_dimname;
2585  string lat_dimnewname;
2586  string lon_dimname;
2587  string lon_dimnewname;
2588  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2589  irv !=this->cvars.end(); ++irv) {
2590  if ("lat" == (*irv)->name || "Latitude" == (*irv)->name) {
2591  (*irv)->newname = (*irv)->name;
2592  lat_dimnewname = (((*irv)->dims)[0])->newname;
2593  lat_dimnewname = HDF5CFUtil::obtain_string_after_lastslash(lat_dimnewname);
2594  if (""== lat_dimnewname)
2595  throw2("/ is not included in the dimension new name ",(((*irv)->dims)[0])->newname);
2596  (((*irv)->dims)[0])->newname = lat_dimnewname;
2597  lat_dimname = (*irv)->cfdimname;
2598  }
2599  else if ("lon" == (*irv)->name || "Longitude" == (*irv)->name) {
2600  (*irv)->newname = (*irv)->name;
2601  string lon_dimnewname = (((*irv)->dims)[0])->newname;
2602  lon_dimnewname = HDF5CFUtil::obtain_string_after_lastslash(lon_dimnewname);
2603  if (""== lon_dimnewname)
2604  throw2("/ is not included in the dimension new name ",(((*irv)->dims)[0])->newname);
2605  (((*irv)->dims)[0])->newname = lon_dimnewname;
2606  lon_dimname = (*irv)->cfdimname;
2607  }
2608  } // for (vector<EOS5CVar *>::iterator irv = this->cvars.begin(); ...
2609 
2610  for (vector<Var *>::iterator irv = this->vars.begin();
2611  irv !=this->vars.end(); ++irv) {
2612  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
2613  ird !=(*irv)->dims.end();++ird) {
2614  if ((*ird)->name == lat_dimname)
2615  (*ird)->newname = lat_dimnewname;
2616  else if((*ird)->name == lon_dimname)
2617  (*ird)->newname = lon_dimnewname;
2618  }
2619  }
2620  } // if ((this->eos5cfgrids.size() > 1) && ...
2621 }
2622 
2623 void EOS5File::Flatten_Obj_Name(bool include_attr) throw(Exception){
2624 
2625  File::Flatten_Obj_Name(include_attr);
2626 
2627  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2628  irv != this->cvars.end(); ++irv) {
2629  (*irv)->newname = get_CF_string((*irv)->newname);
2630 
2631  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
2632  ird != (*irv)->dims.end(); ++ird) {
2633  (*ird)->newname = get_CF_string((*ird)->newname);
2634  }
2635 
2636  if (true == include_attr) {
2637  for (vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
2638  ira != (*irv)->attrs.end(); ++ira) {
2639  (*ira)->newname = get_CF_string((*ira)->newname);
2640  }
2641  }
2642  } // for (vector<EOS5CVar *>::iterator irv = this->cvars.begin(); ...
2643 }
2644 
2645 void EOS5File::Handle_Obj_NameClashing(bool include_attr) throw(Exception) {
2646 
2647  // objnameset will be filled with all object names that we are going to check the name clashing.
2648  // For example, we want to see if there are any name clashings for all variable names in this file.
2649  // objnameset will include all variable names. If a name clashing occurs, we can figure out from the set operation immediately.
2650  set<string>objnameset;
2651  Handle_EOS5CVar_NameClashing(objnameset);
2652  File::Handle_GeneralObj_NameClashing(include_attr,objnameset);
2653  if (true == include_attr) {
2654  Handle_EOS5CVar_AttrNameClashing();
2655  }
2656 
2657  //if (this->cvars.size() >0)
2658  // Handle_DimNameClashing();
2659 }
2660 
2661 void EOS5File::Handle_EOS5CVar_NameClashing(set<string> &objnameset ) throw(Exception) {
2662 
2663  EOS5Handle_General_NameClashing(objnameset,this->cvars);
2664 }
2665 
2667 
2668  set<string> objnameset;
2669 
2670  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2671  irv != this->cvars.end(); ++irv) {
2672  Handle_General_NameClashing(objnameset,(*irv)->attrs);
2673  objnameset.clear();
2674  }
2675 }
2676 
2677 //class T must have member string newname
2678 template<class T> void
2679 EOS5File::EOS5Handle_General_NameClashing(set <string>&objnameset, vector<T*>& objvec) throw(Exception){
2680 
2681  pair<set<string>::iterator,bool> setret;
2682  set<string>::iterator iss;
2683 
2684  vector<string> clashnamelist;
2685  vector<string>::iterator ivs;
2686 
2687  map<int,int> cl_to_ol;
2688  int ol_index = 0;
2689  int cl_index = 0;
2690 
2691  typename vector<T*>::iterator irv;
2692 
2693  for (irv = objvec.begin();
2694  irv != objvec.end(); ++irv) {
2695 
2696  setret = objnameset.insert((*irv)->newname);
2697  if (!setret.second ) {
2698  clashnamelist.insert(clashnamelist.end(),(*irv)->newname);
2699  cl_to_ol[cl_index] = ol_index;
2700  cl_index++;
2701  }
2702  ol_index++;
2703  }
2704 
2705  // Now change the clashed elements to unique elements;
2706  // Generate the set which has the same size as the original vector.
2707  for (ivs=clashnamelist.begin(); ivs!=clashnamelist.end(); ++ivs) {
2708  int clash_index = 1;
2709  string temp_clashname = *ivs +'_';
2710  HDF5CFUtil::gen_unique_name(temp_clashname,objnameset,clash_index);
2711  *ivs = temp_clashname;
2712  }
2713 
2714  // Now go back to the original vector, make it unique.
2715  for (unsigned int i =0; i <clashnamelist.size(); i++)
2716  objvec[cl_to_ol[i]]->newname = clashnamelist[i];
2717 
2718 }
2719 
2721 
2722  map<string,string>dimname_to_dimnewname;
2723  pair<map<string,string>::iterator,bool>mapret;
2724  set<string> dimnameset;
2725  vector<Dimension*>vdims;
2726  set<string> dimnewnameset;
2727  pair<set<string>::iterator,bool> setret;
2728 
2729  // First: Generate the dimset/dimvar based on coordinate variables.
2730  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2731  irv !=this->cvars.end(); ++irv) {
2732  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2733  ird !=(*irv)->dims.end();++ird) {
2734  //setret = dimnameset.insert((*ird)->newname);
2735  setret = dimnameset.insert((*ird)->name);
2736  if (setret.second) vdims.push_back(*ird);
2737  }
2738  }
2739 
2740  // For some cases, dimension names are provided but there are no corresponding coordinate
2741  // variables. For now, we will assume no such cases.
2742  // Actually, we find such a case in our fake testsuite. So we need to fix it.
2743 
2744  for(vector<Var *>::iterator irv= this->vars.begin();
2745  irv != this->vars.end();++irv) {
2746  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2747  ird !=(*irv)->dims.end();++ird) {
2748  //setret = dimnameset.insert((*ird)->newname);
2749  setret = dimnameset.insert((*ird)->name);
2750  if (setret.second) vdims.push_back(*ird);
2751  }
2752  }
2753 
2754 #if 0
2755 for (vector<Dimension*>::iterator ird=vdims.begin();ird!=vdims.end();++ird)
2756 cerr<<"dimension name "<<(*ird)->name <<endl;
2757 #endif
2758 
2759  // For some cases, dimension names are provided but there are no corresponding coordinate
2760  // variables. For now, we will assume no such cases.
2761  EOS5Handle_General_NameClashing(dimnewnameset,vdims);
2762 
2763  // Third: Make dimname_to_dimnewname map
2764  for (vector<Dimension*>::iterator ird = vdims.begin();ird!=vdims.end();++ird) {
2765  mapret = dimname_to_dimnewname.insert(pair<string,string>((*ird)->name,(*ird)->newname));
2766  if (false == mapret.second)
2767  throw4("The dimension name ",(*ird)->name," should map to ",
2768  (*ird)->newname);
2769  }
2770 
2771  // Fourth: Change the original dimension new names to the unique dimension new names
2772  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2773  irv !=this->cvars.end(); ++irv)
2774  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2775  ird!=(*irv)->dims.end();++ird)
2776  (*ird)->newname = dimname_to_dimnewname[(*ird)->name];
2777 
2778  for (vector<Var *>::iterator irv = this->vars.begin();
2779  irv != this->vars.end(); ++irv)
2780  for (vector <Dimension *>:: iterator ird = (*irv)->dims.begin();
2781  ird !=(*irv)->dims.end();++ird)
2782  (*ird)->newname = dimname_to_dimnewname[(*ird)->name];
2783 
2784 }
2785 
2787 
2788  iscoard = true;
2789  for (vector <EOS5CFGrid *>::iterator irg = this->eos5cfgrids.begin();
2790  irg != this->eos5cfgrids.end(); ++irg) {
2791  if (false == (*irg)->has_1dlatlon) {
2792  if (false == (*irg)->has_nolatlon || (HE5_GCTP_GEO != (*irg)->eos5_projcode))
2793  iscoard = false;
2794  break;
2795  }
2796  }
2797 
2798  if (true == iscoard) {
2799  for (vector <EOS5CFSwath *>::iterator irg = this->eos5cfswaths.begin();
2800  irg != this->eos5cfswaths.end(); ++irg) {
2801  if (false == (*irg)->has_1dlatlon) {
2802  iscoard = false;
2803  break;
2804  }
2805  }
2806  }
2807 }
2808 
2810 
2811  if (true == this->isaura){
2812  Adjust_Attr_Name();
2814  }
2815  else
2817 
2818 
2819 }
2821 
2822  for (vector<Var*>::iterator irv = this->vars.begin();
2823  irv !=this->vars.end(); ++irv) {
2824  for(vector <Attribute*>::iterator ira = (*irv)->attrs.begin();
2825  ira != (*irv)->attrs.end(); ++ira) {
2826  if (eos5_to_cf_attr_map.find((*ira)->name) != eos5_to_cf_attr_map.end())
2827  (*ira)->newname = eos5_to_cf_attr_map[(*ira)->name];
2828 
2829  }
2830  }
2831 
2832  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2833  irv !=this->cvars.end(); ++irv) {
2834  for(vector <Attribute*>::iterator ira = (*irv)->attrs.begin();
2835  ira != (*irv)->attrs.end(); ++ira) {
2836  if (eos5_to_cf_attr_map.find((*ira)->name) != eos5_to_cf_attr_map.end())
2837  (*ira)->newname = eos5_to_cf_attr_map[(*ira)->name];
2838 
2839  }
2840  }
2841 }
2842 
2844 
2845  // Handle Units
2848 
2849  // Handle Time. This is just for Aura files.
2850  string time_cf_units_value = "seconds since 1993-01-01";
2851  for (vector<Var*>::iterator irv = this->vars.begin();
2852  irv !=this->vars.end(); irv++) {
2853  if(((*irv)->name == "Time") || ((*irv)->name == "nTimes")) {
2854  for(vector <Attribute*>::iterator ira = (*irv)->attrs.begin();
2855  ira != (*irv)->attrs.end(); ira++) {
2856  if ("units" == (*ira)->name){
2857  Retrieve_H5_Attr_Value(*ira,(*irv)->fullpath);
2858  string units_value((*ira)->value.begin(),(*ira)->value.end());
2859  if (time_cf_units_value != units_value) {
2860 
2861  units_value = time_cf_units_value;
2862  (*ira)->value.resize(units_value.size());
2863  if (H5FSTRING == (*ira)->dtype)
2864  (*ira)->fstrsize = units_value.size();
2865  // strsize is used by both fixed and variable length strings.
2866  (*ira)->strsize.resize(1);
2867  (*ira)->strsize[0] = units_value.size();
2868 
2869  copy(units_value.begin(),units_value.end(),(*ira)->value.begin());
2870  }
2871  break;
2872  } // if ("units" == (*ira)->name)
2873  } // for(vector <Attribute*>::iterator ira = (*irv)->attrs.begin();
2874  } // if(((*irv)->name == "Time") || ((*irv)->name == "nTimes"))
2875  } // for (vector<Var*>::iterator irv = this->vars.begin()...
2876 }
2877 
2879 
2880  if (true == this->isaura && MLS == this->aura_name) {
2881 
2882  const string File_attr_group_path = "/HDFEOS/ADDITIONAL/FILE_ATTRIBUTES";
2883  const string PCF1_attr_name = "PCF1";
2884  bool find_group = false;
2885  bool find_attr = false;
2886  for (vector<Group*>::iterator it_g = this->groups.begin();
2887  it_g != this->groups.end(); ++it_g) {
2888  if (File_attr_group_path == (*it_g)->path) {
2889  find_group = true;
2890  for (vector<Attribute *>::iterator ira = (*it_g)->attrs.begin();
2891  ira != (*it_g)->attrs.end(); ++ira) {
2892  if (PCF1_attr_name == (*ira)->name) {
2893  Retrieve_H5_Attr_Value(*ira,(*it_g)->path);
2894  string pcf_value((*ira)->value.begin(),(*ira)->value.end());
2896  (*ira)->value.resize(pcf_value.size());
2897  if (H5FSTRING == (*ira)->dtype)
2898  (*ira)->fstrsize = pcf_value.size();
2899  // strsize is used by both fixed and variable length strings.
2900  (*ira)->strsize.resize(1);
2901  (*ira)->strsize[0] = pcf_value.size();
2902 
2903  copy(pcf_value.begin(),pcf_value.end(),(*ira)->value.begin());
2904  find_attr = true;
2905  break;
2906  } // if (PCF1_attr_name == (*ira)->name)
2907  }// for (vector<Attribute *>::iterator ira = (*it_g)->attrs.begin()
2908  } // if (File_attr_group_path == (*it_g)->path)
2909  if(true == find_group && true == find_attr)
2910  break;
2911  }// for (vector<Group*>::iterator it_g = this->groups.begin() ...
2912  } // if (true == this->isaura && MLS == this->aura_name)
2913 }
2914 
2915 
2917 
2918  string unit_attrname = "units";
2919  string nonll_cf_level_attrvalue ="level";
2920  string lat_cf_unit_attrvalue ="degrees_north";
2921  string lon_cf_unit_attrvalue ="degrees_east";
2922  string tes_cf_pre_attrvalue ="hPa";
2923 
2924 
2925  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
2926  irv !=this->cvars.end(); ++irv) {
2927  switch((*irv)->cvartype) {
2928  case CV_EXIST:
2929  case CV_MODIFY:
2930  {
2931  for(vector <Attribute*>::iterator ira = (*irv)->attrs.begin();
2932  ira != (*irv)->attrs.end(); ++ira) {
2933  if ((*ira)->newname ==unit_attrname) {
2934  Retrieve_H5_Attr_Value(*ira,(*irv)->fullpath);
2935  string units_value((*ira)->value.begin(),(*ira)->value.end());
2936  if ((lat_cf_unit_attrvalue !=units_value) &&
2937  (((*irv)->name == "Latitude") ||
2938  ((this->eos5cfzas.size() > 0) && ((*irv)->name == "nLats")))) {
2939  units_value = lat_cf_unit_attrvalue;
2940  (*ira)->value.resize(units_value.size());
2941  if (H5FSTRING == (*ira)->dtype)
2942  (*ira)->fstrsize = units_value.size();
2943  // strsize is used by both fixed and variable length strings.
2944  (*ira)->strsize.resize(1);
2945  (*ira)->strsize[0] = units_value.size();
2946  copy(units_value.begin(),units_value.end(),(*ira)->value.begin());
2947  string tempstring((*ira)->value.begin(),(*ira)->value.end());
2948  }
2949  else if ((lon_cf_unit_attrvalue !=units_value) && (*irv)->name == "Longitude"){
2950  units_value = lon_cf_unit_attrvalue;
2951  (*ira)->value.resize(units_value.size());
2952  if (H5FSTRING == (*ira)->dtype)
2953  (*ira)->fstrsize = units_value.size();
2954  // strsize is used by both fixed and variable length strings.
2955  (*ira)->strsize.resize(1);
2956  (*ira)->strsize[0] = units_value.size();
2957 
2958  copy(units_value.begin(),units_value.end(),(*ira)->value.begin());
2959  }
2960  break;
2961  } // if ((*ira)->newname ==unit_attrname)
2962  }
2963  }
2964  break;
2965 
2966  case CV_LAT_MISS:
2967  {
2968  Attribute * attr = new Attribute();
2969  Add_Str_Attr(attr,unit_attrname,lat_cf_unit_attrvalue);
2970  (*irv)->attrs.push_back(attr);
2971  }
2972  break;
2973 
2974  case CV_LON_MISS:
2975  {
2976  Attribute * attr = new Attribute();
2977  Add_Str_Attr(attr,unit_attrname,lon_cf_unit_attrvalue);
2978  (*irv)->attrs.push_back(attr);
2979  }
2980  break;
2981 
2982  case CV_NONLATLON_MISS:
2983  {
2984  Attribute * attr = new Attribute();
2985  Add_Str_Attr(attr,unit_attrname,nonll_cf_level_attrvalue);
2986  (*irv)->attrs.push_back(attr);
2987  }
2988  break;
2989  case CV_SPECIAL:
2990  {
2991  if (true == this->isaura && TES == this->aura_name) {
2992  Attribute * attr = new Attribute();
2993  Add_Str_Attr(attr,unit_attrname,tes_cf_pre_attrvalue);
2994  (*irv)->attrs.push_back(attr);
2995  }
2996  }
2997  break;
2998  default:
2999  throw1("Non-supported Coordinate Variable Type.");
3000  } // switch((*irv)->cvartype)
3001  } // for (vector<EOS5CVar *>::iterator irv = this->cvars.begin() ...
3002 }
3003 
3004 
3006 
3007  if (false == this->iscoard)
3008  return;
3009  else {
3010  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
3011  irv !=this->cvars.end(); irv++) {
3012  if ((*irv)->dims.size()!=1)
3013  throw3("Coard coordinate variable ",(*irv)->name, "is not 1D");
3014  if ((*irv)->newname != (((*irv)->dims)[0]->newname)) {
3015  ((*irv)->dims)[0]->newname = (*irv)->newname;
3016 
3017  // For all variables that have this dimension,the dimension newname should also change.
3018  for (vector<Var*>::iterator irv2 = this->vars.begin();
3019  irv2 != this->vars.end(); irv2++) {
3020  for (vector<Dimension *>::iterator ird = (*irv2)->dims.begin();
3021  ird !=(*irv2)->dims.end(); ird++) {
3022  // This is the key, the dimension name of this dimension
3023  // should be equal to the dimension name of the coordinate variable.
3024  // Then the dimension name matches and the dimension name should be changed to
3025  // the new dimension name.
3026  if ((*ird)->name == ((*irv)->dims)[0]->name)
3027  (*ird)->newname = ((*irv)->dims)[0]->newname;
3028  }
3029  }
3030  }// if ((*irv)->newname != (((*irv)->dims)[0]->newname))
3031  } // for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
3032  }// else
3033 }
3034 
3035 
3036 void
3038 
3039  if(true == add_path) {
3040 
3041  File::Add_Supplement_Attrs(add_path);
3042 
3043  // Adding variable original name(origname) and full path(fullpath)
3044  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
3045  irv != this->cvars.end(); ++irv) {
3046  if (((*irv)->cvartype == CV_EXIST) || ((*irv)->cvartype == CV_MODIFY)) {
3047  Attribute * attr = new Attribute();
3048  const string varname = (*irv)->name;
3049  const string attrname = "origname";
3050  Add_Str_Attr(attr,attrname,varname);
3051  (*irv)->attrs.push_back(attr);
3052  }
3053  }
3054 
3055  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
3056  irv != this->cvars.end(); ++irv) {
3057  if (((*irv)->cvartype == CV_EXIST) || ((*irv)->cvartype == CV_MODIFY)) {
3058  Attribute * attr = new Attribute();
3059  const string varname = (*irv)->fullpath;
3060  const string attrname = "fullnamepath";
3061  Add_Str_Attr(attr,attrname,varname);
3062  (*irv)->attrs.push_back(attr);
3063  }
3064  }
3065  } // if(true == add_path)
3066 
3067  if(true == this->iscoard ) {
3068  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
3069  irv != this->cvars.end(); ++irv) {
3070  if (((*irv)->cvartype == CV_EXIST) || ((*irv)->cvartype == CV_MODIFY)) {
3071  Attribute * attr = new Attribute();
3072  const string attrname = "orig_dimname";
3073  string orig_dimname = (((*irv)->dims)[0])->name;
3074  orig_dimname = HDF5CFUtil::obtain_string_after_lastslash(orig_dimname);
3075  if ("" == orig_dimname)
3076  throw2("wrong dimension name ",orig_dimname);
3077  if(orig_dimname.find("FakeDim") != string::npos)
3078  orig_dimname = "";
3079  Add_Str_Attr(attr,attrname,orig_dimname);
3080  (*irv)->attrs.push_back(attr);
3081  }
3082  } // for (vector<EOS5CVar *>::iterator irv = this->cvars.begin()
3083 
3084  for (vector<Var *>::iterator irv = this->vars.begin();
3085  irv != this->vars.end(); ++irv) {
3086 
3087  if ((*irv)->dims.size() >0 ) {
3088  Attribute * attr = new Attribute();
3089  if (1 == (*irv)->dims.size()) {
3090  const string attrname = "orig_dimname";
3091  string orig_dimname = (((*irv)->dims)[0])->name;
3092  if (""==orig_dimname) orig_dimname="NoDimName";
3093  else orig_dimname = HDF5CFUtil::obtain_string_after_lastslash(orig_dimname);
3094  if(orig_dimname.find("FakeDim") != string::npos) orig_dimname = "NoDimName";
3095  Add_Str_Attr(attr,attrname,orig_dimname);
3096  }
3097  else {
3098  const string attrname ="orig_dimname_list";
3099  string orig_dimname_list;
3100  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
3101  ird != (*irv)->dims.end(); ++ird) {
3102  string orig_dimname =(*ird)->name;
3103  if (""==orig_dimname) orig_dimname="NoDimName";
3104  else orig_dimname = HDF5CFUtil::obtain_string_after_lastslash((*ird)->name);
3105  if(orig_dimname.find("FakeDim") != string::npos) orig_dimname = "NoDimName";
3106  if(""==orig_dimname_list)
3107  orig_dimname_list = orig_dimname;
3108  else
3109  orig_dimname_list = orig_dimname_list +" "+orig_dimname;
3110 // orig_dimname_list = orig_dimname_list + " ";
3111  }
3112  Add_Str_Attr(attr,attrname,orig_dimname_list);
3113  }
3114  (*irv)->attrs.push_back(attr);
3115  } // if ((*irv)->dims.size() >0 )
3116  } // for (vector<Var *>::iterator irv = this->vars.begin();
3117  } // if(true == this->iscoard )
3118 
3119 }
3120 
3122 
3123  string co_attrname = "coordinates";
3124  string co_attrvalue="";
3125 
3126  if (iscoard)
3127  return;
3128 
3129  for (vector<Var *>::iterator irv = this->vars.begin();
3130  irv != this->vars.end(); ++irv) {
3131 
3132  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
3133  ird != (*irv)->dims.end(); ++ ird) {
3134  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
3135  ircv != this->cvars.end(); ++ircv) {
3136  if ((*ird)->name == (*ircv)->cfdimname)
3137  co_attrvalue = (co_attrvalue.empty())?(*ircv)->newname:co_attrvalue + " "+(*ircv)->newname;
3138  }
3139  }
3140  if (false == co_attrvalue.empty()) {
3141  Attribute * attr = new Attribute();
3142  Add_Str_Attr(attr,co_attrname,co_attrvalue);
3143  (*irv)->attrs.push_back(attr);
3144  }
3145  co_attrvalue.clear();
3146  } // for (vector<Var *>::iterator irv = this->vars.begin(); ...
3147 
3148  // We will check if 2dlatlon coordinate variables exist
3149  bool has_2dlatlon_cv = false;
3150  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
3151  ircv != this->cvars.end(); ++ircv) {
3152  if (true == (*ircv)->is_2dlatlon) {
3153  has_2dlatlon_cv = true;
3154  break;
3155  }
3156  }
3157 
3158  if (true == has_2dlatlon_cv) {
3159 
3160  string dimname1, dimname2;
3161  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
3162  ircv != this->cvars.end(); ++ircv) {
3163  if (true == (*ircv)->is_2dlatlon) {
3164  dimname1 = (((*ircv)->dims)[0])->name;
3165  dimname2 = (((*ircv)->dims)[1])->name;
3166  break;
3167  }
3168  }
3169 
3170  int num_latlondims = 0;
3171 
3172  for (vector<Var *>::iterator irv = this->vars.begin();
3173  irv != this->vars.end(); ++irv) {
3174  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
3175  ird != (*irv)->dims.end(); ++ ird) {
3176  if (dimname1 == (*ird)->name) num_latlondims++;
3177  if (dimname2 == (*ird)->name) num_latlondims++;
3178  }
3179  if ((num_latlondims !=0) && (num_latlondims !=2)) {
3180  // need to remove the coordinates attribute.
3181  for (vector<Attribute *>::iterator ira = (*irv)->attrs.begin();
3182  ira != (*irv)->attrs.end(); ++ira) {
3183  if (co_attrname == (*ira)->name) {
3184  delete(*ira);
3185  (*irv)->attrs.erase(ira);
3186  break;
3187  }
3188  }
3189  }
3190  num_latlondims = 0;
3191  } // for (vector<Var *>::iterator irv = this->vars.begin();
3192  } // if (true == has_2dlatlon_cv)
3193 }
3194 
3195 // This function is from the original requirement of NASA, then
3196 // NASA changes the requirment. Still leave it here for future usage.
3197 #if 0
3198 void EOS5File::Adjust_Special_EOS5CVar_Name() throw(Exception) {
3199 
3200  int num_grids =this->eos5cfgrids.size();
3201  int num_swaths = this->eos5cfswaths.size();
3202  int num_zas = this->eos5cfzas.size();
3203 
3204  bool mixed_eos5typefile = false;
3205 
3206  // Check if this file mixes grid,swath and zonal average
3207  if (((num_grids > 0) && (num_swaths > 0)) ||
3208  ((num_grids > 0) && (num_zas > 0)) ||
3209  ((num_swaths >0) && (num_zas > 0)))
3210  mixed_eos5typefile = true;
3211 
3212 
3213  if (false == mixed_eos5typefile) {
3214 
3215  // Grid is very special since all grids may share the same lat/lon.
3216  // so we also consider this case.
3217 
3218  if ((1 == num_swaths) || ( 1 == num_zas) ||
3219  (1 == num_grids) || ((num_grids >1) && (this->grids_multi_latloncvs))) {
3220 
3221  string unit_attrname = "units";
3222  string nonll_cf_level_attralue ="level";
3223  string lat_cf_unit_attrvalue ="degrees_north";
3224  string lon_cf_unit_attrvalue ="degrees_east";
3225 
3226  for (vector<EOS5CVar *>::iterator irv = this->cvars.begin();
3227  irv != this->cvars.end(); irv++){
3228  switch((*irv)->eos_type) {
3229  case CV_EXIST:
3230  case CV_MODIFY:
3231  case CV_LAT_MISS:
3232  case CV_LON_MISS:
3233  {
3234  for(vector <Attribute*>::iterator ira = (*irv)->attrs.begin();
3235  ira != (*irv)->attrs.end(); ira++) {
3236  if ((*ira)->name ==unit_attrname) {
3237  if ((*ira)->value.size() > 0) {
3238  string units_value((*ira)->value.begin(),(*ira)->value.end());
3239  if (lat_cf_unit_attrvalue ==units_value) (*irv)->newname = "lat";
3240  if (lon_cf_unit_attrvalue ==units_value) (*irv)->newname = "lon";
3241  }
3242  }
3243  }
3244  }
3245  break;
3246  case CV_NONLATLON_MISS:
3247  {
3248  for(vector <Attribute*>::iterator ira = (*irv)->attrs.begin();
3249  ira != (*irv)->attrs.end(); ira++) {
3250  if ((*ira)->name ==unit_attrname) {
3251  if ((*ira)->value.size() > 0) {
3252  string units_value((*ira)->value.begin(),(*ira)->value.end());
3253  if (nonll_cf_level_attralue ==units_value) {
3254  (*irv)->newname = "lev";
3255  break;
3256  }
3257  }
3258  }
3259  }
3260  }
3261  break;
3262  default:
3263  throw1("Non-supported coordinate variable type");
3264  }
3265  }
3266  }
3267  }
3268 }
3269 #endif
3270 
3271 
3272 template<class T>
3273 void EOS5File:: Create_Missing_CV(T* eos5data,EOS5CVar *EOS5cvar, const string& dimname,
3274  EOS5Type eos5type,int num_eos5data) throw(Exception) {
3275 
3276  string reduced_dimname = HDF5CFUtil::obtain_string_after_lastslash(dimname);
3277  if ("" == reduced_dimname) throw2("wrong dimension name ",dimname);
3278  EOS5cvar->name = reduced_dimname;
3279  Create_Added_Var_NewName_FullPath(eos5type,eos5data->name,EOS5cvar->name,EOS5cvar->newname,EOS5cvar->fullpath);
3280  EOS5cvar->rank = 1;
3281  EOS5cvar->dtype = H5INT32;
3282  hsize_t eos5cvar_dimsize = (eos5data->dimnames_to_dimsizes)[dimname];
3283  Dimension* eos5cvar_dim = new Dimension(eos5cvar_dimsize);
3284  eos5cvar_dim->name = dimname;
3285  if (1 == num_eos5data)
3286  eos5cvar_dim->newname = reduced_dimname;
3287  else eos5cvar_dim->newname = dimname;
3288 
3289  EOS5cvar->dims.push_back(eos5cvar_dim);
3290  EOS5cvar->cfdimname = dimname;
3291  EOS5cvar->cvartype = CV_NONLATLON_MISS;
3292  EOS5cvar->eos_type = eos5type;
3293 }
3294 
3295 void EOS5File::Create_Added_Var_NewName_FullPath(EOS5Type eos5type, const string& eos5_groupname,
3296  const string& varname, string &var_newname,
3297  string &var_fullpath) throw(Exception) {
3298 
3299  string fslash_str="/";
3300  string eos5typestr="";
3301  string top_eos5_groupname ="/HDFEOS";
3302 
3303  switch(eos5type) {
3304  case GRID:
3305  {
3306  eos5typestr ="/GRIDS/";
3307  var_newname = eos5typestr + eos5_groupname + fslash_str +varname;
3308  var_fullpath = top_eos5_groupname + eos5typestr +eos5_groupname + fslash_str + varname;
3309  }
3310  break;
3311 
3312  case SWATH:
3313  {
3314  eos5typestr ="/SWATHS/";
3315  var_newname = eos5typestr + eos5_groupname + fslash_str +varname;
3316  var_fullpath = top_eos5_groupname + eos5typestr +eos5_groupname + fslash_str + varname;
3317 
3318  }
3319  break;
3320 
3321  case ZA:
3322  {
3323  eos5typestr ="/ZAS/";
3324  var_newname = eos5typestr + eos5_groupname + fslash_str +varname;
3325  var_fullpath = top_eos5_groupname + eos5typestr +eos5_groupname + fslash_str + varname;
3326 
3327  }
3328  break;
3329  case OTHERVARS:
3330  default:
3331  throw1("Non-supported EOS type");
3332  }
3333 }
3334 
3335 void EOS5File:: Handle_SpVar() throw(Exception) {
3336 
3337  if (true == this->isaura && TES == this->aura_name) {
3338  const string ProHist_full_path = "/HDFEOS/ADDITIONAL/FILE_ATTRIBUTES/ProductionHistory";
3339  for (vector<Var *>::iterator irv = this->vars.begin();
3340  irv != this->vars.end(); ++irv) {
3341  if (ProHist_full_path == (*irv)->fullpath) {
3342  delete (*irv);
3343  this->vars.erase(irv);
3344  break;
3345  }
3346  }
3347  }
3348 
3349  // First, if the duplicate dimension exists,
3350  if(dimname_to_dupdimnamelist.size() > 0) {
3351 //cerr<<"coming to change duplicate var. type. "<<endl;
3352 // pair<multimap<string,string>::iterator,multimap<string,string>::iterator> mm_er_ret;
3353 // multimap<string,string>::iterator itmm;
3354  // for (itmm = dimname_to_dupdimnamelist.begin(); itmm!=dimname_to_dupdimnamelist.end();++itmm) {
3355  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
3356  ircv != this->cvars.end(); ircv++) {
3357  if((*ircv)->cvartype == CV_EXIST) {
3358 //cerr<<"cf dim. name is "<<(*ircv)->cfdimname <<endl;
3359  pair<multimap<string,string>::iterator,multimap<string,string>::iterator> mm_er_ret;
3360  multimap<string,string>::iterator itmm;
3361  for (itmm = dimname_to_dupdimnamelist.begin(); itmm!=dimname_to_dupdimnamelist.end();++itmm) {
3362 
3363 //cerr<<"the first dim. name is "<<(*itmm).first <<endl;
3364  // Find the original dimension(the coordinate variable)
3365  if((*ircv)->cfdimname == (*itmm).first) {
3366 //cerr<<"find the original dimension variable "<<endl;
3367  // Loop through the cv again,this time just check CV_NONLATLON_MISS
3368  for (vector<EOS5CVar *>::iterator irv2 = this->cvars.begin();
3369  irv2 != this->cvars.end(); irv2++) {
3370  if((*irv2)->cvartype == CV_NONLATLON_MISS) {
3371 //cerr<<"go to fake cv "<<endl;
3372 //cerr<<"the duplicate cf dimension name "<<(*irv2)->cfdimname <<endl;
3373  // Obtain the fake CV that has the duplicate dimension.
3374  //if((*irv2)->cfdimname == (*ircv)->cfdimname) {
3375  if((*irv2)->cfdimname == (*itmm).second) {
3376 //cerr<<"find the duplicate dimension name "<<endl;
3377  string dup_var_name = (*irv2)->newname;
3378  Replace_Var_Info((*ircv),(*irv2));
3379  (*irv2)->newname = dup_var_name;
3380  (*irv2)->getDimensions()[0]->newname = dup_var_name;
3381  }
3382 
3383  }
3384  }
3385  //break;//Just for debugging
3386 
3387  }
3388 
3389  }
3390 
3391 
3392  }
3393  }
3394  }
3395 
3396  // No need to loop through the variables. We just need to loop through the coordinate variables and check cfdimname.
3397 #if 0
3398  // For the EOS case, Loop through every variable that has a >=2 rank,
3399  for (vector<Var *>::iterator irv = this->vars.begin();
3400  irv != this->vars.end(); ++irv) {
3401 
3402  // Check if having the duplicate dimensions.
3403  if((*irv)->rank >=2) {
3404  // Loop through the dimensions
3405  for (vector<Dimension *>::iterator ird = (*irv)->dims.begin();
3406  ird != (*irv)->dims.end(); ++ ird) {
3407  pair<multimap<string,string>::iterator,multimap<string,string>::iterator> mm_er_ret;
3408  multimap<string,string>::iterator itmm;
3409  for (itmm = dimname_to_dupdimnamelist.begin(); itmm!=dimname_to_dupdimnamelist.end();++itmm) {
3410 cerr<<"the original dim. name is "<<(*itmm).first <<endl;
3411 cerr<<"the duplicate dim. name is "<<(*itmm).second <<endl;
3412 if((*irv)->name == "RetrievalAveragingKernelMatrixDay")
3413 cerr<<"duplicate dimension name of a variable is "<<(*ird)->name <<endl;
3414  // Find the duplicated dim name in the dimname_to_dupdimnamelist,
3415  // Now retrieve the dim. name and loop through all CV_EXIST variable to see if
3416  // one CV_EXIST variable has a dimension of which name is the dim. name.
3417  // If yes, loop through all CV_NONLLMISS variables and find the CV variable that has the
3418  // duplicate dim. name. If found, replace this variable's information(except name and newname) with the
3419  // fullpath of the CV_EXIST variable. In this way, the duplicate CV variable will read
3420  // correctly the existing CV values and other information. This is the most complicate process.
3421 
3422 // if((*itmm).second == HDF5CFUtil::obtain_string_after_lastslash((*ird)->name)) {
3423  if((*itmm).second == (*ird)->name) {
3424 cerr<<"coming to find the duplicate dim. name "<<endl;
3425  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
3426  ircv != this->cvars.end(); ircv++) {
3427  if((*ircv)->cvartype == CV_EXIST) {
3428 cerr<<"cf dim. name is "<<(*ircv)->cfdimname <<endl;
3429  // Find the original dimension(the coordinate variable)
3430  if((*ircv)->cfdimname == (*itmm).first) {
3431  // Loop through the cv again,this time just check CV_NONLATLON_MISS
3432  for (vector<EOS5CVar *>::iterator irv2 = this->cvars.begin();
3433  irv2 != this->cvars.end(); irv2++) {
3434  if((*irv2)->cvartype == CV_NONLATLON_MISS) {
3435  // Obtain the fake CV that has the duplicate dimension.
3436  if((*irv2)->cfdimname == (*itmm).second) {
3437  string dup_var_name = (*irv2)->newname;
3438  Replace_Var_Info((*ircv),(*irv2));
3439  (*irv2)->newname = dup_var_name;
3440  (*irv2)->getDimensions()[0]->newname = dup_var_name;
3441  }
3442 
3443  }
3444  }
3445 
3446  }
3447 
3448  }
3449 
3450  }
3451 
3452  }
3453 
3454  }
3455 
3456 
3457  }
3458 
3459  }
3460  }
3461 
3462  }
3463 #endif
3464 }
3465 
3466 void EOS5File:: Handle_SpVar_Attr() throw(Exception) {
3467 
3468  // First, if the duplicate dimension exists,
3469  if(dimname_to_dupdimnamelist.size() > 0) {
3470 
3471  pair<multimap<string,string>::iterator,multimap<string,string>::iterator> mm_er_ret;
3472  multimap<string,string>::iterator itmm;
3473  for (itmm = dimname_to_dupdimnamelist.begin(); itmm!=dimname_to_dupdimnamelist.end();++itmm) {
3474  for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin();
3475  ircv != this->cvars.end(); ircv++) {
3476  // The duplicated CV must share with an existing coordinate variable
3477  if((*ircv)->cvartype == CV_EXIST) {
3478 
3479  // Find the original dimension(the coordinate variable)
3480  if((*ircv)->cfdimname == (*itmm).first) {
3481 
3482  // Loop through the cv again,this time just check CV_NONLATLON_MISS
3483  // The duplciated CV must be CV_NONLATLON_MISS.
3484  for (vector<EOS5CVar *>::iterator irv2 = this->cvars.begin();
3485  irv2 != this->cvars.end(); irv2++) {
3486  if((*irv2)->cvartype == CV_NONLATLON_MISS) {
3487 
3488  // Obtain the fake CV that has the duplicate dimension.
3489  //if((*irv2)->cfdimname == (*ircv)->cfdimname)
3490  if((*irv2)->cfdimname == (*itmm).second)
3491  Replace_Var_Attrs((*ircv),(*irv2));
3492 
3493  }
3494  }
3495  } // if((*ircv)->cfdimname == (*itmm).first)
3496  } // if((*ircv)->cvartype == CV_EXIST)
3497  } // for (vector<EOS5CVar *>::iterator ircv = this->cvars.begin()
3498  } // for (itmm = dimname_to_dupdimnamelist.begin();
3499  } // if(dimname_to_dupdimnamelist.size() > 0)
3500 }
3501 void EOS5File::Adjust_Obj_Name() throw(Exception) {
3502 
3503 }
3504 
3506 
3507  File::Replace_Var_Info(src,target);
3508  target->cfdimname = src->cfdimname;
3509  target->cvartype = src->cvartype;
3510  target->eos_type = src->eos_type;
3511 
3512 }
3514 
3515  File::Replace_Var_Attrs(src,target);
3516 
3517 }
Definition: HDF5CF.h:54
void EOS5Handle_nonlatlon_dimcvars(vector< HE5Var > &eos5varlist, EOS5Type, string groupname, map< string, string > &dnamesgeo1dvnames)
Definition: HDFEOS5CF.cc:697
void Handle_NonLatLon_Swath_CVar(EOS5CFSwath *cfswath, set< string > &tempvardimnamelist)
Definition: HDFEOS5CF.cc:2239
Definition: HDF5CF.h:60
void Handle_EOS5CVar_Unit_Attr()
Definition: HDFEOS5CF.cc:2916
void EOS5Handle_General_NameClashing(set< string > &objnameset, vector< T * > &objvec)
Definition: HDFEOS5CF.cc:2679
void Retrieve_H5_Attr_Value(Attribute *attr, string)
Definition: HDF5CF.cc:614
#define throw5(a1, a2, a3, a4, a5)
Definition: HDFSP.cc:84
vector< Dimension * > dims
Definition: HDF5CF.h:320
void Check_Aura_Product_Status()
Check if the HDF-EOS5 file is an Aura file. Special CF operations need to be used.
Definition: HDFEOS5CF.cc:1218
std::string newname
Definition: HDF5CF.h:310
void Get_Unique_Name(set< string > &, string &)
Definition: HDFEOS5CF.cc:1110
EOS5Type
Definition: HDF5CF.h:54
size_t fstrsize
Definition: HDF5CF.h:236
string Create_Unique_FakeDimName(T *, EOS5Type)
Definition: HDFEOS5CF.cc:1119
This class represents one HDF5 dataset(CF variable)
Definition: HDF5CF.h:251
void Handle_EOS5CVar_AttrNameClashing()
Definition: HDFEOS5CF.cc:2666
Definition: HE5Dim.h:8
Definition: HDF5CF.h:54
vector< HE5Dim > dim_list
Definition: HE5Var.h:11
string name
Definition: HE5Za.h:9
vector< HE5Dim > dim_list
Definition: HE5Swath.h:11
void Handle_EOS5CVar_Special_Attr()
Definition: HDFEOS5CF.cc:2878
void Add_Dim_Name(HE5Parser *)
Add the dimension name for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:838
float point_right
The rightmost coordinate value of a Grid.
Definition: HE5Grid.h:26
void Handle_SpVar()
Handle special variables for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:3335
virtual void Replace_Var_Info(Var *src, Var *target)
Definition: HDF5CF.cc:1365
void Remove_MultiDim_LatLon_EOS5CFGrid()
Definition: HDFEOS5CF.cc:1497
Definition: HDF5CF.h:56
vector< HE5Dim > dim_list
Definition: HE5Za.h:10
void Handle_GeneralObj_NameClashing(bool, set< string > &objnameset)
Definition: HDF5CF.cc:1016
void Condense_EOS5Dim_List(vector< HE5Dim > &)
Definition: HDFEOS5CF.cc:260
std::string name
Definition: HDF5CF.h:311
bool Check_Augmented_Var_Candidate(T *, Var *, EOS5Type)
Definition: HDFEOS5CF.cc:1399
string name
Definition: HE5Grid.h:15
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_Obj_NameClashing(bool)
Handle the object name clashing for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:2645
vector< size_t > strsize
Definition: HDF5CF.h:235
void Adjust_EOS5GridDimNames(EOS5CFGrid *)
Definition: HDFEOS5CF.cc:1937
vector< char > value
Definition: HDF5CF.h:237
void Adjust_Per_Var_Dim_NewName_Before_Flattening(T *, bool, int, int, int)
Definition: HDFEOS5CF.cc:2469
vector< HE5Var > data_var_list
Definition: HE5Swath.h:13
void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:156
static void replace_double_quote(string &str)
Definition: h5cfdaputil.cc:99
This class simulates an HDF-EOS5 Swath.
Definition: HDF5CF.h:830
void Adjust_EOS5Dim_Info(HE5Parser *strmeta_info)
Adjust HDF-EOS5 dimension information.
Definition: HDFEOS5CF.cc:198
string name
Definition: HE5Dim.h:9
void Adjust_Attr_Value()
Definition: HDFEOS5CF.cc:2843
Definition: HDF5CF.h:54
string Obtain_Var_EOS5Type_GroupName(Var *, EOS5Type)
Definition: HDFEOS5CF.cc:1146
virtual void Handle_Unsupported_Dtype(bool)
Handle unsupported HDF5 datatypes.
Definition: HDF5CF.cc:776
void Adjust_Attr_Name()
Definition: HDFEOS5CF.cc:2820
int Check_EOS5Swath_FieldType(Var *)
Definition: HDFEOS5CF.cc:1174
void Adjust_SharedLatLon_Grid_Var_Dim_Name()
Definition: HDFEOS5CF.cc:2572
EOS5GridPRType pixelregistration
Definition: HE5Grid.h:35
void Obtain_Var_NewName(Var *)
Definition: HDFEOS5CF.cc:757
int rank
Definition: HDF5CF.h:314
string newname
Definition: HDF5CF.h:232
Definition: HDF5CF.h:56
bool Handle_Single_Nonaugment_Grid_CVar_OwnLatLon(EOS5CFGrid *, set< string > &)
Definition: HDFEOS5CF.cc:1591
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_Augmented_Grid_CVar()
Definition: HDFEOS5CF.cc:1435
void Handle_Swath_CVar(bool)
Definition: HDFEOS5CF.cc:1975
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
void Adjust_Var_Dim_NewName_Before_Flattening()
Adjust variable dimension names before the flattening for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:2431
void Create_Added_Var_NewName_FullPath(EOS5Type, const string &, const string &, string &, string &)
Definition: HDFEOS5CF.cc:3295
void Adjust_EOS5Dim_List(vector< HE5Dim > &)
Definition: HDFEOS5CF.cc:235
vector< Var * > vars
Var vectors.
Definition: HDF5CF.h:639
virtual string get_CF_string(string)
Definition: HDF5CF.cc:1026
bool Check_Augmented_Var_Attrs(Var *var)
Definition: HDFEOS5CF.cc:1370
void Handle_DimNameClashing()
Handle dimension name clashing. Since COARDS requires the change of cv names, So we need to handle di...
Definition: HDFEOS5CF.cc:2720
float point_left
The leftmost coordinate value of a Grid.
Definition: HE5Grid.h:24
void Add_Str_Attr(Attribute *attr, const string &attrname, const string &strvalue)
Definition: HDF5CF.cc:1163
void Handle_CVar()
Handle coordinate variable for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:1269
void Handle_Single_Augment_CVar(T *, EOS5Type)
Definition: HDFEOS5CF.cc:1443
This class is a derived class of CVar. It represents a coordinate variable for HDF-EOS5 files...
Definition: HDF5CF.h:404
EOS5GridPCType projection
Definition: HE5Grid.h:42
#define NULL
Definition: wcsUtil.h:65
virtual void Handle_Unsupported_Dspace()
Handle unsupported HDF5 dataspaces for datasets.
Definition: HDF5CF.cc:850
void Replace_Var_Info(EOS5CVar *src, EOS5CVar *target)
Definition: HDFEOS5CF.cc:3505
void Adjust_Obj_Name()
This method is a no-op operation. Leave here since the method in the base class is pure virtual...
Definition: HDFEOS5CF.cc:3501
bool Obtain_Var_Dims(Var *, HE5Parser *)
Definition: HDFEOS5CF.cc:854
void Handle_Single_Nonaugment_Grid_CVar(EOS5CFGrid *)
Definition: HDFEOS5CF.cc:1561
void Handle_Unsupported_Dspace()
Handle unsupported HDF5 dataspaces for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:183
#define throw1(a1)
The followings are convenient functions to throw exceptions with different.
Definition: HDFSP.cc:80
bool Set_Var_Dims(T *, Var *, vector< HE5Var > &, const string &, int, EOS5Type)
Definition: HDFEOS5CF.cc:923
void Adjust_Var_NewName_After_Parsing()
Adjust variable names for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:749
H5DataType dtype
Definition: HDF5CF.h:233
Definition: HDF5CF.h:56
string name
Definition: HE5Swath.h:10
hsize_t count
Definition: HDF5CF.h:234
bool Handle_Single_Nonaugment_Grid_CVar_EOS5LatLon(EOS5CFGrid *, set< string > &)
Definition: HDFEOS5CF.cc:1690
H5DataType dtype
Definition: HDF5CF.h:313
void Update_Dimnamelist()
Definition: HDFEOS5CF.cc:77
void Handle_Za_CVar(bool)
Definition: HDFEOS5CF.cc:2419
float point_lower
The bottom coordinate value of a Grid.
Definition: HE5Grid.h:20
float point_upper
The top coordinate value of a Grid.
Definition: HE5Grid.h:22
int size
Definition: HE5Dim.h:10
void Create_Missing_CV(T *, EOS5CVar *, const string &, EOS5Type, int)
Definition: HDFEOS5CF.cc:3273
string get_CF_string(string s)
Definition: HDFEOS5CF.cc:121
string name
Definition: HE5Var.h:10
Definition: HE5Za.h:7
EOS5GridOriginType gridorigin
Definition: HE5Grid.h:39
static std::string obtain_string_after_lastslash(const std::string s)
Definition: HDF5CFUtil.cc:115
void Create_Unique_DimName(T *, set< string > &, Dimension *, int, EOS5Type)
Definition: HDFEOS5CF.cc:1016
void Add_EOS5File_Info(HE5Parser *, bool)
Add HDF-EOS5 dimension and coordinate variable related info. to EOS5Grid,EOS5Swath etc...
Definition: HDFEOS5CF.cc:369
void Set_NonParse_Var_Dims(T *, Var *, map< hsize_t, string > &, int, EOS5Type)
Definition: HDFEOS5CF.cc:1201
void Retrieve_H5_Info(const char *path, hid_t file_id, bool include_attr)
Retrieve DDS information from the HDF5 file; a real implementation for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:131
virtual void Replace_Var_Attrs(Var *src, Var *target)
Definition: HDF5CF.cc:1424
void Adjust_EOS5VarDim_Info(vector< HE5Dim > &, vector< HE5Dim > &, const string &, EOS5Type)
Definition: HDFEOS5CF.cc:293
vector< Attribute * > attrs
Definition: HDF5CF.h:319
This class simulates an HDF-EOS5 Zonal average object.
Definition: HDF5CF.h:860
This class represents one attribute.
Definition: HDF5CF.h:184
string newname
Definition: HDF5CF.h:171
void Handle_Special_NonLatLon_Swath_CVar(EOS5CFSwath *cfswath, set< string > &tempvardimnamelist)
Definition: HDFEOS5CF.cc:2311
void Flatten_Obj_Name(bool include_attr)
Flatten the object name for HDF-EOS5 files.
Definition: HDFEOS5CF.cc:2623
void Set_COARDS_Status()
Set COARDS flag.
Definition: HDFEOS5CF.cc:2786
void Remove_NegativeSizeDims(vector< HE5Dim > &)
Definition: HDFEOS5CF.cc:244
bool Check_All_DimNames(T *, string &, hsize_t)
Definition: HDFEOS5CF.cc:1093
This class simulates an HDF-EOS5 Grid. Currently only geographic projection is supported.
Definition: HDF5CF.h:788
void Handle_EOS5CVar_NameClashing(set< string > &)
Definition: HDFEOS5CF.cc:2661
void Add_Supplement_Attrs(bool)
Add the supplemental attributes for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3037
#define throw3(a1, a2, a3)
Definition: HDFSP.cc:82
vector< HE5Var > data_var_list
Definition: HE5Grid.h:17
vector< HE5Var > data_var_list
Definition: HE5Za.h:11
std::string fullpath
Definition: HDF5CF.h:312
EOS5Type Get_Var_EOS5_Type(Var *)
Definition: HDFEOS5CF.cc:812
void Handle_Multi_Nonaugment_Grid_CVar()
Definition: HDFEOS5CF.cc:1858
bool unsupported_attr_dtype
Definition: HDF5CF.h:315
vector< HE5Var > geo_var_list
Definition: HE5Swath.h:12
Definition: HDF5CF.h:56
#define throw2(a1, a2)
Definition: HDFSP.cc:81
This class repersents one dimension of an HDF5 dataset(variable).
Definition: HDF5CF.h:145
void Adjust_Attr_Info()
Adjust the attribute info for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:2809
vector< HE5Dim > dim_list
Definition: HE5Grid.h:16
bool unsupported_var_dspace
Definition: HDF5CF.h:650
static bool cf_strict_support_type(H5DataType dtype)
Definition: HDF5CFUtil.cc:106
void EOS5SwathGrid_Set_LatLon_Flags(T *eos5gridswath, vector< HE5Var > &eos5varlist)
Definition: HDFEOS5CF.cc:628
void Handle_Single_1DLatLon_Swath_CVar(EOS5CFSwath *cfswath, bool is_augmented)
Definition: HDFEOS5CF.cc:2002
bool Check_Augmentation_Status()
Definition: HDFEOS5CF.cc:1317
void Handle_Grid_CVar(bool)
Definition: HDFEOS5CF.cc:1295
void Handle_NonLatLon_Grid_CVar(EOS5CFGrid *, set< string > &)
Definition: HDFEOS5CF.cc:1795
#define throw4(a1, a2, a3, a4)
Definition: HDFSP.cc:83
virtual void Flatten_Obj_Name(bool)
Flatten the object name.
Definition: HDF5CF.cc:866
This class represents an HDF5 group. The group will be flattened according to the CF conventions...
Definition: HDF5CF.h:464
void Adjust_H5_Attr_Value(Attribute *attr)
Definition: HDFEOS5CF.cc:152
void Handle_Single_2DLatLon_Swath_CVar(EOS5CFSwath *cfswath, bool is_augmented)
Definition: HDFEOS5CF.cc:2100
void Retrieve_H5_Supported_Attr_Values()
Retrieve attribute values for the supported HDF5 datatypes for HDF-EOS5 products. ...
Definition: HDFEOS5CF.cc:138
vector< Attribute * > attrs
Definition: HDF5CF.h:496
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. ...
Definition: HE5Var.h:9
void Handle_General_NameClashing(set< string > &objnameset, vector< T * > &objvec)
Definition: HDF5CF.cc:971
void Replace_Var_Attrs(EOS5CVar *src, EOS5CVar *target)
Definition: HDFEOS5CF.cc:3513
virtual ~EOS5File()
Definition: HDFEOS5CF.cc:105
void Adjust_Dim_Name()
Adjust the dimension name for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3005
void Handle_Coor_Attr()
Handle the coordinates attribute for HDF-EOS5 products.
Definition: HDFEOS5CF.cc:3121