OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
HDF5GCFProduct.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 
31 
32 
33 #include <InternalErr.h>
34 #include <assert.h>
35 #include "HDF5GCFProduct.h"
36 using namespace libdap;
37 
38 
39 // The knowledge on how to distinguish each HDF5 product is all buried here
40 // All product attribute names and values are defined at the header files.
41 H5GCFProduct check_product(hid_t file_id) {
42 
43  hid_t root_id = -1;
44  H5GCFProduct product_type = General_Product;
45 
46  // Open the root group.
47  if ((root_id = H5Gopen(file_id,ROOT_NAME,H5P_DEFAULT))<0){
48  string msg = "cannot open the HDF5 root group ";
49  msg += string(ROOT_NAME);
50  //H5Fclose(file_id);
51  throw InternalErr(__FILE__, __LINE__, msg);
52  }
53 
54  // Check if the product is MEaSUREs SeaWiFS
55  int s_level = -1;
56 
57  // Also set Aquarius level, although we only support
58  // Aquarius level 3, in the future we may support Aquarius
59  // level 2.
60  int a_level = -1;
61 
62 
63  // Check if the product is GPM level 1, if yes, just return.
64  if (true == check_gpm_l1(root_id)){
65 //cerr<<"Find GPM level 1 "<<endl;
66  product_type = GPM_L1;
67  }
68 
69  // Check if the product is GPM level 3, if yes, just return.
70  else if (true == check_gpms_l3(root_id)){
71  product_type = GPMS_L3;
72  }
73 
74  else if (true == check_gpmm_l3(root_id)) {
75  product_type = GPMM_L3;
76 
77  }
78 
79  else if (true == check_measure_seawifs(root_id,s_level)) {
80  // cerr <<"after check seawifs " <<endl << " level is "<< s_level <<endl;
81  if (2 == s_level) product_type = Mea_SeaWiFS_L2;
82  if (3 == s_level) product_type = Mea_SeaWiFS_L3;
83  }
84 
85  else if (true == check_aquarius(root_id,a_level)){
86  // cerr <<"after check aquarius" <<endl << " level is "<< a_level <<endl;
87  if (3 == a_level) product_type = Aqu_L3;
88  }
89  else if (true == check_obpg(root_id,a_level)){
90  // cerr <<"after check aquarius" <<endl << " level is "<< a_level <<endl;
91  if (3 == a_level) product_type = OBPG_L3;
92  }
93 
94  else if (true == check_measure_ozone(root_id)) {
95  // cerr<<"after check ozone level 3 zonal average" <<endl;
96  product_type = Mea_Ozone;
97  }
98  else {
99  int smap_flag = 1; // This is SMAP
100  if (true == check_smap_acosl2s(root_id,smap_flag))
101  product_type = SMAP;
102  // cerr <<"After checking smap, product type is " << product_type << endl;
103 
104  if (General_Product == product_type) {
105 
106  int acosl2s_flag = 2; // This is ACOSL2S
107  if (true == check_smap_acosl2s(root_id,acosl2s_flag))
108  product_type = ACOS_L2S;
109 
110  // cerr <<" After checking acos, product type is " << product_type <<endl;
111  }
112 
113  }
114 
115  H5Gclose(root_id);
116  return product_type;
117 }
118 
119 // Function to check if the product is GPM level 1
120 bool check_gpm_l1(hid_t s_root_id) {
121 
122  htri_t has_gpm_l1_attr1 = -1;
123  bool ret_flag = false;
124 
125 //cerr <<"coming to gpm level 3 "<<endl;
126 
127  // Here we check the existence of attribute 1 first
128  has_gpm_l1_attr1 = H5Aexists(s_root_id,GPM_ATTR1_NAME);
129 
130  if(has_gpm_l1_attr1 >0) {
131 
132  H5G_info_t g_info;
133  hsize_t nelms = 0;
134 
135  if(H5Gget_info(s_root_id,&g_info) <0) {
136  H5Gclose(s_root_id);
137  throw InternalErr(__FILE__,__LINE__,"Cannot get the HDF5 object info. successfully");
138  }
139 
140  nelms = g_info.nlinks;
141 
142  hid_t cgroup = -1;
143  hid_t attrid = -1;
144 
145  for (unsigned int i = 0; i<nelms; i++) {
146 
147  try {
148 
149  size_t dummy_name_len = 1;
150 
151  // Query the length of object name.
152  ssize_t oname_size =
153  H5Lget_name_by_idx(s_root_id,".",H5_INDEX_NAME,H5_ITER_NATIVE,i,NULL,
154  dummy_name_len, H5P_DEFAULT);
155  if (oname_size <= 0)
156  throw InternalErr(__FILE__,__LINE__,"Error getting the size of the hdf5 object from the root group. ");
157 
158  // Obtain the name of the object
159  vector<char> oname;
160  oname.resize((size_t)oname_size+1);
161 
162  if (H5Lget_name_by_idx(s_root_id,".",H5_INDEX_NAME,H5_ITER_NATIVE,i,&oname[0],
163  (size_t)(oname_size+1), H5P_DEFAULT) < 0)
164  throw InternalErr(__FILE__,__LINE__,"Error getting the hdf5 object name from the root group. ");
165 
166  // Check if it is the hard link or the soft link
167  H5L_info_t linfo;
168  if (H5Lget_info(s_root_id,&oname[0],&linfo,H5P_DEFAULT)<0)
169  throw InternalErr (__FILE__,__LINE__,"HDF5 link name error from the root group. ");
170 
171  // Ignore soft links and external links
172  if(H5L_TYPE_SOFT == linfo.type || H5L_TYPE_EXTERNAL == linfo.type)
173  continue;
174 
175  // Obtain the object type, such as group or dataset.
176  H5O_info_t soinfo;
177  if(H5Oget_info_by_idx(s_root_id,".",H5_INDEX_NAME,H5_ITER_NATIVE, (hsize_t)i,&soinfo,H5P_DEFAULT)<0)
178  throw InternalErr(__FILE__,__LINE__,"Cannot get the HDF5 object info. successfully. ");
179 
180  H5O_type_t obj_type = soinfo.type;
181 
182  // We only need to check the group attribute.
183  if(obj_type == H5O_TYPE_GROUP) {
184 
185  // Check the attribute name of that group
186  cgroup = H5Gopen(s_root_id,&oname[0],H5P_DEFAULT);
187  if(cgroup < 0)
188  throw InternalErr(__FILE__,__LINE__,"Cannot open the group.");
189 
190  int num_attrs = soinfo.num_attrs;
191 
192  // Loop through all the attributes to see if the GPM level 1 swath header exists.
193  for (int j = 0; j < num_attrs; j++) {
194 
195  // Obtain the attribute ID.
196  if ((attrid = H5Aopen_by_idx(cgroup, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC,(hsize_t)j, H5P_DEFAULT, H5P_DEFAULT)) < 0)
197  throw InternalErr(__FILE__,__LINE__,"Unable to open attribute by index " );
198 
199  // Obtain the size of the attribute name.
200  ssize_t name_size = H5Aget_name(attrid, 0, NULL);
201  if (name_size < 0)
202  throw InternalErr(__FILE__,__LINE__,"Unable to obtain the size of the hdf5 attribute name " );
203 
204  string attr_name;
205  attr_name.resize(name_size+1);
206 
207  // Obtain the attribute name.
208  if ((H5Aget_name(attrid, name_size+1, &attr_name[0])) < 0)
209  throw InternalErr(__FILE__,__LINE__,"unable to obtain the hdf5 attribute name ");
210 
211  string swathheader(GPM_SWATH_ATTR2_NAME);
212  if(attr_name.rfind(swathheader) !=string::npos) {
213  H5Aclose(attrid);
214  ret_flag = true;
215  break;
216  }
217  H5Aclose(attrid);
218  }
219 
220  if(true == ret_flag){
221  H5Gclose(cgroup);
222  break;
223  }
224  H5Gclose(cgroup);
225  }
226  }
227  catch(...) {
228  if(s_root_id != -1)
229  H5Gclose(s_root_id);
230  if(cgroup != -1)
231  H5Gclose(cgroup);
232  if(attrid != -1)
233  H5Aclose(attrid);
234  throw;
235  }
236  }
237 
238  }
239 
240  return ret_flag;
241 
242 }
243 
244 
245 // Function to check if the product is GPM level 3
246 bool check_gpms_l3(hid_t s_root_id) {
247 
248  htri_t has_gpm_l3_attr1 = -1;
249  bool ret_flag = false;
250 
251 //cerr <<"coming to gpm level 3 "<<endl;
252 
253  // Here we check the existence of attribute 1 first
254  has_gpm_l3_attr1 = H5Aexists(s_root_id,GPM_ATTR1_NAME);
255 
256  if(has_gpm_l3_attr1 >0) {
257 
258  htri_t has_gpm_grid_group = -1;
259 
260 // cerr <<"coming to gpm grid "<<endl;
261  has_gpm_grid_group = H5Lexists(s_root_id,GPM_GRID_GROUP_NAME1,H5P_DEFAULT);
262 
263  hid_t s_group_id = -1;
264  if (has_gpm_grid_group >0){
265 
266  // Open the group
267  if ((s_group_id = H5Gopen(s_root_id, GPM_GRID_GROUP_NAME1,H5P_DEFAULT))<0) {
268  string msg = "Cannot open the HDF5 Group ";
269  msg += string(GPM_GRID_GROUP_NAME1);
270  H5Gclose(s_root_id);
271  throw InternalErr(__FILE__, __LINE__, msg);
272  }
273  }
274  else {
275 
276  if(H5Lexists(s_root_id,GPM_GRID_GROUP_NAME2,H5P_DEFAULT) >0) {
277  // Open the group
278  if ((s_group_id = H5Gopen(s_root_id, GPM_GRID_GROUP_NAME2,H5P_DEFAULT))<0) {
279  string msg = "Cannot open the HDF5 Group ";
280  msg += string(GPM_GRID_GROUP_NAME2);
281  H5Gclose(s_root_id);
282  throw InternalErr(__FILE__, __LINE__, msg);
283  }
284 
285  }
286 
287  }
288  if (s_group_id >0) {
289  htri_t has_gpm_l3_attr2 = -1;
290  has_gpm_l3_attr2 = H5Aexists(s_group_id,GPM_ATTR2_NAME);
291  if (has_gpm_l3_attr2 >0)
292  ret_flag = true;
293 
294  H5Gclose(s_group_id);
295  }
296 
297 
298  }
299 
300  return ret_flag;
301 
302 }
303 
304 
305 bool check_gpmm_l3(hid_t s_root_id) {
306 
307  htri_t has_gpm_l3_attr1 = -1;
308  bool ret_flag = false;
309 
310 //cerr <<"coming to gpm level 3 "<<endl;
311 
312  // Here we check the existence of attribute 1 first
313  has_gpm_l3_attr1 = H5Aexists(s_root_id,GPM_ATTR1_NAME);
314 
315  if(has_gpm_l3_attr1 >0) {
316 
317  if(H5Lexists(s_root_id,GPM_GRID_MULTI_GROUP_NAME,H5P_DEFAULT) >0) {
318  hid_t cgroup_id = -1;
319 //cerr<<"coming to check multi-groups 2"<<endl;
320  // Open the group
321  if ((cgroup_id = H5Gopen(s_root_id, GPM_GRID_MULTI_GROUP_NAME,H5P_DEFAULT))<0) {
322  string msg = "Cannot open the HDF5 Group ";
323  msg += string(GPM_GRID_MULTI_GROUP_NAME);
324  H5Gclose(s_root_id);
325  throw InternalErr(__FILE__, __LINE__, msg);
326  }
327 
328  H5G_info_t g_info;
329  hsize_t nelms = 0;
330 
331  if(H5Gget_info(cgroup_id,&g_info) <0) {
332  H5Gclose(cgroup_id);
333  H5Gclose(s_root_id);
334  throw InternalErr(__FILE__,__LINE__,"Cannot get the HDF5 object info. successfully");
335  }
336 
337  nelms = g_info.nlinks;
338 //cerr<<"nelms is "<<nelms <<endl;
339 
340  hid_t cgroup2_id = -1;
341  hid_t attrid = -1;
342 
343  for (unsigned int i = 0; i<nelms; i++) {
344 
345  try {
346 
347  size_t dummy_name_len = 1;
348 
349  // Query the length of object name.
350  ssize_t oname_size =
351  H5Lget_name_by_idx(cgroup_id,".",H5_INDEX_NAME,H5_ITER_NATIVE,i,NULL,
352  dummy_name_len, H5P_DEFAULT);
353  if (oname_size <= 0)
354  throw InternalErr(__FILE__,__LINE__,"Error getting the size of the hdf5 object from the grid group. ");
355 
356  // Obtain the name of the object
357  vector<char> oname;
358  oname.resize((size_t)oname_size+1);
359 
360  if (H5Lget_name_by_idx(cgroup_id,".",H5_INDEX_NAME,H5_ITER_NATIVE,i,&oname[0],
361  (size_t)(oname_size+1), H5P_DEFAULT) < 0)
362  throw InternalErr(__FILE__,__LINE__,"Error getting the hdf5 object name from the root group. ");
363 
364  // Check if it is the hard link or the soft link
365  H5L_info_t linfo;
366  if (H5Lget_info(cgroup_id,&oname[0],&linfo,H5P_DEFAULT)<0)
367  throw InternalErr (__FILE__,__LINE__,"HDF5 link name error from the root group. ");
368 
369  // Ignore soft links and external links
370  if(H5L_TYPE_SOFT == linfo.type || H5L_TYPE_EXTERNAL == linfo.type)
371  continue;
372 
373  // Obtain the object type, such as group or dataset.
374  H5O_info_t soinfo;
375  if(H5Oget_info_by_idx(cgroup_id,".",H5_INDEX_NAME,H5_ITER_NATIVE, (hsize_t)i,&soinfo,H5P_DEFAULT)<0)
376  throw InternalErr(__FILE__,__LINE__,"Cannot get the HDF5 object info. successfully. ");
377 
378  H5O_type_t obj_type = soinfo.type;
379 
380  // We only need to check the group attribute.
381  if(obj_type == H5O_TYPE_GROUP) {
382 
383  // Check the attribute name of that group
384  cgroup2_id = H5Gopen(cgroup_id,&oname[0],H5P_DEFAULT);
385  if(cgroup2_id < 0)
386  throw InternalErr(__FILE__,__LINE__,"Cannot open the group.");
387 
388 //string onamestr(oname.begin(),oname.end());
389 //cerr<<"object name is "<<onamestr <<endl;
390 
391  htri_t has_gpm_l3_attr2;
392  has_gpm_l3_attr2 = H5Aexists(cgroup2_id,GPM_ATTR2_NAME);
393  if (has_gpm_l3_attr2 >0) {
394  ret_flag = true;
395  H5Gclose(cgroup2_id);
396  break;
397  }
398  else {
399 
400  int num_attrs = soinfo.num_attrs;
401 
402  // Loop through all the attributes to see if the GPM level 1 swath header exists.
403  for (int j = 0; j < num_attrs; j++) {
404 
405  // Obtain the attribute ID.
406  if ((attrid = H5Aopen_by_idx(cgroup2_id, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC,(hsize_t)j, H5P_DEFAULT, H5P_DEFAULT)) < 0)
407  throw InternalErr(__FILE__,__LINE__,"Unable to open attribute by index " );
408 
409  // Obtain the size of the attribute name.
410  ssize_t name_size = H5Aget_name(attrid, 0, NULL);
411  if (name_size < 0)
412  throw InternalErr(__FILE__,__LINE__,"Unable to obtain the size of the hdf5 attribute name " );
413 
414  string attr_name;
415  attr_name.resize(name_size+1);
416 
417  // Obtain the attribute name.
418  if ((H5Aget_name(attrid, name_size+1, &attr_name[0])) < 0)
419  throw InternalErr(__FILE__,__LINE__,"unable to obtain the hdf5 attribute name ");
420 
421 //cerr<<"attrname is "<<attr_name <<endl;
422  string gridheader(GPM_ATTR2_NAME);
423  if(attr_name.find(gridheader) !=string::npos) {
424  ret_flag = true;
425  break;
426  }
427  }
428 
429  if(true == ret_flag)
430  break;
431 
432  }
433 
434  H5Gclose(cgroup2_id);
435 
436  }
437  }
438  catch(...) {
439  if(s_root_id != -1)
440  H5Gclose(s_root_id);
441  if(cgroup_id != -1)
442  H5Gclose(cgroup_id);
443  if(cgroup2_id != -1)
444  H5Gclose(cgroup2_id);
445  throw;
446  }
447  }
448  H5Gclose(cgroup_id);
449  }
450  }
451  return ret_flag;
452 
453 
454 }
455 
456 // Function to check if the product is MeaSure seaWiFS
457 bool check_measure_seawifs(hid_t s_root_id,int & s_lflag) {
458 
459  htri_t has_seawifs_attr1 = -1;
460  bool ret_flag = false;
461  // cerr <<"coming to measure seawifs "<<endl;
462 
463  // Here we check the existence of attribute 1 first since
464  // attribute 1 will tell if the product is SeaWIFS or not.
465  // attribute 2 and 3 will distinguish if it is level 2 or level 3.
466  has_seawifs_attr1 = H5Aexists(s_root_id,SeaWiFS_ATTR1_NAME);
467 
468  if (has_seawifs_attr1 >0) {
469 
470  string attr1_value="";
471  obtain_gm_attr_value(s_root_id, SeaWiFS_ATTR1_NAME, attr1_value);
472  // cerr<<"seawifs attr1 value size " << attr1_value.length() <<endl;
473  // cerr <<"seawifs ATTR1_VALUE size "<< SeaWiFS_ATTR1_VALUE.length() <<endl;
474  if (0 == attr1_value.compare(SeaWiFS_ATTR1_VALUE)) {
475  // cerr<<"coming after comparing "<<endl;
476  htri_t has_seawifs_attr2 = -1;
477  htri_t has_seawifs_attr3 = -1;
478  has_seawifs_attr2 = H5Aexists(s_root_id,SeaWiFS_ATTR2_NAME);
479  has_seawifs_attr3 = H5Aexists(s_root_id,SeaWiFS_ATTR3_NAME);
480 
481  if ((has_seawifs_attr2 >0) && (has_seawifs_attr3 > 0)){
482  // cerr <<"coming to seawifs attr2 and 3" <<endl;
483  string attr2_value ="";
484  string attr3_value ="";
485  obtain_gm_attr_value(s_root_id,SeaWiFS_ATTR2_NAME, attr2_value);
486  obtain_gm_attr_value(s_root_id,SeaWiFS_ATTR3_NAME, attr3_value);
487 
488  // The first part of the <long_name> should be "SeaWiFS"
489  // "Level 2" or "Level 3" should also be inside <long_name>.
490  // OR the short_name should start with "SWDB_L2" and "SWDB_L3".
491 
492  if (((0 == attr2_value.find(SeaWiFS_ATTR2_FPVALUE)) &&
493  (attr2_value.find(SeaWiFS_ATTR2_L2PVALUE)!=string::npos))
494  ||(0 == attr3_value.find(SeaWiFS_ATTR3_L2FPVALUE))) {
495  // cerr <<"coming to seaWiFS level 2" <<endl;
496  s_lflag = 2;
497  ret_flag = true;
498  }
499  else if (((0 == attr2_value.find(SeaWiFS_ATTR2_FPVALUE)) &&
500  (attr2_value.find(SeaWiFS_ATTR2_L3PVALUE)!=string::npos))
501  ||(0 == attr3_value.find(SeaWiFS_ATTR3_L3FPVALUE))) {
502  s_lflag = 3;
503  ret_flag = true;
504  }
505  }
506  // else if long_name or short_name don't exist, not what we supported.
507  else if ((0 == has_seawifs_attr2 ) || (0 == has_seawifs_attr3))
508  ; // no op
509  else {
510  string msg = "Fail to determine if the HDF5 attribute ";
511  msg += string(SeaWiFS_ATTR2_NAME);
512  msg += "or the HDF5 attribute ";
513  msg += string(SeaWiFS_ATTR3_NAME);
514  msg +=" exists ";
515  H5Gclose(s_root_id);
516  throw InternalErr(__FILE__, __LINE__, msg);
517  }
518  }
519  }
520  else if (0 == has_seawifs_attr1)
521  ;//no op
522  else {
523  string msg = "Fail to determine if the HDF5 attribute ";
524  msg += string(SeaWiFS_ATTR1_NAME);
525  msg +=" exists ";
526  H5Gclose(s_root_id);
527  throw InternalErr(__FILE__, __LINE__, msg);
528  }
529  return ret_flag;
530 }
531 
532  // Function to check if the product is MeaSure seaWiFS
533 bool check_measure_ozone(hid_t s_root_id) {
534 
535  htri_t has_ozone_attr1 = -1;
536  bool ret_flag = false;
537  // cerr <<"coming to measure ozone "<<endl;
538 
539  // Here we check the existence of attribute 1 first since
540  // attribute 1 will tell if the product is SeaWIFS or not.
541  // attribute 2 and 3 will distinguish if it is level 2 or level 3.
542  has_ozone_attr1 = H5Aexists(s_root_id,Ozone_ATTR1_NAME);
543 
544  if (has_ozone_attr1 >0) {
545  string attr1_value = "";
546  obtain_gm_attr_value(s_root_id, Ozone_ATTR1_NAME, attr1_value);
547  // cerr<<"ozone attr1 value size " << attr1_value.length() <<endl;
548  // cerr <<"ozone ATTR1_VALUE size "<< Ozone_ATTR1_VALUE.length() <<endl;
549  if ((0 == attr1_value.compare(Ozone_ATTR1_VALUE1)) ||
550  (0 == attr1_value.compare(Ozone_ATTR1_VALUE2))) {
551  htri_t has_ozone_attr2 = -1;
552  has_ozone_attr2 = H5Aexists(s_root_id,Ozone_ATTR2_NAME);
553  if (has_ozone_attr2 >0) {
554  string attr2_value = "";
555  obtain_gm_attr_value(s_root_id,Ozone_ATTR2_NAME, attr2_value);
556  if(0 == attr2_value.compare(Ozone_ATTR2_VALUE))
557  ret_flag = true;
558  }
559  // else if "ParameterName" attributes don't exist, not what we supported.
560  else if (0 == has_ozone_attr2)
561  ;// no op
562  else {
563  string msg = "Fail to determine if the HDF5 attribute ";
564  msg += string(Ozone_ATTR2_NAME);
565  msg +=" exists ";
566  H5Gclose(s_root_id);
567  throw InternalErr(__FILE__, __LINE__, msg);
568  }
569  }
570  }
571  else if (0 == has_ozone_attr1 )
572  ; // no op
573  else {
574  string msg = "Fail to determine if the HDF5 attribute ";
575  msg += string(Ozone_ATTR1_NAME);
576  msg +=" exists ";
577  H5Gclose(s_root_id);
578  throw InternalErr(__FILE__, __LINE__, msg);
579  }
580  return ret_flag;
581 }
582 // Function to check if the product is Aquarius
583 // We still leave a flag to indicate the level although
584 // we just support the special arrangement of level 3 now.
585 // Possibly level 2 can be added
586 // in the future.
587 bool check_aquarius(hid_t s_root_id,int & s_level) {
588 
589  htri_t has_aquarius_attr1 = -1;
590  bool ret_flag = false;
591  // cerr <<"coming to aquarius "<<endl;
592 
593  // Here we check the existence of attribute 1 first since
594  // attribute 1 will tell if the product is Aquarius or not.
595  // attribute 2 will tell its level.
596  has_aquarius_attr1 = H5Aexists(s_root_id,Aquarius_ATTR1_NAME);
597  if (has_aquarius_attr1 >0) {
598  string attr1_value = "";
599  obtain_gm_attr_value(s_root_id, Aquarius_ATTR1_NAME, attr1_value);
600  if (0 == attr1_value.compare(Aquarius_ATTR1_VALUE)) {
601  htri_t has_aquarius_attr2 = -1;
602  has_aquarius_attr2 = H5Aexists(s_root_id,Aquarius_ATTR2_NAME);
603  if (has_aquarius_attr2 >0) {
604  string attr2_value ="";
605  obtain_gm_attr_value(s_root_id,Aquarius_ATTR2_NAME, attr2_value);
606 
607  // The "Title" of Aquarius should include "Level-3".
608  if (attr2_value.find(Aquarius_ATTR2_PVALUE)!=string::npos){
609  // Set it to level 3
610  s_level = 3;
611  ret_flag = true;
612  }
613  }
614  // else if long_name or short_name don't exist, not what we supported.
615  else if (0 == has_aquarius_attr2)
616  ; // no op
617  else {
618  string msg = "Fail to determine if the HDF5 attribute ";
619  msg += string(Aquarius_ATTR2_NAME);
620  msg +=" exists ";
621  H5Gclose(s_root_id);
622  throw InternalErr(__FILE__, __LINE__, msg);
623  }
624  }
625  }
626  else if (0 == has_aquarius_attr1)
627  ;// no op
628  else {
629  string msg = "Fail to determine if the HDF5 attribute ";
630  msg += string(Aquarius_ATTR1_NAME);
631  msg +=" exists ";
632  H5Gclose(s_root_id);
633  throw InternalErr(__FILE__, __LINE__, msg);
634  }
635  return ret_flag;
636 }
637 
638 // Function to check if the product is OBPG level 3.
639 // We leave a flag to indicate if this product is level 3 for
640 // possible level 2 support later.
641 bool check_obpg(hid_t s_root_id,int & s_level) {
642 
643  htri_t has_obpg_attr1 = -1;
644  bool ret_flag = false;
645 // cerr <<"coming to obpg "<<endl;
646 
647  // Here we check the existence of attribute 1 first since
648  // attribute 1 will tell if the product is OBPG or not.
649  // attribute 2 will tell its level.
650  has_obpg_attr1 = H5Aexists(s_root_id,Obpgl3_ATTR1_NAME);
651  if (has_obpg_attr1 >0) {
652  string attr1_value = "";
653  obtain_gm_attr_value(s_root_id, Obpgl3_ATTR1_NAME, attr1_value);
654  htri_t has_obpg_attr2 = -1;
655  has_obpg_attr2 = H5Aexists(s_root_id,Obpgl3_ATTR2_NAME);
656  if (has_obpg_attr2 >0) {
657  string attr2_value ="";
658  obtain_gm_attr_value(s_root_id,Obpgl3_ATTR2_NAME, attr2_value);
659  if ((0 == attr1_value.compare(Obpgl3_ATTR1_VALUE)) &&
660  (0 == attr2_value.compare(Obpgl3_ATTR2_VALUE))) {
661  // Set it to level 3
662 //cerr<<"This is OBPG product"<<endl;
663  s_level = 3;
664  ret_flag = true;
665  }
666 
667  // else if long_name or short_name don't exist, not what we supported.
668  else if (0 == has_obpg_attr2)
669  ; // no op
670  else {
671  string msg = "Fail to determine if the HDF5 attribute ";
672  msg += string(Obpgl3_ATTR2_NAME);
673  msg +=" exists ";
674  H5Gclose(s_root_id);
675  throw InternalErr(__FILE__, __LINE__, msg);
676  }
677  }
678  }
679  else if (0 == has_obpg_attr1)
680  ;// no op
681  else {
682  string msg = "Fail to determine if the HDF5 attribute ";
683  msg += string(Obpgl3_ATTR1_NAME);
684  msg +=" exists ";
685  H5Gclose(s_root_id);
686  throw InternalErr(__FILE__, __LINE__, msg);
687  }
688  return ret_flag;
689 }
690 // Function to check if the product is ACOS Level 2 or SMAP.
691 bool check_smap_acosl2s(hid_t s_root_id, int which_pro) {
692 
693  htri_t has_smac_group;
694  // cerr <<"coming to smap acos "<<endl;
695  bool return_flag = false;
696  has_smac_group = H5Lexists(s_root_id,SMAC2S_META_GROUP_NAME,H5P_DEFAULT);
697 
698  if (has_smac_group >0){
699  hid_t s_group_id = -1;
700 
701  // Open the group
702  if ((s_group_id = H5Gopen(s_root_id, SMAC2S_META_GROUP_NAME,H5P_DEFAULT))<0) {
703  string msg = "Cannot open the HDF5 Group ";
704  msg += string(SMAC2S_META_GROUP_NAME);
705  H5Gclose(s_root_id);
706  throw InternalErr(__FILE__, __LINE__, msg);
707  }
708 
709  // SMAP
710  if (1 == which_pro) {
711 
712  htri_t has_smap_attr = -1;
713  // SMAP will have an attribute called ProjectID
714  has_smap_attr = H5Aexists(s_group_id,SMAP_ATTR_NAME);
715  if (has_smap_attr >0) {
716  string attr_value = "";
717  obtain_gm_attr_value(s_group_id, SMAP_ATTR_NAME, attr_value);
718  if (attr_value.compare(SMAP_ATTR_VALUE) == 0)
719  return_flag = true;
720  else
721  return_flag = false;
722  H5Gclose(s_group_id);
723  }
724  else if (0 == has_smap_attr) {
725  H5Gclose(s_group_id);
726  return_flag = false;
727  }
728  else {
729  string msg = "Fail to determine if the HDF5 link ";
730  msg += string(SMAP_ATTR_NAME);
731  msg +=" exists ";
732  H5Gclose(s_group_id);
733  H5Gclose(s_root_id);
734  throw InternalErr(__FILE__, __LINE__, msg);
735  }
736  }
737  else if (2 == which_pro) {
738  // cerr <<"coming to acos l2s "<<endl;
739 
740  htri_t has_acos_dset = -1;
741 
742  // ACOSL2S will have a dataset called ProjectID
743  has_acos_dset = H5Lexists(s_group_id,ACOS_L2S_DSET_NAME,H5P_DEFAULT);
744  if (has_acos_dset > 0) {
745  // cerr <<"coming to acos l2s dataset "<<endl;
746  // Obtain the dataset ID
747  hid_t s_dset_id = -1;
748  if ((s_dset_id = H5Dopen(s_group_id, ACOS_L2S_DSET_NAME,H5P_DEFAULT)) < 0) {
749  string msg = "cannot open the HDF5 dataset ";
750  msg += string(ACOS_L2S_DSET_NAME);
751  H5Gclose(s_group_id);
752  H5Gclose(s_root_id);
753  throw InternalErr(__FILE__, __LINE__, msg);
754  }
755 
756  // Obtain the datatype ID
757  hid_t dtype = -1;
758  if ((dtype = H5Dget_type(s_dset_id)) < 0) {
759  H5Dclose(s_dset_id);
760  H5Gclose(s_group_id);
761  H5Gclose(s_root_id);
762  string msg = "cannot get the datatype of HDF5 dataset ";
763  msg += string(ACOS_L2S_DSET_NAME);
764  throw InternalErr(__FILE__, __LINE__, msg);
765  }
766 
767  // Obtain the datatype class
768  H5T_class_t ty_class = H5Tget_class(dtype);
769  if (ty_class < 0) {
770  H5Tclose(dtype);
771  H5Dclose(s_dset_id);
772  H5Gclose(s_group_id);
773  H5Gclose(s_root_id);
774  string msg = "cannot get the datatype class of HDF5 dataset ";
775  msg += string(ACOS_L2S_DSET_NAME);
776  throw InternalErr(__FILE__, __LINE__, msg);
777  }
778 
779  if (ty_class != H5T_STRING) {
780  H5Tclose(dtype);
781  H5Dclose(s_dset_id);
782  H5Gclose(s_group_id);
783  H5Gclose(s_root_id);
784  string msg = "This dataset must be a H5T_STRING class ";
785  msg += string(ACOS_L2S_DSET_NAME);
786  throw InternalErr(__FILE__, __LINE__, msg);
787  }
788 
789 
790  hid_t dspace = -1;
791  if ((dspace = H5Dget_space(s_dset_id)) < 0) {
792  H5Tclose(dtype);
793  H5Dclose(s_dset_id);
794  H5Gclose(s_group_id);
795  H5Gclose(s_root_id);
796  string msg = "cannot get the the dataspace of HDF5 dataset ";
797  msg += string(ACOS_L2S_DSET_NAME);
798  throw InternalErr(__FILE__, __LINE__, msg);
799  }
800 
801  hssize_t num_elem = 0;
802  if ((num_elem = H5Sget_simple_extent_npoints(dspace))<=0) {
803  H5Tclose(dtype);
804  H5Sclose(dspace);
805  H5Dclose(s_dset_id);
806  H5Gclose(s_group_id);
807  H5Gclose(s_root_id);
808  string msg = "cannot get the the number of points of HDF5 dataset ";
809  msg += string(ACOS_L2S_DSET_NAME);
810  throw InternalErr(__FILE__, __LINE__, msg);
811  }
812 
813  size_t dtype_size = H5Tget_size(dtype);
814  if (dtype_size <= 0) {
815  H5Tclose(dtype);
816  H5Dclose(s_dset_id);
817  H5Sclose(dspace);
818  H5Gclose(s_group_id);
819  H5Gclose(s_root_id);
820  string msg = "cannot get the the dataspace of HDF5 dataset ";
821  msg += string(ACOS_L2S_DSET_NAME);
822  throw InternalErr(__FILE__, __LINE__, msg);
823  }
824 
825  size_t total_data_size = num_elem * H5Tget_size(dtype);
826 
827  if (H5Tis_variable_str(dtype)) {
828 
829  // cerr <<"coming to variable length string "<<endl;
830  vector<char>temp_buf;
831  temp_buf.resize(total_data_size);
832 
833  //if (H5Dread(s_dset_id,dtype,H5S_ALL,H5S_ALL,H5P_DEFAULT, temp_buf)<0)
834  if (H5Dread(s_dset_id,dtype,H5S_ALL,H5S_ALL,H5P_DEFAULT, &temp_buf[0])<0){
835  H5Tclose(dtype);
836  H5Dclose(s_dset_id);
837  H5Sclose(dspace);
838  H5Gclose(s_group_id);
839  H5Gclose(s_root_id);
840  string msg = "cannot get the the dataspace of HDF5 dataset ";
841  msg += string(ACOS_L2S_DSET_NAME);
842  throw InternalErr(__FILE__, __LINE__, msg);
843  }
844 
845  char *temp_bp = &temp_buf[0];
846  char *onestring = NULL;
847  string total_string="";
848 
849  for (int temp_i = 0; temp_i <num_elem; temp_i++) {
850 
851  // This line will assure that we get the real variable length string value.
852  onestring =*(char **)temp_bp;
853 
854  // Change the C-style string to C++ STD string just for easy handling.
855  if (onestring !=NULL) {
856  string tempstring(onestring);
857  total_string+=tempstring;
858  // cerr <<"temp_string attr "<<tempstring <<endl;
859  }
860  // going to the next value.
861  temp_bp += dtype_size;
862  }
863 
864  // Reclaim any VL memory if necessary.
865  H5Dvlen_reclaim(dtype,dspace,H5P_DEFAULT,&temp_buf[0]);
866 
867 
868  H5Sclose(dspace);
869  H5Tclose(dtype);
870  H5Dclose(s_dset_id);
871  H5Gclose(s_group_id);
872 
873  if (total_string.compare(ACOS_L2S_ATTR_VALUE) ==0)
874  return_flag = true;
875  }
876  else {
877  vector<char> temp_buf(total_data_size+1);
878  if (H5Dread(s_dset_id,dtype,H5S_ALL,H5S_ALL,H5P_DEFAULT, &temp_buf[0])<0){
879  H5Tclose(dtype);
880  H5Dclose(s_dset_id);
881  H5Sclose(dspace);
882  H5Gclose(s_group_id);
883  H5Gclose(s_root_id);
884  string msg = "cannot data of HDF5 dataset ";
885  msg += string(ACOS_L2S_DSET_NAME);
886  throw InternalErr(__FILE__, __LINE__, msg);
887  }
888 
889  string total_string(temp_buf.begin(),temp_buf.end()-1);
890  H5Sclose(dspace);
891  H5Tclose(dtype);
892  H5Dclose(s_dset_id);
893  H5Gclose(s_group_id);
894  // cerr<<"total_string "<<total_string <<endl;
895 
896  if (0 == total_string.compare(ACOS_L2S_ATTR_VALUE))
897  return_flag = true;
898  else
899  return_flag = false;
900  }
901  }
902  else if (0 == has_acos_dset) {
903  H5Gclose(s_group_id);
904  return_flag = false;
905  }
906  else {
907  string msg = "Fail to determine if the HDF5 link ";
908  msg += string(ACOS_L2S_DSET_NAME);
909  msg +=" exists ";
910  H5Gclose(s_group_id);
911  H5Gclose(s_root_id);
912  throw InternalErr(__FILE__, __LINE__, msg);
913  }
914  }
915  else ;// Other product, don't do anything.
916  }
917  else if (0 == has_smac_group)
918  return_flag = false;
919  else {
920  string msg = "Fail to determine if the link ";
921  msg += string(SMAC2S_META_GROUP_NAME);
922  msg +=" exists or not ";
923  H5Gclose(s_root_id);
924  throw InternalErr(__FILE__, __LINE__, msg);
925  }
926  return return_flag;
927 }
928 
929 void obtain_gm_attr_value(hid_t s_root_id, const char* s_attr_name, string & s_attr_value) {
930 
931  hid_t s_attr_id = -1;
932  if ((s_attr_id = H5Aopen_by_name(s_root_id,".",s_attr_name,
933  H5P_DEFAULT, H5P_DEFAULT)) <0) {
934  string msg = "Cannot open the HDF5 attribute ";
935  msg += string(s_attr_name);
936  H5Gclose(s_root_id);
937  throw InternalErr(__FILE__, __LINE__, msg);
938  }
939 
940  hid_t attr_type = -1;
941  if ((attr_type = H5Aget_type(s_attr_id)) < 0) {
942  string msg = "cannot get the attribute datatype for the attribute ";
943  msg += string(s_attr_name);
944  H5Aclose(s_attr_id);
945  H5Gclose(s_root_id);
946  }
947 
948  hid_t attr_space = -1;
949  if ((attr_space = H5Aget_space(s_attr_id)) < 0) {
950  string msg = "cannot get the hdf5 dataspace id for the attribute ";
951  msg += string(s_attr_name);
952  H5Tclose(attr_type);
953  H5Aclose(s_attr_id);
954  H5Gclose(s_root_id);
955  throw InternalErr(__FILE__, __LINE__, msg);
956  }
957 
958  int num_elm = H5Sget_simple_extent_npoints(attr_space);
959  if (0 == num_elm) {
960  string msg = "cannot get the number for the attribute ";
961  msg += string(s_attr_name);
962  H5Tclose(attr_type);
963  H5Aclose(s_attr_id);
964  H5Sclose(attr_space);
965  H5Gclose(s_root_id);
966  throw InternalErr(__FILE__, __LINE__, msg);
967  }
968 
969  size_t atype_size = H5Tget_size(attr_type);
970  if (atype_size <= 0) {
971  string msg = "cannot obtain the datatype size of the attribute ";
972  msg += string(s_attr_name);
973  H5Tclose(attr_type);
974  H5Aclose(s_attr_id);
975  H5Sclose(attr_space);
976  H5Gclose(s_root_id);
977  throw InternalErr(__FILE__, __LINE__, msg);
978  }
979 
980  vector<char> temp_buf(atype_size*num_elm+1);
981  // cerr <<"attribute size "<<atype_size*num_elm <<endl;
982  if (H5Aread(s_attr_id,attr_type, &temp_buf[0])<0){
983  string msg = "cannot retrieve the value of the attribute ";
984  msg += string(s_attr_name);
985  H5Tclose(attr_type);
986  H5Aclose(s_attr_id);
987  H5Sclose(attr_space);
988  H5Gclose(s_root_id);
989  throw InternalErr(__FILE__, __LINE__, msg);
990 
991  }
992 
993  string temp_attr_value(temp_buf.begin(),temp_buf.end());
994  // cerr <<"size of temp_attr_value "<<temp_attr_value.size() <<endl;
995  size_t temp_null_pos = temp_attr_value.find_first_of('\0');
996  s_attr_value = temp_attr_value.substr(0,temp_null_pos);
997  //s_attr_value(temp_buf.begin(),temp_buf.end()-1);
998  H5Tclose(attr_type);
999  H5Sclose(attr_space);
1000  H5Aclose(s_attr_id);
1001 }
1002 
bool check_aquarius(hid_t s_root_id, int &s_level)
bool check_measure_ozone(hid_t s_root_id)
static class NCMLUtil overview
This file includes functions to identify different NASA HDF5 products. Current supported products inc...
H5GCFProduct
#define NULL
Definition: wcsUtil.h:65
bool check_gpm_l1(hid_t s_root_id)
bool check_gpms_l3(hid_t s_root_id)
void obtain_gm_attr_value(hid_t s_root_id, const char *s_attr_name, string &s_attr_value)
bool check_gpmm_l3(hid_t s_root_id)
bool check_obpg(hid_t s_root_id, int &s_level)
bool check_smap_acosl2s(hid_t s_root_id, int which_pro)
H5GCFProduct check_product(hid_t file_id)
bool check_measure_seawifs(hid_t s_root_id, int &s_lflag)