2 #include "config_hdf.h"
9 #include"HDFSPArray_RealField.h"
10 #include"HDFSPArrayMissField.h"
11 #include"HDFEOS2GeoCFProj.h"
12 #include"HDFEOS2GeoCF1D.h"
14 #include <libdap/debug.h>
16 #define SIGNED_BYTE_TO_INT32 1
21 #include "HDFUInt16.h"
23 #include "HDFUInt32.h"
24 #include "HDFFloat32.h"
25 #include "HDFFloat64.h"
27 #include "HDF4RequestHandler.h"
32 #define ERR_LOC1(x) #x
33 #define ERR_LOC2(x) ERR_LOC1(x)
34 #define ERR_LOC __FILE__ " : " ERR_LOC2(__LINE__)
44 HDFCFUtil::check_beskeys(
const string& key) {
48 const string dosettrue =
"true";
49 const string dosetyes =
"yes";
54 if( dosettrue == doset || dosetyes == doset )
67 split_helper(vector<string> &tokens,
const string &text,
const char sep)
69 string::size_type start = 0, end = 0;
70 while ((end = text.find(sep, start)) != string::npos) {
71 tokens.push_back(text.substr(start, end - start));
74 tokens.push_back(text.substr(start));
83 split_helper(names,
string(s, len), sep);
87 for (
int i = 0, j = 0; j <= len; ++j) {
88 if ((j == len && len) || s[j] == sep) {
89 string elem(s + i, j - i);
90 names.push_back(elem);
106 DBG(std::cerr <<
"HDFCFUtil::Split: sz: <" << sz <<
">, sep: <" << sep <<
">" << std::endl);
108 split_helper(names,
string(sz), sep);
112 Split(sz, (
int)strlen(sz), sep, names);
120 HDFCFUtil::Split(
const char *s,
int len,
char sep, std::vector<std::string> &names)
123 for (
int i = 0, j = 0; j <= len; ++j) {
124 if ((j == len && len) || s[j] == sep) {
125 string elem(s + i, j - i);
126 names.push_back(elem);
137 Split(sz, (
int)strlen(sz), sep, names);
150 pair<map<string,string>::iterator,
bool> ret;
151 ret = m.insert(make_pair(key, val));
152 if(ret.second ==
false){
154 ret = m.insert(make_pair(key, val));
155 if(ret.second ==
false){
156 BESDEBUG(
"h4",
"insert_map():insertion failed on Key=" << key <<
" Val=" << val << endl);
169 string insertString(1,
'_');
172 if (
true == isdigit(s[0]))
173 s.insert(0,insertString);
179 for(
unsigned int i=0; i < s.length(); i++)
180 if((
false == isalnum(s[i])) && (s[i]!=
'_'))
196 pair<set<string>::iterator,
bool> ret;
198 stringstream sclash_index;
199 sclash_index << clash_index;
200 newstr = str + sclash_index.str();
202 ret = namelist.insert(newstr);
203 if (
false == ret.second) {
205 gen_unique_name(str,namelist,clash_index);
218 pair<set<string>::iterator,
bool> setret;
219 set<string>::iterator iss;
221 vector<string> clashnamelist;
222 vector<string>::iterator ivs;
225 map<int,int> cl_to_ol;
229 vector<string>::const_iterator irv;
231 for (irv = newobjnamelist.begin(); irv != newobjnamelist.end(); ++irv) {
232 setret = objnameset.insert(*irv);
233 if (
false == setret.second ) {
234 clashnamelist.insert(clashnamelist.end(),(*irv));
235 cl_to_ol[cl_index] = ol_index;
243 for (ivs=clashnamelist.begin(); ivs!=clashnamelist.end(); ivs++) {
245 string temp_clashname = *ivs +
'_';
247 *ivs = temp_clashname;
251 for (
unsigned int i =0; i <clashnamelist.size(); i++)
252 newobjnamelist[cl_to_ol[i]] = clashnamelist[i];
262 set<string> objnameset;
263 Handle_NameClashing(newobjnamelist,objnameset);
290 gp.ucp = (
unsigned char *) vals;
300 gp.cp = (
char *) vals;
311 return escattr(
static_cast<const char*
>(vals));
316 gp.sp = (
short *) vals;
323 gp.usp = (
unsigned short *) vals;
324 rep << *(gp.usp+loc);
330 gp.lp = (int32 *) vals;
337 gp.ui = (
unsigned int *) vals;
344 float attr_val = *(
float*)vals;
345 bool is_a_fin = isfinite(attr_val);
346 gp.fp = (
float *) vals;
351 rep << setprecision(10);
353 string tmp_rep_str = rep.str();
354 if (tmp_rep_str.find(
'.') == string::npos
355 && tmp_rep_str.find(
'e') == string::npos
356 && tmp_rep_str.find(
'E') == string::npos) {
366 double attr_val = *(
double*)vals;
367 bool is_a_fin = isfinite(attr_val);
368 gp.dp = (
double *) vals;
369 rep << std::showpoint;
370 rep << std::setprecision(17);
372 string tmp_rep_str = rep.str();
373 if (tmp_rep_str.find(
'.') == string::npos
374 && tmp_rep_str.find(
'e') == string::npos
375 && tmp_rep_str.find(
'E') == string::npos) {
382 return string(
"UNKNOWN");
393 static const char UNKNOWN[]=
"Unknown";
394 static const char BYTE[]=
"Byte";
395 static const char INT16[]=
"Int16";
396 static const char UINT16[]=
"UInt16";
397 static const char INT32[]=
"Int32";
398 static const char UINT32[]=
"UInt32";
399 static const char FLOAT32[]=
"Float32";
400 static const char FLOAT64[]=
"Float64";
401 static const char STRING[]=
"String";
418 #ifndef SIGNED_BYTE_TO_INT32
460 return sizeof(
unsigned char);
463 return sizeof(
unsigned char);
468 #ifndef SIGNED_BYTE_TO_INT32
475 return sizeof(
unsigned short);
478 return sizeof(short);
484 return sizeof(
unsigned int);
487 return sizeof(float);
490 return sizeof(double);
499 template <
typename T >
500 void HDFCFUtil::LatLon2DSubset (T * outlatlon,
513 T (*templatlonptr)[majordim][minordim] = (typeof templatlonptr) latlon;
515 T (*templatlonptr)[majordim][minordim] = (T *) latlon;
520 int dim0count = count[0];
521 int dim1count = count[1];
522 int dim0index[dim0count], dim1index[dim1count];
524 for (i = 0; i < count[0]; i++)
525 dim0index[i] = offset[0] + i * step[0];
528 for (j = 0; j < count[1]; j++)
529 dim1index[j] = offset[1] + j * step[1];
534 for (i = 0; i < count[0]; i++) {
535 for (j = 0; j < count[1]; j++) {
536 outlatlon[k] = (*templatlonptr)[dim0index[i]][dim1index[j]];
549 AttrTable::Attr_iter it = at->attr_begin();
550 bool find_fvalue =
false;
551 while (it!=at->attr_end() &&
false==find_fvalue) {
552 if (at->get_name(it) ==
"_FillValue")
555 string fillvalue =
"";
556 string fillvalue_type =
"";
557 if((*at->get_attr_vector(it)).size() !=1)
558 throw InternalErr(__FILE__,__LINE__,
"The number of _FillValue must be 1.");
559 fillvalue = (*at->get_attr_vector(it)->begin());
560 fillvalue_type = at->get_type(it);
563 if(fillvalue_type != var_type){
565 at->del_attr(
"_FillValue");
567 if (fillvalue_type ==
"String") {
571 if(fillvalue.size() >1) {
573 long int fillvalue_int = 0;
574 vector<char> fillvalue_temp(fillvalue.size());
576 fillvalue_int = strtol((fillvalue.substr(1)).c_str(),&pEnd,8);
577 stringstream convert_str;
578 convert_str << fillvalue_int;
579 at->append_attr(
"_FillValue",var_type,convert_str.str());
588 short fillvalue_int = fillvalue.at(0);
590 stringstream convert_str;
591 convert_str << fillvalue_int;
592 if(fillvalue_int <0 || fillvalue_int >128)
593 throw InternalErr(__FILE__,__LINE__,
594 "If the fillvalue is a char type, the value must be between 0 and 128.");
597 at->append_attr(
"_FillValue",var_type,convert_str.str());
602 at->append_attr(
"_FillValue",var_type,fillvalue);
616 AttrTable::Attr_iter it = at->attr_begin();
617 bool find_scale =
false;
618 bool find_offset =
false;
621 string scale_factor_type;
622 string add_offset_type;
623 string scale_factor_value;
624 string add_offset_value;
626 while (it!=at->attr_end() &&((find_scale!=
true) ||(find_offset!=
true))) {
627 if (at->get_name(it) ==
"scale_factor")
630 scale_factor_value = (*at->get_attr_vector(it)->begin());
631 scale_factor_type = at->get_type(it);
634 if(at->get_name(it)==
"add_offset")
637 add_offset_value = (*at->get_attr_vector(it)->begin());
638 add_offset_type = at->get_type(it);
645 if((
true==find_scale) && (
true==find_offset)) {
646 if(scale_factor_type != add_offset_type) {
647 at->del_attr(
"add_offset");
648 at->append_attr(
"add_offset",scale_factor_type,add_offset_value);
654 #ifdef USE_HDFEOS2_LIB
660 bool HDFCFUtil::is_special_value(int32 dtype,
float fillvalue,
float realvalue) {
662 bool ret_value =
false;
664 if (DFNT_UINT16 == dtype) {
666 int fillvalue_int = (
int)fillvalue;
667 if (MAX_NON_SCALE_SPECIAL_VALUE == fillvalue_int) {
668 int realvalue_int = (
int)realvalue;
669 if (realvalue_int <= MAX_NON_SCALE_SPECIAL_VALUE && realvalue_int >=MIN_NON_SCALE_SPECIAL_VALUE)
684 int HDFCFUtil::check_geofile_dimmap(
const string & geofilename) {
686 int32 fileid = SWopen(
const_cast<char*
>(geofilename.c_str()),DFACC_READ);
689 string swathname =
"MODIS_Swath_Type_GEO";
690 int32 datasetid = SWattach(fileid,
const_cast<char*
>(swathname.c_str()));
700 if ((nummaps = SWnentries(datasetid, HDFE_NENTMAP, &bufsize)) == -1) {
723 bool HDFCFUtil::change_data_type(DAS & das, SOType scaletype,
const string &new_field_name)
726 AttrTable *at = das.get_table(new_field_name);
734 if(scaletype!=DEFAULT_CF_EQU && at!=NULL)
736 AttrTable::Attr_iter it = at->attr_begin();
737 string scale_factor_value=
"";
738 string add_offset_value=
"0";
739 string radiance_scales_value=
"";
740 string radiance_offsets_value=
"";
741 string reflectance_scales_value=
"";
742 string reflectance_offsets_value=
"";
743 string scale_factor_type, add_offset_type;
744 while (it!=at->attr_end())
746 if(at->get_name(it)==
"radiance_scales")
747 radiance_scales_value = *(at->get_attr_vector(it)->begin());
748 if(at->get_name(it)==
"radiance_offsets")
749 radiance_offsets_value = *(at->get_attr_vector(it)->begin());
750 if(at->get_name(it)==
"reflectance_scales")
751 reflectance_scales_value = *(at->get_attr_vector(it)->begin());
752 if(at->get_name(it)==
"reflectance_offsets")
753 reflectance_offsets_value = *(at->get_attr_vector(it)->begin());
758 if(at->get_name(it).find(
"scale_factor")!=string::npos){
759 string temp_attr_name = at->get_name(it);
760 if (temp_attr_name !=
"scale_factor_err") {
761 scale_factor_value = *(at->get_attr_vector(it)->begin());
762 scale_factor_type = at->get_type(it);
765 if(at->get_name(it).find(
"add_offset")!=string::npos)
767 string temp_attr_name = at->get_name(it);
768 if (temp_attr_name !=
"add_offset_err") {
769 add_offset_value = *(at->get_attr_vector(it)->begin());
770 add_offset_type = at->get_type(it);
776 if((radiance_scales_value.length()!=0 && radiance_offsets_value.length()!=0)
777 || (reflectance_scales_value.length()!=0 && reflectance_offsets_value.length()!=0))
780 if(scale_factor_value.length()!=0)
782 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
791 void HDFCFUtil::obtain_dimmap_info(
const string& filename,HDFEOS2::Dataset*dataset,
792 vector<struct dimmap_entry> & dimmaps,
793 string & modis_geofilename,
bool& geofile_has_dimmap) {
796 HDFEOS2::SwathDataset *sw =
static_cast<HDFEOS2::SwathDataset *
>(dataset);
797 const vector<HDFEOS2::SwathDataset::DimensionMap*>& origdimmaps = sw->getDimensionMaps();
798 vector<HDFEOS2::SwathDataset::DimensionMap*>::const_iterator it_dmap;
802 for(
size_t i=0;i<origdimmaps.size();i++){
803 tempdimmap.geodim = origdimmaps[i]->getGeoDimension();
804 tempdimmap.datadim = origdimmaps[i]->getDataDimension();
805 tempdimmap.offset = origdimmaps[i]->getOffset();
806 tempdimmap.inc = origdimmaps[i]->getIncrement();
807 dimmaps.push_back(tempdimmap);
811 string check_modis_geofile_key =
"H4.EnableCheckMODISGeoFile";
812 bool check_geofile_key =
false;
813 check_geofile_key = HDFCFUtil::check_beskeys(check_modis_geofile_key);
818 if((origdimmaps.size() != 0) && (
true == HDF4RequestHandler::get_enable_check_modis_geo_file()) ) {
822 tempcstr =
new char [filename.size()+1];
823 strncpy (tempcstr,filename.c_str(),filename.size());
824 string basefilename = basename(tempcstr);
825 string dirfilename = dirname(tempcstr);
829 bool is_modis_geofile =
false;
830 if(basefilename.size() >5) {
831 if((0 == basefilename.compare(0,5,
"MOD03")) || (0 == basefilename.compare(0,5,
"MYD03")))
832 is_modis_geofile =
true;
851 if ((
false == is_modis_geofile) && (basefilename.size() >3)) {
853 string fnameprefix = basefilename.substr(0,3);
855 if(fnameprefix ==
"MYD" || fnameprefix ==
"MOD") {
856 size_t fnamemidpos = basefilename.find(
".A");
857 if(fnamemidpos != string::npos) {
858 string fnamemiddle = basefilename.substr(fnamemidpos,14);
859 if(fnamemiddle.size()==14) {
860 string geofnameprefix = fnameprefix+
"03";
862 string geofnamefp = geofnameprefix + fnamemiddle;
867 dirp = opendir(dirfilename.c_str());
869 throw InternalErr(__FILE__,__LINE__,
"opendir fails.");
871 while ((dirs = readdir(dirp))!= NULL){
872 if(strncmp(dirs->d_name,geofnamefp.c_str(),geofnamefp.size())==0){
873 modis_geofilename = dirfilename +
"/"+ dirs->d_name;
874 int num_dimmap = HDFCFUtil::check_geofile_dimmap(modis_geofilename);
875 if (num_dimmap < 0) {
877 throw InternalErr(__FILE__,__LINE__,
"this file is not a MODIS geolocation file.");
879 geofile_has_dimmap = (num_dimmap >0)?
true:
false;
894 bool HDFCFUtil::is_modis_dimmap_nonll_field(
string & fieldname) {
896 bool modis_dimmap_nonll_field =
false;
897 vector<string> modis_dimmap_nonll_fieldlist;
899 modis_dimmap_nonll_fieldlist.push_back(
"Height");
900 modis_dimmap_nonll_fieldlist.push_back(
"SensorZenith");
901 modis_dimmap_nonll_fieldlist.push_back(
"SensorAzimuth");
902 modis_dimmap_nonll_fieldlist.push_back(
"Range");
903 modis_dimmap_nonll_fieldlist.push_back(
"SolarZenith");
904 modis_dimmap_nonll_fieldlist.push_back(
"SolarAzimuth");
905 modis_dimmap_nonll_fieldlist.push_back(
"Land/SeaMask");
906 modis_dimmap_nonll_fieldlist.push_back(
"gflags");
907 modis_dimmap_nonll_fieldlist.push_back(
"Solar_Zenith");
908 modis_dimmap_nonll_fieldlist.push_back(
"Solar_Azimuth");
909 modis_dimmap_nonll_fieldlist.push_back(
"Sensor_Azimuth");
910 modis_dimmap_nonll_fieldlist.push_back(
"Sensor_Zenith");
912 map<string,string>modis_field_to_geofile_field;
913 map<string,string>::iterator itmap;
914 modis_field_to_geofile_field[
"Solar_Zenith"] =
"SolarZenith";
915 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
916 modis_field_to_geofile_field[
"Sensor_Zenith"] =
"SensorZenith";
917 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
919 for (
unsigned int i = 0; i <modis_dimmap_nonll_fieldlist.size(); i++) {
921 if (fieldname == modis_dimmap_nonll_fieldlist[i]) {
922 itmap = modis_field_to_geofile_field.find(fieldname);
923 if (itmap !=modis_field_to_geofile_field.end())
924 fieldname = itmap->second;
925 modis_dimmap_nonll_field =
true;
930 return modis_dimmap_nonll_field;
933 void HDFCFUtil::add_scale_offset_attrs(AttrTable*at,
const std::string& s_type,
float svalue_f,
double svalue_d,
bool add_offset_found,
934 const std::string& o_type,
float ovalue_f,
double ovalue_d) {
935 at->del_attr(
"scale_factor");
937 if(s_type!=
"Float64") {
939 at->append_attr(
"scale_factor",
"Float32", print_rep);
943 at->append_attr(
"scale_factor",
"Float64", print_rep);
946 if (
true == add_offset_found) {
947 at->del_attr(
"add_offset");
948 if(o_type!=
"Float64") {
950 at->append_attr(
"add_offset",
"Float32", print_rep);
954 at->append_attr(
"add_offset",
"Float64", print_rep);
959 void HDFCFUtil::add_scale_str_offset_attrs(AttrTable*at,
const std::string& s_type,
const std::string& s_value_str,
bool add_offset_found,
960 const std::string& o_type,
float ovalue_f,
double ovalue_d) {
961 at->del_attr(
"scale_factor");
963 if(s_type!=
"Float64")
964 at->append_attr(
"scale_factor",
"Float32", s_value_str);
966 at->append_attr(
"scale_factor",
"Float64", s_value_str);
968 if (
true == add_offset_found) {
969 at->del_attr(
"add_offset");
970 if(o_type!=
"Float64") {
972 at->append_attr(
"add_offset",
"Float32", print_rep);
976 at->append_attr(
"add_offset",
"Float64", print_rep);
981 void HDFCFUtil::handle_modis_special_attrs_disable_scale_comp(AttrTable *at,
982 const string &filename,
984 const string & newfname,
988 string scale_factor_type;
989 string add_offset_type;
992 string scale_factor_value=
"";
993 float orig_scale_value_float = 1;
994 float orig_scale_value_double = 1;
995 string add_offset_value=
"0";
996 float orig_offset_value_float = 0;
997 float orig_offset_value_double = 0;
998 bool add_offset_found =
false;
1003 AttrTable::Attr_iter it = at->attr_begin();
1004 while (it!=at->attr_end())
1006 if(at->get_name(it)==
"scale_factor")
1008 scale_factor_value = (*at->get_attr_vector(it)->begin());
1009 scale_factor_type = at->get_type(it);
1010 if(scale_factor_type ==
"Float64")
1011 orig_scale_value_double=atof(scale_factor_value.c_str());
1013 orig_scale_value_float = atof(scale_factor_value.c_str());
1016 if(at->get_name(it)==
"add_offset")
1018 add_offset_value = (*at->get_attr_vector(it)->begin());
1019 add_offset_type = at->get_type(it);
1021 if(add_offset_type ==
"Float64")
1022 orig_offset_value_double = atof(add_offset_value.c_str());
1024 orig_offset_value_float = atof(add_offset_value.c_str());
1025 add_offset_found =
true;
1051 if(scale_factor_value.length()!=0) {
1052 if (MODIS_EQ_SCALE == sotype || MODIS_MUL_SCALE == sotype) {
1053 if (orig_scale_value_float > 1 || orig_scale_value_double >1) {
1055 bool need_change_scale =
true;
1056 if(
true == is_grid) {
1057 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
1058 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
1059 need_change_scale =
false;
1061 else if((filename.size() >7)&&((filename.compare(0,7,
"MOD16A2") == 0)|| (filename.compare(0,7,
"MYD16A2")==0) ||
1062 (filename.compare(0,7,
"MOD16A3")==0) || (filename.compare(0,7,
"MYD16A3")==0)))
1063 need_change_scale =
false;
1065 if(
true == need_change_scale) {
1066 sotype = MODIS_DIV_SCALE;
1067 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< scale_factor_value << endl
1068 <<
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE. " << endl
1069 <<
" Now change it to MODIS_DIV_SCALE. "<<endl;
1074 if (MODIS_DIV_SCALE == sotype) {
1075 if (orig_scale_value_float < 1 || orig_scale_value_double<1) {
1076 sotype = MODIS_MUL_SCALE;
1077 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< scale_factor_value << endl
1078 <<
" But the original scale factor type is MODIS_DIV_SCALE. " << endl
1079 <<
" Now change it to MODIS_MUL_SCALE. "<<endl;
1084 if ((MODIS_MUL_SCALE == sotype) &&(
true == add_offset_found)) {
1086 float new_offset_value_float=0;
1087 double new_offset_value_double=0;
1088 if(add_offset_type!=
"Float64")
1089 new_offset_value_float = (orig_offset_value_float ==0)?0:(-1 * orig_offset_value_float *orig_scale_value_float);
1091 new_offset_value_double = (orig_offset_value_double ==0)?0:(-1 * orig_offset_value_double *orig_scale_value_double);
1094 add_scale_str_offset_attrs(at,scale_factor_type,scale_factor_value,add_offset_found,
1095 add_offset_type,new_offset_value_float,new_offset_value_double);
1099 if (MODIS_DIV_SCALE == sotype) {
1101 float new_scale_value_float=1;
1102 double new_scale_value_double=1;
1103 float new_offset_value_float=0;
1104 double new_offset_value_double=0;
1107 if(scale_factor_type !=
"Float64") {
1108 new_scale_value_float = 1.0/orig_scale_value_float;
1109 if (
true == add_offset_found) {
1110 if(add_offset_type !=
"Float64")
1111 new_offset_value_float = (orig_offset_value_float==0)?0:(-1 * orig_offset_value_float *new_scale_value_float);
1113 new_offset_value_double = (orig_offset_value_double==0)?0:(-1 * orig_offset_value_double *new_scale_value_float);
1118 new_scale_value_double = 1.0/orig_scale_value_double;
1119 if (
true == add_offset_found) {
1120 if(add_offset_type !=
"Float64")
1121 new_offset_value_float = (orig_offset_value_float==0)?0:(-1 * orig_offset_value_float *new_scale_value_double);
1123 new_offset_value_double = (orig_offset_value_double==0)?0:(-1 * orig_offset_value_double *new_scale_value_double);
1127 add_scale_offset_attrs(at,scale_factor_type,new_scale_value_float,new_scale_value_double,add_offset_found,
1128 add_offset_type,new_offset_value_float,new_offset_value_double);
1152 void HDFCFUtil::handle_modis_special_attrs(AttrTable *at,
const string & filename,
1153 bool is_grid,
const string & newfname,
1154 SOType sotype,
bool gridname_change_valid_range,
1155 bool changedtype,
bool & change_fvtype){
1158 string scale_factor_type;
1159 string add_offset_type;
1160 string fillvalue_type;
1161 string valid_range_type;
1165 string scale_factor_value=
"";
1166 float orig_scale_value = 1;
1167 string add_offset_value=
"0";
1168 float orig_offset_value = 0;
1169 bool add_offset_found =
false;
1172 string fillvalue=
"";
1175 string valid_range_value=
"";
1177 bool has_valid_range =
false;
1180 float orig_valid_min = 0;
1181 float orig_valid_max = 0;
1184 string number_type_value=
"";
1185 string number_type_dap_type=
"";
1189 AttrTable::Attr_iter it = at->attr_begin();
1190 while (it!=at->attr_end())
1192 if(at->get_name(it)==
"scale_factor")
1194 scale_factor_value = (*at->get_attr_vector(it)->begin());
1195 orig_scale_value = atof(scale_factor_value.c_str());
1196 scale_factor_type = at->get_type(it);
1199 if(at->get_name(it)==
"add_offset")
1201 add_offset_value = (*at->get_attr_vector(it)->begin());
1202 orig_offset_value = atof(add_offset_value.c_str());
1203 add_offset_type = at->get_type(it);
1204 add_offset_found =
true;
1207 if(at->get_name(it)==
"_FillValue")
1209 fillvalue = (*at->get_attr_vector(it)->begin());
1210 fillvalue_type = at->get_type(it);
1213 if(at->get_name(it)==
"valid_range")
1215 vector<string> *avalue = at->get_attr_vector(it);
1216 vector<string>::iterator ait = avalue->begin();
1217 while(ait!=avalue->end())
1219 valid_range_value += *ait;
1221 if(ait!=avalue->end())
1222 valid_range_value +=
", ";
1224 valid_range_type = at->get_type(it);
1225 if (
false == gridname_change_valid_range) {
1226 orig_valid_min = (float)(atof((avalue->at(0)).c_str()));
1227 orig_valid_max = (float)(atof((avalue->at(1)).c_str()));
1229 has_valid_range =
true;
1232 if(
true == changedtype && (at->get_name(it)==
"Number_Type"))
1234 number_type_value = (*at->get_attr_vector(it)->begin());
1235 number_type_dap_type= at->get_type(it);
1243 if(scale_factor_value.length()!=0)
1245 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
1247 at->del_attr(
"scale_factor");
1248 at->append_attr(
"orig_scale_factor", scale_factor_type, scale_factor_value);
1249 if(add_offset_found)
1251 at->del_attr(
"add_offset");
1252 at->append_attr(
"orig_add_offset", add_offset_type, add_offset_value);
1258 if(
true == changedtype && fillvalue.length()!=0 && fillvalue_type!=
"Float32" && fillvalue_type!=
"Float64")
1260 change_fvtype =
true;
1261 at->del_attr(
"_FillValue");
1262 at->append_attr(
"_FillValue",
"Float32", fillvalue);
1265 float valid_max = 0;
1266 float valid_min = 0;
1268 it = at->attr_begin();
1269 bool handle_modis_l1b =
false;
1274 if (sotype == MODIS_MUL_SCALE &&
true ==changedtype) {
1277 string emissive_str =
"Emissive";
1278 string RefSB_str =
"RefSB";
1279 bool is_emissive_field =
false;
1280 bool is_refsb_field =
false;
1281 if(newfname.find(emissive_str)!=string::npos) {
1282 if(0 == newfname.compare(newfname.size()-emissive_str.size(),emissive_str.size(),emissive_str))
1283 is_emissive_field =
true;
1286 if(newfname.find(RefSB_str)!=string::npos) {
1287 if(0 == newfname.compare(newfname.size()-RefSB_str.size(),RefSB_str.size(),RefSB_str))
1288 is_refsb_field =
true;
1292 if ((
true == is_emissive_field) || (
true== is_refsb_field)){
1294 float scale_max = 0;
1295 float scale_min = 100000;
1297 float offset_max = 0;
1298 float offset_min = 0;
1300 float temp_var_val = 0;
1302 string orig_long_name_value;
1303 string modify_long_name_value;
1304 string str_removed_from_long_name=
" Scaled Integers";
1305 string radiance_units_value;
1307 while (it!=at->attr_end())
1310 if(
true == is_emissive_field) {
1312 if (
"radiance_scales" == (at->get_name(it))) {
1313 vector<string> *avalue = at->get_attr_vector(it);
1314 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1315 temp_var_val = (float)(atof((*ait).c_str()));
1316 if (temp_var_val > scale_max)
1317 scale_max = temp_var_val;
1318 if (temp_var_val < scale_min)
1319 scale_min = temp_var_val;
1323 if (
"radiance_offsets" == (at->get_name(it))) {
1324 vector<string> *avalue = at->get_attr_vector(it);
1325 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1326 temp_var_val = (float)(atof((*ait).c_str()));
1327 if (temp_var_val > offset_max)
1328 offset_max = temp_var_val;
1329 if (temp_var_val < scale_min)
1330 offset_min = temp_var_val;
1334 if (
"long_name" == (at->get_name(it))) {
1335 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1336 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1337 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1338 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1340 modify_long_name_value =
1341 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1342 at->del_attr(
"long_name");
1343 at->append_attr(
"long_name",
"String",modify_long_name_value);
1344 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1349 if (
"radiance_units" == (at->get_name(it)))
1350 radiance_units_value = (*at->get_attr_vector(it)->begin());
1353 if (
true == is_refsb_field) {
1354 if (
"reflectance_scales" == (at->get_name(it))) {
1355 vector<string> *avalue = at->get_attr_vector(it);
1356 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1357 temp_var_val = (float)(atof((*ait).c_str()));
1358 if (temp_var_val > scale_max)
1359 scale_max = temp_var_val;
1360 if (temp_var_val < scale_min)
1361 scale_min = temp_var_val;
1365 if (
"reflectance_offsets" == (at->get_name(it))) {
1367 vector<string> *avalue = at->get_attr_vector(it);
1368 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1369 temp_var_val = (float)(atof((*ait).c_str()));
1370 if (temp_var_val > offset_max)
1371 offset_max = temp_var_val;
1372 if (temp_var_val < scale_min)
1373 offset_min = temp_var_val;
1377 if (
"long_name" == (at->get_name(it))) {
1378 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1379 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1380 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1381 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1383 modify_long_name_value =
1384 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1385 at->del_attr(
"long_name");
1386 at->append_attr(
"long_name",
"String",modify_long_name_value);
1387 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1397 throw InternalErr(__FILE__,__LINE__,
"the scale factor should always be greater than 0.");
1399 if (orig_valid_max > offset_min)
1400 valid_max = (orig_valid_max-offset_min)*scale_max;
1402 valid_max = (orig_valid_max-offset_min)*scale_min;
1404 if (orig_valid_min > offset_max)
1405 valid_min = (orig_valid_min-offset_max)*scale_min;
1407 valid_min = (orig_valid_min -offset_max)*scale_max;
1414 at->append_attr(
"valid_min",
"Float32",print_rep);
1416 at->append_attr(
"valid_max",
"Float32",print_rep);
1417 at->del_attr(
"valid_range");
1418 handle_modis_l1b =
true;
1421 if (
true == is_emissive_field && radiance_units_value.size() >0) {
1422 at->del_attr(
"units");
1423 at->append_attr(
"units",
"String",radiance_units_value);
1429 if(
true == changedtype &&
true == has_valid_range &&
false == handle_modis_l1b) {
1432 if (
true == gridname_change_valid_range)
1433 HDFCFUtil::handle_modis_vip_special_attrs(valid_range_value,scale_factor_value,valid_min,valid_max);
1434 else if(scale_factor_value.length()!=0) {
1453 if (MODIS_EQ_SCALE == sotype || MODIS_MUL_SCALE == sotype) {
1454 if (orig_scale_value > 1) {
1456 bool need_change_scale =
true;
1457 if(
true == is_grid) {
1458 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
1459 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
1460 need_change_scale =
false;
1463 else if((filename.size() >7)&&((filename.compare(0,7,
"MOD16A2") == 0)|| (filename.compare(0,7,
"MYD16A2")==0) ||
1464 (filename.compare(0,7,
"MOD16A3")==0) || (filename.compare(0,7,
"MYD16A3")==0)))
1465 need_change_scale =
false;
1467 if(
true == need_change_scale) {
1468 sotype = MODIS_DIV_SCALE;
1469 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< orig_scale_value << endl
1470 <<
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE. " << endl
1471 <<
" Now change it to MODIS_DIV_SCALE. "<<endl;
1476 if (MODIS_DIV_SCALE == sotype) {
1477 if (orig_scale_value < 1) {
1478 sotype = MODIS_MUL_SCALE;
1479 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< orig_scale_value << endl
1480 <<
" But the original scale factor type is MODIS_DIV_SCALE. " << endl
1481 <<
" Now change it to MODIS_MUL_SCALE. "<<endl;
1485 if(sotype == MODIS_MUL_SCALE) {
1486 valid_min = (orig_valid_min - orig_offset_value)*orig_scale_value;
1487 valid_max = (orig_valid_max - orig_offset_value)*orig_scale_value;
1489 else if (sotype == MODIS_DIV_SCALE) {
1490 valid_min = (orig_valid_min - orig_offset_value)/orig_scale_value;
1491 valid_max = (orig_valid_max - orig_offset_value)/orig_scale_value;
1493 else if (sotype == MODIS_EQ_SCALE) {
1494 valid_min = orig_valid_min * orig_scale_value + orig_offset_value;
1495 valid_max = orig_valid_max * orig_scale_value + orig_offset_value;
1499 if (MODIS_MUL_SCALE == sotype || MODIS_DIV_SCALE == sotype) {
1500 valid_min = orig_valid_min - orig_offset_value;
1501 valid_max = orig_valid_max - orig_offset_value;
1503 else if (MODIS_EQ_SCALE == sotype) {
1504 valid_min = orig_valid_min + orig_offset_value;
1505 valid_max = orig_valid_max + orig_offset_value;
1511 at->append_attr(
"valid_min",
"Float32",print_rep);
1513 at->append_attr(
"valid_max",
"Float32",print_rep);
1514 at->del_attr(
"valid_range");
1520 if(
true == changedtype && number_type_dap_type !=
"" ) {
1521 at->del_attr(
"Number_Type");
1522 at->append_attr(
"Number_Type_Orig",number_type_dap_type,number_type_value);
1528 void HDFCFUtil::handle_modis_vip_special_attrs(
const std::string& valid_range_value,
1529 const std::string& scale_factor_value,
1530 float& valid_min,
float &valid_max) {
1532 int16 vip_orig_valid_min = 0;
1533 int16 vip_orig_valid_max = 0;
1535 size_t found = valid_range_value.find_first_of(
",");
1536 size_t found_from_end = valid_range_value.find_last_of(
",");
1537 if (string::npos == found)
1538 throw InternalErr(__FILE__,__LINE__,
"should find the separator ,");
1539 if (found != found_from_end)
1540 throw InternalErr(__FILE__,__LINE__,
"There should be only one separator.");
1547 vip_orig_valid_min = atoi((valid_range_value.substr(0,found)).c_str());
1548 vip_orig_valid_max = atoi((valid_range_value.substr(found+1)).c_str());
1550 int16 scale_factor_number = 1;
1552 scale_factor_number = atoi(scale_factor_value.c_str());
1554 if(scale_factor_number !=0) {
1555 valid_min = (float)(vip_orig_valid_min/scale_factor_number);
1556 valid_max = (float)(vip_orig_valid_max/scale_factor_number);
1559 throw InternalErr(__FILE__,__LINE__,
"The scale_factor_number should not be zero.");
1564 void HDFCFUtil::handle_amsr_attrs(AttrTable *at) {
1566 AttrTable::Attr_iter it = at->attr_begin();
1567 string scale_factor_value=
"", add_offset_value=
"0";
1568 string scale_factor_type, add_offset_type;
1569 bool OFFSET_found =
false;
1570 bool Scale_found =
false;
1571 bool SCALE_FACTOR_found =
false;
1573 while (it!=at->attr_end())
1575 if(at->get_name(it)==
"SCALE_FACTOR")
1577 scale_factor_value = (*at->get_attr_vector(it)->begin());
1578 scale_factor_type = at->get_type(it);
1579 SCALE_FACTOR_found =
true;
1582 if(at->get_name(it)==
"Scale")
1584 scale_factor_value = (*at->get_attr_vector(it)->begin());
1585 scale_factor_type = at->get_type(it);
1589 if(at->get_name(it)==
"OFFSET")
1591 add_offset_value = (*at->get_attr_vector(it)->begin());
1592 add_offset_type = at->get_type(it);
1593 OFFSET_found =
true;
1598 if (
true == SCALE_FACTOR_found) {
1599 at->del_attr(
"SCALE_FACTOR");
1600 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1603 if (
true == Scale_found) {
1604 at->del_attr(
"Scale");
1605 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1608 if (
true == OFFSET_found) {
1609 at->del_attr(
"OFFSET");
1610 at->append_attr(
"add_offset",add_offset_type,add_offset_value);
1618 void HDFCFUtil::obtain_grid_latlon_dim_info(HDFEOS2::GridDataset* gdset,
1624 const vector<HDFEOS2::Field*>gfields = gdset->getDataFields();
1625 vector<HDFEOS2::Field*>::const_iterator it_gf;
1626 for (it_gf = gfields.begin();it_gf != gfields.end();++it_gf) {
1629 if(1 == (*it_gf)->getFieldType()) {
1630 const vector<HDFEOS2::Dimension*>& dims= (*it_gf)->getCorrectedDimensions();
1633 if(2 == dims.size()) {
1636 if(
true == (*it_gf)->getYDimMajor()) {
1637 dim0name = dims[0]->getName();
1638 dim0size = dims[0]->getSize();
1639 dim1name = dims[1]->getName();
1640 dim1size = dims[1]->getSize();
1643 dim0name = dims[1]->getName();
1644 dim0size = dims[1]->getSize();
1645 dim1name = dims[0]->getName();
1646 dim1size = dims[0]->getSize();
1652 if( 1 == dims.size()) {
1653 dim0name = dims[0]->getName();
1654 dim0size = dims[0]->getSize();
1659 if(2 == (*it_gf)->getFieldType()) {
1660 const vector<HDFEOS2::Dimension*>& dims= (*it_gf)->getCorrectedDimensions();
1661 if(2 == dims.size()) {
1665 if(
true == (*it_gf)->getYDimMajor()) {
1666 dim0name = dims[0]->getName();
1667 dim0size = dims[0]->getSize();
1668 dim1name = dims[1]->getName();
1669 dim1size = dims[1]->getSize();
1672 dim0name = dims[1]->getName();
1673 dim0size = dims[1]->getSize();
1674 dim1name = dims[0]->getName();
1675 dim1size = dims[0]->getSize();
1679 if( 1 == dims.size()) {
1680 dim1name = dims[0]->getName();
1681 dim1size = dims[0]->getSize();
1686 if(
""==dim0name ||
""==dim1name || dim0size<0 || dim1size <0)
1687 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain grid lat/lon dimension info.");
1693 void HDFCFUtil::add_cf_grid_mapping_attr(DAS &das, HDFEOS2::GridDataset*gdset,
const string& cf_projection,
1694 const string & dim0name,int32 dim0size,
const string &dim1name,int32 dim1size) {
1697 const vector<HDFEOS2::Field*>gfields = gdset->getDataFields();
1698 vector<HDFEOS2::Field*>::const_iterator it_gf;
1699 for (it_gf = gfields.begin();it_gf != gfields.end();++it_gf) {
1701 if(0 == (*it_gf)->getFieldType() && (*it_gf)->getRank() >1) {
1702 bool has_dim0 =
false;
1703 bool has_dim1 =
false;
1704 const vector<HDFEOS2::Dimension*>& dims= (*it_gf)->getCorrectedDimensions();
1705 for (vector<HDFEOS2::Dimension *>::const_iterator j =
1706 dims.begin(); j!= dims.end();++j){
1707 if((*j)->getName()== dim0name && (*j)->getSize() == dim0size)
1709 else if((*j)->getName()== dim1name && (*j)->getSize() == dim1size)
1713 if(
true == has_dim0 &&
true == has_dim1) {
1714 AttrTable *at = das.get_table((*it_gf)->getNewName());
1716 at = das.add_table((*it_gf)->getNewName(),
new AttrTable);
1719 at->append_attr(
"grid_mapping",
"String",cf_projection);
1726 void HDFCFUtil::add_cf_grid_cv_attrs(DAS & das, HDFEOS2::GridDataset *gdset) {
1729 if(GCTP_SNSOID == gdset->getProjection().getCode()) {
1732 string dim0name,dim1name;
1733 int32 dim0size = -1,dim1size = -1;
1734 HDFCFUtil::obtain_grid_latlon_dim_info(gdset,dim0name,dim0size,dim1name,dim1size);
1737 AttrTable *at = das.get_table(dim0name);
1739 at = das.add_table(dim0name,
new AttrTable);
1740 at->append_attr(
"standard_name",
"String",
"projection_y_coordinate");
1742 string long_name=
"y coordinate of projection for grid "+ gdset->getName();
1743 at->append_attr(
"long_name",
"String",long_name);
1745 at->append_attr(
"units",
"string",
"meter");
1747 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoY");
1749 at = das.get_table(dim1name);
1751 at = das.add_table(dim1name,
new AttrTable);
1753 at->append_attr(
"standard_name",
"String",
"projection_x_coordinate");
1754 long_name=
"x coordinate of projection for grid "+ gdset->getName();
1755 at->append_attr(
"long_name",
"String",long_name);
1758 at->append_attr(
"units",
"string",
"meter");
1759 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoX");
1762 string cf_projection_base =
"eos_cf_projection";
1764 at = das.get_table(cf_projection);
1766 at = das.add_table(cf_projection,
new AttrTable);
1768 at->append_attr(
"grid_mapping_name",
"String",
"sinusoidal");
1769 at->append_attr(
"longitude_of_central_meridian",
"Float64",
"0.0");
1770 at->append_attr(
"earth_radius",
"Float64",
"6371007.181");
1772 at->append_attr(
"_CoordinateAxisTypes",
"string",
"GeoX GeoY");
1776 HDFCFUtil::add_cf_grid_mapping_attr(das,gdset,cf_projection,dim0name,dim0size,dim1name,dim1size);
1785 void HDFCFUtil::add_cf_grid_cvs(DDS & dds, HDFEOS2::GridDataset *gdset) {
1788 if(GCTP_SNSOID == gdset->getProjection().getCode()) {
1791 string dim0name,dim1name;
1792 int32 dim0size = -1,dim1size = -1;
1793 HDFCFUtil::obtain_grid_latlon_dim_info(gdset,dim0name,dim0size,dim1name,dim1size);
1798 BaseType *bt_dim0 = NULL;
1799 BaseType *bt_dim1 = NULL;
1801 HDFEOS2GeoCF1D * ar_dim0 = NULL;
1802 HDFEOS2GeoCF1D * ar_dim1 = NULL;
1804 float64 *upleft = NULL;
1805 float64 *lowright = NULL;
1809 bt_dim0 =
new(
HDFFloat64)(dim0name,gdset->getName());
1810 bt_dim1 =
new(
HDFFloat64)(dim1name,gdset->getName());
1813 upleft =
const_cast<float64 *
>(gdset->getInfo().getUpLeft());
1814 lowright =
const_cast<float64 *
>(gdset->getInfo().getLowRight());
1817 ar_dim0 =
new HDFEOS2GeoCF1D(GCTP_SNSOID,
1818 upleft[1],lowright[1],dim0size,dim0name,bt_dim0);
1819 ar_dim0->append_dim(dim0size,dim0name);
1821 ar_dim1 =
new HDFEOS2GeoCF1D(GCTP_SNSOID,
1822 upleft[0],lowright[0],dim1size,dim1name,bt_dim1);
1823 ar_dim1->append_dim(dim1size,dim1name);
1824 dds.add_var(ar_dim0);
1825 dds.add_var(ar_dim1);
1837 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFEOS2GeoCF1D instance.");
1850 string cf_projection_base =
"eos_cf_projection";
1855 HDFEOS2GeoCFProj * dummy_proj_cf =
new HDFEOS2GeoCFProj(cf_projection,gdset->getName());
1856 dds.add_var(dummy_proj_cf);
1858 delete dummy_proj_cf;
1867 void HDFCFUtil::check_obpg_global_attrs(
HDFSP::File *f, std::string & scaling,
1868 float & slope,
bool &global_slope_flag,
1869 float & intercept,
bool & global_intercept_flag){
1882 if((*i)->getName()==
"Scaling")
1884 string tmpstring((*i)->getValue().begin(), (*i)->getValue().end());
1885 scaling = tmpstring;
1887 if((*i)->getName()==
"Slope" || (*i)->getName()==
"slope")
1889 global_slope_flag =
true;
1891 switch((*i)->getType())
1893 #define GET_SLOPE(TYPE, CAST) \
1896 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1897 slope = (float)tmpvalue; \
1900 GET_SLOPE(INT16, int16);
1901 GET_SLOPE(INT32, int32);
1902 GET_SLOPE(FLOAT32,
float);
1903 GET_SLOPE(FLOAT64,
double);
1905 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1910 if((*i)->getName()==
"Intercept" || (*i)->getName()==
"intercept")
1912 global_intercept_flag =
true;
1913 switch((*i)->getType())
1915 #define GET_INTERCEPT(TYPE, CAST) \
1918 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1919 intercept = (float)tmpvalue; \
1922 GET_INTERCEPT(INT16, int16);
1923 GET_INTERCEPT(INT32, int32);
1924 GET_INTERCEPT(FLOAT32,
float);
1925 GET_INTERCEPT(FLOAT64,
double);
1927 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1928 #undef GET_INTERCEPT
1939 void HDFCFUtil::add_obpg_special_attrs(
HDFSP::File*f,DAS &das,
1941 string& scaling,
float& slope,
1942 bool& global_slope_flag,
1944 bool & global_intercept_flag) {
1946 AttrTable *at = das.get_table(onespsds->
getNewName());
1948 at = das.add_table(onespsds->
getNewName(),
new AttrTable);
1952 bool scale_factor_flag =
false;
1953 bool add_offset_flag =
false;
1954 bool slope_flag =
false;
1955 bool intercept_flag =
false;
1958 for(vector<HDFSP::Attribute *>::const_iterator i=onespsds->
getAttributes().begin();
1960 if(global_slope_flag !=
true && ((*i)->getName()==
"Slope" || (*i)->getName()==
"slope"))
1964 switch((*i)->getType())
1966 #define GET_SLOPE(TYPE, CAST) \
1969 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1970 slope = (float)tmpvalue; \
1974 GET_SLOPE(INT16, int16);
1975 GET_SLOPE(INT32, int32);
1976 GET_SLOPE(FLOAT32,
float);
1977 GET_SLOPE(FLOAT64,
double);
1979 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1985 if(global_intercept_flag !=
true && ((*i)->getName()==
"Intercept" || (*i)->getName()==
"intercept"))
1987 intercept_flag =
true;
1988 switch((*i)->getType())
1990 #define GET_INTERCEPT(TYPE, CAST) \
1993 CAST tmpvalue = *(CAST*)&((*i)->getValue()[0]); \
1994 intercept = (float)tmpvalue; \
1997 GET_INTERCEPT(INT16, int16);
1998 GET_INTERCEPT(INT32, int32);
1999 GET_INTERCEPT(FLOAT32,
float);
2000 GET_INTERCEPT(FLOAT64,
double);
2002 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
2004 #undef GET_INTERCEPT
2014 if((f->
getSPType()==OBPGL3 || f->
getSPType() == OBPGL2) && (*i)->getName()==
"scale_factor")
2015 scale_factor_flag =
true;
2017 if((f->
getSPType()==OBPGL3 || f->
getSPType() == OBPGL2) && (*i)->getName()==
"add_offset")
2018 add_offset_flag =
true;
2023 if((f->
getSPType() == OBPGL2 || f->
getSPType()==OBPGL3 )&& onespsds->getFieldType()==0)
2026 if((OBPGL3 == f->
getSPType() && (scaling.find(
"linear")!=string::npos)) || OBPGL2 == f->
getSPType() ) {
2028 if(
false == scale_factor_flag && (
true == slope_flag ||
true == global_slope_flag))
2034 if(
false == add_offset_flag && (
true == intercept_flag ||
true == global_intercept_flag))
2041 bool has_fill_value =
false;
2043 if (
"_FillValue" == (*i)->getNewName()){
2044 has_fill_value =
true;
2052 if ((
false == has_fill_value) &&(DFNT_INT16 == onespsds->
getType())) {
2053 short fill_value = -32767;
2058 if ((
false == has_fill_value) &&(DFNT_UINT16 == onespsds->
getType())) {
2059 unsigned short fill_value = 65535;
2070 void HDFCFUtil::handle_otherhdf_special_attrs(
HDFSP::File*f,DAS &das) {
2079 vector<HDFSP::SDField *>::const_iterator it_g;
2083 bool latflag =
false;
2084 bool latunitsflag =
false;
2085 bool lonflag =
false;
2086 bool lonunitsflag =
false;
2087 int llcheckoverflag = 0;
2099 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2103 if (
true == f->
Has_Dim_NoScale_Field() && ((*it_g)->getFieldType() !=0) && ((*it_g)->IsDimScale() ==
false))
2107 if (OTHERHDF == f->
getSPType() &&
true == (*it_g)->IsDimNoScale())
2110 AttrTable *at = das.get_table((*it_g)->getNewName());
2112 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2114 for(vector<HDFSP::Attribute *>::const_iterator i=(*it_g)->getAttributes().begin();i!=(*it_g)->getAttributes().end();i++) {
2115 if((*i)->getType()==DFNT_UCHAR || (*i)->getType() == DFNT_CHAR){
2117 if((*i)->getName() ==
"long_name") {
2118 string tempstring2((*i)->getValue().begin(),(*i)->getValue().end());
2119 string tempfinalstr= string(tempstring2.c_str());
2120 if(tempfinalstr==
"latitude" || tempfinalstr ==
"Latitude")
2122 if(tempfinalstr==
"longitude" || tempfinalstr ==
"Longitude")
2129 for(vector<HDFSP::Attribute *>::const_iterator i=(*it_g)->getAttributes().begin();i!=(*it_g)->getAttributes().end();i++) {
2130 if((*i)->getName() ==
"units")
2131 latunitsflag =
true;
2136 for(vector<HDFSP::Attribute *>::const_iterator i=(*it_g)->getAttributes().begin();i!=(*it_g)->getAttributes().end();i++) {
2137 if((*i)->getName() ==
"units")
2138 lonunitsflag =
true;
2141 if(latflag && !latunitsflag){
2142 at->append_attr(
"units",
"String",
"degrees_north");
2144 latunitsflag =
false;
2148 if(lonflag && !lonunitsflag){
2149 at->append_attr(
"units",
"String",
"degrees_east");
2151 lonunitsflag =
false;
2154 if(llcheckoverflag ==2)
break;
2164 HDFCFUtil::add_missing_cf_attrs(
HDFSP::File*f,DAS &das) {
2168 vector<HDFSP::SDField *>::const_iterator it_g;
2174 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2175 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_FLOAT32) {
2177 AttrTable *at = das.get_table((*it_g)->getNewName());
2179 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2180 string print_rep =
"-9999.9";
2186 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2187 if((*it_g)->getFieldType() == 0 && (((*it_g)->getType()==DFNT_INT32) || ((*it_g)->getType()==DFNT_INT16))) {
2189 AttrTable *at = das.get_table((*it_g)->getNewName());
2191 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2192 string print_rep =
"-9999";
2193 if((*it_g)->getType()==DFNT_INT32)
2203 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2204 if((*it_g)->getFieldType() == 6 && (*it_g)->getNewName()==
"nlayer") {
2206 AttrTable *at = das.get_table((*it_g)->getNewName());
2208 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2209 at->append_attr(
"units",
"String",
"km");
2212 else if((*it_g)->getFieldType() == 4) {
2214 if ((*it_g)->getNewName()==
"nh3" ||
2215 (*it_g)->getNewName()==
"ncat3" ||
2216 (*it_g)->getNewName()==
"nthrshZO" ||
2217 (*it_g)->getNewName()==
"nthrshHB" ||
2218 (*it_g)->getNewName()==
"nthrshSRT")
2222 "http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2225 AttrTable *at = das.get_table((*it_g)->getNewName());
2227 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2229 if((*it_g)->getNewName()==
"nh3") {
2230 comment=
"Index number to represent the fixed heights above the earth ellipsoid,";
2231 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
2234 else if((*it_g)->getNewName()==
"ncat3") {
2235 comment=
"Index number to represent catgories for probability distribution functions.";
2236 comment=comment +
"Check more information from the references.";
2239 else if((*it_g)->getNewName()==
"nthrshZO")
2240 comment=
"Q-thresholds for Zero order used for probability distribution functions.";
2242 else if((*it_g)->getNewName()==
"nthrshHB")
2243 comment=
"Q-thresholds for HB used for probability distribution functions.";
2245 else if((*it_g)->getNewName()==
"nthrshSRT")
2246 comment=
"Q-thresholds for SRT used for probability distribution functions.";
2248 at->append_attr(
"comment",
"String",comment);
2249 at->append_attr(
"references",
"String",references);
2261 string base_filename;
2262 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
2263 if(last_slash_pos != string::npos)
2264 base_filename = f->
getPath().substr(last_slash_pos+1);
2265 if(
""==base_filename)
2267 bool t3a26_flag = ((base_filename.find(
"3A26")!=string::npos)?
true:
false);
2269 if(
true == t3a26_flag) {
2271 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2273 if((*it_g)->getFieldType() == 0 && ((*it_g)->getType()==DFNT_FLOAT32)) {
2274 AttrTable *at = das.get_table((*it_g)->getNewName());
2276 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2277 at->del_attr(
"_FillValue");
2278 at->append_attr(
"_FillValue",
"Float32",
"-999");
2279 at->append_attr(
"valid_min",
"Float32",
"0");
2289 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2291 if((*it_g)->getFieldType() == 4 ) {
2293 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2294 if ((*it_g)->getNewName()==
"nh1") {
2296 AttrTable *at = das.get_table((*it_g)->getNewName());
2298 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2300 string comment=
"Number of fixed heights above the earth ellipsoid,";
2301 comment= comment +
" at 2, 4, 6, 10, and 15 km plus one for path-average.";
2303 at->append_attr(
"comment",
"String",comment);
2304 at->append_attr(
"references",
"String",references);
2307 if ((*it_g)->getNewName()==
"nh3") {
2309 AttrTable *at = das.get_table((*it_g)->getNewName());
2311 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2313 string comment=
"Number of fixed heights above the earth ellipsoid,";
2314 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
2316 at->append_attr(
"comment",
"String",comment);
2317 at->append_attr(
"references",
"String",references);
2321 if ((*it_g)->getNewName()==
"nang") {
2323 AttrTable *at = das.get_table((*it_g)->getNewName());
2325 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2327 string comment=
"Number of fixed incidence angles, at 0, 5, 10 and 15 degree and all angles.";
2328 references =
"http://pps.gsfc.nasa.gov/Documents/ICSVol4.pdf";
2330 at->append_attr(
"comment",
"String",comment);
2331 at->append_attr(
"references",
"String",references);
2335 if ((*it_g)->getNewName()==
"ncat2") {
2337 AttrTable *at = das.get_table((*it_g)->getNewName());
2339 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2341 string comment=
"Second number of categories for histograms (30). ";
2342 comment=comment +
"Check more information from the references.";
2344 at->append_attr(
"comment",
"String",comment);
2345 at->append_attr(
"references",
"String",references);
2359 string base_filename;
2360 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
2361 if(last_slash_pos != string::npos)
2362 base_filename = f->
getPath().substr(last_slash_pos+1);
2363 if(
""==base_filename)
2365 bool t2b31_flag = ((base_filename.find(
"2B31")!=string::npos)?
true:
false);
2366 bool t2a21_flag = ((base_filename.find(
"2A21")!=string::npos)?
true:
false);
2367 bool t2a12_flag = ((base_filename.find(
"2A12")!=string::npos)?
true:
false);
2370 bool t2a25_flag = ((base_filename.find(
"2A25")!=string::npos)?
true:
false);
2371 bool t1c21_flag = ((base_filename.find(
"1C21")!=string::npos)?
true:
false);
2372 bool t1b21_flag = ((base_filename.find(
"1B21")!=string::npos)?
true:
false);
2373 bool t1b11_flag = ((base_filename.find(
"1B11")!=string::npos)?
true:
false);
2374 bool t1b01_flag = ((base_filename.find(
"1B01")!=string::npos)?
true:
false);
2379 if(t2b31_flag || t2a12_flag || t2a21_flag) {
2384 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2387 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2389 AttrTable *at = das.get_table((*it_g)->getNewName());
2391 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2393 AttrTable::Attr_iter it = at->attr_begin();
2394 while (it!=at->attr_end()) {
2395 if(at->get_name(it)==
"scale_factor")
2398 string scale_factor_value=
"";
2399 string scale_factor_type;
2401 scale_factor_value = (*at->get_attr_vector(it)->begin());
2402 scale_factor_type = at->get_type(it);
2404 if(scale_factor_type ==
"Float64") {
2405 double new_scale = 1.0/strtod(scale_factor_value.c_str(),NULL);
2406 at->del_attr(
"scale_factor");
2408 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2412 if(scale_factor_type ==
"Float32") {
2413 float new_scale = 1.0/strtof(scale_factor_value.c_str(),NULL);
2414 at->del_attr(
"scale_factor");
2416 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2429 if(t2a12_flag==
true) {
2431 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2433 if((*it_g)->getFieldType() == 6 && (*it_g)->getNewName()==
"nlayer") {
2435 AttrTable *at = das.get_table((*it_g)->getNewName());
2437 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2438 at->append_attr(
"units",
"String",
"km");
2443 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT8) {
2445 AttrTable *at = das.get_table((*it_g)->getNewName());
2447 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2448 at->append_attr(
"_FillValue",
"Int32",
"-99");
2458 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2459 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_FLOAT32) {
2461 AttrTable *at = das.get_table((*it_g)->getNewName());
2463 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2464 string print_rep =
"-9999.9";
2470 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2473 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2475 AttrTable *at = das.get_table((*it_g)->getNewName());
2477 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2479 string print_rep =
"-9999";
2488 else if(t2a21_flag ==
true || t2a25_flag ==
true) {
2491 if(t2a25_flag ==
true) {
2493 unsigned char handle_scale = 0;
2494 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2496 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2497 bool has_dBZ =
false;
2498 bool has_rainrate =
false;
2499 bool has_scale =
false;
2500 string scale_factor_value;
2501 string scale_factor_type;
2503 AttrTable *at = das.get_table((*it_g)->getNewName());
2505 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2506 AttrTable::Attr_iter it = at->attr_begin();
2507 while (it!=at->attr_end()) {
2508 if(at->get_name(it)==
"units"){
2509 string units_value = *at->get_attr_vector(it)->begin();
2510 if(
"dBZ" == units_value) {
2514 else if(
"mm/hr" == units_value){
2515 has_rainrate =
true;
2518 if(at->get_name(it)==
"scale_factor")
2520 scale_factor_value = *at->get_attr_vector(it)->begin();
2521 scale_factor_type = at->get_type(it);
2528 if((
true == has_rainrate ||
true == has_dBZ) &&
true == has_scale) {
2531 short valid_min = 0;
2532 short valid_max = 0;
2535 if(
true == has_rainrate)
2536 valid_max = (short)(300*strtof(scale_factor_value.c_str(),NULL));
2537 else if(
true == has_dBZ)
2538 valid_max = (short)(80*strtof(scale_factor_value.c_str(),NULL));
2541 at->append_attr(
"valid_min",
"Int16",print_rep1);
2543 at->append_attr(
"valid_max",
"Int16",print_rep1);
2545 at->del_attr(
"scale_factor");
2546 if(scale_factor_type ==
"Float64") {
2547 double new_scale = 1.0/strtod(scale_factor_value.c_str(),NULL);
2549 at->append_attr(
"scale_factor", scale_factor_type,print_rep2);
2553 if(scale_factor_type ==
"Float32") {
2554 float new_scale = 1.0/strtof(scale_factor_value.c_str(),NULL);
2556 at->append_attr(
"scale_factor", scale_factor_type,print_rep3);
2563 if(2 == handle_scale)
2572 else if(t1b21_flag || t1c21_flag || t1b11_flag) {
2575 if(t1b21_flag || t1c21_flag) {
2577 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2579 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2581 bool has_dBm =
false;
2582 bool has_dBZ =
false;
2584 AttrTable *at = das.get_table((*it_g)->getNewName());
2586 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2587 AttrTable::Attr_iter it = at->attr_begin();
2589 while (it!=at->attr_end()) {
2590 if(at->get_name(it)==
"units"){
2592 string units_value = *at->get_attr_vector(it)->begin();
2593 if(
"dBm" == units_value) {
2598 else if(
"dBZ" == units_value){
2606 if(has_dBm ==
true || has_dBZ ==
true) {
2607 it = at->attr_begin();
2608 while (it!=at->attr_end()) {
2609 if(at->get_name(it)==
"scale_factor")
2612 string scale_value = *at->get_attr_vector(it)->begin();
2614 if(
true == has_dBm) {
2615 short valid_min = (short)(-120 *strtof(scale_value.c_str(),NULL));
2616 short valid_max = (short)(-20 *strtof(scale_value.c_str(),NULL));
2618 at->append_attr(
"valid_min",
"Int16",print_rep);
2620 at->append_attr(
"valid_max",
"Int16",print_rep);
2625 else if(
true == has_dBZ){
2626 short valid_min = (short)(-20 *strtof(scale_value.c_str(),NULL));
2627 short valid_max = (short)(80 *strtof(scale_value.c_str(),NULL));
2629 at->append_attr(
"valid_min",
"Int16",print_rep);
2631 at->append_attr(
"valid_max",
"Int16",print_rep);
2647 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2649 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_INT16) {
2651 AttrTable *at = das.get_table((*it_g)->getNewName());
2653 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2654 AttrTable::Attr_iter it = at->attr_begin();
2657 while (it!=at->attr_end()) {
2659 if(at->get_name(it)==
"scale_factor")
2662 string scale_factor_value=
"";
2663 string scale_factor_type;
2665 scale_factor_value = (*at->get_attr_vector(it)->begin());
2666 scale_factor_type = at->get_type(it);
2668 if(scale_factor_type ==
"Float64") {
2669 double new_scale = 1.0/strtod(scale_factor_value.c_str(),NULL);
2670 at->del_attr(
"scale_factor");
2672 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2676 if(scale_factor_type ==
"Float32") {
2677 float new_scale = 1.0/strtof(scale_factor_value.c_str(),NULL);
2678 at->del_attr(
"scale_factor");
2680 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2691 at->append_attr(
"_FillValue",
"Int16",
"-9999");
2698 else if(t1b01_flag ==
true) {
2699 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2701 if((*it_g)->getFieldType() == 0 && (*it_g)->getType()==DFNT_FLOAT32) {
2702 AttrTable *at = das.get_table((*it_g)->getNewName());
2704 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2706 at->append_attr(
"_FillValue",
"Float32",
"-9999.9");
2713 AttrTable *at = das.get_table(
"HDF_GLOBAL");
2715 at = das.add_table(
"HDF_GLOBAL",
new AttrTable);
2716 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2717 string comment=
"The HDF4 OPeNDAP handler adds _FillValue, valid_min and valid_max for some TRMM level 1 and level 2 products.";
2718 comment= comment +
" It also changes scale_factor to follow CF conventions. ";
2720 at->append_attr(
"comment",
"String",comment);
2721 at->append_attr(
"references",
"String",references);
2739 void HDFCFUtil::handle_merra_ceres_attrs_with_bes_keys(
HDFSP::File *f, DAS &das,
const string& filename) {
2741 string base_filename = filename.substr(filename.find_last_of(
"/")+1);
2744 string check_ceres_merra_short_name_key=
"H4.EnableCERESMERRAShortName";
2745 bool turn_on_ceres_merra_short_name_key=
false;
2747 turn_on_ceres_merra_short_name_key = HDFCFUtil::check_beskeys(check_ceres_merra_short_name_key);
2750 bool merra_is_eos2 =
false;
2751 if(0== (base_filename.compare(0,5,
"MERRA"))) {
2753 for (vector < HDFSP::Attribute * >::const_iterator i =
2758 if(((*i)->getName().compare(0, 14,
"StructMetadata" )== 0) ||
2759 ((*i)->getName().compare(0, 14,
"structmetadata" )== 0)) {
2760 merra_is_eos2 =
true;
2767 if (
true == HDF4RequestHandler::get_enable_ceres_merra_short_name() && (CER_ES4 == f->
getSPType() || CER_SRB == f->
getSPType()
2770 || CER_AVG == f->
getSPType() || (
true == merra_is_eos2))) {
2773 vector<HDFSP::SDField *>::const_iterator it_g;
2774 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
2776 AttrTable *at = das.get_table((*it_g)->getNewName());
2778 at = das.add_table((*it_g)->getNewName(),
new AttrTable);
2780 at->append_attr(
"fullpath",
"String",(*it_g)->getSpecFullPath());
2790 void HDFCFUtil::handle_vdata_attrs_with_desc_key(
HDFSP::File*f,libdap::DAS &das) {
2797 string check_vdata_desc_key=
"H4.EnableVdataDescAttr";
2798 bool turn_on_vdata_desc_key=
false;
2800 turn_on_vdata_desc_key = HDFCFUtil::check_beskeys(check_vdata_desc_key);
2803 string VDdescname =
"hdf4_vd_desc";
2804 string VDdescvalue =
"This is an HDF4 Vdata.";
2805 string VDfieldprefix =
"Vdata_field_";
2806 string VDattrprefix =
"Vdata_attr_";
2807 string VDfieldattrprefix =
"Vdata_field_attr_";
2811 string check_ceres_vdata_key=
"H4.EnableCERESVdata";
2812 bool turn_on_ceres_vdata_key=
false;
2813 turn_on_ceres_vdata_key = HDFCFUtil::check_beskeys(check_ceres_vdata_key);
2816 bool output_vdata_flag =
true;
2817 if (
false == HDF4RequestHandler::get_enable_ceres_vdata() &&
2822 output_vdata_flag =
false;
2824 if (
true == output_vdata_flag) {
2826 for(vector<HDFSP::VDATA *>::const_iterator i=f->
getVDATAs().begin(); i!=f->
getVDATAs().end();i++) {
2828 AttrTable *at = das.get_table((*i)->getNewName());
2830 at = das.add_table((*i)->getNewName(),
new AttrTable);
2832 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2834 bool emptyvddasflag =
true;
2835 if(!((*i)->getAttributes().empty())) emptyvddasflag =
false;
2836 if((*i)->getTreatAsAttrFlag())
2837 emptyvddasflag =
false;
2839 for(vector<HDFSP::VDField *>::const_iterator j=(*i)->getFields().begin();j!=(*i)->getFields().end();j++) {
2840 if(!((*j)->getAttributes().empty())) {
2841 emptyvddasflag =
false;
2849 at->append_attr(VDdescname,
"String" , VDdescvalue);
2851 for(vector<HDFSP::Attribute *>::const_iterator it_va = (*i)->getAttributes().begin();it_va!=(*i)->getAttributes().end();it_va++) {
2853 if((*it_va)->getType()==DFNT_UCHAR || (*it_va)->getType() == DFNT_CHAR){
2855 string tempstring2((*it_va)->getValue().begin(),(*it_va)->getValue().end());
2856 string tempfinalstr= string(tempstring2.c_str());
2857 at->append_attr(VDattrprefix+(*it_va)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2860 for (
int loc=0; loc < (*it_va)->getCount() ; loc++) {
2861 string print_rep =
HDFCFUtil::print_attr((*it_va)->getType(), loc, (
void*) &((*it_va)->getValue()[0]));
2862 at->append_attr(VDattrprefix+(*it_va)->getNewName(),
HDFCFUtil::print_type((*it_va)->getType()), print_rep);
2869 if(
false == ((*i)->getTreatAsAttrFlag())){
2871 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2875 for(vector<HDFSP::VDField *>::const_iterator j=(*i)->getFields().begin();j!=(*i)->getFields().end();j++) {
2880 if((*j)->getAttributes().size() !=0) {
2882 AttrTable *at_v = das.get_table((*j)->getNewName());
2884 at_v = das.add_table((*j)->getNewName(),
new AttrTable);
2886 for(vector<HDFSP::Attribute *>::const_iterator it_va = (*j)->getAttributes().begin();it_va!=(*j)->getAttributes().end();it_va++) {
2888 if((*it_va)->getType()==DFNT_UCHAR || (*it_va)->getType() == DFNT_CHAR){
2890 string tempstring2((*it_va)->getValue().begin(),(*it_va)->getValue().end());
2891 string tempfinalstr= string(tempstring2.c_str());
2892 at_v->append_attr((*it_va)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2895 for (
int loc=0; loc < (*it_va)->getCount() ; loc++) {
2896 string print_rep =
HDFCFUtil::print_attr((*it_va)->getType(), loc, (
void*) &((*it_va)->getValue()[0]));
2910 for(vector<HDFSP::VDField *>::const_iterator j=(*i)->getFields().begin();j!=(*i)->getFields().end();j++) {
2912 if((*j)->getFieldOrder() == 1) {
2913 if((*j)->getType()==DFNT_UCHAR || (*j)->getType() == DFNT_CHAR){
2914 string tempfinalstr;
2915 tempfinalstr.resize((*j)->getValue().size());
2916 copy((*j)->getValue().begin(),(*j)->getValue().end(),tempfinalstr.begin());
2917 at->append_attr(VDfieldprefix+(*j)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2920 for (
int loc=0; loc < (*j)->getNumRec(); loc++) {
2922 at->append_attr(VDfieldprefix+(*j)->getNewName(),
HDFCFUtil::print_type((*j)->getType()), print_rep);
2928 if((*j)->getValue().size() != (
unsigned int)(DFKNTsize((*j)->getType())*((*j)->getFieldOrder())*((*j)->getNumRec()))){
2929 throw InternalErr(__FILE__,__LINE__,
"the vdata field size doesn't match the vector value");
2932 if((*j)->getNumRec()==1){
2933 if((*j)->getType()==DFNT_UCHAR || (*j)->getType() == DFNT_CHAR){
2934 string tempstring2((*j)->getValue().begin(),(*j)->getValue().end());
2935 string tempfinalstr= string(tempstring2.c_str());
2936 at->append_attr(VDfieldprefix+(*j)->getNewName(),
"String",
HDFCFUtil::escattr(tempfinalstr));
2939 for (
int loc=0; loc < (*j)->getFieldOrder(); loc++) {
2941 at->append_attr(VDfieldprefix+(*j)->getNewName(),
HDFCFUtil::print_type((*j)->getType()), print_rep);
2948 if((*j)->getType()==DFNT_UCHAR || (*j)->getType() == DFNT_CHAR){
2950 for(
int tempcount = 0; tempcount < (*j)->getNumRec()*DFKNTsize((*j)->getType());tempcount ++) {
2951 vector<char>::const_iterator tempit;
2952 tempit = (*j)->getValue().begin()+tempcount*((*j)->getFieldOrder());
2953 string tempstring2(tempit,tempit+(*j)->getFieldOrder());
2954 string tempfinalstr= string(tempstring2.c_str());
2955 string tempoutstring =
"'"+tempfinalstr+
"'";
2956 at->append_attr(VDfieldprefix+(*j)->getNewName(),
"String",
HDFCFUtil::escattr(tempoutstring));
2961 for(
int tempcount = 0; tempcount < (*j)->getNumRec();tempcount ++) {
2963 for (
int loc=0; loc < (*j)->getFieldOrder(); loc++) {
2964 string print_rep =
HDFCFUtil::print_attr((*j)->getType(), loc, (
void*) &((*j)->getValue()[tempcount*((*j)->getFieldOrder())]));
2965 at->append_attr(VDfieldprefix+(*j)->getNewName(),
HDFCFUtil::print_type((*j)->getType()), print_rep);
2974 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2975 for(vector<HDFSP::Attribute *>::const_iterator it_va = (*j)->getAttributes().begin();it_va!=(*j)->getAttributes().end();it_va++) {
2977 if((*it_va)->getType()==DFNT_UCHAR || (*it_va)->getType() == DFNT_CHAR){
2979 string tempstring2((*it_va)->getValue().begin(),(*it_va)->getValue().end());
2980 string tempfinalstr= string(tempstring2.c_str());
2981 at->append_attr(VDfieldattrprefix+(*it_va)->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2984 for (
int loc=0; loc < (*it_va)->getCount() ; loc++) {
2985 string print_rep =
HDFCFUtil::print_attr((*it_va)->getType(), loc, (
void*) &((*it_va)->getValue()[0]));
2986 at->append_attr(VDfieldattrprefix+(*it_va)->getNewName(),
HDFCFUtil::print_type((*it_va)->getType()), print_rep);
2999 void HDFCFUtil::map_eos2_objects_attrs(libdap::DAS &das,
const string &filename) {
3002 int32 status_32 = -1;
3004 int32 vgroup_id = -1;
3005 int32 lone_vg_number = -1;
3006 int32 num_of_lones = 0;
3007 uint16 name_len = 0;
3009 file_id = Hopen (filename.c_str(), DFACC_READ, 0);
3011 throw InternalErr(__FILE__,__LINE__,
"Hopen failed.");
3013 status_n = Vstart (file_id);
3014 if(status_n == FAIL) {
3016 throw InternalErr(__FILE__,__LINE__,
"Vstart failed.");
3020 bool unexpected_fail =
false;
3024 num_of_lones = Vlone (file_id, NULL, num_of_lones );
3028 if (num_of_lones > 0)
3032 vector<int32> ref_array;
3033 ref_array.resize(num_of_lones);
3039 num_of_lones = Vlone (file_id, &ref_array[0], num_of_lones);
3042 for (lone_vg_number = 0; lone_vg_number < num_of_lones;
3049 vgroup_id = Vattach(file_id, ref_array[lone_vg_number],
"r");
3050 if(vgroup_id == FAIL) {
3051 unexpected_fail =
true;
3052 err_msg = string(ERR_LOC) +
" Vattach failed. ";
3056 status_32 = Vgetnamelen(vgroup_id, &name_len);
3057 if(status_32 == FAIL) {
3058 unexpected_fail =
true;
3060 err_msg = string(ERR_LOC) +
" Vgetnamelen failed. ";
3064 vector<char> vgroup_name;
3065 vgroup_name.resize(name_len+1);
3066 status_32 = Vgetname (vgroup_id, &vgroup_name[0]);
3067 if(status_32 == FAIL) {
3068 unexpected_fail =
true;
3070 err_msg = string(ERR_LOC) +
" Vgetname failed. ";
3074 status_32 = Vgetclassnamelen(vgroup_id, &name_len);
3075 if(status_32 == FAIL) {
3076 unexpected_fail =
true;
3078 err_msg = string(ERR_LOC) +
" Vgetclassnamelen failed. ";
3082 vector<char>vgroup_class;
3083 vgroup_class.resize(name_len+1);
3084 status_32 = Vgetclass (vgroup_id, &vgroup_class[0]);
3085 if(status_32 == FAIL) {
3086 unexpected_fail =
true;
3088 err_msg = string(ERR_LOC) +
" Vgetclass failed. ";
3092 string vgroup_name_str(vgroup_name.begin(),vgroup_name.end());
3093 vgroup_name_str = vgroup_name_str.substr(0,vgroup_name_str.size()-1);
3095 string vgroup_class_str(vgroup_class.begin(),vgroup_class.end());
3096 vgroup_class_str = vgroup_class_str.substr(0,vgroup_class_str.size()-1);
3098 if(vgroup_class_str ==
"GRID")
3099 map_eos2_one_object_attrs_wrapper(das,file_id,vgroup_id,vgroup_name_str,
true);
3100 else if(vgroup_class_str ==
"SWATH")
3101 map_eos2_one_object_attrs_wrapper(das,file_id,vgroup_id,vgroup_name_str,
false);
3107 throw InternalErr(__FILE__,__LINE__,
"map_eos2_one_object_attrs_wrapper failed.");
3109 Vdetach (vgroup_id);
3117 if(
true == unexpected_fail)
3118 throw InternalErr(__FILE__,__LINE__,err_msg);
3124 void HDFCFUtil::map_eos2_one_object_attrs_wrapper(libdap:: DAS &das,int32 file_id,int32 vgroup_id,
const string& vgroup_name,
bool is_grid) {
3128 int32 num_gobjects = Vntagrefs (vgroup_id);
3129 if(num_gobjects < 0)
3130 throw InternalErr(__FILE__,__LINE__,
"Cannot obtain the number of objects under a vgroup.");
3132 for(
int i = 0; i<num_gobjects;i++) {
3134 int32 obj_tag, obj_ref;
3135 if (Vgettagref (vgroup_id, i, &obj_tag, &obj_ref) == FAIL)
3136 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain the tag and reference of an object under a vgroup.");
3138 if (Visvg (vgroup_id, obj_ref) == TRUE) {
3140 int32 object_attr_vgroup = Vattach(file_id,obj_ref,
"r");
3141 if(object_attr_vgroup == FAIL)
3142 throw InternalErr(__FILE__,__LINE__,
"Failed to attach an EOS2 vgroup.");
3144 uint16 name_len = 0;
3145 int32 status_32 = Vgetnamelen(object_attr_vgroup, &name_len);
3146 if(status_32 == FAIL) {
3147 Vdetach(object_attr_vgroup);
3148 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain an EOS2 vgroup name length.");
3150 vector<char> attr_vgroup_name;
3151 attr_vgroup_name.resize(name_len+1);
3152 status_32 = Vgetname (object_attr_vgroup, &attr_vgroup_name[0]);
3153 if(status_32 == FAIL) {
3154 Vdetach(object_attr_vgroup);
3155 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain an EOS2 vgroup name. ");
3158 string attr_vgroup_name_str(attr_vgroup_name.begin(),attr_vgroup_name.end());
3159 attr_vgroup_name_str = attr_vgroup_name_str.substr(0,attr_vgroup_name_str.size()-1);
3162 if(
true == is_grid && attr_vgroup_name_str==
"Grid Attributes"){
3163 map_eos2_one_object_attrs(das,file_id,object_attr_vgroup,vgroup_name);
3164 Vdetach(object_attr_vgroup);
3167 else if(
false == is_grid && attr_vgroup_name_str==
"Swath Attributes") {
3168 map_eos2_one_object_attrs(das,file_id,object_attr_vgroup,vgroup_name);
3169 Vdetach(object_attr_vgroup);
3174 Vdetach(object_attr_vgroup);
3175 throw InternalErr(__FILE__,__LINE__,
"Cannot map eos2 object attributes to DAP2.");
3177 Vdetach(object_attr_vgroup);
3184 void HDFCFUtil::map_eos2_one_object_attrs(libdap:: DAS &das,int32 file_id, int32 obj_attr_group_id,
const string& vgroup_name) {
3186 int32 num_gobjects = Vntagrefs(obj_attr_group_id);
3187 if(num_gobjects < 0)
3188 throw InternalErr(__FILE__,__LINE__,
"Cannot obtain the number of objects under a vgroup.");
3191 AttrTable *at = das.get_table(vgroup_cf_name);
3193 at = das.add_table(vgroup_cf_name,
new AttrTable);
3195 for(
int i = 0; i<num_gobjects;i++) {
3197 int32 obj_tag, obj_ref;
3198 if (Vgettagref(obj_attr_group_id, i, &obj_tag, &obj_ref) == FAIL)
3199 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain the tag and reference of an object under a vgroup.");
3201 if(Visvs(obj_attr_group_id,obj_ref)) {
3203 int32 vdata_id = VSattach(file_id,obj_ref,
"r");
3204 if(vdata_id == FAIL)
3205 throw InternalErr(__FILE__,__LINE__,
"Failed to attach a vdata.");
3208 if(VSisattr(vdata_id)) {
3211 int32 num_field = VFnfields(vdata_id);
3214 throw InternalErr(__FILE__,__LINE__,
"Number of vdata field for an EOS2 object must be 1.");
3216 int32 num_record = VSelts(vdata_id);
3219 throw InternalErr(__FILE__,__LINE__,
"Number of vdata record for an EOS2 object must be 1.");
3221 char vdata_name[VSNAMELENMAX];
3222 if(VSQueryname(vdata_id,vdata_name) == FAIL) {
3224 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata name.");
3226 string vdatanamestr(vdata_name);
3228 int32 fieldsize = VFfieldesize(vdata_id,0);
3229 if(fieldsize == FAIL) {
3231 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field size.");
3234 char* fieldname = VFfieldname(vdata_id,0);
3235 if(fieldname == NULL) {
3237 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field name.");
3239 int32 fieldtype = VFfieldtype(vdata_id,0);
3240 if(fieldtype == FAIL) {
3242 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field type.");
3245 if(VSsetfields(vdata_id,fieldname) == FAIL) {
3247 throw InternalErr(__FILE__,__LINE__,
"EOS2 object vdata: VSsetfields failed.");
3250 vector<char> vdata_value;
3251 vdata_value.resize(fieldsize);
3252 if(VSread(vdata_id,(uint8*)&vdata_value[0],1,FULL_INTERLACE) == FAIL) {
3254 throw InternalErr(__FILE__,__LINE__,
"EOS2 object vdata: VSread failed.");
3258 if(fieldtype == DFNT_UCHAR || fieldtype == DFNT_CHAR){
3259 string tempstring(vdata_value.begin(),vdata_value.end());
3261 string tempstring2 = string(tempstring.c_str());
3285 #define ESCAPE_STRING_ATTRIBUTES 0
3289 const string printable =
" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|\\:;<,>.?/'\"\n\t\r";
3290 const string ESC =
"\\";
3291 #if ESCAPE_STRING_ATTRIBUTES
3292 const string DOUBLE_ESC = ESC + ESC;
3293 const string QUOTE =
"\"";
3294 const string ESCQUOTE = ESC + QUOTE;
3298 while ((ind = s.find(ESC, ind)) != string::npos) {
3299 s.replace(ind, 1, DOUBLE_ESC);
3300 ind += DOUBLE_ESC.length();
3305 while ((ind = s.find(QUOTE, ind)) != string::npos) {
3307 s.replace(ind, 1, ESCQUOTE);
3308 ind += ESCQUOTE.length();
3313 while ((ind = s.find_first_not_of(printable, ind)) != string::npos) {
3314 s.replace(ind, 1, ESC + octstring(s[ind]));
3321 void HDFCFUtil::parser_trmm_v7_gridheader(
const vector<char>& value,
3322 int& latsize,
int&lonsize,
3323 float& lat_start,
float& lon_start,
3324 float& lat_res,
float& lon_res,
3325 bool check_reg_orig ){
3327 float lat_north = 0.;
3328 float lat_south = 0.;
3329 float lon_east = 0.;
3330 float lon_west = 0.;
3332 vector<string> ind_elems;
3339 if(ind_elems.size()<9)
3340 throw InternalErr(__FILE__,__LINE__,
"The number of elements in the TRMM level 3 GridHeader is not right.");
3342 if(
false == check_reg_orig) {
3343 if (0 != ind_elems[1].find(
"Registration=CENTER"))
3344 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid registration is not center.");
3347 if (0 == ind_elems[2].find(
"LatitudeResolution")){
3349 size_t equal_pos = ind_elems[2].find_first_of(
'=');
3350 if(string::npos == equal_pos)
3351 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3353 size_t scolon_pos = ind_elems[2].find_first_of(
';');
3354 if(string::npos == scolon_pos)
3355 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3356 if (equal_pos < scolon_pos){
3358 string latres_str = ind_elems[2].substr(equal_pos+1,scolon_pos-equal_pos-1);
3359 lat_res = strtof(latres_str.c_str(),NULL);
3362 throw InternalErr(__FILE__,__LINE__,
"latitude resolution is not right for TRMM level 3 products");
3365 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LatitudeResolution doesn't exist.");
3367 if (0 == ind_elems[3].find(
"LongitudeResolution")){
3369 size_t equal_pos = ind_elems[3].find_first_of(
'=');
3370 if(string::npos == equal_pos)
3371 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
3373 size_t scolon_pos = ind_elems[3].find_first_of(
';');
3374 if(string::npos == scolon_pos)
3375 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
3376 if (equal_pos < scolon_pos){
3377 string lonres_str = ind_elems[3].substr(equal_pos+1,scolon_pos-equal_pos-1);
3378 lon_res = strtof(lonres_str.c_str(),NULL);
3381 throw InternalErr(__FILE__,__LINE__,
"longitude resolution is not right for TRMM level 3 products");
3384 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LongitudeResolution doesn't exist.");
3386 if (0 == ind_elems[4].find(
"NorthBoundingCoordinate")){
3388 size_t equal_pos = ind_elems[4].find_first_of(
'=');
3389 if(string::npos == equal_pos)
3390 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3392 size_t scolon_pos = ind_elems[4].find_first_of(
';');
3393 if(string::npos == scolon_pos)
3394 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3395 if (equal_pos < scolon_pos){
3396 string north_bounding_str = ind_elems[4].substr(equal_pos+1,scolon_pos-equal_pos-1);
3397 lat_north = strtof(north_bounding_str.c_str(),NULL);
3400 throw InternalErr(__FILE__,__LINE__,
"NorthBoundingCoordinate is not right for TRMM level 3 products");
3404 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid NorthBoundingCoordinate doesn't exist.");
3406 if (0 == ind_elems[5].find(
"SouthBoundingCoordinate")){
3408 size_t equal_pos = ind_elems[5].find_first_of(
'=');
3409 if(string::npos == equal_pos)
3410 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3412 size_t scolon_pos = ind_elems[5].find_first_of(
';');
3413 if(string::npos == scolon_pos)
3414 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3415 if (equal_pos < scolon_pos){
3416 string lat_south_str = ind_elems[5].substr(equal_pos+1,scolon_pos-equal_pos-1);
3417 lat_south = strtof(lat_south_str.c_str(),NULL);
3420 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3424 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid SouthBoundingCoordinate doesn't exist.");
3426 if (0 == ind_elems[6].find(
"EastBoundingCoordinate")){
3428 size_t equal_pos = ind_elems[6].find_first_of(
'=');
3429 if(string::npos == equal_pos)
3430 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3432 size_t scolon_pos = ind_elems[6].find_first_of(
';');
3433 if(string::npos == scolon_pos)
3434 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3435 if (equal_pos < scolon_pos){
3436 string lon_east_str = ind_elems[6].substr(equal_pos+1,scolon_pos-equal_pos-1);
3437 lon_east = strtof(lon_east_str.c_str(),NULL);
3440 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3444 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid EastBoundingCoordinate doesn't exist.");
3446 if (0 == ind_elems[7].find(
"WestBoundingCoordinate")){
3448 size_t equal_pos = ind_elems[7].find_first_of(
'=');
3449 if(string::npos == equal_pos)
3450 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3452 size_t scolon_pos = ind_elems[7].find_first_of(
';');
3453 if(string::npos == scolon_pos)
3454 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3455 if (equal_pos < scolon_pos){
3456 string lon_west_str = ind_elems[7].substr(equal_pos+1,scolon_pos-equal_pos-1);
3457 lon_west = strtof(lon_west_str.c_str(),NULL);
3460 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3464 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid WestBoundingCoordinate doesn't exist.");
3466 if (
false == check_reg_orig) {
3467 if (0 != ind_elems[8].find(
"Origin=SOUTHWEST"))
3468 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid origin is not SOUTHWEST.");
3473 latsize =(
int)((lat_north-lat_south)/lat_res);
3474 lonsize =(
int)((lon_east-lon_west)/lon_res);
3475 lat_start = lat_south;
3476 lon_start = lon_west;
3484 void HDFCFUtil::rev_str(
char *str,
int len)
3502 int HDFCFUtil::int_to_str(
int x,
char str[],
int d)
3507 str[i++] = (x%10) +
'0';
3522 void HDFCFUtil::dtoa(
double n,
char *res,
int afterpoint)
3528 double fpart = n - (double)ipart;
3531 int i = int_to_str(ipart, res, 0);
3534 if (afterpoint != 0)
3541 fpart = fpart * pow(10, afterpoint);
3545 int final_fpart = (
int)fpart;
3546 if(fpart -(
int)fpart >0.5)
3547 final_fpart = (
int)fpart +1;
3548 int_to_str(final_fpart, res + i + 1, afterpoint);
3553 string HDFCFUtil::get_double_str(
double x,
int total_digit,
int after_point) {
3558 res.resize(total_digit);
3559 for(
int i = 0; i<total_digit;i++)
3563 dtoa(-x,&res[0],after_point);
3564 for(
int i = 0; i<total_digit;i++) {
3566 str.push_back(res[i]);
3570 dtoa(x, &res[0], after_point);
3571 for(
int i = 0; i<total_digit;i++) {
3573 str.push_back(res[i]);
3585 string HDFCFUtil::get_int_str(
int x) {
3589 str.push_back(x+
'0');
3591 else if (x >10 && x<100) {
3592 str.push_back(x/10+
'0');
3593 str.push_back(x%10+
'0');
3597 int abs_x = (x<0)?-x:x;
3603 buf.resize(num_digit);
3604 snprintf(&buf[0],num_digit,
"%d",x);
3605 str.assign(&buf[0]);
3614 template<
typename T>
3615 size_t HDFCFUtil::write_vector_to_file(
const string & fname,
const vector<T> &val,
size_t dtypesize) {
3618 size_t HDFCFUtil::write_vector_to_file(
const string & fname,
const vector<double> &val,
size_t dtypesize) {
3622 cerr<<
"Open a file with the name "<<fname<<endl;
3623 pFile = fopen(fname.c_str(),
"wb");
3624 ret_val = fwrite(&val[0],dtypesize,val.size(),pFile);
3625 cerr<<
"ret_val for write is "<<ret_val <<endl;
3631 ssize_t HDFCFUtil::write_vector_to_file2(
const string & fname,
const vector<double> &val,
size_t dtypesize) {
3635 int fd = open(fname.c_str(),O_RDWR|O_CREAT|O_EXCL,0666);
3636 cerr<<
"The first val is "<<val[0] <<endl;
3637 ret_val = write(fd,&val[0],dtypesize*val.size());
3639 cerr<<
"ret_val for write is "<<ret_val <<endl;
3645 ssize_t HDFCFUtil::read_vector_from_file(
int fd, vector<double> &val,
size_t dtypesize) {
3648 ret_val = read(fd,&val[0],val.size()*dtypesize);
3651 cerr<<
"Open a file with the name "<<fname<<endl;
3652 pFile = fopen(fname.c_str(),
"wb");
3653 ret_val = fwrite(&val[0],dtypesize,val.size(),pFile);
3654 cerr<<
"ret_val for write is "<<ret_val <<endl;
3662 ssize_t HDFCFUtil::read_buffer_from_file(
int fd,
void*buf,
size_t total_read) {
3665 ret_val = read(fd,buf,total_read);
3671 if(
false == pass_fileid) {
3676 #ifdef USE_HDFEOS2_LIB
3689 string HDFCFUtil::obtain_cache_fname(
const string & fprefix,
const string &fname,
const string &vname) {
3691 string cache_fname = fprefix;
3692 string base_file_name = basename(fname);
3694 if((base_file_name.size() >12)
3695 && (base_file_name.compare(0,4,
"AIRS") == 0)
3696 && (base_file_name.find(
".L3.")!=string::npos)
3697 && (base_file_name.find(
".v6.")!=string::npos)
3698 && ((vname ==
"Latitude") ||(vname ==
"Longitude")))
3699 cache_fname = cache_fname +
"AIRS"+
".L3."+
".v6."+vname;
3701 cache_fname = cache_fname + base_file_name +
"_"+vname;
3708 size_t HDFCFUtil::obtain_dds_cache_size(
HDFSP::File*spf) {
3710 size_t total_bytes_written = 0;
3711 const vector<HDFSP::SDField *>& spsds = spf->
getSD()->
getFields();
3712 vector<HDFSP::SDField *>::const_iterator it_g;
3713 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
3716 if(DFNT_CHAR == (*it_g)->getType()) {
3717 total_bytes_written = 0;
3722 int temp_rank = (*it_g)->getRank();
3723 const vector<HDFSP::Dimension*>& dims= (*it_g)->getDimensions();
3724 vector<HDFSP::Dimension*>::const_iterator it_d;
3725 for(it_d = dims.begin(); it_d != dims.end(); ++it_d)
3726 total_bytes_written += ((*it_d)->getName()).size()+1;
3728 total_bytes_written +=((*it_g)->getName()).size()+1;
3732 if(((*it_g)->getName()) != ((*it_g)->getNewName()))
3733 total_bytes_written +=((*it_g)->getNewName()).size()+1;
3735 total_bytes_written +=1;
3738 total_bytes_written +=(temp_rank+4)*
sizeof(
int);
3742 if(total_bytes_written != 0)
3743 total_bytes_written +=1;
3745 return total_bytes_written;
3750 void HDFCFUtil::write_sp_sds_dds_cache(
HDFSP::File* spf,FILE*dds_file,
size_t total_bytes_dds_cache,
const string &dds_filename) {
3752 BESDEBUG(
"h4",
" Coming to write SDS DDS to a cache" << endl);
3753 char delimiter =
'\0';
3755 size_t total_written_bytes_count = 0;
3758 vector<char>temp_buf;
3759 temp_buf.resize(total_bytes_dds_cache);
3760 char* temp_pointer = &temp_buf[0];
3762 const vector<HDFSP::SDField *>& spsds = spf->
getSD()->
getFields();
3765 vector<HDFSP::SDField *>::const_iterator it_g;
3766 for(it_g = spsds.begin(); it_g != spsds.end(); it_g++){
3769 int sds_rank = (*it_g)->getRank();
3770 int sds_ref = (*it_g)->getFieldRef();
3771 int sds_dtype = (*it_g)->getType();
3772 int sds_ftype = (*it_g)->getFieldType();
3774 vector<int32>dimsizes;
3775 dimsizes.resize(sds_rank);
3778 const vector<HDFSP::Dimension*>& dims= (*it_g)->getDimensions();
3779 for(
int i = 0; i < sds_rank; i++)
3780 dimsizes[i] = dims[i]->getSize();
3782 memcpy((
void*)temp_pointer,(
void*)&sds_rank,
sizeof(
int));
3783 temp_pointer +=
sizeof(
int);
3784 memcpy((
void*)temp_pointer,(
void*)&sds_ref,
sizeof(
int));
3785 temp_pointer +=
sizeof(
int);
3786 memcpy((
void*)temp_pointer,(
void*)&sds_dtype,
sizeof(
int));
3787 temp_pointer +=
sizeof(
int);
3788 memcpy((
void*)temp_pointer,(
void*)&sds_ftype,
sizeof(
int));
3789 temp_pointer +=
sizeof(
int);
3791 memcpy((
void*)temp_pointer,(
void*)&dimsizes[0],sds_rank*
sizeof(
int));
3792 temp_pointer +=sds_rank*
sizeof(
int);
3795 total_written_bytes_count +=(sds_rank+4)*
sizeof(
int);
3799 string temp_varname = (*it_g)->getName();
3800 vector<char>temp_val1(temp_varname.begin(),temp_varname.end());
3801 memcpy((
void*)temp_pointer,(
void*)&temp_val1[0],temp_varname.size());
3802 temp_pointer +=temp_varname.size();
3803 memcpy((
void*)temp_pointer,&delimiter,1);
3806 total_written_bytes_count =total_written_bytes_count +(1+temp_varname.size());
3812 if((*it_g)->getName() == (*it_g)->getNewName()){
3813 memcpy((
void*)temp_pointer,&delimiter,1);
3815 total_written_bytes_count +=1;
3818 string temp_varnewname = (*it_g)->getNewName();
3819 vector<char>temp_val2(temp_varnewname.begin(),temp_varnewname.end());
3820 memcpy((
void*)temp_pointer,(
void*)&temp_val2[0],temp_varnewname.size());
3821 temp_pointer +=temp_varnewname.size();
3822 memcpy((
void*)temp_pointer,&delimiter,1);
3824 total_written_bytes_count =total_written_bytes_count +(1+temp_varnewname.size());
3828 for(
int i = 0; i < sds_rank; i++) {
3829 string temp_dimname = dims[i]->getName();
3830 vector<char>temp_val3(temp_dimname.begin(),temp_dimname.end());
3831 memcpy((
void*)temp_pointer,(
void*)&temp_val3[0],temp_dimname.size());
3832 temp_pointer +=temp_dimname.size();
3833 memcpy((
void*)temp_pointer,&delimiter,1);
3835 total_written_bytes_count =total_written_bytes_count +(1+temp_dimname.size());
3839 memcpy((
void*)temp_pointer,&cend,1);
3840 total_written_bytes_count +=1;
3842 if(total_written_bytes_count != total_bytes_dds_cache) {
3843 stringstream s_total_written_count;
3844 s_total_written_count << total_written_bytes_count;
3845 stringstream s_total_bytes_dds_cache;
3846 s_total_bytes_dds_cache << total_bytes_dds_cache;
3847 string msg =
"DDs cached file "+ dds_filename +
" buffer size should be " + s_total_bytes_dds_cache.str() ;
3848 msg = msg +
". But the real size written in the buffer is " + s_total_written_count.str();
3849 throw InternalErr (__FILE__, __LINE__,msg);
3852 size_t bytes_really_written = fwrite((
const void*)&temp_buf[0],1,total_bytes_dds_cache,dds_file);
3854 if(bytes_really_written != total_bytes_dds_cache) {
3855 stringstream s_expected_bytes;
3856 s_expected_bytes << total_bytes_dds_cache;
3857 stringstream s_really_written_bytes;
3858 s_really_written_bytes << bytes_really_written;
3859 string msg =
"DDs cached file "+ dds_filename +
" size should be " + s_expected_bytes.str() ;
3860 msg +=
". But the real size written to the file is " + s_really_written_bytes.str();
3861 throw InternalErr (__FILE__, __LINE__,msg);
3867 void HDFCFUtil::read_sp_sds_dds_cache(FILE* dds_file,libdap::DDS * dds_ptr,
3868 const std::string &cache_filename,
const std::string &hdf4_filename) {
3870 BESDEBUG(
"h4",
" Coming to read SDS DDS from a cache" << endl);
3874 if(stat(cache_filename.c_str(),&sb)!=0) {
3875 string err_mesg=
"The DDS cache file " + cache_filename;
3876 err_mesg = err_mesg +
" doesn't exist. ";
3877 throw InternalErr(__FILE__,__LINE__,err_mesg);
3880 size_t bytes_expected_read = (size_t)sb.st_size;
3883 vector<char> temp_buf;
3884 temp_buf.resize(bytes_expected_read);
3885 size_t bytes_really_read = fread((
void*)&temp_buf[0],1,bytes_expected_read,dds_file);
3888 if(bytes_really_read != bytes_expected_read) {
3889 stringstream s_bytes_really_read;
3890 s_bytes_really_read << bytes_really_read ;
3891 stringstream s_bytes_expected_read;
3892 s_bytes_expected_read << bytes_expected_read;
3893 string msg =
"The expected bytes to read from DDS cache file " + cache_filename +
" is " + s_bytes_expected_read.str();
3894 msg = msg +
". But the real read size from the buffer is " + s_bytes_really_read.str();
3895 throw InternalErr (__FILE__, __LINE__,msg);
3897 char* temp_pointer = &temp_buf[0];
3899 char delimiter =
'\0';
3902 bool end_file_flag =
false;
3906 int sds_rank = *((
int *)(temp_pointer));
3907 temp_pointer = temp_pointer +
sizeof(
int);
3909 int sds_ref = *((
int *)(temp_pointer));
3910 temp_pointer = temp_pointer +
sizeof(
int);
3912 int sds_dtype = *((
int *)(temp_pointer));
3913 temp_pointer = temp_pointer +
sizeof(
int);
3915 int sds_ftype = *((
int *)(temp_pointer));
3916 temp_pointer = temp_pointer +
sizeof(
int);
3918 vector<int32>dimsizes;
3920 throw InternalErr (__FILE__, __LINE__,
"SDS rank must be >0");
3922 dimsizes.resize(sds_rank);
3923 for (
int i = 0; i <sds_rank;i++) {
3924 dimsizes[i] = *((
int *)(temp_pointer));
3925 temp_pointer = temp_pointer +
sizeof(
int);
3928 vector<string>dimnames;
3929 dimnames.resize(sds_rank);
3930 string varname,varnewname;
3931 for (
int i = 0; i <sds_rank+2;i++) {
3932 vector<char> temp_vchar;
3933 char temp_char = *temp_pointer;
3936 if(temp_char == delimiter)
3937 temp_vchar.push_back(temp_char);
3938 while(temp_char !=delimiter) {
3939 temp_vchar.push_back(temp_char);
3941 temp_char = *temp_pointer;
3945 string temp_string(temp_vchar.begin(),temp_vchar.end());
3947 varname = temp_string;
3949 varnewname = temp_string;
3951 dimnames[i-2] = temp_string;
3956 if(varnewname[0] == delimiter)
3957 varnewname = varname;
3960 BaseType *bt = NULL;
3962 #define HANDLE_CASE(tid, type) \
3964 bt = new (type)(varnewname,hdf4_filename); \
3968 HANDLE_CASE(DFNT_CHAR,
HDFStr);
3969 #ifndef SIGNED_BYTE_TO_INT32
3970 HANDLE_CASE(DFNT_INT8,
HDFByte);
3974 HANDLE_CASE(DFNT_UINT8,
HDFByte);
3979 HANDLE_CASE(DFNT_UCHAR8,
HDFByte);
3981 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
3986 throw InternalErr(__FILE__,__LINE__,
"Cannot create the basetype when creating DDS from a cache file.");
3988 SPType sptype = OTHERHDF;
4010 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFSPArray_RealField instance.");
4013 for(
int i = 0; i <sds_rank; i++)
4014 ar->append_dim(dimsizes[i],dimnames[i]);
4015 dds_ptr->add_var(ar);
4031 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFSPArray_RealField instance.");
4034 ar->append_dim(dimsizes[0],dimnames[0]);
4035 dds_ptr->add_var(ar);
4040 throw InternalErr(__FILE__,__LINE__,
"SDS rank must be 1 for the missing coordinate.");
4043 if(*temp_pointer == cend)
4044 end_file_flag =
true;
4045 if((temp_pointer - &temp_buf[0]) > (
int)bytes_expected_read) {
4046 string msg = cache_filename +
" doesn't have the end-line character at the end. The file may be corrupted.";
4047 throw InternalErr (__FILE__, __LINE__,msg);
4049 }
while(
false == end_file_flag);
4051 dds_ptr->set_dataset_name(basename(hdf4_filename));
4069 void HDFCFUtil::reset_fileid(
int& sdfd,
int& fileid,
int& gridfd,
int& swathfd) {
static std::string lowercase(const std::string &s)
const std::vector< Attribute * > & getAttributes() const
Get the attributes of this field.
int32 getType() const
Get the data type of this field.
const std::string & getNewName() const
Get the CF name(special characters replaced by underscores) of this field.
bool Has_Dim_NoScale_Field() const
This file has a field that is a SDS dimension but no dimension scale.
SD * getSD() const
Public interface to Obtain SD.
const std::vector< VDATA * > & getVDATAs() const
Public interface to Obtain Vdata.
SPType getSPType() const
Obtain special HDF4 product type.
const std::string & getPath() const
Obtain the path of the file.
One instance of this class represents one SDS object.
This class retrieves all SDS objects and SD file attributes.
const std::vector< SDField * > & getFields() const
Redundant member function.
const std::vector< Attribute * > & getAttributes() const
Public interface to obtain the SD(file) attributes.
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()
static short obtain_type_size(int32)
Obtain datatype size.
static bool insert_map(std::map< std::string, std::string > &m, std::string key, std::string val)
static std::string print_attr(int32, int, void *)
Print attribute values in string.
static std::string print_type(int32)
Print datatype in string.
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 Handle_NameClashing(std::vector< std::string > &newobjnamelist)
General routines to handle name clashings.
static void correct_scale_offset_type(libdap::AttrTable *at)
static std::string get_CF_string(std::string s)
Change special characters to "_".
static void Split(const char *s, int len, char sep, std::vector< std::string > &names)
static std::string escattr(std::string s)
static void correct_fvalue_type(libdap::AttrTable *at, int32 dtype)
static void close_fileid(int32 sdfd, int32 file_id, int32 gridfd, int32 swathfd, bool pass_fileid_key)