bes  Updated for version 3.20.8
HDF5GMCFMissLLArray.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-2016 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 #include "config_hdf5.h"
33 #include <iostream>
34 #include <sstream>
35 #include <cassert>
36 #include <BESDebug.h>
37 #include "InternalErr.h"
38 #include "HDF5RequestHandler.h"
39 
40 #include "HDF5GMCFMissLLArray.h"
41 
42 using namespace std;
43 using namespace libdap;
44 
45 BaseType *HDF5GMCFMissLLArray::ptr_duplicate()
46 {
47  return new HDF5GMCFMissLLArray(*this);
48 }
49 
50 bool HDF5GMCFMissLLArray::read()
51 {
52 
53  BESDEBUG("h5", "Coming to HDF5GMCFMissLLArray read "<<endl);
54 
55  if (NULL == HDF5RequestHandler::get_lrdata_mem_cache())
56  read_data_NOT_from_mem_cache(false, NULL);
57 
58  else {
59 
60  vector<string> cur_lrd_non_cache_dir_list;
61  HDF5RequestHandler::get_lrd_non_cache_dir_list(cur_lrd_non_cache_dir_list);
62 
63  string cache_key;
64 
65  // Check if this file is included in the non-cache directory
66  if ((cur_lrd_non_cache_dir_list.size() == 0)
67  || ("" == check_str_sect_in_list(cur_lrd_non_cache_dir_list, filename, '/'))) {
68  short cache_flag = 2;
69  vector<string> cur_cache_dlist;
70  HDF5RequestHandler::get_lrd_cache_dir_list(cur_cache_dlist);
71  string cache_dir = check_str_sect_in_list(cur_cache_dlist, filename, '/');
72  if (cache_dir != "") {
73  cache_flag = 3;
74  cache_key = cache_dir + varname;
75  }
76  else
77  cache_key = filename + varname;
78 
79  // Need to obtain the total number of elements.
80  // Obtain dimension size info.
81  vector<size_t> dim_sizes;
82  Dim_iter i_dim = dim_begin();
83  Dim_iter i_enddim = dim_end();
84  while (i_dim != i_enddim) {
85  dim_sizes.push_back(dimension_size(i_dim));
86  ++i_dim;
87  }
88 
89  size_t total_elems = 1;
90  for (unsigned int i = 0; i < dim_sizes.size(); i++)
91  total_elems = total_elems * dim_sizes[i];
92 
93  handle_data_with_mem_cache(dtype, total_elems, cache_flag, cache_key);
94  }
95  else
96  read_data_NOT_from_mem_cache(false, NULL);
97  }
98  return true;
99 }
100 
101 // Obtain latitude and longitude for Aquarius and OBPG level 3 products
102 void HDF5GMCFMissLLArray::obtain_aqu_obpg_l3_ll(int* offset, int* step, int nelms, bool add_cache, void* buf)
103 {
104 
105  BESDEBUG("h5", "Coming to obtain_aqu_obpg_l3_ll read "<<endl);
106 
107  // Read File attributes
108  // Latitude Step, SW Point Latitude, Number of Lines
109  // Longitude Step, SW Point Longitude, Number of Columns
110  if (1 != rank)
111  throw InternalErr(__FILE__, __LINE__, "The number of dimension for Aquarius Level 3 map data must be 1");
112 
113  bool check_pass_fileid_key = HDF5RequestHandler::get_pass_fileid();
114  if (false == check_pass_fileid_key) {
115  if ((fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) {
116  ostringstream eherr;
117  eherr << "HDF5 File " << filename << " cannot be opened. " << endl;
118  throw InternalErr(__FILE__, __LINE__, eherr.str());
119  }
120  }
121 
122  hid_t rootid = -1;
123  if ((rootid = H5Gopen(fileid, "/", H5P_DEFAULT)) < 0) {
124  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
125  ostringstream eherr;
126  eherr << "HDF5 dataset " << varname << " cannot be opened. " << endl;
127  throw InternalErr(__FILE__, __LINE__, eherr.str());
128  }
129 
130  float LL_first_point = 0.0;
131  float LL_step = 0.0;
132  int LL_total_num = 0;
133 
134  if (CV_LAT_MISS == cvartype) {
135  string Lat_SWP_name = (Aqu_L3 == product_type) ? "SW Point Latitude" : "sw_point_latitude";
136  string Lat_step_name = (Aqu_L3 == product_type) ? "Latitude Step" : "latitude_step";
137  string Num_lines_name = (Aqu_L3 == product_type) ? "Number of Lines" : "number_of_lines";
138  float Lat_SWP = 0.0;
139  float Lat_step = 0.0;
140  int Num_lines = 0;
141  vector<char> dummy_str;
142 
143  obtain_ll_attr_value(fileid, rootid, Lat_SWP_name, Lat_SWP, dummy_str);
144  obtain_ll_attr_value(fileid, rootid, Lat_step_name, Lat_step, dummy_str);
145  obtain_ll_attr_value(fileid, rootid, Num_lines_name, Num_lines, dummy_str);
146  if (Num_lines <= 0) {
147  H5Gclose(rootid);
148  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
149  throw InternalErr(__FILE__, __LINE__, "The number of line must be >0");
150  }
151 
152  // The first number of the latitude is at the north west corner
153  LL_first_point = (float)(Lat_SWP + (Num_lines - 1) * Lat_step);
154  LL_step = (float)(Lat_step * (-1.0));
155  LL_total_num = Num_lines;
156  }
157 
158  if (CV_LON_MISS == cvartype) {
159 
160  string Lon_SWP_name = (Aqu_L3 == product_type) ? "SW Point Longitude" : "sw_point_longitude";
161  string Lon_step_name = (Aqu_L3 == product_type) ? "Longitude Step" : "longitude_step";
162  string Num_columns_name = (Aqu_L3 == product_type) ? "Number of Columns" : "number_of_columns";
163  float Lon_SWP = 0.0;
164  float Lon_step = 0.0;
165  int Num_cols = 0;
166 
167  vector<char> dummy_str_value;
168 
169  obtain_ll_attr_value(fileid, rootid, Lon_SWP_name, Lon_SWP, dummy_str_value);
170  obtain_ll_attr_value(fileid, rootid, Lon_step_name, Lon_step, dummy_str_value);
171  obtain_ll_attr_value(fileid, rootid, Num_columns_name, Num_cols, dummy_str_value);
172  if (Num_cols <= 0) {
173  H5Gclose(rootid);
174  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
175  throw InternalErr(__FILE__, __LINE__, "The number of line must be >0");
176  }
177 
178  // The first number of the latitude is at the north west corner
179  LL_first_point = Lon_SWP;
180  LL_step = Lon_step;
181  LL_total_num = Num_cols;
182  }
183 
184  vector<float> val;
185  val.resize(nelms);
186 
187  if (nelms > LL_total_num) {
188  H5Gclose(rootid);
189  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
190  throw InternalErr(__FILE__, __LINE__,
191  "The number of elements exceeds the total number of Latitude or Longitude");
192  }
193 
194  for (int i = 0; i < nelms; ++i)
195  val[i] = LL_first_point + (offset[0] + i * step[0]) * LL_step;
196 
197  if (true == add_cache) {
198  vector<float> total_val;
199  total_val.resize(LL_total_num);
200  for (int total_i = 0; total_i < LL_total_num; total_i++)
201  total_val[total_i] = LL_first_point + total_i * LL_step;
202  memcpy(buf, &total_val[0], 4 * LL_total_num);
203  }
204 
205  set_value((dods_float32 *) &val[0], nelms);
206  H5Gclose(rootid);
207  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
208 }
209 
210 // Obtain lat/lon for GPM level 3 products
211 void HDF5GMCFMissLLArray::obtain_gpm_l3_ll(int* offset, int* step, int nelms, bool add_cache, void*buf)
212 {
213 
214  if (1 != rank)
215  throw InternalErr(__FILE__, __LINE__, "The number of dimension for Aquarius Level 3 map data must be 1");
216 
217  bool check_pass_fileid_key = HDF5RequestHandler::get_pass_fileid();
218 
219  if (false == check_pass_fileid_key) {
220  if ((fileid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) {
221  ostringstream eherr;
222  eherr << "HDF5 File " << filename << " cannot be opened. " << endl;
223  throw InternalErr(__FILE__, __LINE__, eherr.str());
224  }
225  }
226 
227  vector<char> grid_info_value;
228  float lat_start = 0;
229  float lon_start = 0.;
230  float lat_res = 0.;
231  float lon_res = 0.;
232 
233  int latsize = 0;
234  int lonsize = 0;
235 
236 
237 if(GPMM_L3 == product_type || GPMS_L3 == product_type) {
238  hid_t grid_grp_id = -1;
239 
240  string grid_grp_name;
241 
242  if ((name() == "nlat") || (name() == "nlon")) {
243 
244  string temp_grid_grp_name(GPM_GRID_GROUP_NAME1, strlen(GPM_GRID_GROUP_NAME1));
245  temp_grid_grp_name = "/" + temp_grid_grp_name;
246  if (H5Lexists(fileid, temp_grid_grp_name.c_str(), H5P_DEFAULT) > 0)
247  grid_grp_name = temp_grid_grp_name;
248  else {
249  string temp_grid_grp_name2(GPM_GRID_GROUP_NAME2, strlen(GPM_GRID_GROUP_NAME2));
250  temp_grid_grp_name2 = "/" + temp_grid_grp_name2;
251  if (H5Lexists(fileid, temp_grid_grp_name2.c_str(), H5P_DEFAULT) > 0)
252  grid_grp_name = temp_grid_grp_name2;
253  else
254  throw InternalErr(__FILE__, __LINE__, "Unknown GPM grid group name ");
255 
256  }
257  }
258 
259  else {
260  string temp_grids_group_name(GPM_GRID_MULTI_GROUP_NAME, strlen(GPM_GRID_MULTI_GROUP_NAME));
261  if (name() == "lnH" || name() == "ltH")
262  grid_grp_name = temp_grids_group_name + "/G2";
263  else if (name() == "lnL" || name() == "ltL") grid_grp_name = temp_grids_group_name + "/G1";
264  }
265 // varname is supposed to include the full path. However, it takes too much effort to obtain the full path
266 // for a created coordiate variable based on the dimension name only. Since GPM has a fixed group G1
267 // for lnL and ltL and another fixed group G2 for lnH and ltH. We just use these names. These information
268 // is from GPM file specification.
269 #if 0
270  if(name() == "lnH" || name() == "ltH" ||
271  name() == "lnL" || name() == "ltL") {
272  string temp_grids_group_name(GPM_GRID_MULTI_GROUP_NAME,strlen(GPM_GRID_MULTI_GROUP_NAME));
273 
274 //cerr<<"varname is "<<varname <<endl;
275  size_t grids_group_pos = varname.find(temp_grids_group_name);
276  if(string::npos == grids_group_pos) {
277  throw InternalErr (__FILE__, __LINE__,
278  "Cannot find group Grids.");
279  }
280 
281  string grids_cgroup_path = varname.substr(grids_group_pos+1);
282  size_t grids_cgroup_pos = varname.find_first_of("/");
283  if(string::npos == grids_cgroup_pos) {
284  throw InternalErr (__FILE__, __LINE__,
285  "Cannot find child group of group Grids.");
286  }
287 
288  string temp_sub_grp_name = grids_cgroup_path.substr(0,grids_cgroup_pos);
289  if(name() == "lnH" || name() == "ltH")
290  sub_grp1_name = temp_sub_grp_name;
291  else if(name() == "lnL" || name() == "ltL")
292  sub_grp2_name = temp_sub_grp_name;
293 
294  grid_grp_name = temp_grids_group_name + "/" + temp_sub_grp_name;
295 
296  }
297 #endif
298 
299 
300  if ((grid_grp_id = H5Gopen(fileid, grid_grp_name.c_str(), H5P_DEFAULT)) < 0) {
301  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
302  ostringstream eherr;
303  eherr << "HDF5 dataset " << varname << " cannot be opened. " << endl;
304  throw InternalErr(__FILE__, __LINE__, eherr.str());
305  }
306 
307  // GPMDPR: update grid_info_name.
308  string grid_info_name(GPM_ATTR2_NAME, strlen(GPM_ATTR2_NAME));
309  if (name() == "lnL" || name() == "ltL")
310  grid_info_name = "G1_" + grid_info_name;
311  else if (name() == "lnH" || name() == "ltH") grid_info_name = "G2_" + grid_info_name;
312 
313  float dummy_value = 0.0;
314  try {
315  obtain_ll_attr_value(fileid, grid_grp_id, grid_info_name, dummy_value, grid_info_value);
316  HDF5CFUtil::parser_gpm_l3_gridheader(grid_info_value, latsize, lonsize, lat_start, lon_start, lat_res, lon_res,
317  false);
318 
319  H5Gclose(grid_grp_id);
320  }
321  catch (...) {
322  H5Gclose(grid_grp_id);
323  H5Fclose(fileid);
324  throw;
325 
326  }
327 
328 
329 }
330  else {
331  vector<char> grid_info_value1;
332  vector<char> grid_info_value2;
333  obtain_gpm_l3_new_grid_info(fileid,grid_info_value1,grid_info_value2);
334  obtain_lat_lon_info(grid_info_value1,grid_info_value2,latsize,lonsize,lat_start,lon_start,lat_res,lon_res);
335  }
336 
337  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
338 
339  try {
340  send_gpm_l3_ll_to_dap(latsize,lonsize,lat_start,lon_start,lat_res,lon_res,offset,step,nelms,add_cache, buf);
341  }
342  catch (...) {
343  throw;
344  }
345 #if 0
346  float lat_start = 0;
347  float lon_start = 0.;
348  float lat_res = 0.;
349  float lon_res = 0.;
350 
351  int latsize = 0;
352  int lonsize = 0;
353 
354  HDF5CFUtil::parser_gpm_l3_gridheader(grid_info_value, latsize, lonsize, lat_start, lon_start, lat_res, lon_res,
355  false);
356 
357  if (0 == latsize || 0 == lonsize) {
358  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
359  throw InternalErr(__FILE__, __LINE__, "Either latitude or longitude size is 0. ");
360  }
361 
362  vector<float> val;
363  val.resize(nelms);
364 
365  if (CV_LAT_MISS == cvartype) {
366 
367  if (nelms > latsize) {
368  H5Gclose(grid_grp_id);
369  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
370  throw InternalErr(__FILE__, __LINE__, "The number of elements exceeds the total number of Latitude ");
371 
372  }
373  for (int i = 0; i < nelms; ++i)
374  val[i] = lat_start + offset[0] * lat_res + lat_res / 2 + i * lat_res * step[0];
375 
376  if (add_cache == true) {
377  vector<float> total_val;
378  total_val.resize(latsize);
379  for (int total_i = 0; total_i < latsize; total_i++)
380  total_val[total_i] = lat_start + lat_res / 2 + total_i * lat_res;
381  memcpy(buf, &total_val[0], 4 * latsize);
382  }
383  }
384  else if (CV_LON_MISS == cvartype) {
385 
386  if (nelms > lonsize) {
387  H5Gclose(grid_grp_id);
388  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
389  throw InternalErr(__FILE__, __LINE__, "The number of elements exceeds the total number of Longitude");
390 
391  }
392 
393  for (int i = 0; i < nelms; ++i)
394  val[i] = lon_start + offset[0] * lon_res + lon_res / 2 + i * lon_res * step[0];
395 
396  if (add_cache == true) {
397  vector<float> total_val;
398  total_val.resize(lonsize);
399  for (int total_i = 0; total_i < lonsize; total_i++)
400  total_val[total_i] = lon_start + lon_res / 2 + total_i * lon_res;
401  memcpy(buf, &total_val[0], 4 * lonsize);
402  }
403 
404  }
405 
406  set_value((dods_float32 *) &val[0], nelms);
407 
408  H5Gclose(grid_grp_id);
409  HDF5CFUtil::close_fileid(fileid, check_pass_fileid_key);
410 #endif
411 
412 #if 0
413 
414  vector<float>val;
415  val.resize(nelms);
416 
417  if (nelms > LL_total_num) {
418  H5Gclose(rootid);
419  //H5Fclose(fileid);
420  throw InternalErr (__FILE__, __LINE__,
421  "The number of elements exceeds the total number of Latitude or Longitude");
422  }
423 
424  for (int i = 0; i < nelms; ++i)
425  val[i] = LL_first_point + (offset[0] + i*step[0])*LL_step;
426 
427  set_value ((dods_float32 *) &val[0], nelms);
428  H5Gclose(rootid);
429  //H5Fclose(fileid);
430 #endif
431 
432 }
433 
434 
435 // Obtain latitude/longitude attribute values
436 //template<class T>
437 template<typename T>
438 void HDF5GMCFMissLLArray::obtain_ll_attr_value(hid_t /*file_id*/, hid_t s_root_id, const string & s_attr_name,
439  T& attr_value, vector<char> & str_attr_value)
440 {
441 
442  BESDEBUG("h5", "Coming to obtain_ll_attr_value"<<endl);
443  hid_t s_attr_id = -1;
444  if ((s_attr_id = H5Aopen_by_name(s_root_id, ".", s_attr_name.c_str(),
445  H5P_DEFAULT, H5P_DEFAULT)) < 0) {
446  string msg = "Cannot open the HDF5 attribute ";
447  msg += s_attr_name;
448  H5Gclose(s_root_id);
449  throw InternalErr(__FILE__, __LINE__, msg);
450  }
451 
452  hid_t attr_type = -1;
453  if ((attr_type = H5Aget_type(s_attr_id)) < 0) {
454  string msg = "cannot get the attribute datatype for the attribute ";
455  msg += s_attr_name;
456  H5Aclose(s_attr_id);
457  H5Gclose(s_root_id);
458  throw InternalErr(__FILE__, __LINE__, msg);
459  }
460 
461  hid_t attr_space = -1;
462  if ((attr_space = H5Aget_space(s_attr_id)) < 0) {
463  string msg = "cannot get the hdf5 dataspace id for the attribute ";
464  msg += s_attr_name;
465  H5Tclose(attr_type);
466  H5Aclose(s_attr_id);
467  H5Gclose(s_root_id);
468  throw InternalErr(__FILE__, __LINE__, msg);
469  }
470 
471  hssize_t num_elm = H5Sget_simple_extent_npoints(attr_space);
472 
473  if (0 == num_elm) {
474  string msg = "cannot get the number for the attribute ";
475  msg += s_attr_name;
476  H5Tclose(attr_type);
477  H5Aclose(s_attr_id);
478  H5Sclose(attr_space);
479  H5Gclose(s_root_id);
480  throw InternalErr(__FILE__, __LINE__, msg);
481  }
482 
483  if (1 != num_elm) {
484  string msg = "The number of attribute must be 1 for Aquarius level 3 data ";
485  msg += s_attr_name;
486  H5Tclose(attr_type);
487  H5Aclose(s_attr_id);
488  H5Sclose(attr_space);
489  H5Gclose(s_root_id);
490  throw InternalErr(__FILE__, __LINE__, msg);
491  }
492 
493  size_t atype_size = H5Tget_size(attr_type);
494  if (atype_size <= 0) {
495  string msg = "cannot obtain the datatype size of the attribute ";
496  msg += s_attr_name;
497  H5Tclose(attr_type);
498  H5Aclose(s_attr_id);
499  H5Sclose(attr_space);
500  H5Gclose(s_root_id);
501  throw InternalErr(__FILE__, __LINE__, msg);
502  }
503 
504  if (H5T_STRING == H5Tget_class(attr_type)) {
505  if (H5Tis_variable_str(attr_type)) {
506  H5Tclose(attr_type);
507  H5Aclose(s_attr_id);
508  H5Sclose(attr_space);
509  H5Gclose(s_root_id);
510  throw InternalErr(__FILE__, __LINE__,
511  "Currently we assume the attributes we use to retrieve lat and lon are NOT variable length string.");
512  }
513  else {
514  str_attr_value.resize(atype_size);
515  if (H5Aread(s_attr_id, attr_type, &str_attr_value[0]) < 0) {
516  string msg = "cannot retrieve the value of the attribute ";
517  msg += s_attr_name;
518  H5Tclose(attr_type);
519  H5Aclose(s_attr_id);
520  H5Sclose(attr_space);
521  H5Gclose(s_root_id);
522  throw InternalErr(__FILE__, __LINE__, msg);
523 
524  }
525  }
526  }
527 
528  else if (H5Aread(s_attr_id, attr_type, &attr_value) < 0) {
529  string msg = "cannot retrieve the value of the attribute ";
530  msg += s_attr_name;
531  H5Tclose(attr_type);
532  H5Aclose(s_attr_id);
533  H5Sclose(attr_space);
534  H5Gclose(s_root_id);
535  throw InternalErr(__FILE__, __LINE__, msg);
536 
537  }
538 
539  H5Tclose(attr_type);
540  H5Sclose(attr_space);
541  H5Aclose(s_attr_id);
542 }
543 
544 void HDF5GMCFMissLLArray::obtain_gpm_l3_new_grid_info(hid_t file,vector<char>& grid_info_value1, vector<char>& grid_info_value2){
545 
546  typedef struct {
547  char* name;
548  char* value;
549  } attr_info_t;
550 
551  attr_info_t attr_na;
552  attr_na.name = NULL;
553  attr_na.value = NULL;
554 
555  herr_t ret_o= H5Ovisit(file, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, (void*)&attr_na);
556  //herr_t ret_o= H5Ovisit3(file, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, (void*)&attr_na,H5O_INFO_BASIC);
557  //
558  if(ret_o < 0){
559  H5Fclose(file);
560  throw InternalErr(__FILE__, __LINE__, "H5Ovisit failed. ");
561  }
562  else if(ret_o >0) {
563  //printf("Found the attribute.\n");
564  BESDEBUG("h5","Found the GPM level 3 Grid_info attribute."<<endl);
565  //string grid_info_name_1(attr_na.name);
566  //string grid_info_name_2;
567 
568  //string grid_info_value_1(attr_na.value);
569 
570 #if 0
571  vector<char> grid_info_value_1(attr_na.value,attr_na.value+strlen(attr_na.value));
572  vector<char> grid_info_value_2;
573 #endif
574  //grid_info_value1(attr_na.value,attr_na.value+strlen(attr_na.value));
575  grid_info_value1.resize(strlen(attr_na.value));
576  memcpy(&grid_info_value1[0],attr_na.value,strlen(attr_na.value));
577 string tv(grid_info_value1.begin(),grid_info_value1.end());
578 //cerr<<"grid_info_value1 is "<<tv <<endl;
579 #if 0
580  printf("attr_name 1st is %s\n",attr_na.name);
581  printf("attr_value 1st is %s\n",attr_na.value);
582 #endif
583  herr_t ret_o2= H5Ovisit(file, H5_INDEX_NAME, H5_ITER_INC, visit_obj_cb, (void*)&attr_na);
584 
585  if(ret_o2 < 0) {
586  H5Fclose(file);
587  throw InternalErr(__FILE__, __LINE__, "H5Ovisit failed again. ");
588  }
589  else if(ret_o2>0) {
590 
591  if(attr_na.name) {
592  //printf("attr_name second is %s\n",attr_na.name);
593  free(attr_na.name);
594  }
595  if(attr_na.value) {
596  //printf("attr_value second is %s\n",attr_na.value);
597  //grid_info_value2(attr_na.value,attr_na.value+strlen(attr_na.value));
598  grid_info_value2.resize(strlen(attr_na.value));
599  memcpy(&grid_info_value2[0],attr_na.value,strlen(attr_na.value));
600 string tv(grid_info_value2.begin(),grid_info_value2.end());
601 //cerr<<"grid_info_value2 is "<<tv <<endl;
602  free(attr_na.value);
603  }
604  }
605  }
606 
607 
608 }
609 void HDF5GMCFMissLLArray::obtain_lat_lon_info(const vector<char>& grid_info_value1,
610  const vector<char>& grid_info_value2,
611  int& latsize,int& lonsize,
612  float& lat_start,float& lon_start,
613  float& lat_res,float& lon_res){
614 
615  float lat1_start = 0;
616  float lon1_start = 0.;
617  float lat1_res = 0.;
618  float lon1_res = 0.;
619  int lat1size = 0;
620  int lon1size = 0;
621 
622  float lat2_start = 0;
623  float lon2_start = 0.;
624  float lat2_res = 0.;
625  float lon2_res = 0.;
626  int lat2size = 0;
627  int lon2size = 0;
628 
629  HDF5CFUtil::parser_gpm_l3_gridheader(grid_info_value1, lat1size, lon1size, lat1_start, lon1_start,
630  lat1_res, lon1_res,false);
631 
632  HDF5CFUtil::parser_gpm_l3_gridheader(grid_info_value2, lat2size, lon2size, lat2_start, lon2_start,
633  lat2_res, lon2_res,false);
634 
635  bool pick_gv1 = true;
636  if (name() == "lnL" || name() == "ltL") {
637  if(lat1_res <lat2_res)
638  pick_gv1 = false;
639  }
640  else if (name() == "lnH" || name() == "ltH") {
641  if(lat1_res >lat2_res)
642  pick_gv1 = false;
643  }
644 
645  if(true == pick_gv1) {
646 
647  latsize = lat1size;
648  lonsize = lon1size;
649  lat_start = lat1_start;
650  lon_start = lon1_start;
651  lat_res = lat1_res;
652  lon_res = lon1_res;
653 
654  }
655  else {
656  latsize = lat2size;
657  lonsize = lon2size;
658  lat_start = lat2_start;
659  lon_start = lon2_start;
660  lat_res = lat2_res;
661  lon_res = lon2_res;
662 
663  }
664 
665 }
666 /*
667  * Operator function.
668  */
669 static herr_t
670 attr_info(hid_t loc_id, const char *name, const H5A_info_t *ainfo, void *_op_data)
671 {
672 
673  typedef struct {
674  char* name;
675  char* value;
676  } attr_info_t;
677 
678  /* avoid warnings */
679  herr_t ret = 0;
680  attr_info_t *op_data = (attr_info_t *)_op_data;
681  //printf("attribute name is %s\n",name);
682  if(strstr(name,GPM_ATTR2_NAME)!=NULL) {
683  //if(strstr(name,"GridHeader")!=NULL) {
684 
685  hid_t attr, atype, aspace; /* Attribute, datatype and dataspace identifiers */
686  attr = H5Aopen(loc_id, name, H5P_DEFAULT);
687  if(attr<0)
688  return -1;
689  //printf("attribute cannot be opened\n");
690  atype = H5Aget_type(attr);
691  if(atype <0)
692  return -1;
693  //printf("attribute type cannot be retrieved");
694  if(H5T_STRING == H5Tget_class(atype)){
695  if(op_data->name) {
696  //obtain_attr_value(attr,atype,(void*)&op_data->value);
697  if(strncmp(name,op_data->name,strlen(name))!=0) {
698  hid_t aspace = H5Aget_space(attr);
699  hsize_t num_elms = H5Tget_size(atype)*H5Sget_simple_extent_npoints(aspace);
700 #if 0
701  char *attr_value = op_data->value;
702  attr_value = malloc(num_elms+1);
703  H5Aread(attr,atype,attr_value);
704  printf("attr_value is %s\n",attr_value);
705 #endif
706  //*((char *)value) = (char*) malloc(num_elms+1);
707  char *cur_attr_value = (char*)malloc(num_elms+1);
708  H5Aread(attr,atype,(void*)cur_attr_value);
709  if(strncmp(cur_attr_value,op_data->value,strlen(op_data->value))!=0) {
710 
711  free(op_data->name);
712  op_data->name = NULL;
713  op_data->name = (char*)malloc(strlen(name)+1);
714  //attr_name = malloc(strlen(name)+1);
715  strncpy(op_data->name,name,strlen(name));
716  // Get the new attribute value,
717  if(op_data->value)
718  free(op_data->value);
719  op_data->value = NULL;
720  op_data->value=(char*)malloc(num_elms+1);
721  //printf("attr value is %s\n",cur_attr_value);
722  strncpy(op_data->value,cur_attr_value,strlen(cur_attr_value));
723  //printf("op_data attr value is %s\n",op_data->value);
724 
725  ret = 1;
726  }
727  free(cur_attr_value);
728  H5Sclose(aspace);
729  }
730  }
731  else {
732  op_data->name = (char*)malloc(strlen(name)+1);
733  //attr_name = malloc(strlen(name)+1);
734  strncpy(op_data->name,name,strlen(name));
735  //obtain_attr_value(attr,atype,(void*)&op_data->value);
736  hid_t aspace = H5Aget_space(attr);
737  hsize_t num_elms = H5Tget_size(atype)*H5Sget_simple_extent_npoints(aspace);
738 #if 0
739  char *attr_value = op_data->value;
740  attr_value = malloc(num_elms+1);
741  H5Aread(attr,atype,attr_value);
742  printf("attr_value is %s\n",attr_value);
743 #endif
744  //*((char *)value) = (char*) malloc(num_elms+1);
745  op_data->value = (char*)malloc(num_elms+1);
746  H5Aread(attr,atype,(void*)op_data->value);
747  H5Sclose(aspace);
748  ret =1;
749 
750  }
751 
752  //printf("Selected attribute name is %s\n",name);
753  }
754  H5Tclose(atype);
755  H5Aclose(attr);
756  }
757  return ret;
758 #if 0
759  attr = H5Aopen(loc_id, name, H5P_DEFAULT);
760 
761  /*
762  * Display attribute name.
763  */
764  printf("\nName : %s\n", name);
765 
766  /*
767  * Get attribute datatype, dataspace, rank, and dimensions.
768  */
769  atype = H5Aget_type(attr);
770  aspace = H5Aget_space(attr);
771  rank = H5Sget_simple_extent_ndims(aspace);
772  ret = H5Sget_simple_extent_dims(aspace, sdim, NULL);
773 
774  /*
775  * Display rank and dimension sizes for the array attribute.
776  */
777 
778  if(rank > 0) {
779  printf("Rank : %d \n", rank);
780  printf("Dimension sizes : ");
781  for (i=0; i< rank; i++)
782  printf("%d ", (int)sdim[i]);
783  printf("\n");
784  }
785 
786  /*
787  * Read array attribute and display its type and values.
788  */
789 
790  if (H5T_FLOAT == H5Tget_class(atype)) {
791  printf("Type : FLOAT \n");
792  npoints = H5Sget_simple_extent_npoints(aspace);
793  float_array = (float *)malloc(sizeof(float)*(int)npoints);
794  ret = H5Aread(attr, atype, float_array);
795  printf("Values : ");
796  for( i = 0; i < (int)npoints; i++)
797  printf("%f ", float_array[i]);
798  printf("\n");
799  free(float_array);
800  }
801 
802  /*
803  * Release all identifiers.
804  */
805  H5Tclose(atype);
806  H5Sclose(aspace);
807  H5Aclose(attr);
808 #endif
809 
810 }
811 
812 
813 static int
814 visit_obj_cb(hid_t group_id, const char *name, const H5O_info_t *oinfo,
815  void *_op_data)
816 {
817  typedef struct {
818  char* name;
819  char* value;
820  } attr_info_t;
821 
822 
823  //lvisit_ud_t *op_data = (lvisit_ud_t *)_op_data;
824  attr_info_t *op_data = (attr_info_t *)_op_data;
825  herr_t ret = 0;
826 
827  if(oinfo->type == H5O_TYPE_GROUP) {
828 
829  hid_t grp = -1;
830  grp = H5Gopen2(group_id,name,H5P_DEFAULT);
831 
832  //printf("link name is %s\n",name);
833  ret = H5Aiterate2(grp, H5_INDEX_NAME, H5_ITER_INC, NULL, attr_info, op_data);
834 #if 0
835  if(ret > 0) {
836  printf("object: attr name is %s\n",op_data->name);
837  printf("object: attr value is %s\n",op_data->value);
838  }
839 #endif
840  if(ret <0)
841  return -1;
842  //printf("H5Aiterate2 failed\n");
843  H5Gclose(grp);
844  }
845  return ret;
846 
847 }
848 
849 
850 
851 #if 0
852 void HDF5GMCFMissLLArray::send_gpm_l3_ll_to_dap(const vector<char>& grid_info_value,int* offset,int* step,
853  int nelms,bool add_cache, void*buf) {
854 
855  float lat_start = 0;
856  float lon_start = 0.;
857  float lat_res = 0.;
858  float lon_res = 0.;
859 
860  int latsize = 0;
861  int lonsize = 0;
862 #endif
863 
864 void HDF5GMCFMissLLArray::send_gpm_l3_ll_to_dap(const int latsize,const int lonsize,const float lat_start,const float lon_start,
865  const float lat_res,const float lon_res, const int* offset,const int* step,
866  const int nelms,const bool add_cache, void*buf) {
867 
868 
869  if (0 == latsize || 0 == lonsize) {
870  throw InternalErr(__FILE__, __LINE__, "Either latitude or longitude size is 0. ");
871  }
872 
873  vector<float> val;
874  val.resize(nelms);
875 
876  if (CV_LAT_MISS == cvartype) {
877 
878  if (nelms > latsize) {
879  throw InternalErr(__FILE__, __LINE__, "The number of elements exceeds the total number of Latitude ");
880 
881  }
882  for (int i = 0; i < nelms; ++i)
883  val[i] = lat_start + offset[0] * lat_res + lat_res / 2 + i * lat_res * step[0];
884 
885  if (add_cache == true) {
886  vector<float> total_val;
887  total_val.resize(latsize);
888  for (int total_i = 0; total_i < latsize; total_i++)
889  total_val[total_i] = lat_start + lat_res / 2 + total_i * lat_res;
890  memcpy(buf, &total_val[0], 4 * latsize);
891  }
892  }
893  else if (CV_LON_MISS == cvartype) {
894 //cerr<<"nelms is "<<nelms <<endl;
895 //cerr<<"lonsize is "<<lonsize <<endl;
896  if (nelms > lonsize) {
897  throw InternalErr(__FILE__, __LINE__, "The number of elements exceeds the total number of Longitude");
898  }
899 
900  for (int i = 0; i < nelms; ++i)
901  val[i] = lon_start + offset[0] * lon_res + lon_res / 2 + i * lon_res * step[0];
902 
903  if (add_cache == true) {
904  vector<float> total_val;
905  total_val.resize(lonsize);
906  for (int total_i = 0; total_i < lonsize; total_i++)
907  total_val[total_i] = lon_start + lon_res / 2 + total_i * lon_res;
908  memcpy(buf, &total_val[0], 4 * lonsize);
909  }
910 
911  }
912 
913  set_value((dods_float32 *) &val[0], nelms);
914 
915 }
916 
917 void HDF5GMCFMissLLArray::read_data_NOT_from_mem_cache(bool add_cache, void*buf)
918 {
919 
920  BESDEBUG("h5", "Coming to HDF5GMCFMissLLArray: read_data_NOT_from_mem_cache "<<endl);
921 
922  // Here we still use vector just in case we need to tackle "rank>1" in the future.
923  // Also we would like to keep it consistent with other similar handlings.
924  vector<int> offset;
925  vector<int> count;
926  vector<int> step;
927 
928  offset.resize(rank);
929  count.resize(rank);
930  step.resize(rank);
931 
932  int nelms = format_constraint(&offset[0], &step[0], &count[0]);
933 
934  if (GPMM_L3 == product_type || GPMS_L3 == product_type || GPM_L3_New == product_type)
935  obtain_gpm_l3_ll(&offset[0], &step[0], nelms, add_cache, buf);
936  else if (Aqu_L3 == product_type || OBPG_L3 == product_type) // Aquarious level 3
937  obtain_aqu_obpg_l3_ll(&offset[0], &step[0], nelms, add_cache, buf);
938 
939  return;
940 
941 }
942 
This class specifies the retrieval of the missing lat/lon values for general HDF5 products.
include the entry functions to execute the handlers