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