36#include <libdap/InternalErr.h>
44BaseType *HDFEOS5CFMissLLArray::ptr_duplicate()
46 auto HDFEOS5CFMissLLArray_unique = make_unique<HDFEOS5CFMissLLArray>(*
this);
47 return HDFEOS5CFMissLLArray_unique.release();
50bool HDFEOS5CFMissLLArray::read()
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);
57 vector<string> cur_lrd_non_cache_dir_list;
58 HDF5RequestHandler::get_lrd_non_cache_dir_list(cur_lrd_non_cache_dir_list);
62 if( (cur_lrd_non_cache_dir_list.empty()) ||
63 (
"" == check_str_sect_in_list(cur_lrd_non_cache_dir_list,filename,
'/'))) {
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,
'/');
69 cache_key = cache_dir + varname;
73 cache_key = filename + varname;
79 if(cvartype == CV_LAT_MISS)
80 handle_data_with_mem_cache(H5FLOAT32,(
size_t)ydimsize,cache_flag,cache_key,
false);
82 handle_data_with_mem_cache(H5FLOAT32,(
size_t)xdimsize,cache_flag,cache_key,
false);
85 read_data_NOT_from_mem_cache(
false,
nullptr);
90void HDFEOS5CFMissLLArray::read_data_NOT_from_mem_cache(
bool add_cache,
void*buf){
92 BESDEBUG(
"h5",
"Coming to read_data_NOT_from_mem_cache "<<endl);
97 if(eos5_projcode == HE5_GCTP_GEO) {
98 read_data_NOT_from_mem_cache_geo(add_cache,buf);
103 vector<int64_t>offset;
104 vector<int64_t>count;
108 throw InternalErr (__FILE__, __LINE__,
109 "The number of dimension of this variable should be greater than 0");
114 nelms = format_constraint (offset.data(), step.data(), count.data());
118 throw InternalErr (__FILE__, __LINE__,
119 "The number of elments is negative.");
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.");
127 vector<size_t>pos(rank,0);
128 for (
int i = 0; i< rank; i++)
131 vector<size_t>dimsizes;
132 dimsizes.push_back(ydimsize);
133 dimsizes.push_back(xdimsize);
141 rows.resize(xdimsize*ydimsize);
142 cols.resize(xdimsize*ydimsize);
143 lon.resize(xdimsize*ydimsize);
144 lat.resize(xdimsize*ydimsize);
146 upleft[0] = point_left;
147 upleft[1] = point_upper;
148 lowright[0] = point_right;
149 lowright[1] = point_lower;
155 for (
int k = j = 0; j < ydimsize; ++j) {
156 for (
int i = 0; i < xdimsize; ++i) {
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);
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);
200 bool ll_read_from_cache =
true;
203 bool use_latlon_cache = HDF5RequestHandler::get_use_eosgeo_cachefile();
207 if(use_latlon_cache ==
true) {
211 string cache_fname = obtain_ll_cache_name();
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();
219 int expected_file_size = 2*xdimsize*ydimsize*
sizeof(double);
222 ll_read_from_cache = ll_cache->get_data_from_cache(cache_fname, expected_file_size,fd);
224 if(ll_read_from_cache ==
true) {
226 BESDEBUG(
"h5",
" Read latitude and longitude from a disk cache. " <<endl);
227 size_t var_offset = 0;
229 if(CV_LON_MISS == cvartype)
230 var_offset = xdimsize*ydimsize*
sizeof(double);
232 vector<double> var_value;
233 var_value.resize(xdimsize*ydimsize);
238 off_t fpos = lseek(fd,var_offset,SEEK_SET);
240 throw InternalErr (__FILE__, __LINE__,
241 "Cannot seek the cached file offset.");
245 ll_cache->unlock_and_close(cache_fname);
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;
254 if(total_elms == nelms)
255 set_value_ll(var_value.data(),total_elms);
268 set_value_ll(val.data(),nelms);
274 ll_read_from_cache =
false;
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);
282 eherr <<
"cannot calculate grid latitude and longitude";
283 throw InternalErr (__FILE__, __LINE__, eherr.str ());
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();
296 BESDEBUG(
"h5",
" Write EOS5 grid latitude and longitude to a disk cache. " <<endl);
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);
308 BESDEBUG(
"h5",
" The first value of lon is " << lon[0] <<endl);
309 BESDEBUG(
"h5",
" The first value of lat is " << lat[0] <<endl);
312 vector<size_t>pos(rank,0);
313 for (
int i = 0; i< rank; i++)
316 vector<size_t>dimsizes;
317 dimsizes.push_back(ydimsize);
318 dimsizes.push_back(xdimsize);
319 int total_elms = xdimsize*ydimsize;
323 if(CV_LON_MISS == cvartype) {
324 if(total_elms == nelms)
325 set_value_ll(lon.data(),total_elms);
338 set_value_ll(val.data(),nelms);
342 else if(CV_LAT_MISS == cvartype) {
344 if(total_elms == nelms)
345 set_value_ll(lat.data(),total_elms);
358 set_value_ll(val.data(),nelms);
365string HDFEOS5CFMissLLArray::obtain_ll_cache_name() {
367 BESDEBUG(
"h5",
"Coming to obtain_ll_cache_name "<<endl);
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();
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.");
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);
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);
396 string err_mesg=
"The cached directory " + bescachedir;
397 err_mesg = err_mesg +
" is not a directory.";
398 throw InternalErr(__FILE__,__LINE__,err_mesg);
403 string cache_fname=HDF5RequestHandler::get_latlon_disk_cachefile_prefix();
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);
412 cache_fname +=HDF5CFUtil::get_int_str(ydimsize);
413 cache_fname +=HDF5CFUtil::get_int_str(xdimsize);
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);
423 for(
int ipar = 0; ipar<13;ipar++) {
424 cache_fname+=HDF5CFUtil::get_double_str(eos5_params[ipar],17,6);
427 string cache_fpath = bescachedir +
"/"+ cache_fname;
431void HDFEOS5CFMissLLArray::read_data_NOT_from_mem_cache_geo(
bool add_cache,
void*buf){
433 BESDEBUG(
"h5",
"Coming to read_data_NOT_from_mem_cache_geo "<<endl);
435 vector<int64_t>offset;
436 vector<int64_t>count;
441 throw InternalErr (__FILE__, __LINE__,
442 "The number of dimension of this variable should be greater than 0");
448 nelms = format_constraint (offset.data(), step.data(), count.data());
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.");
462 if (CV_LAT_MISS == cvartype) {
464 if (HE5_HDFE_GD_UL == eos5_origin || HE5_HDFE_GD_UR == eos5_origin) {
477 throw InternalErr (__FILE__, __LINE__,
478 "The number of elments should be greater than 0.");
480 float lat_step = (end - start) /ydimsize;
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;
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;
494 memcpy(buf,total_val.data(),4*ydimsize);
499 for (
int i = 0; i < nelms; i++)
500 val[i] = ((
float)(offset[0]+i * step[0])*lat_step + start) / 1000000.0F;
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;
509 memcpy(buf,total_val.data(),4*ydimsize);
515 if (CV_LON_MISS == cvartype) {
517 if (HE5_HDFE_GD_UL == eos5_origin || HE5_HDFE_GD_LL == eos5_origin) {
530 throw InternalErr (__FILE__, __LINE__,
531 "The number of elments should be greater than 0.");
532 float lon_step = (end - start) /xdimsize;
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;
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;
545 memcpy(buf,total_val.data(),4*xdimsize);
550 for (
int i = 0; i < nelms; i++)
551 val[i] = ((
float)(offset[0]+i*step[0]) * lon_step + start) / 1000000.0F;
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;
560 memcpy(buf,total_val.data(),4*xdimsize);
566for (
int i =0; i <nelms; i++)
567"h5",
"final data val "<< i <<
" is " << val[i] <<endl;
570 set_value_ll(val.data(), nelms);
580HDFEOS5CFMissLLArray::format_constraint (
int *offset,
int *step,
int *count)
585 Dim_iter p = dim_begin ();
587 while (p != dim_end ()) {
589 int start = dimension_start (p,
true);
590 int stride = dimension_stride (p,
true);
591 int stop = dimension_stop (p,
true);
597 oss <<
"Array/Grid hyperslab start point "<< start <<
598 " is greater than stop point " << stop <<
".";
599 throw Error(malformed_expr, oss.str());
606 count[id] = ((stop - start) / stride) + 1;
610 "=format_constraint():"
611 <<
"id=" <<
id <<
" offset=" << offset[
id]
612 <<
" step=" << step[
id]
613 <<
" count=" << count[
id]
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.