41 #include<InternalErr.h>
47 int hinv_init(
int insys,
int inzone,
double *inparm,
int indatum,
char *fn27,
char *fn83,
int *iflg,
int (*hinv_trans[])(
double,
double,
double*,
double*));
49 int hfor_init(
int outsys,
int outzone,
double *outparm,
int outdatum,
char *fn27,
char *fn83,
int *iflg,
int (*hfor_trans[])(
double,
double,
double *,
double *));
59 switch (H5Tget_class(h5_type_id)) {
62 size = H5Tget_size(h5_type_id);
63 sign = H5Tget_sign(h5_type_id);
66 if (sign == H5T_SGN_2)
72 if (sign == H5T_SGN_2)
78 if (sign == H5T_SGN_2)
84 if (sign == H5T_SGN_2)
89 else return H5UNSUPTYPE;
92 size = H5Tget_size(h5_type_id);
94 if (size == 4)
return H5FLOAT32;
95 else if (size == 8)
return H5FLOAT64;
96 else return H5UNSUPTYPE;
99 if (H5Tis_variable_str(h5_type_id))
101 else return H5FSTRING;
119 size_t HDF5CFUtil::H5_numeric_atomic_type_size(H5DataType h5type) {
137 throw InternalErr(__FILE__,__LINE__,
"This routine doesn't support to return the size of this datatype");
143 bool HDF5CFUtil::use_lrdata_mem_cache(H5DataType h5type, CVType cvtype,
bool islatlon ) {
144 if(h5type != H5CHAR && h5type !=H5UCHAR && h5type!=H5INT16 && h5type !=H5UINT16 &&
145 h5type != H5INT32 && h5type !=H5UINT32 && h5type !=H5FLOAT32 && h5type!=H5FLOAT64 &&
146 h5type != H5INT64 && h5type !=H5UINT64)
149 if(cvtype != CV_UNSUPPORTED)
152 else if(varpath ==
"")
164 bool HDF5CFUtil::use_data_mem_cache(H5DataType h5type, CVType cvtype,
const string &varpath) {
165 if(h5type != H5CHAR && h5type !=H5UCHAR && h5type!=H5INT16 && h5type !=H5UINT16 &&
166 h5type != H5INT32 && h5type !=H5UINT32 && h5type !=H5FLOAT32 && h5type!=H5FLOAT64 &&
167 h5type != H5INT64 && h5type !=H5UINT64)
170 if(cvtype != CV_UNSUPPORTED)
173 else if(varpath ==
"")
182 bool HDF5CFUtil::cf_strict_support_type(H5DataType dtype) {
183 if ((H5UNSUPTYPE == dtype)||(H5REFERENCE == dtype)
184 || (H5COMPOUND == dtype) || (H5ARRAY == dtype))
193 bool HDF5CFUtil::cf_dap2_support_numeric_type(H5DataType dtype) {
194 if ((H5UNSUPTYPE == dtype)||(H5REFERENCE == dtype)
195 || (H5COMPOUND == dtype) || (H5ARRAY == dtype)
196 || (H5INT64 == dtype) ||(H5UINT64 == dtype)
197 || (H5FSTRING == dtype) ||(H5VSTRING == dtype))
203 string HDF5CFUtil::obtain_string_after_lastslash(
const string s) {
206 size_t last_fslash_pos = s.find_last_of(
"/");
207 if (string::npos != last_fslash_pos &&
208 last_fslash_pos != (s.size()-1))
209 ret_str=s.substr(last_fslash_pos+1);
213 string HDF5CFUtil::obtain_string_before_lastslash(
const string & s) {
216 size_t last_fslash_pos = s.find_last_of(
"/");
217 if (string::npos != last_fslash_pos)
218 ret_str=s.substr(0,last_fslash_pos+1);
225 string temp_sect_str =
"";
226 string temp_sect_newstr =
"";
229 for (
int i = 0; i < num_sect; i++) {
231 if (i != (num_sect-1))
232 temp_sect_str = s.substr(i*sect_size,sect_size);
234 temp_sect_str = s.substr((num_sect-1)*sect_size,s.size()-(num_sect-1)*sect_size);
238 if (H5T_STR_NULLTERM == H5Tget_strpad(ty_id))
239 temp_pos = temp_sect_str.find_first_of(
'\0');
240 else if (H5T_STR_SPACEPAD == H5Tget_strpad(ty_id))
241 temp_pos = temp_sect_str.find_last_not_of(
' ')+1;
242 else temp_pos = temp_sect_str.find_last_not_of(
'0')+1;
244 if (temp_pos != string::npos) {
250 if (H5T_STR_SPACEPAD == H5Tget_strpad(ty_id)) {
252 if (temp_pos == temp_sect_str.size())
253 temp_sect_newstr = temp_sect_str +
" ";
255 temp_sect_newstr = temp_sect_str.substr(0,temp_pos+1);
257 sect_newsize[i] = temp_pos +1;
260 temp_sect_newstr = temp_sect_str.substr(0,temp_pos);
261 sect_newsize[i] = temp_pos ;
268 temp_sect_newstr = temp_sect_str;
273 if (H5T_STR_SPACEPAD == H5Tget_strpad(ty_id)) {
274 temp_sect_newstr.resize(temp_sect_str.size()+1);
275 temp_sect_newstr.append(1,
' ');
276 sect_newsize[i] = sect_size + 1;
279 sect_newsize[i] = sect_size;
281 final_str+=temp_sect_newstr;
287 string HDF5CFUtil::remove_substrings(
string str,
const string &substr) {
289 string::size_type i = str.find(substr);
290 while (i != std::string::npos) {
291 str.erase(i, substr.size());
292 i = str.find(substr, i);
297 void HDF5CFUtil::gen_unique_name(
string &str,set<string>& namelist,
int&clash_index) {
299 pair<set<string>::iterator,
bool> ret;
301 stringstream sclash_index;
302 sclash_index << clash_index;
303 newstr = str + sclash_index.str();
305 ret = namelist.insert(newstr);
306 if (
false == ret.second) {
308 gen_unique_name(str,namelist,clash_index);
315 HDF5CFUtil::Split_helper(vector<string> &tokens,
const string &text,
const char sep)
317 string::size_type start = 0, end = 0;
318 while ((end = text.find(sep, start)) != string::npos) {
319 tokens.push_back(text.substr(start, end - start));
322 tokens.push_back(text.substr(start));
332 for (
int i = 0, j = 0; j <= len; ++j) {
333 if ((j == len && len) || s[j] == sep) {
334 string elem(s + i, j - i);
335 names.push_back(elem);
347 Split(sz, (
int)strlen(sz), sep, names);
350 void HDF5CFUtil::parser_gpm_l3_gridheader(
const vector<char>& value,
351 int& latsize,
int&lonsize,
352 float& lat_start,
float& lon_start,
353 float& lat_res,
float& lon_res,
354 bool check_reg_orig ){
356 float lat_north = 0.;
357 float lat_south = 0.;
361 vector<string> ind_elems;
366 if(ind_elems.size()!=10)
367 throw InternalErr(__FILE__,__LINE__,
"The number of elements in the TRMM level 3 GridHeader is not right.");
369 if(
false == check_reg_orig) {
370 if (0 != ind_elems[1].find(
"Registration=CENTER"))
371 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid registration is not center.");
374 if (0 == ind_elems[2].find(
"LatitudeResolution")){
376 size_t equal_pos = ind_elems[2].find_first_of(
'=');
377 if(string::npos == equal_pos)
378 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
380 size_t scolon_pos = ind_elems[2].find_first_of(
';');
381 if(string::npos == scolon_pos)
382 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
383 if (equal_pos < scolon_pos){
385 string latres_str = ind_elems[2].substr(equal_pos+1,scolon_pos-equal_pos-1);
386 lat_res = strtof(latres_str.c_str(),NULL);
389 throw InternalErr(__FILE__,__LINE__,
"latitude resolution is not right for TRMM level 3 products");
392 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LatitudeResolution doesn't exist.");
394 if (0 == ind_elems[3].find(
"LongitudeResolution")){
396 size_t equal_pos = ind_elems[3].find_first_of(
'=');
397 if(string::npos == equal_pos)
398 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
400 size_t scolon_pos = ind_elems[3].find_first_of(
';');
401 if(string::npos == scolon_pos)
402 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
403 if (equal_pos < scolon_pos){
404 string lonres_str = ind_elems[3].substr(equal_pos+1,scolon_pos-equal_pos-1);
405 lon_res = strtof(lonres_str.c_str(),NULL);
408 throw InternalErr(__FILE__,__LINE__,
"longitude resolution is not right for TRMM level 3 products");
411 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LongitudeResolution doesn't exist.");
413 if (0 == ind_elems[4].find(
"NorthBoundingCoordinate")){
415 size_t equal_pos = ind_elems[4].find_first_of(
'=');
416 if(string::npos == equal_pos)
417 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
419 size_t scolon_pos = ind_elems[4].find_first_of(
';');
420 if(string::npos == scolon_pos)
421 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
422 if (equal_pos < scolon_pos){
423 string north_bounding_str = ind_elems[4].substr(equal_pos+1,scolon_pos-equal_pos-1);
424 lat_north = strtof(north_bounding_str.c_str(),NULL);
427 throw InternalErr(__FILE__,__LINE__,
"NorthBoundingCoordinate is not right for TRMM level 3 products");
431 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid NorthBoundingCoordinate doesn't exist.");
433 if (0 == ind_elems[5].find(
"SouthBoundingCoordinate")){
435 size_t equal_pos = ind_elems[5].find_first_of(
'=');
436 if(string::npos == equal_pos)
437 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
439 size_t scolon_pos = ind_elems[5].find_first_of(
';');
440 if(string::npos == scolon_pos)
441 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
442 if (equal_pos < scolon_pos){
443 string lat_south_str = ind_elems[5].substr(equal_pos+1,scolon_pos-equal_pos-1);
444 lat_south = strtof(lat_south_str.c_str(),NULL);
447 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
451 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid SouthBoundingCoordinate doesn't exist.");
453 if (0 == ind_elems[6].find(
"EastBoundingCoordinate")){
455 size_t equal_pos = ind_elems[6].find_first_of(
'=');
456 if(string::npos == equal_pos)
457 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
459 size_t scolon_pos = ind_elems[6].find_first_of(
';');
460 if(string::npos == scolon_pos)
461 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
462 if (equal_pos < scolon_pos){
463 string lon_east_str = ind_elems[6].substr(equal_pos+1,scolon_pos-equal_pos-1);
464 lon_east = strtof(lon_east_str.c_str(),NULL);
467 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
471 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid EastBoundingCoordinate doesn't exist.");
473 if (0 == ind_elems[7].find(
"WestBoundingCoordinate")){
475 size_t equal_pos = ind_elems[7].find_first_of(
'=');
476 if(string::npos == equal_pos)
477 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
479 size_t scolon_pos = ind_elems[7].find_first_of(
';');
480 if(string::npos == scolon_pos)
481 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
482 if (equal_pos < scolon_pos){
483 string lon_west_str = ind_elems[7].substr(equal_pos+1,scolon_pos-equal_pos-1);
484 lon_west = strtof(lon_west_str.c_str(),NULL);
487 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
491 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid WestBoundingCoordinate doesn't exist.");
493 if (
false == check_reg_orig) {
494 if (0 != ind_elems[8].find(
"Origin=SOUTHWEST"))
495 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid origin is not SOUTHWEST.");
500 latsize =(int)((lat_north-lat_south)/lat_res);
501 lonsize =(int)((lon_east-lon_west)/lon_res);
502 lat_start = lat_south;
503 lon_start = lon_west;
506 void HDF5CFUtil::close_fileid(hid_t file_id,
bool pass_fileid) {
507 if(
false == pass_fileid) {
519 void HDF5CFUtil::rev_str(
char *str,
int len)
537 int HDF5CFUtil::int_to_str(
int x,
char str[],
int d)
542 str[i++] = (x%10) +
'0';
557 void HDF5CFUtil::dtoa(
double n,
char *res,
int afterpoint)
563 double fpart = n - (double)ipart;
566 int i = int_to_str(ipart, res, 0);
576 fpart = fpart * pow(10, afterpoint);
580 int final_fpart = (int)fpart;
581 if(fpart -(
int)fpart >0.5)
582 final_fpart = (int)fpart +1;
583 int_to_str(final_fpart, res + i + 1, afterpoint);
589 string HDF5CFUtil::get_int_str(
int x) {
593 str.push_back(x+
'0');
595 else if (x >10 && x<100) {
596 str.push_back(x/10+
'0');
597 str.push_back(x%10+
'0');
601 int abs_x = (x<0)?-x:x;
607 buf.resize(num_digit);
608 snprintf(&buf[0],num_digit,
"%d",x);
618 string HDF5CFUtil::get_double_str(
double x,
int total_digit,
int after_point) {
624 res.resize(total_digit);
625 for(
int i = 0; i<total_digit;i++)
629 dtoa(-x,&res[0],after_point);
630 for(
int i = 0; i<total_digit;i++) {
632 str.push_back(res[i]);
636 dtoa(x, &res[0], after_point);
638 for(
int i = 0; i<total_digit;i++) {
640 str.push_back(res[i]);
654 int GDij2ll(
int projcode,
int zonecode,
double projparm[],
655 int spherecode,
int xdimsize,
int ydimsize,
656 double upleftpt[],
double lowrightpt[],
657 int npnts,
int row[],
int col[],
658 double longitude[],
double latitude[], EOS5GridPRType pixcen, EOS5GridOriginType pixcnr)
666 int(*hinv_trans[100]) (double,double,
double*,
double*);
667 int(*hfor_trans[100]) (double,double,
double*,
double*);
677 double xMtr0, yMtr0, xMtr1, yMtr1;
683 if (pixcen == HE5_HDFE_CENTER)
734 throw InternalErr(__FILE__,__LINE__,
"Unknown pixel corner to retrieve lat/lon from a grid.");
742 if (projcode != HE5_GCTP_GEO && projcode != HE5_GCTP_BCEA)
745 scaleX = (lowrightpt[0] - upleftpt[0]) / xdimsize;
746 scaleY = (lowrightpt[1] - upleftpt[1]) / ydimsize;
747 string eastFile = HDF5RequestHandler::get_stp_east_filename();
748 string northFile = HDF5RequestHandler::get_stp_north_filename();
750 hinv_init(projcode, zonecode, projparm, spherecode, (
char*)eastFile.c_str(), (
char*)northFile.c_str(),
751 &errorcode, hinv_trans);
758 throw InternalErr(__FILE__,__LINE__,
"GCTP hinv_init Error to retrieve lat/lon from a grid.");
765 for (
int i = 0; i < npnts; i++)
779 arg1 = (((int)col[i] + pixadjX) * scaleX + upleftpt[0]);
780 arg2 = (((int)row[i] + pixadjY) * scaleY + upleftpt[1]);
781 errorcode = hinv_trans[projcode] (arg1, arg2, &lonrad, &latrad);
788 if(projcode == HE5_GCTP_LAMAZ) {
789 longitude[i] = 1.0e51;
790 latitude[i] = 1.0e51;
793 throw InternalErr(__FILE__,__LINE__,
"GCTP hinv_trans Error to retrieve lat/lon from a grid.");
801 longitude[i] = HE5_EHconvAng(lonrad, HE5_HDFE_RAD_DEG);
802 latitude[i] = HE5_EHconvAng(latrad, HE5_HDFE_RAD_DEG);
808 else if (projcode == HE5_GCTP_BCEA)
818 hfor_init(projcode, zonecode, projparm, spherecode, NULL, NULL,&errorcode, hfor_trans);
824 throw InternalErr(__FILE__,__LINE__,
"GCTP hfor_init Error to retrieve lat/lon from a grid.");
829 lonrad0 =HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_RAD);
830 lonrad = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_RAD);
834 latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_RAD);
835 latrad = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_RAD);
840 errorcode = hfor_trans[projcode] (lonrad0, latrad0, &xMtr0, &yMtr0);
845 throw InternalErr(__FILE__,__LINE__,
"GCTP hfor_trans Error to retrieve lat/lon from a grid.");
852 errorcode = hfor_trans[projcode] (lonrad, latrad, &xMtr1, &yMtr1);
857 throw InternalErr(__FILE__,__LINE__,
"GCTP hfor_trans Error to retrieve lat/lon from a grid.");
862 scaleX = (xMtr1 - xMtr0) / xdimsize;
866 scaleY = (yMtr1 - yMtr0) / ydimsize;
870 hinv_init(projcode, zonecode, projparm, spherecode, NULL, NULL, &errorcode, hinv_trans);
875 throw InternalErr(__FILE__,__LINE__,
"GCTP hinv_init Error to retrieve lat/lon from a grid.");
879 for (
int i = 0; i < npnts; i++)
884 errorcode = hinv_trans[projcode] (
885 (col[i] + pixadjX) * scaleX + xMtr0,
886 (row[i] + pixadjY) * scaleY + yMtr0,
900 longitude[i] = 1.0e51;
901 latitude[i] = 1.0e51;
906 longitude[i] = HE5_EHconvAng(lonrad, HE5_HDFE_RAD_DEG);
907 latitude[i] = HE5_EHconvAng(latrad, HE5_HDFE_RAD_DEG);
911 else if (projcode == HE5_GCTP_GEO)
924 lonrad0 = HE5_EHconvAng(upleftpt[0], HE5_HDFE_DMS_DEG);
925 lonrad = HE5_EHconvAng(lowrightpt[0], HE5_HDFE_DMS_DEG);
929 scaleX = (lonrad - lonrad0) / xdimsize;
933 latrad0 = HE5_EHconvAng(upleftpt[1], HE5_HDFE_DMS_DEG);
934 latrad = HE5_EHconvAng(lowrightpt[1], HE5_HDFE_DMS_DEG);
938 scaleY = (latrad - latrad0) / ydimsize;
942 for (
int i = 0; i < npnts; i++)
946 longitude[i] = (col[i] + pixadjX) * scaleX + lonrad0;
947 latitude[i] = (row[i] + pixadjY) * scaleY + latrad0;
953 hinv_init(projcode, zonecode, projparm, spherecode, eastFile, northFile,
954 (
int *)&errorcode, hinv_trans);
956 for (
int i = 0; i < npnts; i++)
962 hinv_trans[projcode] (
977 HE5_EHconvAng(
double inAngle,
int code)
983 double outAngle = 0.;
984 double pi = 3.14159265358979324;
985 double r2d = 180 / pi;
986 double d2r = 1 / r2d;
993 case HE5_HDFE_RAD_DEG:
994 outAngle = inAngle * r2d;
999 case HE5_HDFE_DEG_RAD:
1000 outAngle = inAngle * d2r;
1006 case HE5_HDFE_DMS_DEG:
1007 deg = (long)(inAngle / 1000000);
1008 min = (long)((inAngle - deg * 1000000) / 1000);
1009 sec = (inAngle - deg * 1000000 - min * 1000);
1010 outAngle = deg + min / 60.0 + sec / 3600.0;
1016 case HE5_HDFE_DEG_DMS:
1018 deg = (long)inAngle;
1019 min = (long)((inAngle - deg) * 60);
1020 sec = (inAngle - deg - min / 60.0) * 3600;
1030 if ( fabs(sec - 0.0) < 1.e-7 )
1035 if ( (fabs(sec - 60) < 1.e-7 ) || ( sec > 60.0 ))
1049 outAngle = deg * 1000000 + min * 1000 + sec;
1056 case HE5_HDFE_RAD_DMS:
1058 inAngle = inAngle * r2d;
1059 deg = (long)inAngle;
1060 min = (long)((inAngle - deg) * 60);
1061 sec = ((inAngle - deg - min / 60.0) * 3600);
1071 if ( fabs(sec - 0.0) < 1.e-7 )
1076 if ( (fabs(sec - 60) < 1.e-7 ) || ( sec > 60.0 ))
1090 outAngle = deg * 1000000 + min * 1000 + sec;
1097 case HE5_HDFE_DMS_RAD:
1098 deg = (long)(inAngle / 1000000);
1099 min = (long)((inAngle - deg * 1000000) / 1000);
1100 sec = (inAngle - deg * 1000000 - min * 1000);
1101 outAngle = deg + min / 60.0 + sec / 3600.0;
1102 outAngle = outAngle * d2r;
1117 HDF5CFUtil::INDEX_nD_TO_1D (
const std::vector <size_t > &dims,
1118 const std::vector < size_t > &pos)
1124 if(dims.size () != pos.size ())
1125 throw InternalErr(__FILE__,__LINE__,
"dimension error in INDEX_nD_TO_1D routine.");
1129 for (
size_t p = 0; p < pos.size (); p++) {
1132 for (
size_t j = start; j < dims.size (); j++)
1154 template<
typename T>
1155 int HDF5CFUtil::subset(
1162 std::vector<T> *poutput,
1166 for(
int k=0; k<edge[index]; k++)
1168 pos[index] = start[index] + k*stride[index];
1170 subset(input, rank, dim, start, stride, edge, poutput,pos,index+1);
1173 poutput->push_back(input[INDEX_nD_TO_1D( dim, pos)]);
1183 ssize_t ret_val = read(fd,buf,total_read);
1188 string HDF5CFUtil::obtain_cache_fname(
const string & fprefix,
const string &fname,
const string &vname) {
1190 string cache_fname = fprefix;
1192 string correct_fname = fname;
1193 std::replace(correct_fname.begin(),correct_fname.end(),
'/',
'_');
1195 string correct_vname = vname;
1198 std::replace(correct_vname.begin(),correct_vname.end(),
'/',
'_');
1201 std::replace(correct_vname.begin(),correct_vname.end(),
' ',
'_');
1204 cache_fname = cache_fname +correct_fname +correct_vname;
1208 size_t INDEX_nD_TO_1D (
const std::vector < size_t > &dims,
1209 const std::vector < size_t > &pos){
1214 if(dims.size () != pos.size ())
1215 throw InternalErr(__FILE__,__LINE__,
"dimension error in INDEX_nD_TO_1D routine.");
1219 for (
size_t p = 0; p < pos.size (); p++) {
1222 for (
size_t j = start; j < dims.size (); j++)