bes  Updated for version 3.20.6
HDF5GMSPCFArray.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 
33 #include "config_hdf5.h"
34 #include <iostream>
35 #include <sstream>
36 #include <cassert>
37 #include <BESDebug.h>
38 #include "InternalErr.h"
39 
40 #include "HDF5RequestHandler.h"
41 #include "HDF5GMSPCFArray.h"
42 
43 using namespace std;
44 using namespace libdap;
45 
46 BaseType *HDF5GMSPCFArray::ptr_duplicate()
47 {
48  return new HDF5GMSPCFArray(*this);
49 }
50 
51 bool HDF5GMSPCFArray::read()
52 {
53  BESDEBUG("h5","Coming to HDF5GMSPCFArray read "<<endl);
54  if(length() == 0)
55  return true;
56 
57  read_data_NOT_from_mem_cache(false,NULL);
58 
59  return true;
60 }
61 
62 void HDF5GMSPCFArray::read_data_NOT_from_mem_cache(bool /*add_cache*/,void*/*buf*/) {
63 
64  BESDEBUG("h5","Coming to HDF5GMSPCFArray: read_data_NOT_from_mem_cache "<<endl);
65 
66  bool check_pass_fileid_key = HDF5RequestHandler::get_pass_fileid();
67 
68  vector<int>offset;
69  vector<int>count;
70  vector<int>step;
71  vector<hsize_t>hoffset;
72  vector<hsize_t>hcount;
73  vector<hsize_t>hstep;
74 
75  int nelms = 0;
76 
77  if((otype != H5INT64 && otype !=H5UINT64)
78  || (dtype !=H5INT32))
79  throw InternalErr (__FILE__, __LINE__,
80  "The datatype of the special product is not right.");
81 
82  if (rank <= 0)
83  throw InternalErr (__FILE__, __LINE__,
84  "The number of dimension of the variable is <=0 for this array.");
85  else {
86 
87  offset.resize(rank);
88  count.resize(rank);
89  step.resize(rank);
90  hoffset.resize(rank);
91  hcount.resize(rank);
92  hstep.resize(rank);
93 
94 
95  nelms = format_constraint (&offset[0], &step[0], &count[0]);
96 
97  for (int i = 0; i <rank; i++) {
98  hoffset[i] = (hsize_t) offset[i];
99  hcount[i] = (hsize_t) count[i];
100  hstep[i] = (hsize_t) step[i];
101  }
102  }
103 
104  hid_t dsetid = -1;
105  hid_t dspace = -1;
106  hid_t mspace = -1;
107  hid_t dtypeid = -1;
108  hid_t memtype = -1;
109 
110  if(false == check_pass_fileid_key) {
111  if ((fileid = H5Fopen(filename.c_str(),H5F_ACC_RDONLY,H5P_DEFAULT))<0) {
112  ostringstream eherr;
113  eherr << "HDF5 File " << filename
114  << " cannot be opened. "<<endl;
115  throw InternalErr (__FILE__, __LINE__, eherr.str ());
116  }
117  }
118 
119  if ((dsetid = H5Dopen(fileid,varname.c_str(),H5P_DEFAULT))<0) {
120 
121  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
122  ostringstream eherr;
123  eherr << "HDF5 dataset " << varname
124  << " cannot be opened. "<<endl;
125  throw InternalErr (__FILE__, __LINE__, eherr.str ());
126  }
127 
128  if ((dspace = H5Dget_space(dsetid))<0) {
129 
130  H5Dclose(dsetid);
131  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
132  ostringstream eherr;
133  eherr << "Space id of the HDF5 dataset " << varname
134  << " cannot be obtained. "<<endl;
135  throw InternalErr (__FILE__, __LINE__, eherr.str ());
136  }
137 
138 
139  if (H5Sselect_hyperslab(dspace, H5S_SELECT_SET,
140  &hoffset[0], &hstep[0],
141  &hcount[0], NULL) < 0) {
142 
143  H5Sclose(dspace);
144  H5Dclose(dsetid);
145  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
146  ostringstream eherr;
147  eherr << "The selection of hyperslab of the HDF5 dataset " << varname
148  << " fails. "<<endl;
149  throw InternalErr (__FILE__, __LINE__, eherr.str ());
150  }
151 
152  mspace = H5Screate_simple(rank, (const hsize_t*)&hcount[0],NULL);
153  if (mspace < 0) {
154  H5Sclose(dspace);
155  H5Dclose(dsetid);
156  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
157  ostringstream eherr;
158  eherr << "The creation of the memory space of the HDF5 dataset " << varname
159  << " fails. "<<endl;
160  throw InternalErr (__FILE__, __LINE__, eherr.str ());
161  }
162 
163 
164  if ((dtypeid = H5Dget_type(dsetid)) < 0) {
165  H5Sclose(mspace);
166  H5Sclose(dspace);
167  H5Dclose(dsetid);
168  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
169  ostringstream eherr;
170  eherr << "Obtaining the datatype of the HDF5 dataset " << varname
171  << " fails. "<<endl;
172  throw InternalErr (__FILE__, __LINE__, eherr.str ());
173  }
174 
175  if ((memtype = H5Tget_native_type(dtypeid, H5T_DIR_ASCEND))<0) {
176 
177  H5Sclose(mspace);
178  H5Tclose(dtypeid);
179  H5Sclose(dspace);
180  H5Dclose(dsetid);
181  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
182  ostringstream eherr;
183  eherr << "Obtaining the memory type of the HDF5 dataset " << varname
184  << " fails. "<<endl;
185  throw InternalErr (__FILE__, __LINE__, eherr.str ());
186 
187  }
188 
189  H5T_class_t ty_class = H5Tget_class(dtypeid);
190  if (ty_class < 0) {
191 
192  H5Sclose(mspace);
193  H5Tclose(dtypeid);
194  H5Tclose(memtype);
195  H5Sclose(dspace);
196  H5Dclose(dsetid);
197  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
198  ostringstream eherr;
199  eherr << "Obtaining the type class of the HDF5 dataset " << varname
200  << " fails. "<<endl;
201  throw InternalErr (__FILE__, __LINE__, eherr.str ());
202 
203  }
204 
205  if (ty_class !=H5T_INTEGER) {
206  H5Sclose(mspace);
207  H5Tclose(dtypeid);
208  H5Tclose(memtype);
209  H5Sclose(dspace);
210  H5Dclose(dsetid);
211  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
212  ostringstream eherr;
213  eherr << "The type class of the HDF5 dataset " << varname
214  << " is not H5T_INTEGER. "<<endl;
215  throw InternalErr (__FILE__, __LINE__, eherr.str ());
216  }
217 
218  size_t ty_size = H5Tget_size(dtypeid);
219  if (ty_size != H5Tget_size(H5T_STD_I64LE)) {
220  H5Sclose(mspace);
221  H5Tclose(dtypeid);
222  H5Tclose(memtype);
223  H5Sclose(dspace);
224  H5Dclose(dsetid);
225  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
226  ostringstream eherr;
227  eherr << "The type size of the HDF5 dataset " << varname
228  << " is not right. "<<endl;
229  throw InternalErr (__FILE__, __LINE__, eherr.str ());
230  }
231 
232  hid_t read_ret = -1;
233 
234 
235  vector<long long>orig_val;
236  orig_val.resize(nelms);
237 
238  vector<int> val;
239  val.resize(nelms);
240 
241  read_ret = H5Dread(dsetid,memtype,mspace,dspace,H5P_DEFAULT,&orig_val[0]);
242  if (read_ret < 0) {
243  H5Sclose(mspace);
244  H5Tclose(dtypeid);
245  H5Tclose(memtype);
246  H5Sclose(dspace);
247  H5Dclose(dsetid);
248  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
249  ostringstream eherr;
250  eherr << "Cannot read the HDF5 dataset " << varname
251  <<" with type of 64-bit integer"<<endl;
252  throw InternalErr (__FILE__, __LINE__, eherr.str ());
253  }
254 
255  // Create "Time" or "Date" part of the original array.
256  // First get 10 power number of bits right
257  int max_num = 1;
258  for (int i = 0; i <numofdbits; i++)
259  max_num = 10 * max_num;
260 
261  int num_cut = 1;
262  for (int i = 0; i<(sdbit-1) ; i++)
263  num_cut = 10 *num_cut;
264 
265  // Second generate the number based on the starting bit and number of bits
266  // For example, number 1234, starting bit is 1, num of bits is 2
267 
268  // The final number is 34. The formula is
269  // (orig_val/pow(sbit-1)))%(pow(10,nbits))
270  // In this example, 34 = (1234/1)%(100) = 34
271 
272  for (int i = 0; i <nelms; i ++)
273  val[i] = (orig_val[i]/num_cut)%max_num;
274 
275 
276  set_value ((dods_int32 *)&val[0],nelms);
277 
278  H5Sclose(mspace);
279  H5Tclose(dtypeid);
280  H5Tclose(memtype);
281  H5Sclose(dspace);
282  H5Dclose(dsetid);
283  HDF5CFUtil::close_fileid(fileid,check_pass_fileid_key);
284 
285  return;
286 }
287 #if 0
288 // parse constraint expr. and make hdf5 coordinate point location.
289 // return number of elements to read.
290 int
291 HDF5GMSPCFArray::format_constraint (int *offset, int *step, int *count)
292 {
293  long nels = 1;
294  int id = 0;
295 
296  Dim_iter p = dim_begin ();
297 
298  while (p != dim_end ()) {
299 
300  int start = dimension_start (p, true);
301  int stride = dimension_stride (p, true);
302  int stop = dimension_stop (p, true);
303 
304  // Check for illegal constraint
305  if (start > stop) {
306  ostringstream oss;
307 
308  oss << "Array/Grid hyperslab start point "<< start <<
309  " is greater than stop point " << stop <<".";
310  throw Error(malformed_expr, oss.str());
311  }
312 
313 
314  offset[id] = start;
315  step[id] = stride;
316  count[id] = ((stop - start) / stride) + 1; // count of elements
317  nels *= count[id]; // total number of values for variable
318 
319  BESDEBUG ("h5",
320  "=format_constraint():"
321  << "id=" << id << " offset=" << offset[id]
322  << " step=" << step[id]
323  << " count=" << count[id]
324  << endl);
325 
326  id++;
327  p++;
328  }
329  return nels;
330 }
331 #endif
HDF5GMSPCFArray.h
This class specifies the retrieval of data values for special HDF5 products Currently this only appli...
libdap
Definition: BESDapFunctionResponseCache.h:35
HDF5RequestHandler.h
include the entry functions to execute the handlers
Error
HDF5GMSPCFArray
Definition: HDF5GMSPCFArray.h:45