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