bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
HDFEOS5CFMissLLArray.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#include <sys/stat.h>
33#include <memory>
34#include <iostream>
35#include <BESDebug.h>
36#include <libdap/InternalErr.h>
37
39#include "HDF5RequestHandler.h"
40
41using namespace std;
42using namespace libdap;
43
44BaseType *HDFEOS5CFMissLLArray::ptr_duplicate()
45{
46 auto HDFEOS5CFMissLLArray_unique = make_unique<HDFEOS5CFMissLLArray>(*this);
47 return HDFEOS5CFMissLLArray_unique.release();
48}
49
50bool HDFEOS5CFMissLLArray::read()
51{
52
53 BESDEBUG("h5","Coming to HDFEOS5CFMissLLArray read "<<endl);
54 if(nullptr == HDF5RequestHandler::get_lrdata_mem_cache())
55 read_data_NOT_from_mem_cache(false,nullptr);
56 else {
57 vector<string> cur_lrd_non_cache_dir_list;
58 HDF5RequestHandler::get_lrd_non_cache_dir_list(cur_lrd_non_cache_dir_list);
59
60 string cache_key;
61 // Check if this file is included in the non-cache directory
62 if( (cur_lrd_non_cache_dir_list.empty()) ||
63 ("" == check_str_sect_in_list(cur_lrd_non_cache_dir_list,filename,'/'))) {
64 short cache_flag = 2;
65 vector<string> cur_cache_dlist;
66 HDF5RequestHandler::get_lrd_cache_dir_list(cur_cache_dlist);
67 string cache_dir = check_str_sect_in_list(cur_cache_dlist,filename,'/');
68 if(cache_dir != ""){
69 cache_key = cache_dir + varname;
70 cache_flag = 3;
71 }
72 else
73 cache_key = filename + varname;
74
75 // Need to obtain the total number of elements.
76 // Currently only trivial geographic projection is supported.
77 // So the total number of elements for LAT is ydimsize,
78 // the total number of elements for LON is xdimsize.
79 if(cvartype == CV_LAT_MISS)
80 handle_data_with_mem_cache(H5FLOAT32,(size_t)ydimsize,cache_flag,cache_key,false);
81 else
82 handle_data_with_mem_cache(H5FLOAT32,(size_t)xdimsize,cache_flag,cache_key,false);
83 }
84 else
85 read_data_NOT_from_mem_cache(false,nullptr);
86 }
87 return true;
88}
89
90void HDFEOS5CFMissLLArray::read_data_NOT_from_mem_cache(bool add_cache,void*buf){
91
92 BESDEBUG("h5","Coming to read_data_NOT_from_mem_cache "<<endl);
93
94 // First handle geographic projection. No GCTP is needed.Since the calculation
95 // of lat/lon is really simple for this case. No need to provide the disk cache
96 // unless the calculation takes too long. We will see.
97 if(eos5_projcode == HE5_GCTP_GEO) {
98 read_data_NOT_from_mem_cache_geo(add_cache,buf);
99 return;
100 }
101
102 int64_t nelms = -1;
103 vector<int64_t>offset;
104 vector<int64_t>count;
105 vector<int64_t>step;
106
107 if (rank <= 0)
108 throw InternalErr (__FILE__, __LINE__,
109 "The number of dimension of this variable should be greater than 0");
110 else {
111 offset.resize(rank);
112 count.resize(rank);
113 step.resize(rank);
114 nelms = format_constraint (offset.data(), step.data(), count.data());
115 }
116
117 if (nelms <= 0)
118 throw InternalErr (__FILE__, __LINE__,
119 "The number of elments is negative.");
120
121 int64_t total_elms = xdimsize*ydimsize;
122 if (total_elms > DODS_INT_MAX)
123 throw InternalErr (__FILE__, __LINE__,
124 "Currently we cannot calculate lat/lon that is greater than 2G for HDF-EOS5.");
125
126
127 vector<size_t>pos(rank,0);
128 for (int i = 0; i< rank; i++)
129 pos[i] = offset[i];
130
131 vector<size_t>dimsizes;
132 dimsizes.push_back(ydimsize);
133 dimsizes.push_back(xdimsize);
134
135 double upleft[2];
136 double lowright[2];
137 vector<int>rows;
138 vector<int>cols;
139 vector<double>lon;
140 vector<double>lat;
141 rows.resize(xdimsize*ydimsize);
142 cols.resize(xdimsize*ydimsize);
143 lon.resize(xdimsize*ydimsize);
144 lat.resize(xdimsize*ydimsize);
145
146 upleft[0] = point_left;
147 upleft[1] = point_upper;
148 lowright[0] = point_right;
149 lowright[1] = point_lower;
150
151
152 int j = 0;
153 int r = -1;
154
155 for (int k = j = 0; j < ydimsize; ++j) {
156 for (int i = 0; i < xdimsize; ++i) {
157 rows[k] = j;
158 cols[k] = i;
159 ++k;
160 }
161 }
162
163 BESDEBUG("h5", " Before calling GDij2ll, check all projection parameters. " << endl);
164 BESDEBUG("h5", " eos5_projcode is " << eos5_projcode <<endl);
165 BESDEBUG("h5", " eos5_zone is " << eos5_zone <<endl);
166 BESDEBUG("h5", " eos5_params[0] is " << eos5_params[0] <<endl);
167 BESDEBUG("h5", " eos5_params[1] is " << eos5_params[1] <<endl);
168 BESDEBUG("h5", " eos5_sphere is " << eos5_sphere <<endl);
169 BESDEBUG("h5", " xdimsize is " << xdimsize <<endl);
170 BESDEBUG("h5", " ydimsize is " << ydimsize <<endl);
171 BESDEBUG("h5", " eos5_pixelreg is " << eos5_pixelreg <<endl);
172 BESDEBUG("h5", " eos5_origin is " << eos5_origin <<endl);
173 BESDEBUG("h5", " upleft[0] is " << upleft[0] <<endl);
174 BESDEBUG("h5", " upleft[1] is " << upleft[1] <<endl);
175 BESDEBUG("h5", " lowright[0] is " << lowright[0] <<endl);
176 BESDEBUG("h5", " lowright[1] is " << lowright[1] <<endl);
177
178#if 0
179 cerr<< " eos5_params[0] is " << eos5_params[0] <<endl;
180 cerr<< " eos5_params[1] is " << eos5_params[1] <<endl;
181 cerr<< " eos5_sphere is " << eos5_sphere <<endl;
182 cerr<< " eos5_zone is " << eos5_zone <<endl;
183 cerr<< " Before calling GDij2ll, check all projection parameters. " << endl;
184 cerr<< " eos5_zone is " << eos5_zone <<endl;
185 cerr<< " eos5_params[0] is " << eos5_params[0] <<endl;
186 cerr<< " eos5_params[1] is " << eos5_params[1] <<endl;
187 BESDEBUG("h5", " xdimsize is " << xdimsize <<endl);
188 BESDEBUG("h5", " ydimsize is " << ydimsize <<endl);
189 BESDEBUG("h5", " eos5_pixelreg is " << eos5_pixelreg <<endl);
190 BESDEBUG("h5", " eos5_origin is " << eos5_origin <<endl);
191 BESDEBUG("h5", " upleft[0] is " << upleft[0] <<endl);
192 BESDEBUG("h5", " upleft[1] is " << upleft[1] <<endl);
193 BESDEBUG("h5", " lowright[0] is " << lowright[0] <<endl);
194 BESDEBUG("h5", " lowright[1] is " << lowright[1] <<endl);
195#endif
196
197 // boolean to mark if the value can be read from the cache.
198 // Not necessary from programming point of view. Use it to
199 // make the code flow clear.
200 bool ll_read_from_cache = true;
201
202 // Check if geo-cache is turned on.
203 bool use_latlon_cache = HDF5RequestHandler::get_use_eosgeo_cachefile();
204
205
206 // Adding more code to read latlon from cache here.
207 if(use_latlon_cache == true) {
208
209 // Cache name is made in a special way to make sure the same lat/lon
210 // fall into the same cache file.
211 string cache_fname = obtain_ll_cache_name();
212
213 // Obtain eos-geo disk cache size, dir and prefix.
214 long ll_disk_cache_size = HDF5RequestHandler::get_latlon_disk_cache_size();
215 string ll_disk_cache_dir = HDF5RequestHandler::get_latlon_disk_cache_dir();
216 string ll_disk_cache_prefix = HDF5RequestHandler::get_latlon_disk_cachefile_prefix();
217
218 // Expected cache file size
219 int expected_file_size = 2*xdimsize*ydimsize*sizeof(double);
220 HDF5DiskCache *ll_cache = HDF5DiskCache::get_instance(ll_disk_cache_size,ll_disk_cache_dir,ll_disk_cache_prefix);
221 int fd = 0;
222 ll_read_from_cache = ll_cache->get_data_from_cache(cache_fname, expected_file_size,fd);
223
224 if(ll_read_from_cache == true) {
225
226 BESDEBUG("h5", " Read latitude and longitude from a disk cache. " <<endl);
227 size_t var_offset = 0;
228 // Longitude is stored after latitude.
229 if(CV_LON_MISS == cvartype)
230 var_offset = xdimsize*ydimsize*sizeof(double);
231
232 vector<double> var_value;
233 var_value.resize(xdimsize*ydimsize);
234
235#if 0
236 //Latitude starts from 0, longitude starts from xdimsize*ydimsize*sizeof(double);
237#endif
238 off_t fpos = lseek(fd,var_offset,SEEK_SET);
239 if(fpos == -1) {
240 throw InternalErr (__FILE__, __LINE__,
241 "Cannot seek the cached file offset.");
242
243 }
244 ssize_t ret_val = HDF5CFUtil::read_buffer_from_file(fd,(void*)var_value.data(),var_value.size()*sizeof(double));
245 ll_cache->unlock_and_close(cache_fname);
246
247 // If the cached file is not read correctly, we should purge the file.
248 if((-1 == ret_val) || ((size_t)ret_val != (xdimsize*ydimsize*sizeof(double)))) {
249 ll_cache->purge_file(cache_fname);
250 ll_read_from_cache = false;
251 }
252 else {
253 // short-cut, no need to do subset.
254 if(total_elms == nelms)
255 set_value_ll(var_value.data(),total_elms);
256 else {
257 vector<double>val;
259 var_value.data(),
260 rank,
261 dimsizes,
262 offset.data(),
263 step.data(),
264 count.data(),
265 &val,
266 pos,
267 0);
268 set_value_ll(val.data(),nelms);
269 }
270 return;
271 }
272 }
273 else
274 ll_read_from_cache = false;
275 }
276
277 // Calculate Lat/lon by using GCTP
278 r = GDij2ll (eos5_projcode, eos5_zone, eos5_params.data(), eos5_sphere, xdimsize, ydimsize, upleft, lowright,
279 xdimsize * ydimsize, rows.data(), cols.data(), lon.data(), lat.data(), eos5_pixelreg, eos5_origin);
280 if (r != 0) {
281 ostringstream eherr;
282 eherr << "cannot calculate grid latitude and longitude";
283 throw InternalErr (__FILE__, __LINE__, eherr.str ());
284 }
285
286
287 // ll_read_from_cache may be redundant. It is good to remind that we will generate the cache file
288 // when reading from the cache fails.
289 // We are using cache and need to write data to the cache.
290 if(use_latlon_cache == true && ll_read_from_cache == false) {
291 string cache_fname = obtain_ll_cache_name();
292 long ll_disk_cache_size = HDF5RequestHandler::get_latlon_disk_cache_size();
293 string ll_disk_cache_dir = HDF5RequestHandler::get_latlon_disk_cache_dir();
294 string ll_disk_cache_prefix = HDF5RequestHandler::get_latlon_disk_cachefile_prefix();
295
296 BESDEBUG("h5", " Write EOS5 grid latitude and longitude to a disk cache. " <<endl);
297
298 HDF5DiskCache *ll_cache = HDF5DiskCache::get_instance(ll_disk_cache_size,ll_disk_cache_dir,ll_disk_cache_prefix);
299
300 // Merge vector lat and lon. lat first.
301 vector <double>latlon;
302 latlon.reserve(xdimsize*ydimsize*2);
303 latlon.insert(latlon.end(),lat.begin(),lat.end());
304 latlon.insert(latlon.end(),lon.begin(),lon.end());
305 ll_cache->write_cached_data(cache_fname,2*xdimsize*ydimsize*sizeof(double),latlon);
306
307 }
308 BESDEBUG("h5", " The first value of lon is " << lon[0] <<endl);
309 BESDEBUG("h5", " The first value of lat is " << lat[0] <<endl);
310
311#if 0
312 vector<size_t>pos(rank,0);
313 for (int i = 0; i< rank; i++)
314 pos[i] = offset[i];
315
316 vector<size_t>dimsizes;
317 dimsizes.push_back(ydimsize);
318 dimsizes.push_back(xdimsize);
319 int total_elms = xdimsize*ydimsize;
320#endif
321
322
323 if(CV_LON_MISS == cvartype) {
324 if(total_elms == nelms)
325 set_value_ll(lon.data(),total_elms);
326 else {
327 vector<double>val;
329 lon.data(),
330 rank,
331 dimsizes,
332 offset.data(),
333 step.data(),
334 count.data(),
335 &val,
336 pos,
337 0);
338 set_value_ll(val.data(),nelms);
339 }
340
341 }
342 else if(CV_LAT_MISS == cvartype) {
343
344 if(total_elms == nelms)
345 set_value_ll(lat.data(),total_elms);
346 else {
347 vector<double>val;
349 lat.data(),
350 rank,
351 dimsizes,
352 offset.data(),
353 step.data(),
354 count.data(),
355 &val,
356 pos,
357 0);
358 set_value_ll(val.data(),nelms);
359 }
360 }
361 return;
362
363}
364
365string HDFEOS5CFMissLLArray::obtain_ll_cache_name() {
366
367 BESDEBUG("h5","Coming to obtain_ll_cache_name "<<endl);
368
369
370 // Here we have a sanity check for the cached parameters:Cached directory,file prefix and cached directory size.
371 // Supposedly Hyrax BES cache feature should check this and the code exists. However, the
372 string bescachedir = HDF5RequestHandler::get_latlon_disk_cache_dir();
373 string bescacheprefix = HDF5RequestHandler::get_latlon_disk_cachefile_prefix();
374 long cachesize = HDF5RequestHandler::get_latlon_disk_cache_size();
375
376 if(("" == bescachedir)||(""==bescacheprefix)||(cachesize <=0)){
377 throw InternalErr (__FILE__, __LINE__, "Either the cached dir is empty or the prefix is nullptr or the cache size is not set.");
378 }
379 else {
380 struct stat sb;
381 if(stat(bescachedir.c_str(),&sb) !=0) {
382 string err_mesg="The cached directory " + bescachedir;
383 err_mesg = err_mesg + " doesn't exist. ";
384 throw InternalErr(__FILE__,__LINE__,err_mesg);
385
386 }
387 else {
388 if(true == S_ISDIR(sb.st_mode)) {
389 if(access(bescachedir.c_str(),R_OK|W_OK|X_OK) == -1) {
390 string err_mesg="The cached directory " + bescachedir;
391 err_mesg = err_mesg + " can NOT be read,written or executable.";
392 throw InternalErr(__FILE__,__LINE__,err_mesg);
393 }
394 }
395 else {
396 string err_mesg="The cached directory " + bescachedir;
397 err_mesg = err_mesg + " is not a directory.";
398 throw InternalErr(__FILE__,__LINE__,err_mesg);
399 }
400 }
401 }
402
403 string cache_fname=HDF5RequestHandler::get_latlon_disk_cachefile_prefix();
404
405 // Projection code,zone,sphere,pix,origin
406 cache_fname +=HDF5CFUtil::get_int_str(eos5_projcode);
407 cache_fname +=HDF5CFUtil::get_int_str(eos5_zone);
408 cache_fname +=HDF5CFUtil::get_int_str(eos5_sphere);
409 cache_fname +=HDF5CFUtil::get_int_str(eos5_pixelreg);
410 cache_fname +=HDF5CFUtil::get_int_str(eos5_origin);
411
412 cache_fname +=HDF5CFUtil::get_int_str(ydimsize);
413 cache_fname +=HDF5CFUtil::get_int_str(xdimsize);
414
415 // upleft,lowright
416 // HDF-EOS upleft,lowright,params use DDDDMMMSSS.6 digits. So choose %17.6f.
417 cache_fname +=HDF5CFUtil::get_double_str(point_left,17,6);
418 cache_fname +=HDF5CFUtil::get_double_str(point_upper,17,6);
419 cache_fname +=HDF5CFUtil::get_double_str(point_right,17,6);
420 cache_fname +=HDF5CFUtil::get_double_str(point_lower,17,6);
421
422 // According to HDF-EOS2 document, only 13 parameters are used.
423 for(int ipar = 0; ipar<13;ipar++) {
424 cache_fname+=HDF5CFUtil::get_double_str(eos5_params[ipar],17,6);
425 }
426
427 string cache_fpath = bescachedir + "/"+ cache_fname;
428 return cache_fpath;
429
430}
431void HDFEOS5CFMissLLArray::read_data_NOT_from_mem_cache_geo(bool add_cache,void*buf){
432
433 BESDEBUG("h5","Coming to read_data_NOT_from_mem_cache_geo "<<endl);
434 int64_t nelms = -1;
435 vector<int64_t>offset;
436 vector<int64_t>count;
437 vector<int64_t>step;
438
439
440 if (rank <= 0)
441 throw InternalErr (__FILE__, __LINE__,
442 "The number of dimension of this variable should be greater than 0");
443 else {
444
445 offset.resize(rank);
446 count.resize(rank);
447 step.resize(rank);
448 nelms = format_constraint (offset.data(), step.data(), count.data());
449 }
450
451 if (nelms <= 0 || nelms >DODS_INT_MAX)
452 throw InternalErr (__FILE__, __LINE__,
453 "The number of elments for geographic lat/lon is negative or greater than 2G.");
454
455 float start = 0.0;
456 float end = 0.0;
457
458 vector<float>val;
459 val.resize(nelms);
460
461
462 if (CV_LAT_MISS == cvartype) {
463
464 if (HE5_HDFE_GD_UL == eos5_origin || HE5_HDFE_GD_UR == eos5_origin) {
465
466 start = point_upper;
467 end = point_lower;
468
469 }
470 else {// (gridorigin == HE5_HDFE_GD_LL || gridorigin == HE5_HDFE_GD_LR)
471
472 start = point_lower;
473 end = point_upper;
474 }
475
476 if(ydimsize <=0)
477 throw InternalErr (__FILE__, __LINE__,
478 "The number of elments should be greater than 0.");
479
480 float lat_step = (end - start) /ydimsize;
481
482 // Now offset,step and val will always be valid. line 74 and 85 assure this.
483 if ( HE5_HDFE_CENTER == eos5_pixelreg ) {
484 for (int i = 0; i < nelms; i++)
485 val[i] = ((offset[0]+i*step[0] + 0.5F) * lat_step + start) / 1000000.0F;
486
487 // If the memory cache is turned on, we have to save all values to the buf
488 if(add_cache == true) {
489 vector<float>total_val;
490 total_val.resize(ydimsize);
491 for (int total_i = 0; total_i < ydimsize; total_i++)
492 total_val[total_i] = ((total_i + 0.5F) * lat_step + start) / 1000000.0F;
493 // Note: the float is size 4
494 memcpy(buf,total_val.data(),4*ydimsize);
495 }
496
497 }
498 else { // HE5_HDFE_CORNER
499 for (int i = 0; i < nelms; i++)
500 val[i] = ((float)(offset[0]+i * step[0])*lat_step + start) / 1000000.0F;
501
502 // If the memory cache is turned on, we have to save all values to the buf
503 if(add_cache == true) {
504 vector<float>total_val;
505 total_val.resize(ydimsize);
506 for (int total_i = 0; total_i < ydimsize; total_i++)
507 total_val[total_i] = ((float)(total_i) * lat_step + start) / 1000000.0F;
508 // Note: the float is size 4
509 memcpy(buf,total_val.data(),4*ydimsize);
510 }
511
512 }
513 }
514
515 if (CV_LON_MISS == cvartype) {
516
517 if (HE5_HDFE_GD_UL == eos5_origin || HE5_HDFE_GD_LL == eos5_origin) {
518
519 start = point_left;
520 end = point_right;
521
522 }
523 else {// (gridorigin == HE5_HDFE_GD_UR || gridorigin == HE5_HDFE_GD_LR)
524
525 start = point_right;
526 end = point_left;
527 }
528
529 if(xdimsize <=0)
530 throw InternalErr (__FILE__, __LINE__,
531 "The number of elments should be greater than 0.");
532 float lon_step = (end - start) /xdimsize;
533
534 if (HE5_HDFE_CENTER == eos5_pixelreg) {
535 for (int i = 0; i < nelms; i++)
536 val[i] = ((offset[0] + i *step[0] + 0.5F) * lon_step + start ) / 1000000.0F;
537
538 // If the memory cache is turned on, we have to save all values to the buf
539 if(add_cache == true) {
540 vector<float>total_val;
541 total_val.resize(xdimsize);
542 for (int total_i = 0; total_i < xdimsize; total_i++)
543 total_val[total_i] = ((total_i+0.5F) * lon_step + start) / 1000000.0F;
544 // Note: the float is size 4
545 memcpy(buf,total_val.data(),4*xdimsize);
546 }
547
548 }
549 else { // HE5_HDFE_CORNER
550 for (int i = 0; i < nelms; i++)
551 val[i] = ((float)(offset[0]+i*step[0]) * lon_step + start) / 1000000.0F;
552
553 // If the memory cache is turned on, we have to save all values to the buf
554 if(add_cache == true) {
555 vector<float>total_val;
556 total_val.resize(xdimsize);
557 for (int total_i = 0; total_i < xdimsize; total_i++)
558 total_val[total_i] = ((float)(total_i) * lon_step + start) / 1000000.0F;
559 // Note: the float is size 4
560 memcpy(buf,total_val.data(),4*xdimsize);
561 }
562 }
563 }
564
565#if 0
566for (int i =0; i <nelms; i++)
567"h5","final data val "<< i <<" is " << val[i] <<endl;
568#endif
569
570 set_value_ll(val.data(), nelms);
571
572
573 return;
574}
575
576#if 0
577// parse constraint expr. and make hdf5 coordinate point location.
578// return number of elements to read.
579int
580HDFEOS5CFMissLLArray::format_constraint (int *offset, int *step, int *count)
581{
582 long nels = 1;
583 int id = 0;
584
585 Dim_iter p = dim_begin ();
586
587 while (p != dim_end ()) {
588
589 int start = dimension_start (p, true);
590 int stride = dimension_stride (p, true);
591 int stop = dimension_stop (p, true);
592
593 // Check for illegal constraint
594 if (start > stop) {
595 ostringstream oss;
596
597 oss << "Array/Grid hyperslab start point "<< start <<
598 " is greater than stop point " << stop <<".";
599 throw Error(malformed_expr, oss.str());
600 }
601
602
603
604 offset[id] = start;
605 step[id] = stride;
606 count[id] = ((stop - start) / stride) + 1; // count of elements
607 nels *= count[id]; // total number of values for variable
608
609 BESDEBUG ("h5",
610 "=format_constraint():"
611 << "id=" << id << " offset=" << offset[id]
612 << " step=" << step[id]
613 << " count=" << count[id]
614 << endl);
615
616 id++;
617 p++;
618 }
619
620 return nels;
621}
622
623#endif
include the entry functions to execute the handlers
This class specifies the retrieval of the missing lat/lon values for HDF-EOS5 products.
int subset(void *input, int rank, const std::vector< size_t > &dim, int64_t start[], int64_t stride[], int64_t edge[], std::vector< T > *poutput, std::vector< size_t > &pos, int index)
Getting a subset of a variable.
static HDF5DiskCache * get_instance(const long, const std::string &, const std::string &)
static ssize_t read_buffer_from_file(int fd, void *buf, size_t)
Getting a subset of a variable.