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
24#include "HDFFloat32.h"
25#include "HDFFloat64.h"
27#include "HDF4RequestHandler.h"
33#define ERR_LOC2(x) ERR_LOC1(x)
34#define ERR_LOC __FILE__ " : " ERR_LOC2(__LINE__)
44HDFCFUtil::check_beskeys(
const string& key) {
48 const string dosettrue =
"true";
49 const string dosetyes =
"yes";
54 if( dosettrue == doset || dosetyes == doset )
67split_helper(vector<string> &tokens,
const string &text,
const char sep)
69 string::size_type start = 0;
70 string::size_type end = 0;
72 while ((end = text.find(sep, start)) != string::npos) {
73 tokens.push_back(text.substr(start, end - start));
76 tokens.push_back(text.substr(start));
85 split_helper(names,
string(s, len), sep);
89 for (
int i = 0, j = 0; j <= len; ++j) {
90 if ((j == len && len) || s[j] == sep) {
91 string elem(s + i, j - i);
92 names.push_back(elem);
108 DBG(std::cerr <<
"HDFCFUtil::Split: sz: <" << sz <<
">, sep: <" << sep <<
">" << std::endl);
110 split_helper(names,
string(sz), sep);
114 Split(sz, (
int)strlen(sz), sep, names);
122HDFCFUtil::Split(
const char *s,
int len,
char sep, std::vector<std::string> &names)
125 for (
int i = 0, j = 0; j <= len; ++j) {
126 if ((j == len && len) || s[j] == sep) {
127 string elem(s + i, j - i);
128 names.push_back(elem);
139 Split(sz, (
int)strlen(sz), sep, names);
152 pair<map<string,string>::iterator,
bool> ret;
153 ret = m.insert(make_pair(key, val));
154 if(ret.second ==
false){
156 ret = m.insert(make_pair(key, val));
157 if(ret.second ==
false){
158 BESDEBUG(
"h4",
"insert_map():insertion failed on Key=" << key <<
" Val=" << val << endl);
171 string insertString(1,
'_');
174 if (
true == isdigit(s[0]))
175 s.insert(0,insertString);
182 if((
false == isalnum(si)) && (si!=
'_'))
198 pair<set<string>::iterator,
bool> ret;
200 stringstream sclash_index;
201 sclash_index << clash_index;
202 newstr = str + sclash_index.str();
204 ret = namelist.insert(newstr);
205 if (
false == ret.second) {
220 pair<set<string>::iterator,
bool> setret;
221 set<string>::iterator iss;
223 vector<string> clashnamelist;
226 map<int,int> cl_to_ol;
231 for (
const auto &newobjname:newobjnamelist) {
232 setret = objnameset.insert(newobjname);
233 if (
false == setret.second ) {
234 clashnamelist.insert(clashnamelist.end(),newobjname);
235 cl_to_ol[cl_index] = ol_index;
243 for (
auto &clashname:clashnamelist) {
245 string temp_clashname = clashname +
'_';
247 clashname = temp_clashname;
251 for (
unsigned int i =0; i <clashnamelist.size(); i++)
252 newobjnamelist[cl_to_ol[i]] = clashnamelist[i];
262 set<string> 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);
499template <
typename T >
500void HDFCFUtil::LatLon2DSubset (T * outlatlon,
504 const int32 * offset,
513 T (*templatlonptr)[majordim][minordim] = (typeof templatlonptr) latlon;
515 T (*templatlonptr)[majordim][minordim] = (T *) latlon;
522 int dim0count = count[0];
523 int dim1count = count[1];
524 int dim0index[dim0count], dim1index[dim1count];
526 for (i = 0; i < count[0]; i++)
527 dim0index[i] = offset[0] + i * step[0];
530 for (j = 0; j < count[1]; j++)
531 dim1index[j] = offset[1] + j * step[1];
536 for (i = 0; i < count[0]; i++) {
537 for (j = 0; j < count[1]; j++) {
538 outlatlon[k] = (*templatlonptr)[dim0index[i]][dim1index[j]];
551 AttrTable::Attr_iter it = at->attr_begin();
552 bool find_fvalue =
false;
553 while (it!=at->attr_end() &&
false==find_fvalue) {
554 if (at->get_name(it) ==
"_FillValue")
557 string fillvalue =
"";
558 string fillvalue_type =
"";
559 if((*at->get_attr_vector(it)).size() !=1)
560 throw InternalErr(__FILE__,__LINE__,
"The number of _FillValue must be 1.");
561 fillvalue = (*at->get_attr_vector(it)->begin());
562 fillvalue_type = at->get_type(it);
565 if(fillvalue_type != var_type){
567 at->del_attr(
"_FillValue");
569 if (fillvalue_type ==
"String") {
573 if(fillvalue.size() >1) {
575 long int fillvalue_int = 0;
576 vector<char> fillvalue_temp(fillvalue.size());
578 fillvalue_int = strtol((fillvalue.substr(1)).c_str(),&pEnd,8);
579 stringstream convert_str;
580 convert_str << fillvalue_int;
581 at->append_attr(
"_FillValue",var_type,convert_str.str());
590 short fillvalue_int = fillvalue.at(0);
592 stringstream convert_str;
593 convert_str << fillvalue_int;
594 if(fillvalue_int <0 || fillvalue_int >128)
595 throw InternalErr(__FILE__,__LINE__,
596 "If the fillvalue is a char type, the value must be between 0 and 128.");
599 at->append_attr(
"_FillValue",var_type,convert_str.str());
604 at->append_attr(
"_FillValue",var_type,fillvalue);
618 AttrTable::Attr_iter it = at->attr_begin();
619 bool find_scale =
false;
620 bool find_offset =
false;
623 string scale_factor_type;
624 string add_offset_type;
625 string scale_factor_value;
626 string add_offset_value;
628 while (it!=at->attr_end() &&((find_scale!=
true) ||(find_offset!=
true))) {
629 if (at->get_name(it) ==
"scale_factor")
632 scale_factor_value = (*at->get_attr_vector(it)->begin());
633 scale_factor_type = at->get_type(it);
636 if(at->get_name(it)==
"add_offset")
639 add_offset_value = (*at->get_attr_vector(it)->begin());
640 add_offset_type = at->get_type(it);
647 if((
true==find_scale) && (
true==find_offset)) {
648 if(scale_factor_type != add_offset_type) {
649 at->del_attr(
"add_offset");
650 at->append_attr(
"add_offset",scale_factor_type,add_offset_value);
656#ifdef USE_HDFEOS2_LIB
662bool HDFCFUtil::is_special_value(int32 dtype,
float fillvalue,
float realvalue) {
664 bool ret_value =
false;
666 if (DFNT_UINT16 == dtype) {
668 auto fillvalue_int = (
int)fillvalue;
669 if (MAX_NON_SCALE_SPECIAL_VALUE == fillvalue_int) {
670 auto realvalue_int = (
int)realvalue;
671 if (realvalue_int <= MAX_NON_SCALE_SPECIAL_VALUE && realvalue_int >=MIN_NON_SCALE_SPECIAL_VALUE)
686int HDFCFUtil::check_geofile_dimmap(
const string & geofilename) {
688 int32 fileid = SWopen(
const_cast<char*
>(geofilename.c_str()),DFACC_READ);
691 string swathname =
"MODIS_Swath_Type_GEO";
692 int32 datasetid = SWattach(fileid,
const_cast<char*
>(swathname.c_str()));
702 if ((nummaps = SWnentries(datasetid, HDFE_NENTMAP, &bufsize)) == -1) {
725bool HDFCFUtil::change_data_type(DAS & das, SOType scaletype,
const string &new_field_name)
728 AttrTable *at = das.get_table(new_field_name);
736 if(scaletype!=DEFAULT_CF_EQU && at!=
nullptr)
738 AttrTable::Attr_iter it = at->attr_begin();
739 string scale_factor_value=
"";
740 string add_offset_value=
"0";
741 string radiance_scales_value=
"";
742 string radiance_offsets_value=
"";
743 string reflectance_scales_value=
"";
744 string reflectance_offsets_value=
"";
745 string scale_factor_type;
746 string add_offset_type;
748 while (it!=at->attr_end())
750 if(at->get_name(it)==
"radiance_scales")
751 radiance_scales_value = *(at->get_attr_vector(it)->begin());
752 if(at->get_name(it)==
"radiance_offsets")
753 radiance_offsets_value = *(at->get_attr_vector(it)->begin());
754 if(at->get_name(it)==
"reflectance_scales")
755 reflectance_scales_value = *(at->get_attr_vector(it)->begin());
756 if(at->get_name(it)==
"reflectance_offsets")
757 reflectance_offsets_value = *(at->get_attr_vector(it)->begin());
762 if(at->get_name(it).find(
"scale_factor")!=string::npos){
763 string temp_attr_name = at->get_name(it);
764 if (temp_attr_name !=
"scale_factor_err") {
765 scale_factor_value = *(at->get_attr_vector(it)->begin());
766 scale_factor_type = at->get_type(it);
769 if(at->get_name(it).find(
"add_offset")!=string::npos)
771 string temp_attr_name = at->get_name(it);
772 if (temp_attr_name !=
"add_offset_err") {
773 add_offset_value = *(at->get_attr_vector(it)->begin());
774 add_offset_type = at->get_type(it);
780 if((radiance_scales_value.length()!=0 && radiance_offsets_value.length()!=0)
781 || (reflectance_scales_value.length()!=0 && reflectance_offsets_value.length()!=0))
784 if(scale_factor_value.length()!=0)
786 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
795void HDFCFUtil::obtain_dimmap_info(
const string& filename,HDFEOS2::Dataset*dataset,
796 vector<struct dimmap_entry> & dimmaps,
797 string & modis_geofilename,
bool& geofile_has_dimmap) {
800 auto sw =
static_cast<HDFEOS2::SwathDataset *
>(dataset);
801 const vector<HDFEOS2::SwathDataset::DimensionMap*>& origdimmaps = sw->getDimensionMaps();
805 for(
const auto & origdimmap:origdimmaps){
806 tempdimmap.geodim = origdimmap->getGeoDimension();
807 tempdimmap.datadim = origdimmap->getDataDimension();
808 tempdimmap.offset = origdimmap->getOffset();
809 tempdimmap.inc = origdimmap->getIncrement();
810 dimmaps.push_back(tempdimmap);
814 string check_modis_geofile_key =
"H4.EnableCheckMODISGeoFile";
815 bool check_geofile_key =
false;
816 check_geofile_key = HDFCFUtil::check_beskeys(check_modis_geofile_key);
821 if((origdimmaps.empty() !=
false) && (
true == HDF4RequestHandler::get_enable_check_modis_geo_file()) ) {
825 tempcstr =
new char [filename.size()+1];
826 strncpy (tempcstr,filename.c_str(),filename.size());
827 string basefilename = basename(tempcstr);
828 string dirfilename = dirname(tempcstr);
832 bool is_modis_geofile =
false;
833 if(basefilename.size() >5) {
834 if((0 == basefilename.compare(0,5,
"MOD03")) || (0 == basefilename.compare(0,5,
"MYD03")))
835 is_modis_geofile =
true;
854 if ((
false == is_modis_geofile) && (basefilename.size() >3)) {
856 string fnameprefix = basefilename.substr(0,3);
858 if(fnameprefix ==
"MYD" || fnameprefix ==
"MOD") {
859 size_t fnamemidpos = basefilename.find(
".A");
860 if(fnamemidpos != string::npos) {
861 string fnamemiddle = basefilename.substr(fnamemidpos,14);
862 if(fnamemiddle.size()==14) {
863 string geofnameprefix = fnameprefix+
"03";
865 string geofnamefp = geofnameprefix + fnamemiddle;
870 dirp = opendir(dirfilename.c_str());
872 throw InternalErr(__FILE__,__LINE__,
"opendir fails.");
874 while ((dirs = readdir(dirp))!=
nullptr){
875 if(strncmp(dirs->d_name,geofnamefp.c_str(),geofnamefp.size())==0){
876 modis_geofilename = dirfilename +
"/"+ dirs->d_name;
877 int num_dimmap = HDFCFUtil::check_geofile_dimmap(modis_geofilename);
878 if (num_dimmap < 0) {
880 throw InternalErr(__FILE__,__LINE__,
"this file is not a MODIS geolocation file.");
882 geofile_has_dimmap = (num_dimmap >0)?
true:
false;
897bool HDFCFUtil::is_modis_dimmap_nonll_field(
string & fieldname) {
899 bool modis_dimmap_nonll_field =
false;
900 vector<string> modis_dimmap_nonll_fieldlist;
902 modis_dimmap_nonll_fieldlist.emplace_back(
"Height");
903 modis_dimmap_nonll_fieldlist.emplace_back(
"SensorZenith");
904 modis_dimmap_nonll_fieldlist.emplace_back(
"SensorAzimuth");
905 modis_dimmap_nonll_fieldlist.emplace_back(
"Range");
906 modis_dimmap_nonll_fieldlist.emplace_back(
"SolarZenith");
907 modis_dimmap_nonll_fieldlist.emplace_back(
"SolarAzimuth");
908 modis_dimmap_nonll_fieldlist.emplace_back(
"Land/SeaMask");
909 modis_dimmap_nonll_fieldlist.emplace_back(
"gflags");
910 modis_dimmap_nonll_fieldlist.emplace_back(
"Solar_Zenith");
911 modis_dimmap_nonll_fieldlist.emplace_back(
"Solar_Azimuth");
912 modis_dimmap_nonll_fieldlist.emplace_back(
"Sensor_Azimuth");
913 modis_dimmap_nonll_fieldlist.emplace_back(
"Sensor_Zenith");
915 map<string,string>modis_field_to_geofile_field;
916 map<string,string>::iterator itmap;
917 modis_field_to_geofile_field[
"Solar_Zenith"] =
"SolarZenith";
918 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
919 modis_field_to_geofile_field[
"Sensor_Zenith"] =
"SensorZenith";
920 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
922 for (
const auto & modis_dimmap_nonll_f:modis_dimmap_nonll_fieldlist) {
924 if (fieldname == modis_dimmap_nonll_f) {
925 itmap = modis_field_to_geofile_field.find(fieldname);
926 if (itmap !=modis_field_to_geofile_field.end())
927 fieldname = itmap->second;
928 modis_dimmap_nonll_field =
true;
933 return modis_dimmap_nonll_field;
936void HDFCFUtil::add_scale_offset_attrs(AttrTable*at,
const std::string& s_type,
float svalue_f,
double svalue_d,
bool add_offset_found,
937 const std::string& o_type,
float ovalue_f,
double ovalue_d) {
938 at->del_attr(
"scale_factor");
940 if(s_type!=
"Float64") {
942 at->append_attr(
"scale_factor",
"Float32", print_rep);
946 at->append_attr(
"scale_factor",
"Float64", print_rep);
949 if (
true == add_offset_found) {
950 at->del_attr(
"add_offset");
951 if(o_type!=
"Float64") {
953 at->append_attr(
"add_offset",
"Float32", print_rep);
957 at->append_attr(
"add_offset",
"Float64", print_rep);
962void HDFCFUtil::add_scale_str_offset_attrs(AttrTable*at,
const std::string& s_type,
const std::string& s_value_str,
bool add_offset_found,
963 const std::string& o_type,
float ovalue_f,
double ovalue_d) {
964 at->del_attr(
"scale_factor");
966 if(s_type!=
"Float64")
967 at->append_attr(
"scale_factor",
"Float32", s_value_str);
969 at->append_attr(
"scale_factor",
"Float64", s_value_str);
971 if (
true == add_offset_found) {
972 at->del_attr(
"add_offset");
973 if(o_type!=
"Float64") {
975 at->append_attr(
"add_offset",
"Float32", print_rep);
979 at->append_attr(
"add_offset",
"Float64", print_rep);
984void HDFCFUtil::handle_modis_special_attrs_disable_scale_comp(AttrTable *at,
985 const string &filename,
987 const string & newfname,
991 string scale_factor_type;
992 string add_offset_type;
995 string scale_factor_value=
"";
996 float orig_scale_value_float = 1;
997 double orig_scale_value_double = 1;
998 string add_offset_value=
"0";
999 float orig_offset_value_float = 0;
1000 double orig_offset_value_double = 0;
1001 bool add_offset_found =
false;
1006 AttrTable::Attr_iter it = at->attr_begin();
1007 while (it!=at->attr_end())
1009 if(at->get_name(it)==
"scale_factor")
1011 scale_factor_value = (*at->get_attr_vector(it)->begin());
1012 scale_factor_type = at->get_type(it);
1013 if(scale_factor_type ==
"Float64")
1014 orig_scale_value_double=atof(scale_factor_value.c_str());
1016 orig_scale_value_float = (float)(atof(scale_factor_value.c_str()));
1019 if(at->get_name(it)==
"add_offset")
1021 add_offset_value = (*at->get_attr_vector(it)->begin());
1022 add_offset_type = at->get_type(it);
1024 if(add_offset_type ==
"Float64")
1025 orig_offset_value_double = atof(add_offset_value.c_str());
1027 orig_offset_value_float = (float)(atof(add_offset_value.c_str()));
1028 add_offset_found =
true;
1054 if(scale_factor_value.length()!=0) {
1055 if (MODIS_EQ_SCALE == sotype || MODIS_MUL_SCALE == sotype) {
1056 if (orig_scale_value_float > 1 || orig_scale_value_double >1) {
1058 bool need_change_scale =
true;
1059 if(
true == is_grid) {
1060 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
1061 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
1062 need_change_scale =
false;
1064 else if((filename.size() >7)&&((filename.compare(0,7,
"MOD16A2") == 0)|| (filename.compare(0,7,
"MYD16A2")==0) ||
1065 (filename.compare(0,7,
"MOD16A3")==0) || (filename.compare(0,7,
"MYD16A3")==0)))
1066 need_change_scale =
false;
1068 if(
true == need_change_scale) {
1069 sotype = MODIS_DIV_SCALE;
1070 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< scale_factor_value << endl
1071 <<
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE. " << endl
1072 <<
" Now change it to MODIS_DIV_SCALE. "<<endl;
1077 if (MODIS_DIV_SCALE == sotype) {
1078 if (orig_scale_value_float < 1 || orig_scale_value_double<1) {
1079 sotype = MODIS_MUL_SCALE;
1080 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< scale_factor_value << endl
1081 <<
" But the original scale factor type is MODIS_DIV_SCALE. " << endl
1082 <<
" Now change it to MODIS_MUL_SCALE. "<<endl;
1087 if ((MODIS_MUL_SCALE == sotype) &&(
true == add_offset_found)) {
1089 float new_offset_value_float=0;
1090 double new_offset_value_double=0;
1091 if(add_offset_type!=
"Float64")
1092 new_offset_value_float = (orig_offset_value_float ==0)?0:(-1 * orig_offset_value_float *orig_scale_value_float);
1094 new_offset_value_double = (orig_offset_value_double ==0)?0:(-1 * orig_offset_value_double *orig_scale_value_double);
1097 add_scale_str_offset_attrs(at,scale_factor_type,scale_factor_value,add_offset_found,
1098 add_offset_type,new_offset_value_float,new_offset_value_double);
1102 if (MODIS_DIV_SCALE == sotype) {
1104 float new_scale_value_float=1;
1105 double new_scale_value_double=1;
1106 float new_offset_value_float=0;
1107 double new_offset_value_double=0;
1110 if(scale_factor_type !=
"Float64") {
1111 new_scale_value_float = 1.0/orig_scale_value_float;
1112 if (
true == add_offset_found) {
1113 if(add_offset_type !=
"Float64")
1114 new_offset_value_float = (orig_offset_value_float==0)?0:(-1 * orig_offset_value_float *new_scale_value_float);
1116 new_offset_value_double = (orig_offset_value_double==0)?0:(-1 * orig_offset_value_double *new_scale_value_float);
1121 new_scale_value_double = 1.0/orig_scale_value_double;
1122 if (
true == add_offset_found) {
1123 if(add_offset_type !=
"Float64")
1124 new_offset_value_float = (orig_offset_value_float==0)?0:(-1 * orig_offset_value_float *new_scale_value_double);
1126 new_offset_value_double = (orig_offset_value_double==0)?0:(-1 * orig_offset_value_double *new_scale_value_double);
1130 add_scale_offset_attrs(at,scale_factor_type,new_scale_value_float,new_scale_value_double,add_offset_found,
1131 add_offset_type,new_offset_value_float,new_offset_value_double);
1155void HDFCFUtil::handle_modis_special_attrs(AttrTable *at,
const string & filename,
1156 bool is_grid,
const string & newfname,
1157 SOType sotype,
bool gridname_change_valid_range,
1158 bool changedtype,
bool & change_fvtype){
1161 string scale_factor_type;
1162 string add_offset_type;
1163 string fillvalue_type;
1164 string valid_range_type;
1168 string scale_factor_value=
"";
1169 float orig_scale_value = 1;
1170 string add_offset_value=
"0";
1171 float orig_offset_value = 0;
1172 bool add_offset_found =
false;
1175 string fillvalue=
"";
1178 string valid_range_value=
"";
1180 bool has_valid_range =
false;
1183 float orig_valid_min = 0;
1184 float orig_valid_max = 0;
1187 string number_type_value=
"";
1188 string number_type_dap_type=
"";
1192 AttrTable::Attr_iter it = at->attr_begin();
1193 while (it!=at->attr_end())
1195 if(at->get_name(it)==
"scale_factor")
1197 scale_factor_value = (*at->get_attr_vector(it)->begin());
1198 orig_scale_value = (float)(atof(scale_factor_value.c_str()));
1199 scale_factor_type = at->get_type(it);
1202 if(at->get_name(it)==
"add_offset")
1204 add_offset_value = (*at->get_attr_vector(it)->begin());
1205 orig_offset_value = (float)(atof(add_offset_value.c_str()));
1206 add_offset_type = at->get_type(it);
1207 add_offset_found =
true;
1210 if(at->get_name(it)==
"_FillValue")
1212 fillvalue = (*at->get_attr_vector(it)->begin());
1213 fillvalue_type = at->get_type(it);
1216 if(at->get_name(it)==
"valid_range")
1218 vector<string> *avalue = at->get_attr_vector(it);
1219 auto ait = avalue->begin();
1220 while(ait!=avalue->end())
1222 valid_range_value += *ait;
1224 if(ait!=avalue->end())
1225 valid_range_value +=
", ";
1227 valid_range_type = at->get_type(it);
1228 if (
false == gridname_change_valid_range) {
1229 orig_valid_min = (float)(atof((avalue->at(0)).c_str()));
1230 orig_valid_max = (float)(atof((avalue->at(1)).c_str()));
1232 has_valid_range =
true;
1235 if(
true == changedtype && (at->get_name(it)==
"Number_Type"))
1237 number_type_value = (*at->get_attr_vector(it)->begin());
1238 number_type_dap_type= at->get_type(it);
1246 if(scale_factor_value.length()!=0)
1248 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
1250 at->del_attr(
"scale_factor");
1251 at->append_attr(
"orig_scale_factor", scale_factor_type, scale_factor_value);
1252 if(add_offset_found)
1254 at->del_attr(
"add_offset");
1255 at->append_attr(
"orig_add_offset", add_offset_type, add_offset_value);
1261 if(
true == changedtype && fillvalue.length()!=0 && fillvalue_type!=
"Float32" && fillvalue_type!=
"Float64")
1263 change_fvtype =
true;
1264 at->del_attr(
"_FillValue");
1265 at->append_attr(
"_FillValue",
"Float32", fillvalue);
1268 float valid_max = 0;
1269 float valid_min = 0;
1271 it = at->attr_begin();
1272 bool handle_modis_l1b =
false;
1277 if (sotype == MODIS_MUL_SCALE &&
true ==changedtype) {
1280 string emissive_str =
"Emissive";
1281 string RefSB_str =
"RefSB";
1282 bool is_emissive_field =
false;
1283 bool is_refsb_field =
false;
1284 if(newfname.find(emissive_str)!=string::npos) {
1285 if(0 == newfname.compare(newfname.size()-emissive_str.size(),emissive_str.size(),emissive_str))
1286 is_emissive_field =
true;
1289 if(newfname.find(RefSB_str)!=string::npos) {
1290 if(0 == newfname.compare(newfname.size()-RefSB_str.size(),RefSB_str.size(),RefSB_str))
1291 is_refsb_field =
true;
1295 if ((
true == is_emissive_field) || (
true== is_refsb_field)){
1297 float scale_max = 0;
1298 float scale_min = 100000;
1300 float offset_max = 0;
1301 float offset_min = 0;
1303 float temp_var_val = 0;
1305 string orig_long_name_value;
1306 string modify_long_name_value;
1307 string str_removed_from_long_name=
" Scaled Integers";
1308 string radiance_units_value;
1310 while (it!=at->attr_end())
1313 if(
true == is_emissive_field) {
1315 if (
"radiance_scales" == (at->get_name(it))) {
1316 vector<string> *avalue = at->get_attr_vector(it);
1317 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1318 temp_var_val = (float)(atof((*ait).c_str()));
1321 for (
const auto &avalue_ele:*avalue) {
1322 temp_var_val = (float)(atof((avalue_ele).c_str()));
1324 if (temp_var_val > scale_max)
1325 scale_max = temp_var_val;
1326 if (temp_var_val < scale_min)
1327 scale_min = temp_var_val;
1331 if (
"radiance_offsets" == (at->get_name(it))) {
1332 vector<string> *avalue = at->get_attr_vector(it);
1333 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1334 temp_var_val = (float)(atof((*ait).c_str()));
1335 if (temp_var_val > offset_max)
1336 offset_max = temp_var_val;
1337 if (temp_var_val < scale_min)
1338 offset_min = temp_var_val;
1342 if (
"long_name" == (at->get_name(it))) {
1343 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1344 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1345 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1346 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1348 modify_long_name_value =
1349 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1350 at->del_attr(
"long_name");
1351 at->append_attr(
"long_name",
"String",modify_long_name_value);
1352 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1357 if (
"radiance_units" == (at->get_name(it)))
1358 radiance_units_value = (*at->get_attr_vector(it)->begin());
1361 if (
true == is_refsb_field) {
1362 if (
"reflectance_scales" == (at->get_name(it))) {
1363 vector<string> *avalue = at->get_attr_vector(it);
1364 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1365 temp_var_val = (float)(atof((*ait).c_str()));
1366 if (temp_var_val > scale_max)
1367 scale_max = temp_var_val;
1368 if (temp_var_val < scale_min)
1369 scale_min = temp_var_val;
1373 if (
"reflectance_offsets" == (at->get_name(it))) {
1375 vector<string> *avalue = at->get_attr_vector(it);
1376 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1377 temp_var_val = (float)(atof((*ait).c_str()));
1378 if (temp_var_val > offset_max)
1379 offset_max = temp_var_val;
1380 if (temp_var_val < scale_min)
1381 offset_min = temp_var_val;
1385 if (
"long_name" == (at->get_name(it))) {
1386 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1387 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1388 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1389 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1391 modify_long_name_value =
1392 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1393 at->del_attr(
"long_name");
1394 at->append_attr(
"long_name",
"String",modify_long_name_value);
1395 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1405 throw InternalErr(__FILE__,__LINE__,
"the scale factor should always be greater than 0.");
1407 if (orig_valid_max > offset_min)
1408 valid_max = (orig_valid_max-offset_min)*scale_max;
1410 valid_max = (orig_valid_max-offset_min)*scale_min;
1412 if (orig_valid_min > offset_max)
1413 valid_min = (orig_valid_min-offset_max)*scale_min;
1415 valid_min = (orig_valid_min -offset_max)*scale_max;
1422 at->append_attr(
"valid_min",
"Float32",print_rep);
1424 at->append_attr(
"valid_max",
"Float32",print_rep);
1425 at->del_attr(
"valid_range");
1426 handle_modis_l1b =
true;
1429 if (
true == is_emissive_field && radiance_units_value.size() >0) {
1430 at->del_attr(
"units");
1431 at->append_attr(
"units",
"String",radiance_units_value);
1437 if(
true == changedtype &&
true == has_valid_range &&
false == handle_modis_l1b) {
1440 if (
true == gridname_change_valid_range)
1441 HDFCFUtil::handle_modis_vip_special_attrs(valid_range_value,scale_factor_value,valid_min,valid_max);
1442 else if(scale_factor_value.length()!=0) {
1461 if (MODIS_EQ_SCALE == sotype || MODIS_MUL_SCALE == sotype) {
1462 if (orig_scale_value > 1) {
1464 bool need_change_scale =
true;
1465 if(
true == is_grid) {
1466 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
1467 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
1468 need_change_scale =
false;
1471 else if((filename.size() >7)&&((filename.compare(0,7,
"MOD16A2") == 0)|| (filename.compare(0,7,
"MYD16A2")==0) ||
1472 (filename.compare(0,7,
"MOD16A3")==0) || (filename.compare(0,7,
"MYD16A3")==0)))
1473 need_change_scale =
false;
1475 if(
true == need_change_scale) {
1476 sotype = MODIS_DIV_SCALE;
1477 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< orig_scale_value << endl
1478 <<
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE. " << endl
1479 <<
" Now change it to MODIS_DIV_SCALE. "<<endl;
1484 if (MODIS_DIV_SCALE == sotype) {
1485 if (orig_scale_value < 1) {
1486 sotype = MODIS_MUL_SCALE;
1487 (*BESLog::TheLog())<<
"The field " << newfname <<
" scale factor is "<< orig_scale_value << endl
1488 <<
" But the original scale factor type is MODIS_DIV_SCALE. " << endl
1489 <<
" Now change it to MODIS_MUL_SCALE. "<<endl;
1493 if(sotype == MODIS_MUL_SCALE) {
1494 valid_min = (orig_valid_min - orig_offset_value)*orig_scale_value;
1495 valid_max = (orig_valid_max - orig_offset_value)*orig_scale_value;
1497 else if (sotype == MODIS_DIV_SCALE) {
1498 valid_min = (orig_valid_min - orig_offset_value)/orig_scale_value;
1499 valid_max = (orig_valid_max - orig_offset_value)/orig_scale_value;
1501 else if (sotype == MODIS_EQ_SCALE) {
1502 valid_min = orig_valid_min * orig_scale_value + orig_offset_value;
1503 valid_max = orig_valid_max * orig_scale_value + orig_offset_value;
1507 if (MODIS_MUL_SCALE == sotype || MODIS_DIV_SCALE == sotype) {
1508 valid_min = orig_valid_min - orig_offset_value;
1509 valid_max = orig_valid_max - orig_offset_value;
1511 else if (MODIS_EQ_SCALE == sotype) {
1512 valid_min = orig_valid_min + orig_offset_value;
1513 valid_max = orig_valid_max + orig_offset_value;
1519 at->append_attr(
"valid_min",
"Float32",print_rep);
1521 at->append_attr(
"valid_max",
"Float32",print_rep);
1522 at->del_attr(
"valid_range");
1528 if(
true == changedtype && number_type_dap_type !=
"" ) {
1529 at->del_attr(
"Number_Type");
1530 at->append_attr(
"Number_Type_Orig",number_type_dap_type,number_type_value);
1536void HDFCFUtil::handle_modis_vip_special_attrs(
const std::string& valid_range_value,
1537 const std::string& scale_factor_value,
1538 float& valid_min,
float &valid_max) {
1540 int16 vip_orig_valid_min = 0;
1541 int16 vip_orig_valid_max = 0;
1543 size_t found = valid_range_value.find_first_of(
",");
1544 size_t found_from_end = valid_range_value.find_last_of(
",");
1545 if (string::npos == found)
1546 throw InternalErr(__FILE__,__LINE__,
"should find the separator ,");
1547 if (found != found_from_end)
1548 throw InternalErr(__FILE__,__LINE__,
"There should be only one separator.");
1555 vip_orig_valid_min = (short) (atoi((valid_range_value.substr(0,found)).c_str()));
1556 vip_orig_valid_max = (short) (atoi((valid_range_value.substr(found+1)).c_str()));
1558 int16 scale_factor_number = 1;
1560 scale_factor_number = (short)(atoi(scale_factor_value.c_str()));
1562 if(scale_factor_number !=0) {
1563 valid_min = (float)(vip_orig_valid_min/scale_factor_number);
1564 valid_max = (float)(vip_orig_valid_max/scale_factor_number);
1567 throw InternalErr(__FILE__,__LINE__,
"The scale_factor_number should not be zero.");
1572void HDFCFUtil::handle_amsr_attrs(AttrTable *at) {
1574 AttrTable::Attr_iter it = at->attr_begin();
1576 string scale_factor_value=
"";
1577 string add_offset_value=
"0";
1579 string scale_factor_type;
1580 string add_offset_type;
1582 bool OFFSET_found =
false;
1583 bool Scale_found =
false;
1584 bool SCALE_FACTOR_found =
false;
1586 while (it!=at->attr_end())
1588 if(at->get_name(it)==
"SCALE_FACTOR")
1590 scale_factor_value = (*at->get_attr_vector(it)->begin());
1591 scale_factor_type = at->get_type(it);
1592 SCALE_FACTOR_found =
true;
1595 if(at->get_name(it)==
"Scale")
1597 scale_factor_value = (*at->get_attr_vector(it)->begin());
1598 scale_factor_type = at->get_type(it);
1602 if(at->get_name(it)==
"OFFSET")
1604 add_offset_value = (*at->get_attr_vector(it)->begin());
1605 add_offset_type = at->get_type(it);
1606 OFFSET_found =
true;
1611 if (
true == SCALE_FACTOR_found) {
1612 at->del_attr(
"SCALE_FACTOR");
1613 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1616 if (
true == Scale_found) {
1617 at->del_attr(
"Scale");
1618 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1621 if (
true == OFFSET_found) {
1622 at->del_attr(
"OFFSET");
1623 at->append_attr(
"add_offset",add_offset_type,add_offset_value);
1631void HDFCFUtil::obtain_grid_latlon_dim_info(
const HDFEOS2::GridDataset* gdset,
1637 const vector<HDFEOS2::Field*>gfields = gdset->getDataFields();
1638 for (
const auto &gf:gfields) {
1641 if(1 == gf->getFieldType()) {
1642 const vector<HDFEOS2::Dimension*>& dims= gf->getCorrectedDimensions();
1645 if(2 == dims.size()) {
1648 if(
true == gf->getYDimMajor()) {
1649 dim0name = dims[0]->getName();
1650 dim0size = dims[0]->getSize();
1651 dim1name = dims[1]->getName();
1652 dim1size = dims[1]->getSize();
1655 dim0name = dims[1]->getName();
1656 dim0size = dims[1]->getSize();
1657 dim1name = dims[0]->getName();
1658 dim1size = dims[0]->getSize();
1664 if( 1 == dims.size()) {
1665 dim0name = dims[0]->getName();
1666 dim0size = dims[0]->getSize();
1671 if(2 == gf->getFieldType()) {
1672 const vector<HDFEOS2::Dimension*>& dims= gf->getCorrectedDimensions();
1673 if(2 == dims.size()) {
1677 if(
true == gf->getYDimMajor()) {
1678 dim0name = dims[0]->getName();
1679 dim0size = dims[0]->getSize();
1680 dim1name = dims[1]->getName();
1681 dim1size = dims[1]->getSize();
1684 dim0name = dims[1]->getName();
1685 dim0size = dims[1]->getSize();
1686 dim1name = dims[0]->getName();
1687 dim1size = dims[0]->getSize();
1691 if( 1 == dims.size()) {
1692 dim1name = dims[0]->getName();
1693 dim1size = dims[0]->getSize();
1698 if(
""==dim0name ||
""==dim1name || dim0size<0 || dim1size <0)
1699 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain grid lat/lon dimension info.");
1705void HDFCFUtil::add_cf_grid_mapping_attr(DAS &das,
const HDFEOS2::GridDataset*gdset,
const string& cf_projection,
1706 const string & dim0name,int32 dim0size,
const string &dim1name,int32 dim1size) {
1709 const vector<HDFEOS2::Field*>gfields = gdset->getDataFields();
1711 for (
const auto &gf:gfields) {
1712 if(0 == gf->getFieldType() && gf->getRank() >1) {
1713 bool has_dim0 =
false;
1714 bool has_dim1 =
false;
1715 const vector<HDFEOS2::Dimension*>& dims= gf->getCorrectedDimensions();
1716 for (
const auto &dim:dims) {
1717 if(dim->getName()== dim0name && dim->getSize() == dim0size)
1719 else if(dim->getName()== dim1name && dim->getSize() == dim1size)
1723 if(
true == has_dim0 &&
true == has_dim1) {
1724 AttrTable *at = das.get_table(gf->getNewName());
1726 at = das.add_table(gf->getNewName(),
new AttrTable);
1729 at->append_attr(
"grid_mapping",
"String",cf_projection);
1736void HDFCFUtil::add_cf_grid_cv_attrs(DAS & das,
const HDFEOS2::GridDataset *gdset) {
1739 if(GCTP_SNSOID == gdset->getProjection().getCode()) {
1744 int32 dim0size = -1;
1745 int32 dim1size = -1;
1747 HDFCFUtil::obtain_grid_latlon_dim_info(gdset,dim0name,dim0size,dim1name,dim1size);
1750 AttrTable *at = das.get_table(dim0name);
1752 at = das.add_table(dim0name,
new AttrTable);
1753 at->append_attr(
"standard_name",
"String",
"projection_y_coordinate");
1755 string long_name=
"y coordinate of projection for grid "+ gdset->getName();
1756 at->append_attr(
"long_name",
"String",long_name);
1758 at->append_attr(
"units",
"string",
"meter");
1760 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoY");
1762 at = das.get_table(dim1name);
1764 at = das.add_table(dim1name,
new AttrTable);
1766 at->append_attr(
"standard_name",
"String",
"projection_x_coordinate");
1767 long_name=
"x coordinate of projection for grid "+ gdset->getName();
1768 at->append_attr(
"long_name",
"String",long_name);
1771 at->append_attr(
"units",
"string",
"meter");
1772 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoX");
1775 string cf_projection_base =
"eos_cf_projection";
1777 at = das.get_table(cf_projection);
1779 at = das.add_table(cf_projection,
new AttrTable);
1781 at->append_attr(
"grid_mapping_name",
"String",
"sinusoidal");
1782 at->append_attr(
"longitude_of_central_meridian",
"Float64",
"0.0");
1783 at->append_attr(
"earth_radius",
"Float64",
"6371007.181");
1785 at->append_attr(
"_CoordinateAxisTypes",
"string",
"GeoX GeoY");
1789 HDFCFUtil::add_cf_grid_mapping_attr(das,gdset,cf_projection,dim0name,dim0size,dim1name,dim1size);
1798void HDFCFUtil::add_cf_grid_cvs(DDS & dds,
const HDFEOS2::GridDataset *gdset) {
1801 if(GCTP_SNSOID == gdset->getProjection().getCode()) {
1806 int32 dim0size = -1;
1807 int32 dim1size = -1;
1808 HDFCFUtil::obtain_grid_latlon_dim_info(gdset,dim0name,dim0size,dim1name,dim1size);
1813 BaseType *bt_dim0 =
nullptr;
1814 BaseType *bt_dim1 =
nullptr;
1816 HDFEOS2GeoCF1D * ar_dim0 =
nullptr;
1817 HDFEOS2GeoCF1D * ar_dim1 =
nullptr;
1819 const float64 *upleft =
nullptr;
1820 const float64 *lowright =
nullptr;
1824 bt_dim0 =
new(
HDFFloat64)(dim0name,gdset->getName());
1825 bt_dim1 =
new(
HDFFloat64)(dim1name,gdset->getName());
1828 upleft = gdset->getInfo().getUpLeft();
1829 lowright = gdset->getInfo().getLowRight();
1832 ar_dim0 =
new HDFEOS2GeoCF1D(GCTP_SNSOID,
1833 upleft[1],lowright[1],dim0size,dim0name,bt_dim0);
1834 ar_dim0->append_dim(dim0size,dim0name);
1836 ar_dim1 =
new HDFEOS2GeoCF1D(GCTP_SNSOID,
1837 upleft[0],lowright[0],dim1size,dim1name,bt_dim1);
1838 ar_dim1->append_dim(dim1size,dim1name);
1839 dds.add_var(ar_dim0);
1840 dds.add_var(ar_dim1);
1852 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFEOS2GeoCF1D instance.");
1865 string cf_projection_base =
"eos_cf_projection";
1870 HDFEOS2GeoCFProj * dummy_proj_cf =
new HDFEOS2GeoCFProj(cf_projection,gdset->getName());
1871 dds.add_var(dummy_proj_cf);
1873 delete dummy_proj_cf;
1882void HDFCFUtil::check_obpg_global_attrs(
HDFSP::File *f, std::string & scaling,
1883 float & slope,
bool &global_slope_flag,
1884 float & intercept,
bool & global_intercept_flag){
1897 if(attr->getName()==
"Scaling")
1899 string tmpstring(attr->getValue().begin(), attr->getValue().end());
1900 scaling = tmpstring;
1902 if(attr->getName()==
"Slope" || attr->getName()==
"slope")
1904 global_slope_flag =
true;
1906 switch(attr->getType())
1908#define GET_SLOPE(TYPE, CAST) \
1911 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
1912 slope = (float)tmpvalue; \
1915 GET_SLOPE(INT16, int16)
1916 GET_SLOPE(INT32, int32)
1917 GET_SLOPE(FLOAT32,
float)
1918 GET_SLOPE(FLOAT64,
double)
1920 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1927 if(attr->getName()==
"Intercept" || attr->getName()==
"intercept")
1929 global_intercept_flag =
true;
1930 switch(attr->getType())
1932#define GET_INTERCEPT(TYPE, CAST) \
1935 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
1936 intercept = (float)tmpvalue; \
1939 GET_INTERCEPT(INT16, int16)
1940 GET_INTERCEPT(INT32, int32)
1941 GET_INTERCEPT(FLOAT32,
float)
1942 GET_INTERCEPT(FLOAT64,
double)
1944 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1958void HDFCFUtil::add_obpg_special_attrs(
const HDFSP::File*f,DAS &das,
1960 const string& scaling,
float& slope,
1961 const bool& global_slope_flag,
1963 const bool & global_intercept_flag) {
1965 AttrTable *at = das.get_table(onespsds->
getNewName());
1967 at = das.add_table(onespsds->
getNewName(),
new AttrTable);
1971 bool scale_factor_flag =
false;
1972 bool add_offset_flag =
false;
1973 bool slope_flag =
false;
1974 bool intercept_flag =
false;
1978 for(vector<HDFSP::Attribute *>::const_iterator i=onespsds->
getAttributes().begin();
1983 if(global_slope_flag !=
true && (attr->getName()==
"Slope" || attr->getName()==
"slope"))
1987 switch(attr->getType())
1989#define GET_SLOPE(TYPE, CAST) \
1992 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
1993 slope = (float)tmpvalue; \
1997 GET_SLOPE(INT16, int16)
1998 GET_SLOPE(INT32, int32)
1999 GET_SLOPE(FLOAT32,
float)
2000 GET_SLOPE(FLOAT64,
double)
2002 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
2010 if(global_intercept_flag !=
true && (attr->getName()==
"Intercept" || attr->getName()==
"intercept"))
2012 intercept_flag =
true;
2013 switch(attr->getType())
2015#define GET_INTERCEPT(TYPE, CAST) \
2018 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
2019 intercept = (float)tmpvalue; \
2022 GET_INTERCEPT(INT16, int16)
2023 GET_INTERCEPT(INT32, int32)
2024 GET_INTERCEPT(FLOAT32,
float)
2025 GET_INTERCEPT(FLOAT64,
double)
2027 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
2041 if((f->
getSPType()==OBPGL3 || f->
getSPType() == OBPGL2) && attr->getName()==
"scale_factor")
2042 scale_factor_flag =
true;
2044 if((f->
getSPType()==OBPGL3 || f->
getSPType() == OBPGL2) && attr->getName()==
"add_offset")
2045 add_offset_flag =
true;
2050 if((f->
getSPType() == OBPGL2 || f->
getSPType()==OBPGL3 )&& onespsds->getFieldType()==0)
2053 if((OBPGL3 == f->
getSPType() && (scaling.find(
"linear")!=string::npos)) || OBPGL2 == f->
getSPType() ) {
2055 if(
false == scale_factor_flag && (
true == slope_flag ||
true == global_slope_flag))
2061 if(
false == add_offset_flag && (
true == intercept_flag ||
true == global_intercept_flag))
2068 bool has_fill_value =
false;
2070 if (
"_FillValue" == attr->getNewName()){
2071 has_fill_value =
true;
2079 if ((
false == has_fill_value) &&(DFNT_INT16 == onespsds->
getType())) {
2080 short fill_value = -32767;
2085 if ((
false == has_fill_value) &&(DFNT_UINT16 == onespsds->
getType())) {
2086 unsigned short fill_value = 65535;
2097void HDFCFUtil::handle_otherhdf_special_attrs(
const HDFSP::File*f,DAS &das) {
2109 bool latflag =
false;
2110 bool latunitsflag =
false;
2111 bool lonflag =
false;
2112 bool lonunitsflag =
false;
2113 int llcheckoverflag = 0;
2125 for (
const auto &fd:spsds){
2133 if (OTHERHDF == f->
getSPType() &&
true == fd->IsDimNoScale())
2136 AttrTable *at = das.get_table(fd->getNewName());
2138 at = das.add_table(fd->getNewName(),
new AttrTable);
2140 for (
const auto& attr:fd->getAttributes()) {
2141 if(attr->getType()==DFNT_UCHAR || attr->getType() == DFNT_CHAR){
2143 if(attr->getName() ==
"long_name") {
2144 string tempstring2(attr->getValue().begin(),attr->getValue().end());
2145 string tempfinalstr= string(tempstring2.c_str());
2146 if(tempfinalstr==
"latitude" || tempfinalstr ==
"Latitude")
2148 if(tempfinalstr==
"longitude" || tempfinalstr ==
"Longitude")
2155 for (
const auto& attr:fd->getAttributes()) {
2156 if (attr->getName() ==
"units")
2157 latunitsflag =
true;
2162 for(
const auto& attr:fd->getAttributes()) {
2163 if(attr->getName() ==
"units")
2164 lonunitsflag =
true;
2167 if(latflag && !latunitsflag){
2168 at->append_attr(
"units",
"String",
"degrees_north");
2170 latunitsflag =
false;
2174 if(lonflag && !lonunitsflag){
2175 at->append_attr(
"units",
"String",
"degrees_east");
2177 lonunitsflag =
false;
2180 if(llcheckoverflag ==2)
break;
2190HDFCFUtil::add_missing_cf_attrs(
const HDFSP::File*f,DAS &das) {
2197 for(
const auto &fd:spsds){
2198 if(fd->getFieldType() == 0 && fd->getType()==DFNT_FLOAT32) {
2200 AttrTable *at = das.get_table(fd->getNewName());
2202 at = das.add_table(fd->getNewName(),
new AttrTable);
2203 string print_rep =
"-9999.9";
2209 for(
const auto &fd:spsds){
2210 if(fd->getFieldType() == 0 && ((fd->getType()==DFNT_INT32) || (fd->getType()==DFNT_INT16))) {
2212 AttrTable *at = das.get_table(fd->getNewName());
2214 at = das.add_table(fd->getNewName(),
new AttrTable);
2215 string print_rep =
"-9999";
2216 if(fd->getType()==DFNT_INT32)
2226 for(
const auto &fd:spsds){
2227 if(fd->getFieldType() == 6 && fd->getNewName()==
"nlayer") {
2229 AttrTable *at = das.get_table(fd->getNewName());
2231 at = das.add_table(fd->getNewName(),
new AttrTable);
2232 at->append_attr(
"units",
"String",
"km");
2235 else if(fd->getFieldType() == 4) {
2237 if (fd->getNewName()==
"nh3" ||
2238 fd->getNewName()==
"ncat3" ||
2239 fd->getNewName()==
"nthrshZO" ||
2240 fd->getNewName()==
"nthrshHB" ||
2241 fd->getNewName()==
"nthrshSRT")
2245 "http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2248 AttrTable *at = das.get_table(fd->getNewName());
2250 at = das.add_table(fd->getNewName(),
new AttrTable);
2252 if(fd->getNewName()==
"nh3") {
2253 comment=
"Index number to represent the fixed heights above the earth ellipsoid,";
2254 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
2257 else if(fd->getNewName()==
"ncat3") {
2258 comment=
"Index number to represent catgories for probability distribution functions.";
2259 comment=comment +
"Check more information from the references.";
2262 else if(fd->getNewName()==
"nthrshZO")
2263 comment=
"Q-thresholds for Zero order used for probability distribution functions.";
2265 else if(fd->getNewName()==
"nthrshHB")
2266 comment=
"Q-thresholds for HB used for probability distribution functions.";
2268 else if(fd->getNewName()==
"nthrshSRT")
2269 comment=
"Q-thresholds for SRT used for probability distribution functions.";
2271 at->append_attr(
"comment",
"String",comment);
2272 at->append_attr(
"references",
"String",references);
2283 string base_filename;
2284 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
2285 if(last_slash_pos != string::npos)
2286 base_filename = f->
getPath().substr(last_slash_pos+1);
2287 if(
""==base_filename)
2289 bool t3a26_flag = ((base_filename.find(
"3A26")!=string::npos)?
true:
false);
2291 if(
true == t3a26_flag) {
2293 for(
const auto &fd:spsds){
2295 if(fd->getFieldType() == 0 && (fd->getType()==DFNT_FLOAT32)) {
2296 AttrTable *at = das.get_table(fd->getNewName());
2298 at = das.add_table(fd->getNewName(),
new AttrTable);
2299 at->del_attr(
"_FillValue");
2300 at->append_attr(
"_FillValue",
"Float32",
"-999");
2301 at->append_attr(
"valid_min",
"Float32",
"0");
2311 for(
const auto &fd:spsds){
2313 if(fd->getFieldType() == 4 ) {
2315 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2316 if (fd->getNewName()==
"nh1") {
2318 AttrTable *at = das.get_table(fd->getNewName());
2320 at = das.add_table(fd->getNewName(),
new AttrTable);
2322 string comment=
"Number of fixed heights above the earth ellipsoid,";
2323 comment= comment +
" at 2, 4, 6, 10, and 15 km plus one for path-average.";
2325 at->append_attr(
"comment",
"String",comment);
2326 at->append_attr(
"references",
"String",references);
2329 if (fd->getNewName()==
"nh3") {
2331 AttrTable *at = das.get_table(fd->getNewName());
2333 at = das.add_table(fd->getNewName(),
new AttrTable);
2335 string comment=
"Number of fixed heights above the earth ellipsoid,";
2336 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
2338 at->append_attr(
"comment",
"String",comment);
2339 at->append_attr(
"references",
"String",references);
2343 if (fd->getNewName()==
"nang") {
2345 AttrTable *at = das.get_table(fd->getNewName());
2347 at = das.add_table(fd->getNewName(),
new AttrTable);
2349 string comment=
"Number of fixed incidence angles, at 0, 5, 10 and 15 degree and all angles.";
2350 references =
"http://pps.gsfc.nasa.gov/Documents/ICSVol4.pdf";
2352 at->append_attr(
"comment",
"String",comment);
2353 at->append_attr(
"references",
"String",references);
2357 if (fd->getNewName()==
"ncat2") {
2359 AttrTable *at = das.get_table(fd->getNewName());
2361 at = das.add_table(fd->getNewName(),
new AttrTable);
2363 string comment=
"Second number of categories for histograms (30). ";
2364 comment=comment +
"Check more information from the references.";
2366 at->append_attr(
"comment",
"String",comment);
2367 at->append_attr(
"references",
"String",references);
2381 string base_filename;
2382 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
2383 if(last_slash_pos != string::npos)
2384 base_filename = f->
getPath().substr(last_slash_pos+1);
2385 if(
""==base_filename)
2387 bool t2b31_flag = ((base_filename.find(
"2B31")!=string::npos)?
true:
false);
2388 bool t2a21_flag = ((base_filename.find(
"2A21")!=string::npos)?
true:
false);
2389 bool t2a12_flag = ((base_filename.find(
"2A12")!=string::npos)?
true:
false);
2394 bool t2a25_flag = ((base_filename.find(
"2A25")!=string::npos)?
true:
false);
2395 bool t1c21_flag = ((base_filename.find(
"1C21")!=string::npos)?
true:
false);
2396 bool t1b21_flag = ((base_filename.find(
"1B21")!=string::npos)?
true:
false);
2397 bool t1b11_flag = ((base_filename.find(
"1B11")!=string::npos)?
true:
false);
2398 bool t1b01_flag = ((base_filename.find(
"1B01")!=string::npos)?
true:
false);
2403 if(t2b31_flag || t2a12_flag || t2a21_flag) {
2408 for (
const auto &fd:spsds){
2410 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2412 AttrTable *at = das.get_table(fd->getNewName());
2414 at = das.add_table(fd->getNewName(),
new AttrTable);
2416 AttrTable::Attr_iter it = at->attr_begin();
2417 while (it!=at->attr_end()) {
2418 if(at->get_name(it)==
"scale_factor")
2421 string scale_factor_value=
"";
2422 string scale_factor_type;
2424 scale_factor_value = (*at->get_attr_vector(it)->begin());
2425 scale_factor_type = at->get_type(it);
2427 if(scale_factor_type ==
"Float64") {
2428 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
nullptr);
2429 at->del_attr(
"scale_factor");
2431 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2435 if(scale_factor_type ==
"Float32") {
2436 float new_scale = 1.0f/strtof(scale_factor_value.c_str(),
nullptr);
2437 at->del_attr(
"scale_factor");
2439 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2452 if (t2a12_flag==
true) {
2454 for (
const auto &fd:spsds){
2456 if (fd->getFieldType() == 6 && fd->getNewName()==
"nlayer") {
2458 AttrTable *at = das.get_table(fd->getNewName());
2460 at = das.add_table(fd->getNewName(),
new AttrTable);
2461 at->append_attr(
"units",
"String",
"km");
2466 if (fd->getFieldType() == 0 && fd->getType()==DFNT_INT8) {
2468 AttrTable *at = das.get_table(fd->getNewName());
2470 at = das.add_table(fd->getNewName(),
new AttrTable);
2471 at->append_attr(
"_FillValue",
"Int32",
"-99");
2481 for (
const auto & fd:spsds){
2482 if (fd->getFieldType() == 0 && fd->getType()==DFNT_FLOAT32) {
2484 AttrTable *at = das.get_table(fd->getNewName());
2486 at = das.add_table(fd->getNewName(),
new AttrTable);
2487 string print_rep =
"-9999.9";
2493 for (
const auto &fd:spsds){
2496 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2498 AttrTable *at = das.get_table(fd->getNewName());
2500 at = das.add_table(fd->getNewName(),
new AttrTable);
2502 string print_rep =
"-9999";
2511 else if(t2a21_flag ==
true || t2a25_flag ==
true) {
2514 if (t2a25_flag ==
true) {
2516 unsigned char handle_scale = 0;
2518 for (
const auto &fd:spsds){
2520 if (fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2521 bool has_dBZ =
false;
2522 bool has_rainrate =
false;
2523 bool has_scale =
false;
2524 string scale_factor_value;
2525 string scale_factor_type;
2527 AttrTable *at = das.get_table(fd->getNewName());
2529 at = das.add_table(fd->getNewName(),
new AttrTable);
2530 AttrTable::Attr_iter it = at->attr_begin();
2531 while (it!=at->attr_end()) {
2532 if(at->get_name(it)==
"units"){
2533 string units_value = *at->get_attr_vector(it)->begin();
2534 if(
"dBZ" == units_value) {
2538 else if(
"mm/hr" == units_value){
2539 has_rainrate =
true;
2542 if(at->get_name(it)==
"scale_factor")
2544 scale_factor_value = *at->get_attr_vector(it)->begin();
2545 scale_factor_type = at->get_type(it);
2552 if((
true == has_rainrate ||
true == has_dBZ) &&
true == has_scale) {
2555 short valid_min = 0;
2556 short valid_max = 0;
2559 if(
true == has_rainrate)
2560 valid_max = (short)(300*strtof(scale_factor_value.c_str(),
nullptr));
2561 else if(
true == has_dBZ)
2562 valid_max = (short)(80*strtof(scale_factor_value.c_str(),
nullptr));
2565 at->append_attr(
"valid_min",
"Int16",print_rep1);
2567 at->append_attr(
"valid_max",
"Int16",print_rep1);
2569 at->del_attr(
"scale_factor");
2570 if(scale_factor_type ==
"Float64") {
2571 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
nullptr);
2573 at->append_attr(
"scale_factor", scale_factor_type,print_rep2);
2577 if(scale_factor_type ==
"Float32") {
2578 float new_scale = 1.0/strtof(scale_factor_value.c_str(),
nullptr);
2580 at->append_attr(
"scale_factor", scale_factor_type,print_rep3);
2587 if(2 == handle_scale)
2596 else if (t1b21_flag || t1c21_flag || t1b11_flag) {
2599 if (t1b21_flag || t1c21_flag) {
2601 for (
const auto &fd:spsds){
2603 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2605 bool has_dBm =
false;
2606 bool has_dBZ =
false;
2608 AttrTable *at = das.get_table(fd->getNewName());
2610 at = das.add_table(fd->getNewName(),
new AttrTable);
2611 AttrTable::Attr_iter it = at->attr_begin();
2613 while (it!=at->attr_end()) {
2614 if(at->get_name(it)==
"units"){
2616 string units_value = *at->get_attr_vector(it)->begin();
2617 if(
"dBm" == units_value) {
2622 else if(
"dBZ" == units_value){
2630 if(has_dBm ==
true || has_dBZ ==
true) {
2631 it = at->attr_begin();
2632 while (it!=at->attr_end()) {
2633 if(at->get_name(it)==
"scale_factor")
2636 string scale_value = *at->get_attr_vector(it)->begin();
2638 if(
true == has_dBm) {
2639 short valid_min = (short)(-120 *strtof(scale_value.c_str(),
nullptr));
2640 short valid_max = (short)(-20 *strtof(scale_value.c_str(),
nullptr));
2642 at->append_attr(
"valid_min",
"Int16",print_rep);
2644 at->append_attr(
"valid_max",
"Int16",print_rep);
2649 else if(
true == has_dBZ){
2650 short valid_min = (short)(-20 *strtof(scale_value.c_str(),
nullptr));
2651 short valid_max = (short)(80 *strtof(scale_value.c_str(),
nullptr));
2653 at->append_attr(
"valid_min",
"Int16",print_rep);
2655 at->append_attr(
"valid_max",
"Int16",print_rep);
2671 for(
const auto &fd:spsds){
2673 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2675 AttrTable *at = das.get_table(fd->getNewName());
2677 at = das.add_table(fd->getNewName(),
new AttrTable);
2678 AttrTable::Attr_iter it = at->attr_begin();
2681 while (it!=at->attr_end()) {
2683 if(at->get_name(it)==
"scale_factor")
2686 string scale_factor_value=
"";
2687 string scale_factor_type;
2689 scale_factor_value = (*at->get_attr_vector(it)->begin());
2690 scale_factor_type = at->get_type(it);
2692 if(scale_factor_type ==
"Float64") {
2693 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
nullptr);
2694 at->del_attr(
"scale_factor");
2696 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2700 if(scale_factor_type ==
"Float32") {
2701 float new_scale = 1.0f/strtof(scale_factor_value.c_str(),
nullptr);
2702 at->del_attr(
"scale_factor");
2704 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2715 at->append_attr(
"_FillValue",
"Int16",
"-9999");
2722 else if (t1b01_flag ==
true) {
2724 for (
const auto &fd:spsds){
2726 if(fd->getFieldType() == 0 && fd->getType()==DFNT_FLOAT32) {
2728 AttrTable *at = das.get_table(fd->getNewName());
2730 at = das.add_table(fd->getNewName(),
new AttrTable);
2732 at->append_attr(
"_FillValue",
"Float32",
"-9999.9");
2737 AttrTable *at = das.get_table(
"HDF_GLOBAL");
2739 at = das.add_table(
"HDF_GLOBAL",
new AttrTable);
2740 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2741 string comment=
"The HDF4 OPeNDAP handler adds _FillValue, valid_min and valid_max for some TRMM level 1 and level 2 products.";
2742 comment= comment +
" It also changes scale_factor to follow CF conventions. ";
2744 at->append_attr(
"comment",
"String",comment);
2745 at->append_attr(
"references",
"String",references);
2761void HDFCFUtil::handle_merra_ceres_attrs_with_bes_keys(
const HDFSP::File *f, DAS &das,
const string& filename) {
2763 string base_filename = filename.substr(filename.find_last_of(
"/")+1);
2766 string check_ceres_merra_short_name_key=
"H4.EnableCERESMERRAShortName";
2767 bool turn_on_ceres_merra_short_name_key=
false;
2769 turn_on_ceres_merra_short_name_key = HDFCFUtil::check_beskeys(check_ceres_merra_short_name_key);
2772 bool merra_is_eos2 =
false;
2773 if(0== (base_filename.compare(0,5,
"MERRA"))) {
2776 for (vector < HDFSP::Attribute * >::const_iterator i =
2783 if((fd->getName().compare(0, 14,
"StructMetadata" )== 0) ||
2784 (fd->getName().compare(0, 14,
"structmetadata" )== 0)) {
2785 merra_is_eos2 =
true;
2792 if (
true == HDF4RequestHandler::get_enable_ceres_merra_short_name() && (CER_ES4 == f->
getSPType() || CER_SRB == f->
getSPType()
2795 || CER_AVG == f->
getSPType() || (
true == merra_is_eos2))) {
2798 for (
const auto & fd:spsds){
2800 AttrTable *at = das.get_table(fd->getNewName());
2802 at = das.add_table(fd->getNewName(),
new AttrTable);
2804 at->append_attr(
"fullpath",
"String",fd->getSpecFullPath());
2814void HDFCFUtil::handle_vdata_attrs_with_desc_key(
const HDFSP::File*f,libdap::DAS &das) {
2821 string check_vdata_desc_key=
"H4.EnableVdataDescAttr";
2822 bool turn_on_vdata_desc_key=
false;
2824 turn_on_vdata_desc_key = HDFCFUtil::check_beskeys(check_vdata_desc_key);
2827 string VDdescname =
"hdf4_vd_desc";
2828 string VDdescvalue =
"This is an HDF4 Vdata.";
2829 string VDfieldprefix =
"Vdata_field_";
2830 string VDattrprefix =
"Vdata_attr_";
2831 string VDfieldattrprefix =
"Vdata_field_attr_";
2835 string check_ceres_vdata_key=
"H4.EnableCERESVdata";
2836 bool turn_on_ceres_vdata_key=
false;
2837 turn_on_ceres_vdata_key = HDFCFUtil::check_beskeys(check_ceres_vdata_key);
2840 bool output_vdata_flag =
true;
2841 if (
false == HDF4RequestHandler::get_enable_ceres_vdata() &&
2846 output_vdata_flag =
false;
2848 if (
true == output_vdata_flag) {
2852 AttrTable *at = das.get_table(vd->getNewName());
2854 at = das.add_table(vd->getNewName(),
new AttrTable);
2856 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2858 bool emptyvddasflag =
true;
2859 if (!(vd->getAttributes().empty()))
2860 emptyvddasflag =
false;
2861 if (vd->getTreatAsAttrFlag())
2862 emptyvddasflag =
false;
2864 for (
const auto &vfd:vd->getFields()) {
2865 if(!(vfd->getAttributes().empty())) {
2866 emptyvddasflag =
false;
2874 at->append_attr(VDdescname,
"String" , VDdescvalue);
2876 for(
const auto &va:vd->getAttributes()) {
2878 if(va->getType()==DFNT_UCHAR || va->getType() == DFNT_CHAR){
2880 string tempstring2(va->getValue().begin(),va->getValue().end());
2881 string tempfinalstr= string(tempstring2.c_str());
2882 at->append_attr(VDattrprefix+va->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2885 for (
int loc=0; loc < va->getCount() ; loc++) {
2893 if(
false == (vd->getTreatAsAttrFlag())){
2895 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2899 for (
const auto &vdf:vd->getFields()) {
2904 if (vdf->getAttributes().empty() ==
false) {
2906 AttrTable *at_v = das.get_table(vdf->getNewName());
2908 at_v = das.add_table(vdf->getNewName(),
new AttrTable);
2910 for (
const auto &va:vdf->getAttributes()) {
2912 if(va->getType()==DFNT_UCHAR || va->getType() == DFNT_CHAR){
2914 string tempstring2(va->getValue().begin(),va->getValue().end());
2915 string tempfinalstr= string(tempstring2.c_str());
2919 for (
int loc=0; loc < va->getCount() ; loc++) {
2934 for(
const auto & vdf:vd->getFields()) {
2936 if(vdf->getFieldOrder() == 1) {
2937 if(vdf->getType()==DFNT_UCHAR || vdf->getType() == DFNT_CHAR){
2938 string tempfinalstr;
2939 tempfinalstr.resize(vdf->getValue().size());
2940 copy(vdf->getValue().begin(),vdf->getValue().end(),tempfinalstr.begin());
2941 at->append_attr(VDfieldprefix+vdf->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
2944 for (
int loc=0; loc < vdf->getNumRec(); loc++) {
2952 if (vdf->getValue().size() != (
unsigned int)(DFKNTsize(vdf->getType())*(vdf->getFieldOrder())*(vdf->getNumRec()))){
2953 throw InternalErr(__FILE__,__LINE__,
"the vdata field size doesn't match the vector value");
2956 if(vdf->getNumRec()==1){
2957 if(vdf->getType()==DFNT_UCHAR || vdf->getType() == DFNT_CHAR){
2958 string tempstring2(vdf->getValue().begin(),vdf->getValue().end());
2959 string tempfinalstr= string(tempstring2.c_str());
2960 at->append_attr(VDfieldprefix+vdf->getNewName(),
"String",
HDFCFUtil::escattr(tempfinalstr));
2963 for (
int loc=0; loc < vdf->getFieldOrder(); loc++) {
2972 if(vdf->getType()==DFNT_UCHAR || vdf->getType() == DFNT_CHAR){
2974 for(
int tempcount = 0; tempcount < vdf->getNumRec()*DFKNTsize(vdf->getType());tempcount ++) {
2975 vector<char>::const_iterator tempit;
2976 tempit = vdf->getValue().begin()+tempcount*(vdf->getFieldOrder());
2977 string tempstring2(tempit,tempit+vdf->getFieldOrder());
2978 string tempfinalstr= string(tempstring2.c_str());
2979 string tempoutstring =
"'"+tempfinalstr+
"'";
2980 at->append_attr(VDfieldprefix+vdf->getNewName(),
"String",
HDFCFUtil::escattr(tempoutstring));
2985 for(
int tempcount = 0; tempcount < vdf->getNumRec();tempcount ++) {
2987 for (
int loc=0; loc < vdf->getFieldOrder(); loc++) {
2988 string print_rep =
HDFCFUtil::print_attr(vdf->getType(), loc, (
void*) &(vdf->getValue()[tempcount*(vdf->getFieldOrder())]));
2998 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2999 for(
const auto &va:vdf->getAttributes()) {
3001 if(va->getType()==DFNT_UCHAR || va->getType() == DFNT_CHAR){
3003 string tempstring2(va->getValue().begin(),va->getValue().end());
3004 string tempfinalstr= string(tempstring2.c_str());
3005 at->append_attr(VDfieldattrprefix+va->getNewName(),
"String" ,
HDFCFUtil::escattr(tempfinalstr));
3008 for (
int loc=0; loc < va->getCount() ; loc++) {
3010 at->append_attr(VDfieldattrprefix+va->getNewName(),
HDFCFUtil::print_type(va->getType()), print_rep);
3023void HDFCFUtil::map_eos2_objects_attrs(libdap::DAS &das,
const string &filename) {
3026 int32 status_32 = -1;
3028 int32 vgroup_id = -1;
3029 int32 num_of_lones = 0;
3030 uint16 name_len = 0;
3032 file_id = Hopen (filename.c_str(), DFACC_READ, 0);
3034 throw InternalErr(__FILE__,__LINE__,
"Hopen failed.");
3036 status_n = Vstart (file_id);
3037 if(status_n == FAIL) {
3039 throw InternalErr(__FILE__,__LINE__,
"Vstart failed.");
3043 bool unexpected_fail =
false;
3047 num_of_lones = Vlone (file_id,
nullptr, num_of_lones );
3051 if (num_of_lones > 0)
3055 vector<int32> ref_array;
3056 ref_array.resize(num_of_lones);
3062 num_of_lones = Vlone (file_id, ref_array.data(), num_of_lones);
3065 for (
int lone_vg_number = 0; lone_vg_number < num_of_lones;
3072 vgroup_id = Vattach(file_id, ref_array[lone_vg_number],
"r");
3073 if(vgroup_id == FAIL) {
3074 unexpected_fail =
true;
3075 err_msg = string(ERR_LOC) +
" Vattach failed. ";
3079 status_32 = Vgetnamelen(vgroup_id, &name_len);
3080 if(status_32 == FAIL) {
3081 unexpected_fail =
true;
3083 err_msg = string(ERR_LOC) +
" Vgetnamelen failed. ";
3087 vector<char> vgroup_name;
3088 vgroup_name.resize(name_len+1);
3089 status_32 = Vgetname (vgroup_id, vgroup_name.data());
3090 if(status_32 == FAIL) {
3091 unexpected_fail =
true;
3093 err_msg = string(ERR_LOC) +
" Vgetname failed. ";
3097 status_32 = Vgetclassnamelen(vgroup_id, &name_len);
3098 if(status_32 == FAIL) {
3099 unexpected_fail =
true;
3101 err_msg = string(ERR_LOC) +
" Vgetclassnamelen failed. ";
3105 vector<char>vgroup_class;
3106 vgroup_class.resize(name_len+1);
3107 status_32 = Vgetclass (vgroup_id, vgroup_class.data());
3108 if(status_32 == FAIL) {
3109 unexpected_fail =
true;
3111 err_msg = string(ERR_LOC) +
" Vgetclass failed. ";
3115 string vgroup_name_str(vgroup_name.begin(),vgroup_name.end());
3116 vgroup_name_str = vgroup_name_str.substr(0,vgroup_name_str.size()-1);
3118 string vgroup_class_str(vgroup_class.begin(),vgroup_class.end());
3119 vgroup_class_str = vgroup_class_str.substr(0,vgroup_class_str.size()-1);
3121 if(vgroup_class_str ==
"GRID")
3122 map_eos2_one_object_attrs_wrapper(das,file_id,vgroup_id,vgroup_name_str,
true);
3123 else if(vgroup_class_str ==
"SWATH")
3124 map_eos2_one_object_attrs_wrapper(das,file_id,vgroup_id,vgroup_name_str,
false);
3130 throw InternalErr(__FILE__,__LINE__,
"map_eos2_one_object_attrs_wrapper failed.");
3132 Vdetach (vgroup_id);
3140 if(
true == unexpected_fail)
3141 throw InternalErr(__FILE__,__LINE__,err_msg);
3147void HDFCFUtil::map_eos2_one_object_attrs_wrapper(libdap:: DAS &das,int32 file_id,int32 vgroup_id,
const string& vgroup_name,
bool is_grid) {
3149 int32 num_gobjects = Vntagrefs (vgroup_id);
3150 if(num_gobjects < 0)
3151 throw InternalErr(__FILE__,__LINE__,
"Cannot obtain the number of objects under a vgroup.");
3153 for(
int i = 0; i<num_gobjects;i++) {
3157 if (Vgettagref (vgroup_id, i, &obj_tag, &obj_ref) == FAIL)
3158 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain the tag and reference of an object under a vgroup.");
3160 if (Visvg (vgroup_id, obj_ref) == TRUE) {
3162 int32 object_attr_vgroup = Vattach(file_id,obj_ref,
"r");
3163 if(object_attr_vgroup == FAIL)
3164 throw InternalErr(__FILE__,__LINE__,
"Failed to attach an EOS2 vgroup.");
3166 uint16 name_len = 0;
3167 int32 status_32 = Vgetnamelen(object_attr_vgroup, &name_len);
3168 if(status_32 == FAIL) {
3169 Vdetach(object_attr_vgroup);
3170 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain an EOS2 vgroup name length.");
3172 vector<char> attr_vgroup_name;
3173 attr_vgroup_name.resize(name_len+1);
3174 status_32 = Vgetname (object_attr_vgroup, attr_vgroup_name.data());
3175 if(status_32 == FAIL) {
3176 Vdetach(object_attr_vgroup);
3177 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain an EOS2 vgroup name. ");
3180 string attr_vgroup_name_str(attr_vgroup_name.begin(),attr_vgroup_name.end());
3181 attr_vgroup_name_str = attr_vgroup_name_str.substr(0,attr_vgroup_name_str.size()-1);
3184 if(
true == is_grid && attr_vgroup_name_str==
"Grid Attributes"){
3185 map_eos2_one_object_attrs(das,file_id,object_attr_vgroup,vgroup_name);
3186 Vdetach(object_attr_vgroup);
3189 else if(
false == is_grid && attr_vgroup_name_str==
"Swath Attributes") {
3190 map_eos2_one_object_attrs(das,file_id,object_attr_vgroup,vgroup_name);
3191 Vdetach(object_attr_vgroup);
3196 Vdetach(object_attr_vgroup);
3197 throw InternalErr(__FILE__,__LINE__,
"Cannot map eos2 object attributes to DAP2.");
3199 Vdetach(object_attr_vgroup);
3206void HDFCFUtil::map_eos2_one_object_attrs(libdap:: DAS &das,int32 file_id, int32 obj_attr_group_id,
const string& vgroup_name) {
3208 int32 num_gobjects = Vntagrefs(obj_attr_group_id);
3209 if(num_gobjects < 0)
3210 throw InternalErr(__FILE__,__LINE__,
"Cannot obtain the number of objects under a vgroup.");
3213 AttrTable *at = das.get_table(vgroup_cf_name);
3215 at = das.add_table(vgroup_cf_name,
new AttrTable);
3217 for(
int i = 0; i<num_gobjects;i++) {
3219 int32 obj_tag, obj_ref;
3220 if (Vgettagref(obj_attr_group_id, i, &obj_tag, &obj_ref) == FAIL)
3221 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain the tag and reference of an object under a vgroup.");
3223 if(Visvs(obj_attr_group_id,obj_ref)) {
3225 int32 vdata_id = VSattach(file_id,obj_ref,
"r");
3226 if(vdata_id == FAIL)
3227 throw InternalErr(__FILE__,__LINE__,
"Failed to attach a vdata.");
3230 if(VSisattr(vdata_id)) {
3233 int32 num_field = VFnfields(vdata_id);
3236 throw InternalErr(__FILE__,__LINE__,
"Number of vdata field for an EOS2 object must be 1.");
3238 int32 num_record = VSelts(vdata_id);
3241 throw InternalErr(__FILE__,__LINE__,
"Number of vdata record for an EOS2 object must be 1.");
3243 char vdata_name[VSNAMELENMAX];
3244 if(VSQueryname(vdata_id,vdata_name) == FAIL) {
3246 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata name.");
3248 string vdatanamestr(vdata_name);
3250 int32 fieldsize = VFfieldesize(vdata_id,0);
3251 if(fieldsize == FAIL) {
3253 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field size.");
3256 const char* fieldname = VFfieldname(vdata_id,0);
3257 if(fieldname ==
nullptr) {
3259 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field name.");
3261 int32 fieldtype = VFfieldtype(vdata_id,0);
3262 if(fieldtype == FAIL) {
3264 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field type.");
3267 if(VSsetfields(vdata_id,fieldname) == FAIL) {
3269 throw InternalErr(__FILE__,__LINE__,
"EOS2 object vdata: VSsetfields failed.");
3272 vector<char> vdata_value;
3273 vdata_value.resize(fieldsize);
3274 if(VSread(vdata_id,(uint8*)vdata_value.data(),1,FULL_INTERLACE) == FAIL) {
3276 throw InternalErr(__FILE__,__LINE__,
"EOS2 object vdata: VSread failed.");
3280 if(fieldtype == DFNT_UCHAR || fieldtype == DFNT_CHAR){
3281 string tempstring(vdata_value.begin(),vdata_value.end());
3283 auto tempstring2 = string(tempstring.c_str());
3307#define ESCAPE_STRING_ATTRIBUTES 0
3311 const string printable =
" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|\\:;<,>.?/'\"\n\t\r";
3312 const string ESC =
"\\";
3313#if ESCAPE_STRING_ATTRIBUTES
3314 const string DOUBLE_ESC = ESC + ESC;
3315 const string QUOTE =
"\"";
3316 const string ESCQUOTE = ESC + QUOTE;
3320 while ((ind = s.find(ESC, ind)) != string::npos) {
3321 s.replace(ind, 1, DOUBLE_ESC);
3322 ind += DOUBLE_ESC.length();
3327 while ((ind = s.find(QUOTE, ind)) != string::npos) {
3329 s.replace(ind, 1, ESCQUOTE);
3330 ind += ESCQUOTE.length();
3335 while ((ind = s.find_first_not_of(printable, ind)) != string::npos) {
3336 s.replace(ind, 1, ESC + octstring(s[ind]));
3343void HDFCFUtil::parser_trmm_v7_gridheader(
const vector<char>& value,
3344 int& latsize,
int&lonsize,
3345 float& lat_start,
float& lon_start,
3346 float& lat_res,
float& lon_res,
3347 bool check_reg_orig ){
3349 float lat_north = 0.;
3350 float lat_south = 0.;
3351 float lon_east = 0.;
3352 float lon_west = 0.;
3354 vector<string> ind_elems;
3361 if(ind_elems.size()<9)
3362 throw InternalErr(__FILE__,__LINE__,
"The number of elements in the TRMM level 3 GridHeader is not right.");
3364 if(
false == check_reg_orig) {
3365 if (0 != ind_elems[1].find(
"Registration=CENTER"))
3366 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid registration is not center.");
3369 if (0 == ind_elems[2].find(
"LatitudeResolution")){
3371 size_t equal_pos = ind_elems[2].find_first_of(
'=');
3372 if(string::npos == equal_pos)
3373 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3375 size_t scolon_pos = ind_elems[2].find_first_of(
';');
3376 if(string::npos == scolon_pos)
3377 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3378 if (equal_pos < scolon_pos){
3380 string latres_str = ind_elems[2].substr(equal_pos+1,scolon_pos-equal_pos-1);
3381 lat_res = strtof(latres_str.c_str(),
nullptr);
3384 throw InternalErr(__FILE__,__LINE__,
"latitude resolution is not right for TRMM level 3 products");
3387 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LatitudeResolution doesn't exist.");
3389 if (0 == ind_elems[3].find(
"LongitudeResolution")){
3391 size_t equal_pos = ind_elems[3].find_first_of(
'=');
3392 if(string::npos == equal_pos)
3393 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
3395 size_t scolon_pos = ind_elems[3].find_first_of(
';');
3396 if(string::npos == scolon_pos)
3397 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
3398 if (equal_pos < scolon_pos){
3399 string lonres_str = ind_elems[3].substr(equal_pos+1,scolon_pos-equal_pos-1);
3400 lon_res = strtof(lonres_str.c_str(),
nullptr);
3403 throw InternalErr(__FILE__,__LINE__,
"longitude resolution is not right for TRMM level 3 products");
3406 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LongitudeResolution doesn't exist.");
3408 if (0 == ind_elems[4].find(
"NorthBoundingCoordinate")){
3410 size_t equal_pos = ind_elems[4].find_first_of(
'=');
3411 if(string::npos == equal_pos)
3412 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3414 size_t scolon_pos = ind_elems[4].find_first_of(
';');
3415 if(string::npos == scolon_pos)
3416 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3417 if (equal_pos < scolon_pos){
3418 string north_bounding_str = ind_elems[4].substr(equal_pos+1,scolon_pos-equal_pos-1);
3419 lat_north = strtof(north_bounding_str.c_str(),
nullptr);
3422 throw InternalErr(__FILE__,__LINE__,
"NorthBoundingCoordinate is not right for TRMM level 3 products");
3426 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid NorthBoundingCoordinate doesn't exist.");
3428 if (0 == ind_elems[5].find(
"SouthBoundingCoordinate")){
3430 size_t equal_pos = ind_elems[5].find_first_of(
'=');
3431 if(string::npos == equal_pos)
3432 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3434 size_t scolon_pos = ind_elems[5].find_first_of(
';');
3435 if(string::npos == scolon_pos)
3436 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3437 if (equal_pos < scolon_pos){
3438 string lat_south_str = ind_elems[5].substr(equal_pos+1,scolon_pos-equal_pos-1);
3439 lat_south = strtof(lat_south_str.c_str(),
nullptr);
3442 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3446 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid SouthBoundingCoordinate doesn't exist.");
3448 if (0 == ind_elems[6].find(
"EastBoundingCoordinate")){
3450 size_t equal_pos = ind_elems[6].find_first_of(
'=');
3451 if(string::npos == equal_pos)
3452 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3454 size_t scolon_pos = ind_elems[6].find_first_of(
';');
3455 if(string::npos == scolon_pos)
3456 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3457 if (equal_pos < scolon_pos){
3458 string lon_east_str = ind_elems[6].substr(equal_pos+1,scolon_pos-equal_pos-1);
3459 lon_east = strtof(lon_east_str.c_str(),
nullptr);
3462 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3466 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid EastBoundingCoordinate doesn't exist.");
3468 if (0 == ind_elems[7].find(
"WestBoundingCoordinate")){
3470 size_t equal_pos = ind_elems[7].find_first_of(
'=');
3471 if(string::npos == equal_pos)
3472 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3474 size_t scolon_pos = ind_elems[7].find_first_of(
';');
3475 if(string::npos == scolon_pos)
3476 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3477 if (equal_pos < scolon_pos){
3478 string lon_west_str = ind_elems[7].substr(equal_pos+1,scolon_pos-equal_pos-1);
3479 lon_west = strtof(lon_west_str.c_str(),
nullptr);
3482 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3486 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid WestBoundingCoordinate doesn't exist.");
3488 if (
false == check_reg_orig) {
3489 if (0 != ind_elems[8].find(
"Origin=SOUTHWEST"))
3490 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid origin is not SOUTHWEST.");
3495 latsize =(
int)((lat_north-lat_south)/lat_res);
3496 lonsize =(
int)((lon_east-lon_west)/lon_res);
3497 lat_start = lat_south;
3498 lon_start = lon_west;
3506void HDFCFUtil::rev_str(
char *str,
int len)
3524int HDFCFUtil::int_to_str(
int x,
char str[],
int d)
3529 str[i++] = (x%10) +
'0';
3544void HDFCFUtil::dtoa(
double n,
char *res,
int afterpoint)
3547 auto ipart = (
int)n;
3550 double fpart = n - (double)ipart;
3553 int i = int_to_str(ipart, res, 0);
3556 if (afterpoint != 0)
3563 fpart = fpart * pow(10, afterpoint);
3567 auto final_fpart = (
int)fpart;
3568 if(fpart -(
int)fpart >0.5)
3569 final_fpart = (
int)fpart +1;
3570 int_to_str(final_fpart, res + i + 1, afterpoint);
3575string HDFCFUtil::get_double_str(
double x,
int total_digit,
int after_point) {
3580 res.resize(total_digit);
3581 for(
int i = 0; i<total_digit;i++)
3585 dtoa(-x,res.data(),after_point);
3586 for(
int i = 0; i<total_digit;i++) {
3588 str.push_back(res[i]);
3592 dtoa(x, res.data(), after_point);
3593 for(
int i = 0; i<total_digit;i++) {
3595 str.push_back(res[i]);
3607string HDFCFUtil::get_int_str(
int x) {
3611 str.push_back((
char)x+
'0');
3613 else if (x >10 && x<100) {
3614 str.push_back((
char)(x/10)+
'0');
3615 str.push_back((
char)(x%10)+
'0');
3619 int abs_x = (x<0)?-x:x;
3625 buf.resize(num_digit);
3626 snprintf(buf.data(),num_digit,
"%d",x);
3627 str.assign(buf.data());
3635ssize_t HDFCFUtil::read_vector_from_file(
int fd, vector<double> &val,
size_t dtypesize) {
3638 ret_val = read(fd,val.data(),val.size()*dtypesize);
3643ssize_t HDFCFUtil::read_buffer_from_file(
int fd,
void*buf,
size_t total_read) {
3646 ret_val = read(fd,buf,total_read);
3652 if(
false == pass_fileid) {
3657#ifdef USE_HDFEOS2_LIB
3670string HDFCFUtil::obtain_cache_fname(
const string & fprefix,
const string &fname,
const string &vname) {
3672 string cache_fname = fprefix;
3673 string base_file_name = basename(fname);
3675 if((base_file_name.size() >12)
3676 && (base_file_name.compare(0,4,
"AIRS") == 0)
3677 && (base_file_name.find(
".L3.")!=string::npos)
3678 && (base_file_name.find(
".v6.")!=string::npos)
3679 && ((vname ==
"Latitude") ||(vname ==
"Longitude")))
3680 cache_fname = cache_fname +
"AIRS"+
".L3."+
".v6."+vname;
3682 cache_fname = cache_fname + base_file_name +
"_"+vname;
3689size_t HDFCFUtil::obtain_dds_cache_size(
const HDFSP::File*spf) {
3691 size_t total_bytes_written = 0;
3692 const vector<HDFSP::SDField *>& spsds = spf->
getSD()->
getFields();
3693 for (
const auto &fd:spsds){
3696 if(DFNT_CHAR == fd->getType()) {
3697 total_bytes_written = 0;
3702 int temp_rank = fd->getRank();
3703 for (
const auto & dim:fd->getDimensions())
3704 total_bytes_written += (dim->getName()).size()+1;
3706 total_bytes_written +=(fd->getName()).size()+1;
3710 if((fd->getName()) != (fd->getNewName()))
3711 total_bytes_written +=(fd->getNewName()).size()+1;
3713 total_bytes_written +=1;
3716 total_bytes_written +=(temp_rank+4)*
sizeof(
int);
3720 if(total_bytes_written != 0)
3721 total_bytes_written +=1;
3723 return total_bytes_written;
3728void HDFCFUtil::write_sp_sds_dds_cache(
const HDFSP::File* spf,FILE*dds_file,
size_t total_bytes_dds_cache,
const string &dds_filename) {
3730 BESDEBUG(
"h4",
" Coming to write SDS DDS to a cache" << endl);
3731 char delimiter =
'\0';
3733 size_t total_written_bytes_count = 0;
3736 vector<char>temp_buf;
3737 temp_buf.resize(total_bytes_dds_cache);
3738 char* temp_pointer = temp_buf.data();
3740 const vector<HDFSP::SDField *>& spsds = spf->
getSD()->
getFields();
3743 for(
const auto &fd:spsds){
3746 int sds_rank = fd->getRank();
3747 int sds_ref = fd->getFieldRef();
3748 int sds_dtype = fd->getType();
3749 int sds_ftype = fd->getFieldType();
3751 vector<int32>dimsizes;
3752 dimsizes.resize(sds_rank);
3755 const vector<HDFSP::Dimension*>& dims= fd->getDimensions();
3756 for(
int i = 0; i < sds_rank; i++)
3757 dimsizes[i] = dims[i]->getSize();
3759 memcpy((
void*)temp_pointer,(
void*)&sds_rank,
sizeof(
int));
3760 temp_pointer +=
sizeof(
int);
3761 memcpy((
void*)temp_pointer,(
void*)&sds_ref,
sizeof(
int));
3762 temp_pointer +=
sizeof(
int);
3763 memcpy((
void*)temp_pointer,(
void*)&sds_dtype,
sizeof(
int));
3764 temp_pointer +=
sizeof(
int);
3765 memcpy((
void*)temp_pointer,(
void*)&sds_ftype,
sizeof(
int));
3766 temp_pointer +=
sizeof(
int);
3768 memcpy((
void*)temp_pointer,(
void*)dimsizes.data(),sds_rank*
sizeof(
int));
3769 temp_pointer +=sds_rank*
sizeof(
int);
3772 total_written_bytes_count +=(sds_rank+4)*
sizeof(
int);
3776 string temp_varname = fd->getName();
3777 vector<char>temp_val1(temp_varname.begin(),temp_varname.end());
3778 memcpy((
void*)temp_pointer,(
void*)temp_val1.data(),temp_varname.size());
3779 temp_pointer +=temp_varname.size();
3780 memcpy((
void*)temp_pointer,&delimiter,1);
3783 total_written_bytes_count =total_written_bytes_count +(1+temp_varname.size());
3789 if(fd->getName() == fd->getNewName()){
3790 memcpy((
void*)temp_pointer,&delimiter,1);
3792 total_written_bytes_count +=1;
3795 string temp_varnewname = fd->getNewName();
3796 vector<char>temp_val2(temp_varnewname.begin(),temp_varnewname.end());
3797 memcpy((
void*)temp_pointer,(
void*)temp_val2.data(),temp_varnewname.size());
3798 temp_pointer +=temp_varnewname.size();
3799 memcpy((
void*)temp_pointer,&delimiter,1);
3801 total_written_bytes_count =total_written_bytes_count +(1+temp_varnewname.size());
3805 for(
int i = 0; i < sds_rank; i++) {
3806 string temp_dimname = dims[i]->getName();
3807 vector<char>temp_val3(temp_dimname.begin(),temp_dimname.end());
3808 memcpy((
void*)temp_pointer,(
void*)temp_val3.data(),temp_dimname.size());
3809 temp_pointer +=temp_dimname.size();
3810 memcpy((
void*)temp_pointer,&delimiter,1);
3812 total_written_bytes_count =total_written_bytes_count +(1+temp_dimname.size());
3816 memcpy((
void*)temp_pointer,&cend,1);
3817 total_written_bytes_count +=1;
3819 if(total_written_bytes_count != total_bytes_dds_cache) {
3820 stringstream s_total_written_count;
3821 s_total_written_count << total_written_bytes_count;
3822 stringstream s_total_bytes_dds_cache;
3823 s_total_bytes_dds_cache << total_bytes_dds_cache;
3824 string msg =
"DDs cached file "+ dds_filename +
" buffer size should be " + s_total_bytes_dds_cache.str() ;
3825 msg = msg +
". But the real size written in the buffer is " + s_total_written_count.str();
3826 throw InternalErr (__FILE__, __LINE__,msg);
3829 size_t bytes_really_written = fwrite((
const void*)temp_buf.data(),1,total_bytes_dds_cache,dds_file);
3831 if(bytes_really_written != total_bytes_dds_cache) {
3832 stringstream s_expected_bytes;
3833 s_expected_bytes << total_bytes_dds_cache;
3834 stringstream s_really_written_bytes;
3835 s_really_written_bytes << bytes_really_written;
3836 string msg =
"DDs cached file "+ dds_filename +
" size should be " + s_expected_bytes.str() ;
3837 msg +=
". But the real size written to the file is " + s_really_written_bytes.str();
3838 throw InternalErr (__FILE__, __LINE__,msg);
3844void HDFCFUtil::read_sp_sds_dds_cache(FILE* dds_file,libdap::DDS * dds_ptr,
3845 const std::string &cache_filename,
const std::string &hdf4_filename) {
3847 BESDEBUG(
"h4",
" Coming to read SDS DDS from a cache" << endl);
3851 if(stat(cache_filename.c_str(),&sb)!=0) {
3852 string err_mesg=
"The DDS cache file " + cache_filename;
3853 err_mesg = err_mesg +
" doesn't exist. ";
3854 throw InternalErr(__FILE__,__LINE__,err_mesg);
3857 auto bytes_expected_read = (size_t)sb.st_size;
3860 vector<char> temp_buf;
3861 temp_buf.resize(bytes_expected_read);
3862 size_t bytes_really_read = fread((
void*)temp_buf.data(),1,bytes_expected_read,dds_file);
3865 if(bytes_really_read != bytes_expected_read) {
3866 stringstream s_bytes_really_read;
3867 s_bytes_really_read << bytes_really_read ;
3868 stringstream s_bytes_expected_read;
3869 s_bytes_expected_read << bytes_expected_read;
3870 string msg =
"The expected bytes to read from DDS cache file " + cache_filename +
" is " + s_bytes_expected_read.str();
3871 msg = msg +
". But the real read size from the buffer is " + s_bytes_really_read.str();
3872 throw InternalErr (__FILE__, __LINE__,msg);
3874 char* temp_pointer = temp_buf.data();
3876 char delimiter =
'\0';
3879 bool end_file_flag =
false;
3883 int sds_rank = *((
int *)(temp_pointer));
3884 temp_pointer = temp_pointer +
sizeof(
int);
3886 int sds_ref = *((
int *)(temp_pointer));
3887 temp_pointer = temp_pointer +
sizeof(
int);
3889 int sds_dtype = *((
int *)(temp_pointer));
3890 temp_pointer = temp_pointer +
sizeof(
int);
3892 int sds_ftype = *((
int *)(temp_pointer));
3893 temp_pointer = temp_pointer +
sizeof(
int);
3895 vector<int32>dimsizes;
3897 throw InternalErr (__FILE__, __LINE__,
"SDS rank must be >0");
3899 dimsizes.resize(sds_rank);
3900 for (
int i = 0; i <sds_rank;i++) {
3901 dimsizes[i] = *((
int *)(temp_pointer));
3902 temp_pointer = temp_pointer +
sizeof(
int);
3905 vector<string>dimnames;
3906 dimnames.resize(sds_rank);
3909 for (
int i = 0; i <sds_rank+2;i++) {
3910 vector<char> temp_vchar;
3911 char temp_char = *temp_pointer;
3914 if(temp_char == delimiter)
3915 temp_vchar.push_back(temp_char);
3916 while(temp_char !=delimiter) {
3917 temp_vchar.push_back(temp_char);
3919 temp_char = *temp_pointer;
3923 string temp_string(temp_vchar.begin(),temp_vchar.end());
3925 varname = temp_string;
3927 varnewname = temp_string;
3929 dimnames[i-2] = temp_string;
3934 if(varnewname[0] == delimiter)
3935 varnewname = varname;
3938 BaseType *bt =
nullptr;
3940#define HANDLE_CASE(tid, type) \
3942 bt = new (type)(varnewname,hdf4_filename); \
3946 HANDLE_CASE(DFNT_CHAR,
HDFStr)
3947#ifndef SIGNED_BYTE_TO_INT32
3948 HANDLE_CASE(DFNT_INT8,
HDFByte)
3952 HANDLE_CASE(DFNT_UINT8,
HDFByte)
3957 HANDLE_CASE(DFNT_UCHAR8,
HDFByte)
3959 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
3964 throw InternalErr(__FILE__,__LINE__,
"Cannot create the basetype when creating DDS from a cache file.");
3966 SPType sptype = OTHERHDF;
3988 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFSPArray_RealField instance.");
3991 for(
int i = 0; i <sds_rank; i++)
3992 ar->append_dim(dimsizes[i],dimnames[i]);
3993 dds_ptr->add_var(ar);
4009 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFSPArray_RealField instance.");
4012 ar->append_dim(dimsizes[0],dimnames[0]);
4013 dds_ptr->add_var(ar);
4018 throw InternalErr(__FILE__,__LINE__,
"SDS rank must be 1 for the missing coordinate.");
4021 if(*temp_pointer == cend)
4022 end_file_flag =
true;
4023 if((temp_pointer - temp_buf.data()) > (
int)bytes_expected_read) {
4024 string msg = cache_filename +
" doesn't have the end-line character at the end. The file may be corrupted.";
4025 throw InternalErr (__FILE__, __LINE__,msg);
4027 }
while(
false == end_file_flag);
4029 dds_ptr->set_dataset_name(basename(hdf4_filename));
4047void 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.
const std::vector< VDATA * > & getVDATAs() const
Public interface to Obtain Vdata.
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.
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< Attribute * > & getAttributes() const
Public interface to obtain the SD(file) attributes.
const std::vector< SDField * > & getFields() const
Redundant member function.
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)