bes Updated for version 3.20.13
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 <libdap/InternalErr.h>
39
40#include "HDF5RequestHandler.h"
41#include "HDF5GMSPCFArray.h"
42
43using namespace std;
44using namespace libdap;
45
46BaseType *HDF5GMSPCFArray::ptr_duplicate()
47{
48 return new HDF5GMSPCFArray(*this);
49}
50
51bool 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,nullptr);
58
59 return true;
60}
61
62void 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.data(), step.data(), count.data());
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.data(), hstep.data(),
141 hcount.data(), nullptr) < 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.data(),nullptr);
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.data());
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.data(),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.
290int
291HDF5GMSPCFArray::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
This class specifies the retrieval of data values for special HDF5 products Currently this only appli...
include the entry functions to execute the handlers