6 #define SIGNED_BYTE_TO_INT32 1
21 const string dosettrue =
"true";
22 const string dosetyes =
"yes";
27 if( dosettrue == doset || dosetyes == doset )
41 for (
int i = 0, j = 0; j <= len; ++j) {
42 if ((j == len && len) || s[j] == sep) {
43 string elem(s + i, j - i);
44 names.push_back(elem);
55 Split(sz, (
int)strlen(sz), sep, names);
66 pair<map<string,string>::iterator,
bool> ret;
67 ret = m.insert(make_pair(key, val));
68 if(ret.second ==
false){
70 ret = m.insert(make_pair(key, val));
71 if(ret.second ==
false){
72 BESDEBUG(
"h4",
"insert_map():insertion failed on Key=" << key <<
" Val=" << val << endl);
85 string insertString(1,
'_');
88 if (
true == isdigit(s[0]))
89 s.insert(0,insertString);
95 for(
unsigned int i=0; i < s.length(); i++)
96 if((
false == isalnum(s[i])) && (s[i]!=
'_'))
112 pair<set<string>::iterator,
bool> ret;
114 stringstream sclash_index;
115 sclash_index << clash_index;
116 newstr = str + sclash_index.str();
118 ret = namelist.insert(newstr);
119 if (
false == ret.second) {
121 gen_unique_name(str,namelist,clash_index);
134 pair<set<string>::iterator,
bool> setret;
135 set<string>::iterator iss;
137 vector<string> clashnamelist;
138 vector<string>::iterator ivs;
141 map<int,int> cl_to_ol;
145 vector<string>::const_iterator irv;
147 for (irv = newobjnamelist.begin(); irv != newobjnamelist.end(); ++irv) {
148 setret = objnameset.insert((*irv));
149 if (
false == setret.second ) {
150 clashnamelist.insert(clashnamelist.end(),(*irv));
151 cl_to_ol[cl_index] = ol_index;
159 for (ivs=clashnamelist.begin(); ivs!=clashnamelist.end(); ivs++) {
161 string temp_clashname = *ivs +
'_';
163 *ivs = temp_clashname;
167 for (
unsigned int i =0; i <clashnamelist.size(); i++)
168 newobjnamelist[cl_to_ol[i]] = clashnamelist[i];
178 set<string> objnameset;
179 Handle_NameClashing(newobjnamelist,objnameset);
206 gp.ucp = (
unsigned char *) vals;
216 gp.cp = (
char *) vals;
227 return escattr(static_cast<const char*>(vals));
232 gp.sp = (
short *) vals;
239 gp.usp = (
unsigned short *) vals;
240 rep << *(gp.usp+loc);
246 gp.lp = (int32 *) vals;
253 gp.ui = (
unsigned int *) vals;
260 gp.fp = (
float *) vals;
262 rep << setprecision(10);
264 if (rep.str().find(
'.') == string::npos
265 && rep.str().find(
'e') == string::npos)
272 gp.dp = (
double *) vals;
273 rep << std::showpoint;
274 rep << std::setprecision(17);
276 if (rep.str().find(
'.') == string::npos
277 && rep.str().find(
'e') == string::npos)
283 return string(
"UNKNOWN");
294 static const char UNKNOWN[]=
"Unknown";
295 static const char BYTE[]=
"Byte";
296 static const char INT16[]=
"Int16";
297 static const char UINT16[]=
"UInt16";
298 static const char INT32[]=
"Int32";
299 static const char UINT32[]=
"UInt32";
300 static const char FLOAT32[]=
"Float32";
301 static const char FLOAT64[]=
"Float64";
302 static const char STRING[]=
"String";
319 #ifndef SIGNED_BYTE_TO_INT32
352 template <
typename T >
363 T (*templatlonptr)[majordim][minordim] = (typeof templatlonptr) latlon;
368 int dim0count = count[0];
369 int dim1count = count[1];
370 int dim0index[dim0count], dim1index[dim1count];
372 for (i = 0; i < count[0]; i++)
373 dim0index[i] = offset[0] + i * step[0];
376 for (j = 0; j < count[1]; j++)
377 dim1index[j] = offset[1] + j * step[1];
382 for (i = 0; i < count[0]; i++) {
383 for (j = 0; j < count[1]; j++) {
384 outlatlon[k] = (*templatlonptr)[dim0index[i]][dim1index[j]];
397 AttrTable::Attr_iter it = at->attr_begin();
398 bool find_fvalue =
false;
399 while (it!=at->attr_end() &&
false==find_fvalue) {
400 if (at->get_name(it) ==
"_FillValue")
403 string fillvalue =
"";
404 string fillvalue_type =
"";
405 if((*at->get_attr_vector(it)).size() !=1)
406 throw InternalErr(__FILE__,__LINE__,
"The number of _FillValue must be 1.");
407 fillvalue = (*at->get_attr_vector(it)->begin());
408 fillvalue_type = at->get_type(it);
411 if(fillvalue_type != var_type){
413 at->del_attr(
"_FillValue");
415 if (fillvalue_type ==
"String") {
419 if(fillvalue.size() >1) {
421 long int fillvalue_int = 0;
422 vector<char> fillvalue_temp(fillvalue.size());
424 fillvalue_int = strtol((fillvalue.substr(1)).c_str(),&pEnd,8);
425 stringstream convert_str;
426 convert_str << fillvalue_int;
427 at->append_attr(
"_FillValue",var_type,convert_str.str());
436 short fillvalue_int = fillvalue.at(0);
438 stringstream convert_str;
439 convert_str << fillvalue_int;
440 if(fillvalue_int <0 || fillvalue_int >128)
441 throw InternalErr(__FILE__,__LINE__,
442 "If the fillvalue is a char type, the value must be between 0 and 128.");
445 at->append_attr(
"_FillValue",var_type,convert_str.str());
450 at->append_attr(
"_FillValue",var_type,fillvalue);
464 AttrTable::Attr_iter it = at->attr_begin();
465 bool find_scale =
false;
466 bool find_offset =
false;
469 string scale_factor_type;
470 string add_offset_type;
471 string scale_factor_value;
472 string add_offset_value;
474 while (it!=at->attr_end() &&((find_scale!=
true) ||(find_offset!=
true))) {
475 if (at->get_name(it) ==
"scale_factor")
478 scale_factor_value = (*at->get_attr_vector(it)->begin());
479 scale_factor_type = at->get_type(it);
482 if(at->get_name(it)==
"add_offset")
485 add_offset_value = (*at->get_attr_vector(it)->begin());
486 add_offset_type = at->get_type(it);
493 if((
true==find_scale) && (
true==find_offset)) {
494 if(scale_factor_type != add_offset_type) {
495 at->del_attr(
"add_offset");
496 at->append_attr(
"add_offset",scale_factor_type,add_offset_value);
502 #ifdef USE_HDFEOS2_LIB
508 bool HDFCFUtil::is_special_value(int32 dtype,
float fillvalue,
float realvalue) {
510 bool ret_value =
false;
512 if (DFNT_UINT16 == dtype) {
514 int fillvalue_int = (int)fillvalue;
516 int realvalue_int = (int)realvalue;
532 int HDFCFUtil::check_geofile_dimmap(
const string & geofilename) {
534 int32 fileid = SWopen(const_cast<char*>(geofilename.c_str()),DFACC_READ);
537 string swathname =
"MODIS_Swath_Type_GEO";
538 int32 datasetid = SWattach(fileid,const_cast<char*>(swathname.c_str()));
548 if ((nummaps = SWnentries(datasetid, HDFE_NENTMAP, &bufsize)) == -1) {
571 bool HDFCFUtil::change_data_type(DAS & das,
SOType scaletype,
const string &new_field_name)
574 AttrTable *at = das.get_table(new_field_name);
584 AttrTable::Attr_iter it = at->attr_begin();
585 string scale_factor_value=
"";
586 string add_offset_value=
"0";
587 string radiance_scales_value=
"";
588 string radiance_offsets_value=
"";
589 string reflectance_scales_value=
"";
590 string reflectance_offsets_value=
"";
591 string scale_factor_type, add_offset_type;
592 while (it!=at->attr_end())
594 if(at->get_name(it)==
"radiance_scales")
595 radiance_scales_value = *(at->get_attr_vector(it)->begin());
596 if(at->get_name(it)==
"radiance_offsets")
597 radiance_offsets_value = *(at->get_attr_vector(it)->begin());
598 if(at->get_name(it)==
"reflectance_scales")
599 reflectance_scales_value = *(at->get_attr_vector(it)->begin());
600 if(at->get_name(it)==
"reflectance_offsets")
601 reflectance_offsets_value = *(at->get_attr_vector(it)->begin());
606 if(at->get_name(it).find(
"scale_factor")!=string::npos){
607 string temp_attr_name = at->get_name(it);
608 if (temp_attr_name !=
"scale_factor_err") {
609 scale_factor_value = *(at->get_attr_vector(it)->begin());
610 scale_factor_type = at->get_type(it);
613 if(at->get_name(it).find(
"add_offset")!=string::npos)
615 string temp_attr_name = at->get_name(it);
616 if (temp_attr_name !=
"add_offset_err") {
617 add_offset_value = *(at->get_attr_vector(it)->begin());
618 add_offset_type = at->get_type(it);
624 if((radiance_scales_value.length()!=0 && radiance_offsets_value.length()!=0)
625 || (reflectance_scales_value.length()!=0 && reflectance_offsets_value.length()!=0))
628 if(scale_factor_value.length()!=0)
630 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
639 void HDFCFUtil::obtain_dimmap_info(
const string& filename,HDFEOS2::Dataset*dataset,
640 vector<struct dimmap_entry> & dimmaps,
641 string & modis_geofilename,
bool& geofile_has_dimmap) {
644 HDFEOS2::SwathDataset *sw =
static_cast<HDFEOS2::SwathDataset *
>(dataset);
645 const vector<HDFEOS2::SwathDataset::DimensionMap*>& origdimmaps = sw->getDimensionMaps();
646 vector<HDFEOS2::SwathDataset::DimensionMap*>::const_iterator it_dmap;
650 for(
size_t i=0;i<origdimmaps.size();i++){
651 tempdimmap.
geodim = origdimmaps[i]->getGeoDimension();
652 tempdimmap.datadim = origdimmaps[i]->getDataDimension();
653 tempdimmap.offset = origdimmaps[i]->getOffset();
654 tempdimmap.inc = origdimmaps[i]->getIncrement();
655 dimmaps.push_back(tempdimmap);
658 string check_modis_geofile_key =
"H4.EnableCheckMODISGeoFile";
659 bool check_geofile_key =
false;
664 if((origdimmaps.size() != 0) && (
true == check_geofile_key) ) {
668 tempcstr =
new char [filename.size()+1];
669 strncpy (tempcstr,filename.c_str(),filename.size());
670 string basefilename =
basename(tempcstr);
671 string dirfilename = dirname(tempcstr);
675 bool is_modis_geofile =
false;
676 if(basefilename.size() >5) {
677 if((0 == basefilename.compare(0,5,
"MOD03")) || (0 == basefilename.compare(0,5,
"MYD03")))
678 is_modis_geofile =
true;
697 if ((
false == is_modis_geofile) && (basefilename.size() >3)) {
699 string fnameprefix = basefilename.substr(0,3);
701 if(fnameprefix ==
"MYD" || fnameprefix ==
"MOD") {
702 size_t fnamemidpos = basefilename.find(
".A");
703 if(fnamemidpos != string::npos) {
704 string fnamemiddle = basefilename.substr(fnamemidpos,14);
705 if(fnamemiddle.size()==14) {
706 string geofnameprefix = fnameprefix+
"03";
708 string geofnamefp = geofnameprefix + fnamemiddle;
713 dirp = opendir(dirfilename.c_str());
715 throw InternalErr(__FILE__,__LINE__,
"opendir fails.");
717 while ((dirs = readdir(dirp))!=
NULL){
718 if(strncmp(dirs->d_name,geofnamefp.c_str(),geofnamefp.size())==0){
719 modis_geofilename = dirfilename +
"/"+ dirs->d_name;
720 int num_dimmap = HDFCFUtil::check_geofile_dimmap(modis_geofilename);
721 if (num_dimmap < 0) {
723 throw InternalErr(__FILE__,__LINE__,
"this file is not a MODIS geolocation file.");
725 geofile_has_dimmap = (num_dimmap >0)?
true:
false;
740 bool HDFCFUtil::is_modis_dimmap_nonll_field(
string & fieldname) {
742 bool modis_dimmap_nonll_field =
false;
743 vector<string> modis_dimmap_nonll_fieldlist;
745 modis_dimmap_nonll_fieldlist.push_back(
"Height");
746 modis_dimmap_nonll_fieldlist.push_back(
"SensorZenith");
747 modis_dimmap_nonll_fieldlist.push_back(
"SensorAzimuth");
748 modis_dimmap_nonll_fieldlist.push_back(
"Range");
749 modis_dimmap_nonll_fieldlist.push_back(
"SolarZenith");
750 modis_dimmap_nonll_fieldlist.push_back(
"SolarAzimuth");
751 modis_dimmap_nonll_fieldlist.push_back(
"Land/SeaMask");
752 modis_dimmap_nonll_fieldlist.push_back(
"gflags");
753 modis_dimmap_nonll_fieldlist.push_back(
"Solar_Zenith");
754 modis_dimmap_nonll_fieldlist.push_back(
"Solar_Azimuth");
755 modis_dimmap_nonll_fieldlist.push_back(
"Sensor_Azimuth");
756 modis_dimmap_nonll_fieldlist.push_back(
"Sensor_Zenith");
758 map<string,string>modis_field_to_geofile_field;
759 map<string,string>::iterator itmap;
760 modis_field_to_geofile_field[
"Solar_Zenith"] =
"SolarZenith";
761 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
762 modis_field_to_geofile_field[
"Sensor_Zenith"] =
"SensorZenith";
763 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
765 for (
unsigned int i = 0; i <modis_dimmap_nonll_fieldlist.size(); i++) {
767 if (fieldname == modis_dimmap_nonll_fieldlist[i]) {
768 itmap = modis_field_to_geofile_field.find(fieldname);
769 if (itmap !=modis_field_to_geofile_field.end())
770 fieldname = itmap->second;
771 modis_dimmap_nonll_field =
true;
776 return modis_dimmap_nonll_field;
780 void HDFCFUtil::handle_modis_special_attrs_disable_scale_comp(AttrTable *at,
781 const string &filename,
783 const string & newfname,
787 string scale_factor_type;
788 string add_offset_type;
791 string scale_factor_value=
"";
792 float orig_scale_value = 1;
793 string add_offset_value=
"0";
794 float orig_offset_value = 0;
795 bool add_offset_found =
false;
800 AttrTable::Attr_iter it = at->attr_begin();
801 while (it!=at->attr_end())
803 if(at->get_name(it)==
"scale_factor")
805 scale_factor_value = (*at->get_attr_vector(it)->begin());
806 orig_scale_value = atof(scale_factor_value.c_str());
807 scale_factor_type = at->get_type(it);
810 if(at->get_name(it)==
"add_offset")
812 add_offset_value = (*at->get_attr_vector(it)->begin());
813 orig_offset_value = atof(add_offset_value.c_str());
814 add_offset_type = at->get_type(it);
815 add_offset_found =
true;
841 if(scale_factor_value.length()!=0) {
843 if (orig_scale_value > 1) {
845 bool need_change_scale =
true;
846 if(
true == is_grid) {
847 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
848 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
849 need_change_scale =
false;
852 if(
true == need_change_scale) {
854 (*
BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< scale_factor_value << endl
855 <<
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE. " << endl
856 <<
" Now change it to MODIS_DIV_SCALE. "<<endl;
862 if (orig_scale_value < 1) {
864 (*
BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< scale_factor_value << endl
865 <<
" But the original scale factor type is MODIS_DIV_SCALE. " << endl
866 <<
" Now change it to MODIS_MUL_SCALE. "<<endl;
874 at->del_attr(
"scale_factor");
880 if (
true == add_offset_found) {
881 float new_offset_value = (orig_offset_value ==0)?0:(-1 * orig_offset_value *orig_scale_value);
883 at->del_attr(
"add_offset");
890 float new_scale_value = 1.0/orig_scale_value;
892 at->del_attr(
"scale_factor");
898 if (
true == add_offset_found) {
899 float new_offset_value = (orig_offset_value==0)?0:(-1 * orig_offset_value *new_scale_value);
901 at->del_attr(
"add_offset");
926 void HDFCFUtil::handle_modis_special_attrs(AttrTable *at,
const string & filename,
927 bool is_grid,
const string & newfname,
928 SOType sotype,
bool gridname_change_valid_range,
929 bool changedtype,
bool & change_fvtype){
932 string scale_factor_type;
933 string add_offset_type;
934 string fillvalue_type;
935 string valid_range_type;
939 string scale_factor_value=
"";
940 float orig_scale_value = 1;
941 string add_offset_value=
"0";
942 float orig_offset_value = 0;
943 bool add_offset_found =
false;
949 string valid_range_value=
"";
951 bool has_valid_range =
false;
954 float orig_valid_min = 0;
955 float orig_valid_max = 0;
958 string number_type_value=
"";
959 string number_type_dap_type=
"";
963 AttrTable::Attr_iter it = at->attr_begin();
964 while (it!=at->attr_end())
966 if(at->get_name(it)==
"scale_factor")
968 scale_factor_value = (*at->get_attr_vector(it)->begin());
969 orig_scale_value = atof(scale_factor_value.c_str());
970 scale_factor_type = at->get_type(it);
973 if(at->get_name(it)==
"add_offset")
975 add_offset_value = (*at->get_attr_vector(it)->begin());
976 orig_offset_value = atof(add_offset_value.c_str());
977 add_offset_type = at->get_type(it);
978 add_offset_found =
true;
981 if(at->get_name(it)==
"_FillValue")
983 fillvalue = (*at->get_attr_vector(it)->begin());
984 fillvalue_type = at->get_type(it);
987 if(at->get_name(it)==
"valid_range")
989 vector<string> *avalue = at->get_attr_vector(it);
990 vector<string>::iterator ait = avalue->begin();
991 while(ait!=avalue->end())
993 valid_range_value += *ait;
995 if(ait!=avalue->end())
996 valid_range_value +=
", ";
998 valid_range_type = at->get_type(it);
999 if (
false == gridname_change_valid_range) {
1000 orig_valid_min = (float)(atof((avalue->at(0)).c_str()));
1001 orig_valid_max = (float)(atof((avalue->at(1)).c_str()));
1003 has_valid_range =
true;
1006 if(
true == changedtype && (at->get_name(it)==
"Number_Type"))
1008 number_type_value = (*at->get_attr_vector(it)->begin());
1009 number_type_dap_type= at->get_type(it);
1017 if(scale_factor_value.length()!=0)
1019 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
1021 at->del_attr(
"scale_factor");
1022 at->append_attr(
"orig_scale_factor", scale_factor_type, scale_factor_value);
1023 if(add_offset_found)
1025 at->del_attr(
"add_offset");
1026 at->append_attr(
"orig_add_offset", add_offset_type, add_offset_value);
1032 if(
true == changedtype && fillvalue.length()!=0 && fillvalue_type!=
"Float32" && fillvalue_type!=
"Float64")
1034 change_fvtype =
true;
1035 at->del_attr(
"_FillValue");
1036 at->append_attr(
"_FillValue",
"Float32", fillvalue);
1039 float valid_max = 0;
1040 float valid_min = 0;
1042 it = at->attr_begin();
1043 bool handle_modis_l1b =
false;
1051 string emissive_str =
"Emissive";
1052 string RefSB_str =
"RefSB";
1053 bool is_emissive_field =
false;
1054 bool is_refsb_field =
false;
1055 if(newfname.find(emissive_str)!=string::npos) {
1056 if(0 == newfname.compare(newfname.size()-emissive_str.size(),emissive_str.size(),emissive_str))
1057 is_emissive_field =
true;
1060 if(newfname.find(RefSB_str)!=string::npos) {
1061 if(0 == newfname.compare(newfname.size()-RefSB_str.size(),RefSB_str.size(),RefSB_str))
1062 is_refsb_field =
true;
1066 if ((
true == is_emissive_field) || (
true== is_refsb_field)){
1068 float scale_max = 0;
1069 float scale_min = 100000;
1071 float offset_max = 0;
1072 float offset_min = 0;
1074 float temp_var_val = 0;
1076 string orig_long_name_value;
1077 string modify_long_name_value;
1078 string str_removed_from_long_name=
" Scaled Integers";
1079 string radiance_units_value;
1081 while (it!=at->attr_end())
1084 if(
true == is_emissive_field) {
1086 if (
"radiance_scales" == (at->get_name(it))) {
1087 vector<string> *avalue = at->get_attr_vector(it);
1088 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1089 temp_var_val = (float)(atof((*ait).c_str()));
1090 if (temp_var_val > scale_max)
1091 scale_max = temp_var_val;
1092 if (temp_var_val < scale_min)
1093 scale_min = temp_var_val;
1097 if (
"radiance_offsets" == (at->get_name(it))) {
1098 vector<string> *avalue = at->get_attr_vector(it);
1099 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1100 temp_var_val = (float)(atof((*ait).c_str()));
1101 if (temp_var_val > offset_max)
1102 offset_max = temp_var_val;
1103 if (temp_var_val < scale_min)
1104 offset_min = temp_var_val;
1108 if (
"long_name" == (at->get_name(it))) {
1109 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1110 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1111 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1112 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1114 modify_long_name_value =
1115 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1116 at->del_attr(
"long_name");
1117 at->append_attr(
"long_name",
"String",modify_long_name_value);
1118 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1123 if (
"radiance_units" == (at->get_name(it)))
1124 radiance_units_value = (*at->get_attr_vector(it)->begin());
1127 if (
true == is_refsb_field) {
1128 if (
"reflectance_scales" == (at->get_name(it))) {
1129 vector<string> *avalue = at->get_attr_vector(it);
1130 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1131 temp_var_val = (float)(atof((*ait).c_str()));
1132 if (temp_var_val > scale_max)
1133 scale_max = temp_var_val;
1134 if (temp_var_val < scale_min)
1135 scale_min = temp_var_val;
1139 if (
"reflectance_offsets" == (at->get_name(it))) {
1141 vector<string> *avalue = at->get_attr_vector(it);
1142 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1143 temp_var_val = (float)(atof((*ait).c_str()));
1144 if (temp_var_val > offset_max)
1145 offset_max = temp_var_val;
1146 if (temp_var_val < scale_min)
1147 offset_min = temp_var_val;
1151 if (
"long_name" == (at->get_name(it))) {
1152 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1153 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1154 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1155 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1157 modify_long_name_value =
1158 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1159 at->del_attr(
"long_name");
1160 at->append_attr(
"long_name",
"String",modify_long_name_value);
1161 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1171 throw InternalErr(__FILE__,__LINE__,
"the scale factor should always be greater than 0.");
1173 if (orig_valid_max > offset_min)
1174 valid_max = (orig_valid_max-offset_min)*scale_max;
1176 valid_max = (orig_valid_max-offset_min)*scale_min;
1178 if (orig_valid_min > offset_max)
1179 valid_min = (orig_valid_min-offset_max)*scale_min;
1181 valid_min = (orig_valid_min -offset_max)*scale_max;
1188 at->append_attr(
"valid_min",
"Float32",print_rep);
1190 at->append_attr(
"valid_max",
"Float32",print_rep);
1191 at->del_attr(
"valid_range");
1192 handle_modis_l1b =
true;
1195 if (
true == is_emissive_field && radiance_units_value.size() >0) {
1196 at->del_attr(
"units");
1197 at->append_attr(
"units",
"String",radiance_units_value);
1203 if(
true == changedtype &&
true == has_valid_range &&
false == handle_modis_l1b) {
1206 if (
true == gridname_change_valid_range)
1207 HDFCFUtil::handle_modis_vip_special_attrs(valid_range_value,scale_factor_value,valid_min,valid_max);
1208 else if(scale_factor_value.length()!=0) {
1228 if (orig_scale_value > 1) {
1230 bool need_change_scale =
true;
1231 if(
true == is_grid) {
1232 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
1233 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
1234 need_change_scale =
false;
1237 if(
true == need_change_scale) {
1239 (*
BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< orig_scale_value << endl
1240 <<
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE. " << endl
1241 <<
" Now change it to MODIS_DIV_SCALE. "<<endl;
1247 if (orig_scale_value < 1) {
1249 (*
BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< orig_scale_value << endl
1250 <<
" But the original scale factor type is MODIS_DIV_SCALE. " << endl
1251 <<
" Now change it to MODIS_MUL_SCALE. "<<endl;
1256 valid_min = (orig_valid_min - orig_offset_value)*orig_scale_value;
1257 valid_max = (orig_valid_max - orig_offset_value)*orig_scale_value;
1260 valid_min = (orig_valid_min - orig_offset_value)/orig_scale_value;
1261 valid_max = (orig_valid_max - orig_offset_value)/orig_scale_value;
1264 valid_min = orig_valid_min * orig_scale_value + orig_offset_value;
1265 valid_max = orig_valid_max * orig_scale_value + orig_offset_value;
1270 valid_min = orig_valid_min - orig_offset_value;
1271 valid_max = orig_valid_max - orig_offset_value;
1274 valid_min = orig_valid_min + orig_offset_value;
1275 valid_max = orig_valid_max + orig_offset_value;
1281 at->append_attr(
"valid_min",
"Float32",print_rep);
1283 at->append_attr(
"valid_max",
"Float32",print_rep);
1284 at->del_attr(
"valid_range");
1290 if(
true == changedtype && number_type_dap_type !=
"" ) {
1291 at->del_attr(
"Number_Type");
1292 at->append_attr(
"Number_Type_Orig",number_type_dap_type,number_type_value);
1298 void HDFCFUtil::handle_modis_vip_special_attrs(
const std::string& valid_range_value,
1299 const std::string& scale_factor_value,
1300 float& valid_min,
float &valid_max) {
1302 int16 vip_orig_valid_min = 0;
1303 int16 vip_orig_valid_max = 0;
1305 size_t found = valid_range_value.find_first_of(
",");
1306 size_t found_from_end = valid_range_value.find_last_of(
",");
1307 if (string::npos == found)
1308 throw InternalErr(__FILE__,__LINE__,
"should find the separator ,");
1309 if (found != found_from_end)
1310 throw InternalErr(__FILE__,__LINE__,
"There should be only one separator.");
1315 vip_orig_valid_min = atoi((valid_range_value.substr(0,found)).c_str());
1316 vip_orig_valid_max = atoi((valid_range_value.substr(found+1)).c_str());
1318 int16 scale_factor_number = 1;
1321 scale_factor_number = atoi(scale_factor_value.c_str());
1323 valid_min = (float)(vip_orig_valid_min/scale_factor_number);
1324 valid_max = (float)(vip_orig_valid_max/scale_factor_number);
1329 void HDFCFUtil::handle_amsr_attrs(AttrTable *at) {
1331 AttrTable::Attr_iter it = at->attr_begin();
1332 string scale_factor_value=
"", add_offset_value=
"0";
1333 string scale_factor_type, add_offset_type;
1334 bool OFFSET_found =
false;
1335 bool Scale_found =
false;
1336 bool SCALE_FACTOR_found =
false;
1338 while (it!=at->attr_end())
1340 if(at->get_name(it)==
"SCALE_FACTOR")
1342 scale_factor_value = (*at->get_attr_vector(it)->begin());
1343 scale_factor_type = at->get_type(it);
1344 SCALE_FACTOR_found =
true;
1347 if(at->get_name(it)==
"Scale")
1349 scale_factor_value = (*at->get_attr_vector(it)->begin());
1350 scale_factor_type = at->get_type(it);
1354 if(at->get_name(it)==
"OFFSET")
1356 add_offset_value = (*at->get_attr_vector(it)->begin());
1357 add_offset_type = at->get_type(it);
1358 OFFSET_found =
true;
1363 if (
true == SCALE_FACTOR_found) {
1364 at->del_attr(
"SCALE_FACTOR");
1365 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1368 if (
true == Scale_found) {
1369 at->del_attr(
"Scale");
1370 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1373 if (
true == OFFSET_found) {
1374 at->del_attr(
"OFFSET");
1375 at->append_attr(
"add_offset",add_offset_type,add_offset_value);
1385 float & slope,
bool &global_slope_flag,
1386 float & intercept,
bool & global_intercept_flag){
1399 if((*i)->getName()==
"Scaling")
1401 string tmpstring((*i)->getValue().begin(), (*i)->getValue().end());
1402 scaling = tmpstring;
1404 if((*i)->getName()==
"Slope" || (*i)->getName()==
"slope")
1406 global_slope_flag =
true;
1408 switch((*i)->getType())
1410 #define GET_SLOPE(TYPE, CAST) \
1413 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1414 slope = (float)tmpvalue; \
1425 if((*i)->getName()==
"Intercept" || (*i)->getName()==
"intercept")
1427 global_intercept_flag =
true;
1428 switch((*i)->getType())
1430 #define GET_INTERCEPT(TYPE, CAST) \
1433 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1434 intercept = (float)tmpvalue; \
1441 #undef GET_INTERCEPT
1454 string& scaling,
float& slope,
1455 bool& global_slope_flag,
1457 bool & global_intercept_flag) {
1459 AttrTable *at = das.get_table(onespsds->
getNewName());
1461 at = das.add_table(onespsds->
getNewName(),
new AttrTable);
1465 bool scale_factor_flag =
false;
1466 bool add_offset_flag =
false;
1467 bool slope_flag =
false;
1468 bool intercept_flag =
false;
1471 for(vector<HDFSP::Attribute *>::const_iterator i=onespsds->
getAttributes().begin();
1473 if(global_slope_flag !=
true && ((*i)->getName()==
"Slope" || (*i)->getName()==
"slope"))
1477 switch((*i)->getType())
1479 #define GET_SLOPE(TYPE, CAST) \
1482 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1483 slope = (float)tmpvalue; \
1495 if(global_intercept_flag !=
true && ((*i)->getName()==
"Intercept" || (*i)->getName()==
"intercept"))
1497 intercept_flag =
true;
1498 switch((*i)->getType())
1500 #define GET_INTERCEPT(TYPE, CAST) \
1503 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1504 intercept = (float)tmpvalue; \
1511 #undef GET_INTERCEPT
1522 scale_factor_flag =
true;
1525 add_offset_flag =
true;
1535 if(
false == scale_factor_flag && (
true == slope_flag ||
true == global_slope_flag))
1541 if(
false == add_offset_flag && (
true == intercept_flag ||
true == global_intercept_flag))
1548 bool has_fill_value =
false;
1550 if (
"_FillValue" == (*i)->getNewName()){
1551 has_fill_value =
true;
1559 if ((
false == has_fill_value) &&(DFNT_INT16 == onespsds->
getType())) {
1560 short fill_value = -32767;
1565 if ((
false == has_fill_value) &&(DFNT_UINT16 == onespsds->
getType())) {
1566 unsigned short fill_value = 65535;
1586 vector<HDFSP::SDField *>::const_iterator it_g;
1590 bool latflag =
false;
1591 bool latunitsflag =
false;
1592 bool lonflag =
false;
1593 bool lonunitsflag =
false;
1594 int llcheckoverflag = 0;
1606 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1610 if (
true == f->
Has_Dim_NoScale_Field() && ((*it_g)->getFieldType() !=0) && ((*it_g)->IsDimScale() ==
false))
1617 AttrTable *at = das.get_table((*it_g)->getNewName());
1619 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1621 for(vector<HDFSP::Attribute *>::const_iterator i=(*it_g)->getAttributes().begin();i!=(*it_g)->getAttributes().end();i++) {
1622 if((*i)->getType()==DFNT_UCHAR || (*i)->getType() == DFNT_CHAR){
1624 if((*i)->getName() ==
"long_name") {
1625 string tempstring2((*i)->getValue().begin(),(*i)->getValue().end());
1626 string tempfinalstr= string(tempstring2.c_str());
1627 if(tempfinalstr==
"latitude" || tempfinalstr ==
"Latitude")
1629 if(tempfinalstr==
"longitude" || tempfinalstr ==
"Longitude")
1636 for(vector<HDFSP::Attribute *>::const_iterator i=(*it_g)->getAttributes().begin();i!=(*it_g)->getAttributes().end();i++) {
1637 if((*i)->getName() ==
"units")
1638 latunitsflag =
true;
1643 for(vector<HDFSP::Attribute *>::const_iterator i=(*it_g)->getAttributes().begin();i!=(*it_g)->getAttributes().end();i++) {
1644 if((*i)->getName() ==
"units")
1645 lonunitsflag =
true;
1648 if(latflag && !latunitsflag){
1649 at->append_attr(
"units",
"String",
"degrees_north");
1651 latunitsflag =
false;
1655 if(lonflag && !lonunitsflag){
1656 at->append_attr(
"units",
"String",
"degrees_east");
1658 latunitsflag =
false;
1661 if(llcheckoverflag ==2)
break;
1675 vector<HDFSP::SDField *>::const_iterator it_g;
1681 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1682 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_FLOAT32) {
1684 AttrTable *at = das.get_table((*it_g)->getNewName());
1686 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1687 string print_rep =
"-9999.9";
1693 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1694 if((*it_g)->getFieldType() == 0 && (((*it_g)->getType()==DFNT_INT32) || ((*it_g)->getType()==DFNT_INT16))) {
1696 AttrTable *at = das.get_table((*it_g)->getNewName());
1698 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1699 string print_rep =
"-9999";
1700 if((*it_g)->getType()==DFNT_INT32)
1710 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1711 if((*it_g)->getFieldType() == 6 && (*it_g)->getNewName()==
"nlayer") {
1713 AttrTable *at = das.get_table((*it_g)->getNewName());
1715 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1716 at->append_attr(
"units",
"String",
"km");
1719 else if((*it_g)->getFieldType() == 4) {
1721 if ((*it_g)->getNewName()==
"nh3" ||
1722 (*it_g)->getNewName()==
"ncat3" ||
1723 (*it_g)->getNewName()==
"nthrshZO" ||
1724 (*it_g)->getNewName()==
"nthrshHB" ||
1725 (*it_g)->getNewName()==
"nthrshSRT")
1729 "http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
1732 AttrTable *at = das.get_table((*it_g)->getNewName());
1734 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1736 if((*it_g)->getNewName()==
"nh3") {
1737 comment=
"Index number to represent the fixed heights above the earth ellipsoid,";
1738 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
1741 else if((*it_g)->getNewName()==
"ncat3") {
1742 comment=
"Index number to represent catgories for probability distribution functions.";
1743 comment=comment +
"Check more information from the references.";
1746 else if((*it_g)->getNewName()==
"nthrshZO")
1747 comment=
"Q-thresholds for Zero order used for probability distribution functions.";
1749 else if((*it_g)->getNewName()==
"nthrshHB")
1750 comment=
"Q-thresholds for HB used for probability distribution functions.";
1752 else if((*it_g)->getNewName()==
"nthrshSRT")
1753 comment=
"Q-thresholds for SRT used for probability distribution functions.";
1755 at->append_attr(
"comment",
"String",comment);
1756 at->append_attr(
"references",
"String",references);
1768 string base_filename;
1769 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
1770 if(last_slash_pos != string::npos)
1771 base_filename = f->
getPath().substr(last_slash_pos+1);
1772 if(
""==base_filename)
1774 bool t3a26_flag = ((base_filename.find(
"3A26")!=string::npos)?
true:
false);
1776 if(
true == t3a26_flag) {
1778 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1780 if((*it_g)->getFieldType() == 0 && ((*it_g)->getType()==DFNT_FLOAT32)) {
1781 AttrTable *at = das.get_table((*it_g)->getNewName());
1783 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1784 at->del_attr(
"_FillValue");
1785 at->append_attr(
"_FillValue",
"Float32",
"-999");
1786 at->append_attr(
"valid_min",
"Float32",
"0");
1796 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1798 if((*it_g)->getFieldType() == 4 ) {
1800 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
1801 if ((*it_g)->getNewName()==
"nh1") {
1803 AttrTable *at = das.get_table((*it_g)->getNewName());
1805 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1807 string comment=
"Number of fixed heights above the earth ellipsoid,";
1808 comment= comment +
" at 2, 4, 6, 10, and 15 km plus one for path-average.";
1810 at->append_attr(
"comment",
"String",comment);
1811 at->append_attr(
"references",
"String",references);
1814 if ((*it_g)->getNewName()==
"nh3") {
1816 AttrTable *at = das.get_table((*it_g)->getNewName());
1818 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1820 string comment=
"Number of fixed heights above the earth ellipsoid,";
1821 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
1823 at->append_attr(
"comment",
"String",comment);
1824 at->append_attr(
"references",
"String",references);
1828 if ((*it_g)->getNewName()==
"nang") {
1830 AttrTable *at = das.get_table((*it_g)->getNewName());
1832 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1834 string comment=
"Number of fixed incidence angles, at 0, 5, 10 and 15 degree and all angles.";
1835 references =
"http://pps.gsfc.nasa.gov/Documents/ICSVol4.pdf";
1837 at->append_attr(
"comment",
"String",comment);
1838 at->append_attr(
"references",
"String",references);
1842 if ((*it_g)->getNewName()==
"ncat2") {
1844 AttrTable *at = das.get_table((*it_g)->getNewName());
1846 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1848 string comment=
"Second number of categories for histograms (30). ";
1849 comment=comment +
"Check more information from the references.";
1851 at->append_attr(
"comment",
"String",comment);
1852 at->append_attr(
"references",
"String",references);
1866 string base_filename;
1867 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
1868 if(last_slash_pos != string::npos)
1869 base_filename = f->
getPath().substr(last_slash_pos+1);
1870 if(
""==base_filename)
1872 bool t2b31_flag = ((base_filename.find(
"2B31")!=string::npos)?
true:
false);
1873 bool t2a21_flag = ((base_filename.find(
"2A21")!=string::npos)?
true:
false);
1874 bool t2a12_flag = ((base_filename.find(
"2A12")!=string::npos)?
true:
false);
1877 bool t2a25_flag = ((base_filename.find(
"2A25")!=string::npos)?
true:
false);
1878 bool t1c21_flag = ((base_filename.find(
"1C21")!=string::npos)?
true:
false);
1879 bool t1b21_flag = ((base_filename.find(
"1B21")!=string::npos)?
true:
false);
1880 bool t1b11_flag = ((base_filename.find(
"1B11")!=string::npos)?
true:
false);
1881 bool t1b01_flag = ((base_filename.find(
"1B01")!=string::npos)?
true:
false);
1886 if(t2b31_flag || t2a12_flag || t2a21_flag) {
1891 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1894 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
1896 AttrTable *at = das.get_table((*it_g)->getNewName());
1898 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1900 AttrTable::Attr_iter it = at->attr_begin();
1901 while (it!=at->attr_end()) {
1902 if(at->get_name(it)==
"scale_factor")
1905 string scale_factor_value=
"";
1906 string scale_factor_type;
1908 scale_factor_value = (*at->get_attr_vector(it)->begin());
1909 scale_factor_type = at->get_type(it);
1911 if(scale_factor_type ==
"Float64") {
1912 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
NULL);
1913 at->del_attr(
"scale_factor");
1915 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
1919 if(scale_factor_type ==
"Float32") {
1920 float new_scale = 1.0/strtof(scale_factor_value.c_str(),
NULL);
1921 at->del_attr(
"scale_factor");
1923 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
1936 if(t2a12_flag==
true) {
1938 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1940 if((*it_g)->getFieldType() == 6 && (*it_g)->getNewName()==
"nlayer") {
1942 AttrTable *at = das.get_table((*it_g)->getNewName());
1944 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1945 at->append_attr(
"units",
"String",
"km");
1950 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT8) {
1952 AttrTable *at = das.get_table((*it_g)->getNewName());
1954 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1955 at->append_attr(
"_FillValue",
"Int32",
"-99");
1965 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1966 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_FLOAT32) {
1968 AttrTable *at = das.get_table((*it_g)->getNewName());
1970 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1971 string print_rep =
"-9999.9";
1977 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
1980 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
1982 AttrTable *at = das.get_table((*it_g)->getNewName());
1984 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
1986 string print_rep =
"-9999";
1995 else if(t2a21_flag ==
true || t2a25_flag ==
true) {
1998 if(t2a25_flag ==
true) {
2000 unsigned char handle_scale = 0;
2001 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2003 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2004 bool has_dBZ =
false;
2005 bool has_rainrate =
false;
2006 bool has_scale =
false;
2007 string scale_factor_value;
2008 string scale_factor_type;
2010 AttrTable *at = das.get_table((*it_g)->getNewName());
2012 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2013 AttrTable::Attr_iter it = at->attr_begin();
2014 while (it!=at->attr_end()) {
2015 if(at->get_name(it)==
"units"){
2016 string units_value = (*at->get_attr_vector(it)->begin());
2017 if(
"dBZ" == units_value) {
2021 else if(
"mm/hr" == units_value){
2022 has_rainrate =
true;
2025 if(at->get_name(it)==
"scale_factor")
2027 scale_factor_value = (*at->get_attr_vector(it)->begin());
2028 scale_factor_type = at->get_type(it);
2035 if((
true == has_rainrate ||
true == has_dBZ) &&
true == has_scale) {
2038 short valid_min = 0;
2039 short valid_max = 0;
2042 if(
true == has_rainrate)
2043 valid_max = (short)(300*strtof(scale_factor_value.c_str(),
NULL));
2044 else if(
true == has_dBZ)
2045 valid_max = (short)(80*strtof(scale_factor_value.c_str(),
NULL));
2048 at->append_attr(
"valid_min",
"Int16",print_rep);
2050 at->append_attr(
"valid_max",
"Int16",print_rep);
2052 at->del_attr(
"scale_factor");
2053 if(scale_factor_type ==
"Float64") {
2054 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
NULL);
2056 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2060 if(scale_factor_type ==
"Float32") {
2061 float new_scale = 1.0/strtof(scale_factor_value.c_str(),
NULL);
2063 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2070 if(2 == handle_scale)
2079 else if(t1b21_flag || t1c21_flag || t1b11_flag) {
2082 if(t1b21_flag || t1c21_flag) {
2084 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2086 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2088 bool has_dBm =
false;
2089 bool has_dBZ =
false;
2091 AttrTable *at = das.get_table((*it_g)->getNewName());
2093 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2094 AttrTable::Attr_iter it = at->attr_begin();
2096 while (it!=at->attr_end()) {
2097 if(at->get_name(it)==
"units"){
2099 string units_value = (*at->get_attr_vector(it)->begin());
2100 if(
"dBm" == units_value) {
2105 else if(
"dBZ" == units_value){
2113 if(has_dBm ==
true || has_dBZ ==
true) {
2114 it = at->attr_begin();
2115 while (it!=at->attr_end()) {
2116 if(at->get_name(it)==
"scale_factor")
2119 string scale_value = (*at->get_attr_vector(it)->begin());
2121 if(
true == has_dBm) {
2122 short valid_min = (short)(-120 *strtof(scale_value.c_str(),
NULL));
2123 short valid_max = (short)(-20 *strtof(scale_value.c_str(),
NULL));
2125 at->append_attr(
"valid_min",
"Int16",print_rep);
2127 at->append_attr(
"valid_max",
"Int16",print_rep);
2132 else if(
true == has_dBZ){
2133 short valid_min = (short)(-20 *strtof(scale_value.c_str(),
NULL));
2134 short valid_max = (short)(80 *strtof(scale_value.c_str(),
NULL));
2136 at->append_attr(
"valid_min",
"Int16",print_rep);
2138 at->append_attr(
"valid_max",
"Int16",print_rep);
2154 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2156 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2158 AttrTable *at = das.get_table((*it_g)->getNewName());
2160 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2161 AttrTable::Attr_iter it = at->attr_begin();
2164 while (it!=at->attr_end()) {
2166 if(at->get_name(it)==
"scale_factor")
2169 string scale_factor_value=
"";
2170 string scale_factor_type;
2172 scale_factor_value = (*at->get_attr_vector(it)->begin());
2173 scale_factor_type = at->get_type(it);
2175 if(scale_factor_type ==
"Float64") {
2176 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
NULL);
2177 at->del_attr(
"scale_factor");
2179 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2183 if(scale_factor_type ==
"Float32") {
2184 float new_scale = 1.0/strtof(scale_factor_value.c_str(),
NULL);
2185 at->del_attr(
"scale_factor");
2187 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2198 at->append_attr(
"_FillValue",
"Int16",
"-9999");
2205 else if(t1b01_flag ==
true) {
2206 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2208 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_FLOAT32) {
2209 AttrTable *at = das.get_table((*it_g)->getNewName());
2211 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2213 at->append_attr(
"_FillValue",
"Float32",
"-9999.9");
2220 AttrTable *at = das.get_table(
"HDF_GLOBAL");
2222 at = das.add_table(
"HDF_GLOBAL",
new AttrTable);
2223 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2224 string comment=
"The HDF4 OPeNDAP handler adds _FillValue, valid_min and valid_max for some TRMM level 1 and level 2 products.";
2225 comment= comment +
" It also changes scale_factor to follow CF conventions. ";
2227 at->append_attr(
"comment",
"String",comment);
2228 at->append_attr(
"references",
"String",references);
2249 string check_ceres_merra_short_name_key=
"H4.EnableCERESMERRAShortName";
2250 bool turn_on_ceres_merra_short_name_key=
false;
2251 string base_filename = filename.substr(filename.find_last_of(
"/")+1);
2255 bool merra_is_eos2 =
false;
2256 if(0== (base_filename.compare(0,5,
"MERRA"))) {
2258 for (vector < HDFSP::Attribute * >::const_iterator i =
2263 if(((*i)->getName().compare(0, 14,
"StructMetadata" )== 0) ||
2264 ((*i)->getName().compare(0, 14,
"structmetadata" )== 0)) {
2265 merra_is_eos2 =
true;
2278 vector<HDFSP::SDField *>::const_iterator it_g;
2279 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2281 AttrTable *at = das.get_table((*it_g)->getNewName());
2283 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2285 at->append_attr(
"fullpath",
"String",(*it_g)->getSpecFullPath());
2301 string check_vdata_desc_key=
"H4.EnableVdataDescAttr";
2302 bool turn_on_vdata_desc_key=
false;
2306 string VDdescname =
"hdf4_vd_desc";
2307 string VDdescvalue =
"This is an HDF4 Vdata.";
2308 string VDfieldprefix =
"Vdata_field_";
2309 string VDattrprefix =
"Vdata_attr_";
2310 string VDfieldattrprefix =
"Vdata_field_attr_";
2313 string check_ceres_vdata_key=
"H4.EnableCERESVdata";
2314 bool turn_on_ceres_vdata_key=
false;
2317 bool output_vdata_flag =
true;
2318 if (
false == turn_on_ceres_vdata_key &&
2323 output_vdata_flag =
false;
2326 if (
true == output_vdata_flag) {
2328 for(vector<HDFSP::VDATA *>::const_iterator i=f->
getVDATAs().begin(); i!=f->
getVDATAs().end();i++) {
2330 AttrTable *at = das.get_table((*i)->getNewName());
2332 at = das.add_table((*i)->getNewName(),
new AttrTable);
2334 if (
true == turn_on_vdata_desc_key) {
2336 bool emptyvddasflag =
true;
2337 if(!((*i)->getAttributes().empty())) emptyvddasflag =
false;
2338 if(((*i)->getTreatAsAttrFlag()))
2339 emptyvddasflag =
false;
2341 for(vector<HDFSP::VDField *>::const_iterator j=(*i)->getFields().begin();j!=(*i)->getFields().end();j++) {
2342 if(!((*j)->getAttributes().empty())) {
2343 emptyvddasflag =
false;
2351 at->append_attr(VDdescname,
"String" , VDdescvalue);
2353 for(vector<HDFSP::Attribute *>::const_iterator it_va = (*i)->getAttributes().begin();it_va!=(*i)->getAttributes().end();it_va++) {
2355 if((*it_va)->getType()==DFNT_UCHAR || (*it_va)->getType() == DFNT_CHAR){
2357 string tempstring2((*it_va)->getValue().begin(),(*it_va)->getValue().end());
2358 string tempfinalstr= string(tempstring2.c_str());
2359 at->append_attr(VDattrprefix+(*it_va)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2362 for (
int loc=0; loc < (*it_va)->getCount() ; loc++) {
2363 string print_rep =
HDFCFUtil::print_attr((*it_va)->getType(), loc, (
void*) &((*it_va)->getValue()[0]));
2364 at->append_attr(VDattrprefix+(*it_va)->getNewName(),
HDFCFUtil::print_type((*it_va)->getType()), print_rep);
2371 if(
false == ((*i)->getTreatAsAttrFlag())){
2373 if (
true == turn_on_vdata_desc_key) {
2377 for(vector<HDFSP::VDField *>::const_iterator j=(*i)->getFields().begin();j!=(*i)->getFields().end();j++) {
2382 if((*j)->getAttributes().size() !=0) {
2384 AttrTable *at_v = das.get_table((*j)->getNewName());
2386 at_v = das.add_table((*j)->getNewName(),
new AttrTable);
2388 for(vector<HDFSP::Attribute *>::const_iterator it_va = (*j)->getAttributes().begin();it_va!=(*j)->getAttributes().end();it_va++) {
2390 if((*it_va)->getType()==DFNT_UCHAR || (*it_va)->getType() == DFNT_CHAR){
2392 string tempstring2((*it_va)->getValue().begin(),(*it_va)->getValue().end());
2393 string tempfinalstr= string(tempstring2.c_str());
2394 at_v->append_attr((*it_va)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2397 for (
int loc=0; loc < (*it_va)->getCount() ; loc++) {
2398 string print_rep =
HDFCFUtil::print_attr((*it_va)->getType(), loc, (
void*) &((*it_va)->getValue()[0]));
2412 for(vector<HDFSP::VDField *>::const_iterator j=(*i)->getFields().begin();j!=(*i)->getFields().end();j++) {
2414 if((*j)->getFieldOrder() == 1) {
2415 if((*j)->getType()==DFNT_UCHAR || (*j)->getType() == DFNT_CHAR){
2416 string tempfinalstr;
2417 tempfinalstr.resize((*j)->getValue().size());
2418 copy((*j)->getValue().begin(),(*j)->getValue().end(),tempfinalstr.begin());
2419 at->append_attr(VDfieldprefix+(*j)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2422 for (
int loc=0; loc < (*j)->getNumRec(); loc++) {
2424 at->append_attr(VDfieldprefix+(*j)->getNewName(),
HDFCFUtil::print_type((*j)->getType()), print_rep);
2430 if((*j)->getValue().size() != (
unsigned int)(DFKNTsize((*j)->getType())*((*j)->getFieldOrder())*((*j)->getNumRec()))){
2431 throw InternalErr(__FILE__,__LINE__,
"the vdata field size doesn't match the vector value");
2434 if((*j)->getNumRec()==1){
2435 if((*j)->getType()==DFNT_UCHAR || (*j)->getType() == DFNT_CHAR){
2436 string tempstring2((*j)->getValue().begin(),(*j)->getValue().end());
2437 string tempfinalstr= string(tempstring2.c_str());
2438 at->append_attr(VDfieldprefix+(*j)->getNewName(),
"String",
HDFCFUtil::escattr(tempfinalstr));
2441 for (
int loc=0; loc < (*j)->getFieldOrder(); loc++) {
2443 at->append_attr(VDfieldprefix+(*j)->getNewName(),
HDFCFUtil::print_type((*j)->getType()), print_rep);
2450 if((*j)->getType()==DFNT_UCHAR || (*j)->getType() == DFNT_CHAR){
2452 for(
int tempcount = 0; tempcount < (*j)->getNumRec()*DFKNTsize((*j)->getType());tempcount ++) {
2453 vector<char>::const_iterator tempit;
2454 tempit = (*j)->getValue().begin()+tempcount*((*j)->getFieldOrder());
2455 string tempstring2(tempit,tempit+(*j)->getFieldOrder());
2456 string tempfinalstr= string(tempstring2.c_str());
2457 string tempoutstring =
"'"+tempfinalstr+
"'";
2458 at->append_attr(VDfieldprefix+(*j)->getNewName(),
"String",
HDFCFUtil::escattr(tempoutstring));
2463 for(
int tempcount = 0; tempcount < (*j)->getNumRec();tempcount ++) {
2465 for (
int loc=0; loc < (*j)->getFieldOrder(); loc++) {
2466 string print_rep =
HDFCFUtil::print_attr((*j)->getType(), loc, (
void*) &((*j)->getValue()[tempcount*((*j)->getFieldOrder())]));
2467 at->append_attr(VDfieldprefix+(*j)->getNewName(),
HDFCFUtil::print_type((*j)->getType()), print_rep);
2476 if (
true == turn_on_vdata_desc_key) {
2477 for(vector<HDFSP::Attribute *>::const_iterator it_va = (*j)->getAttributes().begin();it_va!=(*j)->getAttributes().end();it_va++) {
2479 if((*it_va)->getType()==DFNT_UCHAR || (*it_va)->getType() == DFNT_CHAR){
2481 string tempstring2((*it_va)->getValue().begin(),(*it_va)->getValue().end());
2482 string tempfinalstr= string(tempstring2.c_str());
2483 at->append_attr(VDfieldattrprefix+(*it_va)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2486 for (
int loc=0; loc < (*it_va)->getCount() ; loc++) {
2487 string print_rep =
HDFCFUtil::print_attr((*it_va)->getType(), loc, (
void*) &((*it_va)->getValue()[0]));
2488 at->append_attr(VDfieldattrprefix+(*it_va)->getNewName(),
HDFCFUtil::print_type((*it_va)->getType()), print_rep);
2504 const string printable =
" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|\\:;<,>.?/'\"\n\t\r";
2505 const string ESC =
"\\";
2506 const string DOUBLE_ESC = ESC + ESC;
2507 const string QUOTE =
"\"";
2508 const string ESCQUOTE = ESC + QUOTE;
2512 string::size_type ind = 0;
2513 while ((ind = s.find(ESC, ind)) != s.npos) {
2514 s.replace(ind, 1, DOUBLE_ESC);
2515 ind += DOUBLE_ESC.length();
2520 while ((ind = s.find_first_not_of(printable, ind)) != s.npos)
2521 s.replace(ind, 1, ESC + octstring(s[ind]));
2525 while ((ind = s.find(QUOTE, ind)) != s.npos) {
2526 s.replace(ind, 1, ESCQUOTE);
2527 ind += ESCQUOTE.length();
2535 int& latsize,
int&lonsize,
2536 float& lat_start,
float& lon_start,
2537 float& lat_res,
float& lon_res,
2538 bool check_reg_orig ){
2544 float lat_north = 0.;
2545 float lat_south = 0.;
2546 float lon_east = 0.;
2547 float lon_west = 0.;
2549 vector<string> ind_elems;
2554 if(ind_elems.size()!=10)
2555 throw InternalErr(__FILE__,__LINE__,
"The number of elements in the TRMM level 3 GridHeader is not right.");
2557 if(
false == check_reg_orig) {
2558 if (0 != ind_elems[1].find(
"Registration=CENTER"))
2559 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid registration is not center.");
2562 if (0 == ind_elems[2].find(
"LatitudeResolution")){
2564 size_t equal_pos = ind_elems[2].find_first_of(
'=');
2565 if(string::npos == equal_pos)
2566 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
2568 size_t scolon_pos = ind_elems[2].find_first_of(
';');
2569 if(string::npos == scolon_pos)
2570 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
2571 if (equal_pos < scolon_pos){
2573 string latres_str = ind_elems[2].substr(equal_pos+1,scolon_pos-equal_pos-1);
2574 lat_res = strtof(latres_str.c_str(),
NULL);
2577 throw InternalErr(__FILE__,__LINE__,
"latitude resolution is not right for TRMM level 3 products");
2580 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LatitudeResolution doesn't exist.");
2582 if (0 == ind_elems[3].find(
"LongitudeResolution")){
2584 size_t equal_pos = ind_elems[3].find_first_of(
'=');
2585 if(string::npos == equal_pos)
2586 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
2588 size_t scolon_pos = ind_elems[3].find_first_of(
';');
2589 if(string::npos == scolon_pos)
2590 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
2591 if (equal_pos < scolon_pos){
2592 string lonres_str = ind_elems[3].substr(equal_pos+1,scolon_pos-equal_pos-1);
2593 lon_res = strtof(lonres_str.c_str(),
NULL);
2596 throw InternalErr(__FILE__,__LINE__,
"longitude resolution is not right for TRMM level 3 products");
2599 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LongitudeResolution doesn't exist.");
2601 if (0 == ind_elems[4].find(
"NorthBoundingCoordinate")){
2603 size_t equal_pos = ind_elems[4].find_first_of(
'=');
2604 if(string::npos == equal_pos)
2605 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
2607 size_t scolon_pos = ind_elems[4].find_first_of(
';');
2608 if(string::npos == scolon_pos)
2609 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
2610 if (equal_pos < scolon_pos){
2611 string north_bounding_str = ind_elems[4].substr(equal_pos+1,scolon_pos-equal_pos-1);
2612 lat_north = strtof(north_bounding_str.c_str(),
NULL);
2615 throw InternalErr(__FILE__,__LINE__,
"NorthBoundingCoordinate is not right for TRMM level 3 products");
2619 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid NorthBoundingCoordinate doesn't exist.");
2621 if (0 == ind_elems[5].find(
"SouthBoundingCoordinate")){
2623 size_t equal_pos = ind_elems[5].find_first_of(
'=');
2624 if(string::npos == equal_pos)
2625 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
2627 size_t scolon_pos = ind_elems[5].find_first_of(
';');
2628 if(string::npos == scolon_pos)
2629 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
2630 if (equal_pos < scolon_pos){
2631 string lat_south_str = ind_elems[5].substr(equal_pos+1,scolon_pos-equal_pos-1);
2632 lat_south = strtof(lat_south_str.c_str(),
NULL);
2635 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
2639 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid SouthBoundingCoordinate doesn't exist.");
2641 if (0 == ind_elems[6].find(
"EastBoundingCoordinate")){
2643 size_t equal_pos = ind_elems[6].find_first_of(
'=');
2644 if(string::npos == equal_pos)
2645 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
2647 size_t scolon_pos = ind_elems[6].find_first_of(
';');
2648 if(string::npos == scolon_pos)
2649 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
2650 if (equal_pos < scolon_pos){
2651 string lon_east_str = ind_elems[6].substr(equal_pos+1,scolon_pos-equal_pos-1);
2652 lon_east = strtof(lon_east_str.c_str(),
NULL);
2655 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
2659 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid EastBoundingCoordinate doesn't exist.");
2661 if (0 == ind_elems[7].find(
"WestBoundingCoordinate")){
2663 size_t equal_pos = ind_elems[7].find_first_of(
'=');
2664 if(string::npos == equal_pos)
2665 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
2667 size_t scolon_pos = ind_elems[7].find_first_of(
';');
2668 if(string::npos == scolon_pos)
2669 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
2670 if (equal_pos < scolon_pos){
2671 string lon_west_str = ind_elems[7].substr(equal_pos+1,scolon_pos-equal_pos-1);
2672 lon_west = strtof(lon_west_str.c_str(),
NULL);
2677 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
2681 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid WestBoundingCoordinate doesn't exist.");
2683 if (
false == check_reg_orig) {
2684 if (0 != ind_elems[8].find(
"Origin=SOUTHWEST"))
2685 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid origin is not SOUTHWEST.");
2690 latsize =(int)((lat_north-lat_south)/lat_res);
2691 lonsize =(int)((lon_east-lon_west)/lon_res);
2692 lat_start = lat_south;
2693 lon_start = lon_west;
2724 str[i++] = (x%10) +
'0';
2745 double fpart = n - (double)ipart;
2748 int i = int_to_str(ipart, res, 0);
2751 if (afterpoint != 0)
2758 fpart = fpart * pow(10, afterpoint);
2762 int final_fpart = (int)fpart;
2763 if(fpart -(
int)fpart >0.5)
2764 final_fpart = (int)fpart +1;
2765 int_to_str(final_fpart, res + i + 1, afterpoint);
2774 char res[total_digit];
2775 for(
int i = 0; i<total_digit;i++)
2779 dtoa(-x,res,after_point);
2780 for(
int i = 0; i<total_digit;i++) {
2782 str.push_back(res[i]);
2786 dtoa(x, res, after_point);
2787 for(
int i = 0; i<total_digit;i++) {
2789 str.push_back(res[i]);
2807 str.push_back(x+
'0');
2809 else if (x >10 && x<100) {
2810 str.push_back(x/10+
'0');
2811 str.push_back(x%10+
'0');
2815 int abs_x = (x<0)?-x:x;
2820 char buf[num_digit];
2821 sprintf(buf,
"%d",x);
2832 template<
typename T>
2833 size_t HDFCFUtil::write_vector_to_file(
const string & fname,
const vector<T> &val,
size_t dtypesize) {
2836 size_t HDFCFUtil::write_vector_to_file(
const string & fname,
const vector<double> &val,
size_t dtypesize) {
2840 cerr<<
"Open a file with the name "<<fname<<endl;
2841 pFile = fopen(fname.c_str(),
"wb");
2842 ret_val = fwrite(&val[0],dtypesize,val.size(),pFile);
2843 cerr<<
"ret_val for write is "<<ret_val <<endl;
2849 ssize_t HDFCFUtil::write_vector_to_file2(
const string & fname,
const vector<double> &val,
size_t dtypesize) {
2853 int fd = open(fname.c_str(),O_RDWR|O_CREAT|O_EXCL,0666);
2854 cerr<<
"The first val is "<<val[0] <<endl;
2855 ret_val = write(fd,&val[0],dtypesize*val.size());
2857 cerr<<
"ret_val for write is "<<ret_val <<endl;
2867 ret_val = read(fd,&val[0],val.size()*dtypesize);
2870 cerr<<
"Open a file with the name "<<fname<<endl;
2871 pFile = fopen(fname.c_str(),
"wb");
2872 ret_val = fwrite(&val[0],dtypesize,val.size(),pFile);
2873 cerr<<
"ret_val for write is "<<ret_val <<endl;
2883 if(
false == pass_fileid) {
2888 #ifdef USE_HDFEOS2_LIB
2912 void HDFCFUtil::reset_fileid(
int& sdfd,
int& fileid,
int& gridfd,
int& swathfd) {
const std::vector< VDATA * > & getVDATAs() const
Public interface to Obtain Vdata.
static void add_missing_cf_attrs(HDFSP::File *f, libdap::DAS &das)
static void parser_trmm_v7_gridheader(const std::vector< char > &value, int &latsize, int &lonsize, float &lat_start, float &lon_start, float &lat_res, float &lon_res, bool check_reg_orig)
static bool insert_map(std::map< std::string, std::string > &m, std::string key, std::string val)
This is a safer way to insert and update a c++ map value. Otherwise, the local testsuite at The HDF G...
string basename(const string &path)
static string lowercase(const string &s)
Convert a string to all lower case.
static void check_obpg_global_attrs(HDFSP::File *f, std::string &scaling, float &slope, bool &global_slope_flag, float &intercept, bool &global_intercept_flag)
This class retrieves all information from an HDF4 file. It is a container for SDS and Vdata...
const std::string & getNewName() const
Get the CF name(special characters replaced by underscores) of this field.
This class retrieves all SDS objects and SD file attributes.
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)
Close HDF4 and HDF-EOS2 file IDs. For performance reasons, we want to keep HDF-EOS2/HDF4 IDs open for...
static void handle_otherhdf_special_attrs(HDFSP::File *f, libdap::DAS &das)
static class NCMLUtil overview
SD * getSD() const
Public interface to Obtain SD.
static void handle_merra_ceres_attrs_with_bes_keys(HDFSP::File *f, libdap::DAS &das, const std::string &filename)
static void handle_vdata_attrs_with_desc_key(HDFSP::File *f, libdap::DAS &das)
static void Handle_NameClashing(std::vector< std::string > &newobjnamelist)
General routines to handle name clashings.
static void correct_fvalue_type(libdap::AttrTable *at, int32 dtype)
CF requires the _FillValue attribute datatype is the same as the corresponding field datatype...
const int getFieldType() const
static std::string get_int_str(int)
static std::string get_double_str(double, int, int)
One instance of this class represents one SDS object.
#define MAX_NON_SCALE_SPECIAL_VALUE
static void gen_unique_name(std::string &str, std::set< std::string > &namelist, int &clash_index)
Obtain the unique name for the clashed names and save it to set namelist.
static void dtoa(double, char *, int)
#define GET_INTERCEPT(TYPE, CAST)
static std::string print_type(int32)
Print datatype in string.
static int int_to_str(int, char str[], int)
const std::string & getPath() const
Obtain the path of the file.
static void add_obpg_special_attrs(HDFSP::File *f, libdap::DAS &das, HDFSP::SDField *spsds, std::string &scaling, float &slope, bool &global_slope_flag, float &intercept, bool &global_intercept_flag)
static void Split(const char *s, int len, char sep, std::vector< std::string > &names)
From a string separated by a separator to a list of string, for example, split "ab,c" to {"ab","c"}.
static std::string escattr(std::string s)
A customized escaping function to escape special characters following OPeNDAP's escattr function that...
static std::string print_attr(int32, int, void *)
Print attribute values in string.
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
const std::vector< Attribute * > & getAttributes() const
Get the attributes of this field.
const std::vector< Attribute * > & getAttributes() const
Public interface to obtain the SD(file) attributes.
static void rev_str(char *str, int len)
static ssize_t read_vector_from_file(int fd, vector< double > &, size_t)
static std::string get_CF_string(std::string s)
Change special characters to "_".
static bool check_beskeys(const std::string &key)
Check the BES key. This function will check a BES key specified at the file h4.conf.in. If the key's value is either true or yes. The handler claims to find a key and will do some operations. Otherwise, will do different operations. For example, One may find a line H4.EnableCF=true at h4.conf.in. That means, the HDF4 handler will handle the HDF4 files by following CF conventions.
static void LatLon2DSubset(T *outlatlon, int ydim, int xdim, T *latlon, int32 *offset, int32 *count, int32 *step)
SPType getSPType() const
Obtain special HDF4 product type.
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
int32 getType() const
Get the data type of this field.
#define GET_SLOPE(TYPE, CAST)
static void correct_scale_offset_type(libdap::AttrTable *at)
CF requires the scale_factor and add_offset attribute datatypes hold the same datatype. So far we haven't found that scale_factor and add_offset attributes hold different datatypes in NASA files. But just in case, we implement a BES key to give users a chance to check this. By default, the key is always off.
bool Has_Dim_NoScale_Field() const
This file has a field that is a SDS dimension but no dimension scale.
const std::vector< SDField * > & getFields() const
Public interface to obtain information of all SDS vectors(objects).
static BESKeys * TheKeys()
#define MIN_NON_SCALE_SPECIAL_VALUE