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"
34#define ERR_LOC2(x) ERR_LOC1(x)
35#define ERR_LOC __FILE__ " : " ERR_LOC2(__LINE__)
43split_helper(vector<string> &tokens,
const string &text,
const char sep)
45 string::size_type start = 0;
46 string::size_type end = 0;
48 while ((end = text.find(sep, start)) != string::npos) {
49 tokens.push_back(text.substr(start, end - start));
52 tokens.push_back(text.substr(start));
61 split_helper(names,
string(s, len), sep);
72 DBG(std::cerr <<
"HDFCFUtil::Split: sz: <" << sz <<
">, sep: <" << sep <<
">" << std::endl);
74 split_helper(names,
string(sz), sep);
86 pair<map<string,string>::iterator,
bool> ret;
87 ret = m.insert(make_pair(key, val));
88 if(ret.second ==
false){
90 ret = m.insert(make_pair(key, val));
91 if(ret.second ==
false){
92 BESDEBUG(
"h4",
"insert_map():insertion failed on Key=" << key <<
" Val=" << val << endl);
105 string insertString(1,
'_');
108 if (
true == isdigit(s[0]))
109 s.insert(0,insertString);
116 if((
false == isalnum(si)) && (si!=
'_'))
132 pair<set<string>::iterator,
bool> ret;
134 stringstream sclash_index;
135 sclash_index << clash_index;
136 newstr = str + sclash_index.str();
138 ret = namelist.insert(newstr);
139 if (
false == ret.second) {
154 pair<set<string>::iterator,
bool> setret;
157 vector<string> clashnamelist;
160 map<int,int> cl_to_ol;
165 for (
const auto &newobjname:newobjnamelist) {
166 setret = objnameset.insert(newobjname);
167 if (
false == setret.second ) {
168 clashnamelist.insert(clashnamelist.end(),newobjname);
169 cl_to_ol[cl_index] = ol_index;
177 for (
auto &clashname:clashnamelist) {
179 string temp_clashname = clashname +
'_';
181 clashname = temp_clashname;
185 for (
unsigned int i =0; i <clashnamelist.size(); i++)
186 newobjnamelist[cl_to_ol[i]] = clashnamelist[i];
196 set<string> objnameset;
224 gp.ucp = (
unsigned char *) vals;
234 gp.cp = (
char *) vals;
244 string tmp_str =
static_cast<const char*
>(vals);
250 gp.sp = (
short *) vals;
257 gp.usp = (
unsigned short *) vals;
258 rep << *(gp.usp+loc);
264 gp.lp = (int32 *) vals;
271 gp.ui = (
unsigned int *) vals;
278 float attr_val = *(
float*)vals;
279 bool is_a_fin = isfinite(attr_val);
280 gp.fp = (
float *) vals;
285 rep << setprecision(10);
287 string tmp_rep_str = rep.str();
288 if (tmp_rep_str.find(
'.') == string::npos
289 && tmp_rep_str.find(
'e') == string::npos
290 && tmp_rep_str.find(
'E') == string::npos) {
300 double attr_val = *(
double*)vals;
301 bool is_a_fin = isfinite(attr_val);
302 gp.dp = (
double *) vals;
303 rep << std::showpoint;
304 rep << std::setprecision(17);
306 string tmp_rep_str = rep.str();
307 if (tmp_rep_str.find(
'.') == string::npos
308 && tmp_rep_str.find(
'e') == string::npos
309 && tmp_rep_str.find(
'E') == string::npos) {
316 return string(
"UNKNOWN");
327 static const char UNKNOWN[]=
"Unknown";
328 static const char BYTE[]=
"Byte";
329 static const char INT16[]=
"Int16";
330 static const char UINT16[]=
"UInt16";
331 static const char INT32[]=
"Int32";
332 static const char UINT32[]=
"UInt32";
333 static const char FLOAT32[]=
"Float32";
334 static const char FLOAT64[]=
"Float64";
335 static const char STRING[]=
"String";
352#ifndef SIGNED_BYTE_TO_INT32
393 return sizeof(
unsigned char);
396 return sizeof(
unsigned char);
401#ifndef SIGNED_BYTE_TO_INT32
408 return sizeof(
unsigned short);
411 return sizeof(short);
417 return sizeof(
unsigned int);
420 return sizeof(float);
423 return sizeof(double);
432template <
typename T >
433void HDFCFUtil::LatLon2DSubset (T * outlatlon,
437 const int32 * offset,
442 T (*templatlonptr)[majordim][minordim] = (T *) latlon;
449 int dim0count = count[0];
450 int dim1count = count[1];
451 vector<int> dim0index(dim0count);
452 vector<int> dim1index(dim1count);
454 for (i = 0; i < count[0]; i++)
455 dim0index[i] = offset[0] + i * step[0];
458 for (j = 0; j < count[1]; j++)
459 dim1index[j] = offset[1] + j * step[1];
464 for (i = 0; i < count[0]; i++) {
465 for (j = 0; j < count[1]; j++) {
466 outlatlon[k] = (*templatlonptr)[dim0index[i]][dim1index[j]];
479 AttrTable::Attr_iter it = at->attr_begin();
480 bool find_fvalue =
false;
481 while (it!=at->attr_end() &&
false==find_fvalue) {
482 if (at->get_name(it) ==
"_FillValue")
485 string fillvalue =
"";
486 string fillvalue_type =
"";
487 if((*at->get_attr_vector(it)).size() !=1)
488 throw InternalErr(__FILE__,__LINE__,
"The number of _FillValue must be 1.");
489 fillvalue = (*at->get_attr_vector(it)->begin());
490 fillvalue_type = at->get_type(it);
493 if(fillvalue_type != var_type){
495 at->del_attr(
"_FillValue");
497 if (fillvalue_type ==
"String") {
501 fillvalue = escattr_fvalue(fillvalue);
502 if(fillvalue.size() >1) {
504 long int fillvalue_int = 0;
505 vector<char> fillvalue_temp(fillvalue.size());
507 fillvalue_int = strtol((fillvalue.substr(1)).c_str(),&pEnd,8);
508 stringstream convert_str;
509 convert_str << fillvalue_int;
510 at->append_attr(
"_FillValue",var_type,convert_str.str());
519 short fillvalue_int = fillvalue.at(0);
521 stringstream convert_str;
522 convert_str << fillvalue_int;
523 at->append_attr(
"_FillValue",var_type,convert_str.str());
528 at->append_attr(
"_FillValue",var_type,fillvalue);
542 AttrTable::Attr_iter it = at->attr_begin();
543 bool find_scale =
false;
544 bool find_offset =
false;
547 string scale_factor_type;
548 string add_offset_type;
549 string scale_factor_value;
550 string add_offset_value;
552 while (it!=at->attr_end() &&((find_scale!=
true) ||(find_offset!=
true))) {
553 if (at->get_name(it) ==
"scale_factor")
556 scale_factor_value = (*at->get_attr_vector(it)->begin());
557 scale_factor_type = at->get_type(it);
560 if(at->get_name(it)==
"add_offset")
563 add_offset_value = (*at->get_attr_vector(it)->begin());
564 add_offset_type = at->get_type(it);
571 if((
true==find_scale) && (
true==find_offset)) {
572 if(scale_factor_type != add_offset_type) {
573 at->del_attr(
"add_offset");
574 at->append_attr(
"add_offset",scale_factor_type,add_offset_value);
580#ifdef USE_HDFEOS2_LIB
586bool HDFCFUtil::is_special_value(int32 dtype,
float fillvalue,
float realvalue) {
588 bool ret_value =
false;
590 if (DFNT_UINT16 == dtype) {
592 auto fillvalue_int = (
int)fillvalue;
593 if (MAX_NON_SCALE_SPECIAL_VALUE == fillvalue_int) {
594 auto realvalue_int = (
int)realvalue;
595 if (realvalue_int <= MAX_NON_SCALE_SPECIAL_VALUE && realvalue_int >=MIN_NON_SCALE_SPECIAL_VALUE)
610int HDFCFUtil::check_geofile_dimmap(
const string & geofilename) {
612 int32 fileid = SWopen(
const_cast<char*
>(geofilename.c_str()),DFACC_READ);
615 string swathname =
"MODIS_Swath_Type_GEO";
616 int32 datasetid = SWattach(fileid,
const_cast<char*
>(swathname.c_str()));
626 if ((nummaps = SWnentries(datasetid, HDFE_NENTMAP, &bufsize)) == -1) {
649bool HDFCFUtil::change_data_type(DAS & das, SOType scaletype,
const string &new_field_name)
652 AttrTable *at = das.get_table(new_field_name);
660 if(scaletype!=SOType::DEFAULT_CF_EQU && at!=
nullptr)
662 AttrTable::Attr_iter it = at->attr_begin();
663 string scale_factor_value=
"";
664 string add_offset_value=
"0";
665 string radiance_scales_value=
"";
666 string radiance_offsets_value=
"";
667 string reflectance_scales_value=
"";
668 string reflectance_offsets_value=
"";
669 string scale_factor_type;
670 string add_offset_type;
672 while (it!=at->attr_end())
674 if(at->get_name(it)==
"radiance_scales")
675 radiance_scales_value = *(at->get_attr_vector(it)->begin());
676 if(at->get_name(it)==
"radiance_offsets")
677 radiance_offsets_value = *(at->get_attr_vector(it)->begin());
678 if(at->get_name(it)==
"reflectance_scales")
679 reflectance_scales_value = *(at->get_attr_vector(it)->begin());
680 if(at->get_name(it)==
"reflectance_offsets")
681 reflectance_offsets_value = *(at->get_attr_vector(it)->begin());
686 if(at->get_name(it).find(
"scale_factor")!=string::npos){
687 string temp_attr_name = at->get_name(it);
688 if (temp_attr_name !=
"scale_factor_err") {
689 scale_factor_value = *(at->get_attr_vector(it)->begin());
690 scale_factor_type = at->get_type(it);
693 if(at->get_name(it).find(
"add_offset")!=string::npos)
695 string temp_attr_name = at->get_name(it);
696 if (temp_attr_name !=
"add_offset_err") {
697 add_offset_value = *(at->get_attr_vector(it)->begin());
698 add_offset_type = at->get_type(it);
704 if((radiance_scales_value.size()!=0 && radiance_offsets_value.size()!=0)
705 || (reflectance_scales_value.size()!=0 && reflectance_offsets_value.size()!=0))
708 if(scale_factor_value.size()!=0)
710 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
719void HDFCFUtil::obtain_dimmap_info(
const string& filename,HDFEOS2::Dataset*dataset,
720 vector<struct dimmap_entry> & dimmaps,
721 string & modis_geofilename,
bool& geofile_has_dimmap) {
724 auto sw =
static_cast<HDFEOS2::SwathDataset *
>(dataset);
725 const vector<HDFEOS2::SwathDataset::DimensionMap*>& origdimmaps = sw->getDimensionMaps();
726 struct dimmap_entry tempdimmap;
729 for(
const auto & origdimmap:origdimmaps){
730 tempdimmap.geodim = origdimmap->getGeoDimension();
731 tempdimmap.datadim = origdimmap->getDataDimension();
732 tempdimmap.offset = origdimmap->getOffset();
733 tempdimmap.inc = origdimmap->getIncrement();
734 dimmaps.push_back(tempdimmap);
739 if((origdimmaps.empty() !=
false) && (
true == HDF4RequestHandler::get_enable_check_modis_geo_file()) ) {
743 tempcstr =
new char [filename.size()+1];
744 strncpy (tempcstr,filename.c_str(),filename.size());
745 string basefilename = basename(tempcstr);
746 string dirfilename = dirname(tempcstr);
750 bool is_modis_geofile =
false;
751 if(basefilename.size() >5) {
752 if((0 == basefilename.compare(0,5,
"MOD03")) || (0 == basefilename.compare(0,5,
"MYD03")))
753 is_modis_geofile =
true;
772 if ((
false == is_modis_geofile) && (basefilename.size() >3)) {
774 string fnameprefix = basefilename.substr(0,3);
776 if(fnameprefix ==
"MYD" || fnameprefix ==
"MOD") {
777 size_t fnamemidpos = basefilename.find(
".A");
778 if(fnamemidpos != string::npos) {
779 string fnamemiddle = basefilename.substr(fnamemidpos,14);
780 if(fnamemiddle.size()==14) {
781 string geofnameprefix = fnameprefix+
"03";
783 string geofnamefp = geofnameprefix + fnamemiddle;
788 dirp = opendir(dirfilename.c_str());
790 throw InternalErr(__FILE__,__LINE__,
"opendir fails.");
792 while ((dirs = readdir(dirp))!=
nullptr){
793 if(strncmp(dirs->d_name,geofnamefp.c_str(),geofnamefp.size())==0){
794 modis_geofilename = dirfilename +
"/"+ dirs->d_name;
795 int num_dimmap = HDFCFUtil::check_geofile_dimmap(modis_geofilename);
796 if (num_dimmap < 0) {
798 throw InternalErr(__FILE__,__LINE__,
"this file is not a MODIS geolocation file.");
800 geofile_has_dimmap = (num_dimmap >0)?
true:false;
815bool HDFCFUtil::is_modis_dimmap_nonll_field(
string & fieldname) {
817 bool modis_dimmap_nonll_field =
false;
818 vector<string> modis_dimmap_nonll_fieldlist;
820 modis_dimmap_nonll_fieldlist.emplace_back(
"Height");
821 modis_dimmap_nonll_fieldlist.emplace_back(
"SensorZenith");
822 modis_dimmap_nonll_fieldlist.emplace_back(
"SensorAzimuth");
823 modis_dimmap_nonll_fieldlist.emplace_back(
"Range");
824 modis_dimmap_nonll_fieldlist.emplace_back(
"SolarZenith");
825 modis_dimmap_nonll_fieldlist.emplace_back(
"SolarAzimuth");
826 modis_dimmap_nonll_fieldlist.emplace_back(
"Land/SeaMask");
827 modis_dimmap_nonll_fieldlist.emplace_back(
"gflags");
828 modis_dimmap_nonll_fieldlist.emplace_back(
"Solar_Zenith");
829 modis_dimmap_nonll_fieldlist.emplace_back(
"Solar_Azimuth");
830 modis_dimmap_nonll_fieldlist.emplace_back(
"Sensor_Azimuth");
831 modis_dimmap_nonll_fieldlist.emplace_back(
"Sensor_Zenith");
833 map<string,string>modis_field_to_geofile_field;
834 map<string,string>::iterator itmap;
835 modis_field_to_geofile_field[
"Solar_Zenith"] =
"SolarZenith";
836 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
837 modis_field_to_geofile_field[
"Sensor_Zenith"] =
"SensorZenith";
838 modis_field_to_geofile_field[
"Solar_Azimuth"] =
"SolarAzimuth";
840 for (
const auto & modis_dimmap_nonll_f:modis_dimmap_nonll_fieldlist) {
842 if (fieldname == modis_dimmap_nonll_f) {
843 itmap = modis_field_to_geofile_field.find(fieldname);
844 if (itmap !=modis_field_to_geofile_field.end())
845 fieldname = itmap->second;
846 modis_dimmap_nonll_field =
true;
851 return modis_dimmap_nonll_field;
854void HDFCFUtil::add_scale_offset_attrs(AttrTable*at,
const std::string& s_type,
float svalue_f,
double svalue_d,
bool add_offset_found,
855 const std::string& o_type,
float ovalue_f,
double ovalue_d) {
856 at->del_attr(
"scale_factor");
858 if(s_type!=
"Float64") {
860 at->append_attr(
"scale_factor",
"Float32", print_rep);
864 at->append_attr(
"scale_factor",
"Float64", print_rep);
867 if (
true == add_offset_found) {
868 at->del_attr(
"add_offset");
869 if(o_type!=
"Float64") {
871 at->append_attr(
"add_offset",
"Float32", print_rep);
875 at->append_attr(
"add_offset",
"Float64", print_rep);
880void HDFCFUtil::add_scale_str_offset_attrs(AttrTable*at,
const std::string& s_type,
const std::string& s_value_str,
bool add_offset_found,
881 const std::string& o_type,
float ovalue_f,
double ovalue_d) {
882 at->del_attr(
"scale_factor");
884 if(s_type!=
"Float64")
885 at->append_attr(
"scale_factor",
"Float32", s_value_str);
887 at->append_attr(
"scale_factor",
"Float64", s_value_str);
889 if (
true == add_offset_found) {
890 at->del_attr(
"add_offset");
891 if(o_type!=
"Float64") {
893 at->append_attr(
"add_offset",
"Float32", print_rep);
897 at->append_attr(
"add_offset",
"Float64", print_rep);
902void HDFCFUtil::handle_modis_special_attrs_disable_scale_comp(AttrTable *at,
903 const string &filename,
905 const string & newfname,
909 string scale_factor_type;
910 string add_offset_type;
913 string scale_factor_value=
"";
914 float orig_scale_value_float = 1;
915 double orig_scale_value_double = 1;
916 string add_offset_value=
"0";
917 float orig_offset_value_float = 0;
918 double orig_offset_value_double = 0;
919 bool add_offset_found =
false;
924 AttrTable::Attr_iter it = at->attr_begin();
925 while (it!=at->attr_end())
927 if(at->get_name(it)==
"scale_factor")
929 scale_factor_value = (*at->get_attr_vector(it)->begin());
930 scale_factor_type = at->get_type(it);
931 if(scale_factor_type ==
"Float64")
932 orig_scale_value_double=atof(scale_factor_value.c_str());
934 orig_scale_value_float = (float)(atof(scale_factor_value.c_str()));
937 if(at->get_name(it)==
"add_offset")
939 add_offset_value = (*at->get_attr_vector(it)->begin());
940 add_offset_type = at->get_type(it);
942 if(add_offset_type ==
"Float64")
943 orig_offset_value_double = atof(add_offset_value.c_str());
945 orig_offset_value_float = (float)(atof(add_offset_value.c_str()));
946 add_offset_found =
true;
972 if(scale_factor_value.size()!=0) {
973 if (SOType::MODIS_EQ_SCALE == sotype || SOType::MODIS_MUL_SCALE == sotype) {
974 if (orig_scale_value_float > 1 || orig_scale_value_double >1) {
976 bool need_change_scale =
true;
977 if(
true == is_grid) {
978 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
979 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
980 need_change_scale =
false;
982 else if((filename.size() >7)&&((filename.compare(0,7,
"MOD16A2") == 0)|| (filename.compare(0,7,
"MYD16A2")==0) ||
983 (filename.compare(0,7,
"MOD16A3")==0) || (filename.compare(0,7,
"MYD16A3")==0)))
984 need_change_scale =
false;
986 if(
true == need_change_scale) {
987 sotype = SOType::MODIS_DIV_SCALE;
988 INFO_LOG(
"The field " + newfname +
" scale factor is "+ scale_factor_value
989 +
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE. "
990 +
" Now change it to MODIS_DIV_SCALE. ");
995 if (SOType::MODIS_DIV_SCALE == sotype) {
996 if (orig_scale_value_float < 1 || orig_scale_value_double<1) {
997 sotype = SOType::MODIS_MUL_SCALE;
998 INFO_LOG(
"The field " + newfname +
" scale factor is "+ scale_factor_value
999 +
" But the original scale factor type is MODIS_DIV_SCALE. "
1000 +
" Now change it to MODIS_MUL_SCALE. ");
1005 if ((SOType::MODIS_MUL_SCALE == sotype) &&(
true == add_offset_found)) {
1007 float new_offset_value_float=0;
1008 double new_offset_value_double=0;
1009 if(add_offset_type!=
"Float64")
1010 new_offset_value_float = (orig_offset_value_float ==0)?0:(-1 * orig_offset_value_float *orig_scale_value_float);
1012 new_offset_value_double = (orig_offset_value_double ==0)?0:(-1 * orig_offset_value_double *orig_scale_value_double);
1015 add_scale_str_offset_attrs(at,scale_factor_type,scale_factor_value,add_offset_found,
1016 add_offset_type,new_offset_value_float,new_offset_value_double);
1020 if (SOType::MODIS_DIV_SCALE == sotype) {
1022 float new_scale_value_float=1;
1023 double new_scale_value_double=1;
1024 float new_offset_value_float=0;
1025 double new_offset_value_double=0;
1028 if(scale_factor_type !=
"Float64") {
1029 new_scale_value_float = 1.0f/orig_scale_value_float;
1030 if (
true == add_offset_found) {
1031 if(add_offset_type !=
"Float64")
1032 new_offset_value_float = (orig_offset_value_float==0)?0:(-1 * orig_offset_value_float *new_scale_value_float);
1034 new_offset_value_double = (orig_offset_value_double==0)?0:(-1 * orig_offset_value_double *new_scale_value_float);
1039 new_scale_value_double = 1.0/orig_scale_value_double;
1040 if (
true == add_offset_found) {
1041 if(add_offset_type !=
"Float64")
1042 new_offset_value_float = (orig_offset_value_float==0)?0:(-1.0f * orig_offset_value_float *((float)new_scale_value_double));
1044 new_offset_value_double = (orig_offset_value_double==0)?0:(-1 * orig_offset_value_double *new_scale_value_double);
1048 add_scale_offset_attrs(at,scale_factor_type,new_scale_value_float,new_scale_value_double,add_offset_found,
1049 add_offset_type,new_offset_value_float,new_offset_value_double);
1073void HDFCFUtil::handle_modis_special_attrs(AttrTable *at,
const string & filename,
1074 bool is_grid,
const string & newfname,
1075 SOType sotype,
bool gridname_change_valid_range,
1076 bool changedtype,
bool & change_fvtype){
1079 string scale_factor_type;
1080 string add_offset_type;
1081 string fillvalue_type;
1082 string valid_range_type;
1086 string scale_factor_value=
"";
1087 float orig_scale_value = 1;
1088 string add_offset_value=
"0";
1089 float orig_offset_value = 0;
1090 bool add_offset_found =
false;
1093 string fillvalue=
"";
1096 string valid_range_value=
"";
1098 bool has_valid_range =
false;
1101 float orig_valid_min = 0;
1102 float orig_valid_max = 0;
1105 string number_type_value=
"";
1106 string number_type_dap_type=
"";
1110 AttrTable::Attr_iter it = at->attr_begin();
1111 while (it!=at->attr_end())
1113 if(at->get_name(it)==
"scale_factor")
1115 scale_factor_value = (*at->get_attr_vector(it)->begin());
1116 orig_scale_value = (float)(atof(scale_factor_value.c_str()));
1117 scale_factor_type = at->get_type(it);
1120 if(at->get_name(it)==
"add_offset")
1122 add_offset_value = (*at->get_attr_vector(it)->begin());
1123 orig_offset_value = (float)(atof(add_offset_value.c_str()));
1124 add_offset_type = at->get_type(it);
1125 add_offset_found =
true;
1128 if(at->get_name(it)==
"_FillValue")
1130 fillvalue = (*at->get_attr_vector(it)->begin());
1131 fillvalue_type = at->get_type(it);
1134 if(at->get_name(it)==
"valid_range")
1136 vector<string> *avalue = at->get_attr_vector(it);
1137 auto ait = avalue->begin();
1138 while(ait!=avalue->end())
1140 valid_range_value += *ait;
1142 if(ait!=avalue->end())
1143 valid_range_value +=
", ";
1145 valid_range_type = at->get_type(it);
1146 if (
false == gridname_change_valid_range) {
1147 orig_valid_min = (float)(atof((avalue->at(0)).c_str()));
1148 orig_valid_max = (float)(atof((avalue->at(1)).c_str()));
1150 has_valid_range =
true;
1153 if(
true == changedtype && (at->get_name(it)==
"Number_Type"))
1155 number_type_value = (*at->get_attr_vector(it)->begin());
1156 number_type_dap_type= at->get_type(it);
1164 if(scale_factor_value.size()!=0)
1166 if(!(atof(scale_factor_value.c_str())==1 && atof(add_offset_value.c_str())==0))
1168 at->del_attr(
"scale_factor");
1169 at->append_attr(
"orig_scale_factor", scale_factor_type, scale_factor_value);
1170 if(add_offset_found)
1172 at->del_attr(
"add_offset");
1173 at->append_attr(
"orig_add_offset", add_offset_type, add_offset_value);
1179 if(
true == changedtype && fillvalue.size()!=0 && fillvalue_type!=
"Float32" && fillvalue_type!=
"Float64")
1181 change_fvtype =
true;
1182 at->del_attr(
"_FillValue");
1183 at->append_attr(
"_FillValue",
"Float32", fillvalue);
1186 float valid_max = 0;
1187 float valid_min = 0;
1189 it = at->attr_begin();
1190 bool handle_modis_l1b =
false;
1195 if (sotype == SOType::MODIS_MUL_SCALE &&
true ==changedtype) {
1198 string emissive_str =
"Emissive";
1199 string RefSB_str =
"RefSB";
1200 bool is_emissive_field =
false;
1201 bool is_refsb_field =
false;
1202 if(newfname.find(emissive_str)!=string::npos) {
1203 if(0 == newfname.compare(newfname.size()-emissive_str.size(),emissive_str.size(),emissive_str))
1204 is_emissive_field =
true;
1207 if(newfname.find(RefSB_str)!=string::npos) {
1208 if(0 == newfname.compare(newfname.size()-RefSB_str.size(),RefSB_str.size(),RefSB_str))
1209 is_refsb_field =
true;
1213 if ((
true == is_emissive_field) || (
true== is_refsb_field)){
1215 float scale_max = 0;
1216 float scale_min = 100000;
1218 float offset_max = 0;
1219 float offset_min = 0;
1221 float temp_var_val = 0;
1223 string orig_long_name_value;
1224 string modify_long_name_value;
1225 string str_removed_from_long_name=
" Scaled Integers";
1226 string radiance_units_value;
1228 while (it!=at->attr_end())
1231 if(
true == is_emissive_field) {
1233 if (
"radiance_scales" == (at->get_name(it))) {
1234 vector<string> *avalue = at->get_attr_vector(it);
1235 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1236 temp_var_val = (float)(atof((*ait).c_str()));
1237 if (temp_var_val > scale_max)
1238 scale_max = temp_var_val;
1239 if (temp_var_val < scale_min)
1240 scale_min = temp_var_val;
1244 if (
"radiance_offsets" == (at->get_name(it))) {
1245 vector<string> *avalue = at->get_attr_vector(it);
1246 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1247 temp_var_val = (float)(atof((*ait).c_str()));
1248 if (temp_var_val > offset_max)
1249 offset_max = temp_var_val;
1250 if (temp_var_val < scale_min)
1251 offset_min = temp_var_val;
1255 if (
"long_name" == (at->get_name(it))) {
1256 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1257 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1258 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1259 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1261 modify_long_name_value =
1262 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1263 at->del_attr(
"long_name");
1264 at->append_attr(
"long_name",
"String",modify_long_name_value);
1265 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1270 if (
"radiance_units" == (at->get_name(it)))
1271 radiance_units_value = (*at->get_attr_vector(it)->begin());
1274 if (
true == is_refsb_field) {
1275 if (
"reflectance_scales" == (at->get_name(it))) {
1276 vector<string> *avalue = at->get_attr_vector(it);
1277 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1278 temp_var_val = (float)(atof((*ait).c_str()));
1279 if (temp_var_val > scale_max)
1280 scale_max = temp_var_val;
1281 if (temp_var_val < scale_min)
1282 scale_min = temp_var_val;
1286 if (
"reflectance_offsets" == (at->get_name(it))) {
1288 vector<string> *avalue = at->get_attr_vector(it);
1289 for (vector<string>::const_iterator ait = avalue->begin();ait !=avalue->end();++ait) {
1290 temp_var_val = (float)(atof((*ait).c_str()));
1291 if (temp_var_val > offset_max)
1292 offset_max = temp_var_val;
1293 if (temp_var_val < scale_min)
1294 offset_min = temp_var_val;
1298 if (
"long_name" == (at->get_name(it))) {
1299 orig_long_name_value = (*at->get_attr_vector(it)->begin());
1300 if (orig_long_name_value.find(str_removed_from_long_name)!=string::npos) {
1301 if(0 == orig_long_name_value.compare(orig_long_name_value.size()-str_removed_from_long_name.size(),
1302 str_removed_from_long_name.size(),str_removed_from_long_name)) {
1304 modify_long_name_value =
1305 orig_long_name_value.substr(0,orig_long_name_value.size()-str_removed_from_long_name.size());
1306 at->del_attr(
"long_name");
1307 at->append_attr(
"long_name",
"String",modify_long_name_value);
1308 at->append_attr(
"orig_long_name",
"String",orig_long_name_value);
1318 throw InternalErr(__FILE__,__LINE__,
"the scale factor should always be greater than 0.");
1320 if (orig_valid_max > offset_min)
1321 valid_max = (orig_valid_max-offset_min)*scale_max;
1323 valid_max = (orig_valid_max-offset_min)*scale_min;
1325 if (orig_valid_min > offset_max)
1326 valid_min = (orig_valid_min-offset_max)*scale_min;
1328 valid_min = (orig_valid_min -offset_max)*scale_max;
1335 at->append_attr(
"valid_min",
"Float32",print_rep);
1337 at->append_attr(
"valid_max",
"Float32",print_rep);
1338 at->del_attr(
"valid_range");
1339 handle_modis_l1b =
true;
1342 if (
true == is_emissive_field && radiance_units_value.size() >0) {
1343 at->del_attr(
"units");
1344 at->append_attr(
"units",
"String",radiance_units_value);
1350 if(
true == changedtype &&
true == has_valid_range &&
false == handle_modis_l1b) {
1353 if (
true == gridname_change_valid_range)
1354 HDFCFUtil::handle_modis_vip_special_attrs(valid_range_value,scale_factor_value,valid_min,valid_max);
1355 else if(scale_factor_value.size()!=0) {
1374 if (SOType::MODIS_EQ_SCALE == sotype || SOType::MODIS_MUL_SCALE == sotype) {
1375 if (orig_scale_value > 1) {
1377 bool need_change_scale =
true;
1378 if(
true == is_grid) {
1379 if ((filename.size() >5) && ((filename.compare(0,5,
"MOD09") == 0)|| (filename.compare(0,5,
"MYD09")==0))) {
1380 if ((newfname.size() >5) && newfname.find(
"Range") != string::npos)
1381 need_change_scale =
false;
1384 else if((filename.size() >7)&&((filename.compare(0,7,
"MOD16A2") == 0)|| (filename.compare(0,7,
"MYD16A2")==0) ||
1385 (filename.compare(0,7,
"MOD16A3")==0) || (filename.compare(0,7,
"MYD16A3")==0)))
1386 need_change_scale =
false;
1388 if(
true == need_change_scale) {
1389 sotype = SOType::MODIS_DIV_SCALE;
1390 INFO_LOG(
"The field " + newfname +
" scale factor is "+ std::to_string(orig_scale_value)
1391 +
" But the original scale factor type is MODIS_MUL_SCALE or MODIS_EQ_SCALE."
1392 +
" Now change it to MODIS_DIV_SCALE. ");
1397 if (SOType::MODIS_DIV_SCALE == sotype) {
1398 if (orig_scale_value < 1) {
1399 sotype = SOType::MODIS_MUL_SCALE;
1400 INFO_LOG(
"The field " + newfname +
" scale factor is " + std::to_string(orig_scale_value)
1401 +
" But the original scale factor type is MODIS_DIV_SCALE."
1402 +
" Now change it to MODIS_MUL_SCALE.");
1406 if(sotype == SOType::MODIS_MUL_SCALE) {
1407 valid_min = (orig_valid_min - orig_offset_value)*orig_scale_value;
1408 valid_max = (orig_valid_max - orig_offset_value)*orig_scale_value;
1410 else if (sotype == SOType::MODIS_DIV_SCALE) {
1411 valid_min = (orig_valid_min - orig_offset_value)/orig_scale_value;
1412 valid_max = (orig_valid_max - orig_offset_value)/orig_scale_value;
1414 else if (sotype == SOType::MODIS_EQ_SCALE) {
1415 valid_min = orig_valid_min * orig_scale_value + orig_offset_value;
1416 valid_max = orig_valid_max * orig_scale_value + orig_offset_value;
1420 if (SOType::MODIS_MUL_SCALE == sotype || SOType::MODIS_DIV_SCALE == sotype) {
1421 valid_min = orig_valid_min - orig_offset_value;
1422 valid_max = orig_valid_max - orig_offset_value;
1424 else if (SOType::MODIS_EQ_SCALE == sotype) {
1425 valid_min = orig_valid_min + orig_offset_value;
1426 valid_max = orig_valid_max + orig_offset_value;
1432 at->append_attr(
"valid_min",
"Float32",print_rep);
1434 at->append_attr(
"valid_max",
"Float32",print_rep);
1435 at->del_attr(
"valid_range");
1441 if(
true == changedtype && number_type_dap_type !=
"" ) {
1442 at->del_attr(
"Number_Type");
1443 at->append_attr(
"Number_Type_Orig",number_type_dap_type,number_type_value);
1449void HDFCFUtil::handle_modis_vip_special_attrs(
const std::string& valid_range_value,
1450 const std::string& scale_factor_value,
1451 float& valid_min,
float &valid_max) {
1453 int16 vip_orig_valid_min = 0;
1454 int16 vip_orig_valid_max = 0;
1456 size_t found = valid_range_value.find_first_of(
",");
1457 size_t found_from_end = valid_range_value.find_last_of(
",");
1458 if (string::npos == found)
1459 throw InternalErr(__FILE__,__LINE__,
"should find the separator ,");
1460 if (found != found_from_end)
1461 throw InternalErr(__FILE__,__LINE__,
"There should be only one separator.");
1464 vip_orig_valid_min = (short) (atoi((valid_range_value.substr(0,found)).c_str()));
1465 vip_orig_valid_max = (short) (atoi((valid_range_value.substr(found+1)).c_str()));
1467 int16 scale_factor_number = 1;
1469 scale_factor_number = (short)(atoi(scale_factor_value.c_str()));
1471 if(scale_factor_number !=0) {
1472 valid_min = (float)(vip_orig_valid_min/scale_factor_number);
1473 valid_max = (float)(vip_orig_valid_max/scale_factor_number);
1476 throw InternalErr(__FILE__,__LINE__,
"The scale_factor_number should not be zero.");
1481void HDFCFUtil::handle_amsr_attrs(AttrTable *at) {
1483 AttrTable::Attr_iter it = at->attr_begin();
1485 string scale_factor_value=
"";
1486 string add_offset_value=
"0";
1488 string scale_factor_type;
1489 string add_offset_type;
1491 bool OFFSET_found =
false;
1492 bool Scale_found =
false;
1493 bool SCALE_FACTOR_found =
false;
1495 while (it!=at->attr_end())
1497 if(at->get_name(it)==
"SCALE_FACTOR")
1499 scale_factor_value = (*at->get_attr_vector(it)->begin());
1500 scale_factor_type = at->get_type(it);
1501 SCALE_FACTOR_found =
true;
1504 if(at->get_name(it)==
"Scale")
1506 scale_factor_value = (*at->get_attr_vector(it)->begin());
1507 scale_factor_type = at->get_type(it);
1511 if(at->get_name(it)==
"OFFSET")
1513 add_offset_value = (*at->get_attr_vector(it)->begin());
1514 add_offset_type = at->get_type(it);
1515 OFFSET_found =
true;
1520 if (
true == SCALE_FACTOR_found) {
1521 at->del_attr(
"SCALE_FACTOR");
1522 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1525 if (
true == Scale_found) {
1526 at->del_attr(
"Scale");
1527 at->append_attr(
"scale_factor",scale_factor_type,scale_factor_value);
1530 if (
true == OFFSET_found) {
1531 at->del_attr(
"OFFSET");
1532 at->append_attr(
"add_offset",add_offset_type,add_offset_value);
1540void HDFCFUtil::obtain_grid_latlon_dim_info(
const HDFEOS2::GridDataset* gdset,
1546 const vector<HDFEOS2::Field*>gfields = gdset->getDataFields();
1547 for (
const auto &gf:gfields) {
1550 if(1 == gf->getFieldType()) {
1551 const vector<HDFEOS2::Dimension*>& dims= gf->getCorrectedDimensions();
1554 if(2 == dims.size()) {
1557 if(
true == gf->getYDimMajor()) {
1558 dim0name = dims[0]->getName();
1559 dim0size = dims[0]->getSize();
1560 dim1name = dims[1]->getName();
1561 dim1size = dims[1]->getSize();
1564 dim0name = dims[1]->getName();
1565 dim0size = dims[1]->getSize();
1566 dim1name = dims[0]->getName();
1567 dim1size = dims[0]->getSize();
1573 if( 1 == dims.size()) {
1574 dim0name = dims[0]->getName();
1575 dim0size = dims[0]->getSize();
1580 if(2 == gf->getFieldType()) {
1581 const vector<HDFEOS2::Dimension*>& dims= gf->getCorrectedDimensions();
1582 if(2 == dims.size()) {
1586 if(
true == gf->getYDimMajor()) {
1587 dim0name = dims[0]->getName();
1588 dim0size = dims[0]->getSize();
1589 dim1name = dims[1]->getName();
1590 dim1size = dims[1]->getSize();
1593 dim0name = dims[1]->getName();
1594 dim0size = dims[1]->getSize();
1595 dim1name = dims[0]->getName();
1596 dim1size = dims[0]->getSize();
1600 if( 1 == dims.size()) {
1601 dim1name = dims[0]->getName();
1602 dim1size = dims[0]->getSize();
1607 if(
""==dim0name ||
""==dim1name || dim0size<0 || dim1size <0)
1608 throw InternalErr (__FILE__, __LINE__,
"Fail to obtain grid lat/lon dimension info.");
1614void HDFCFUtil::add_cf_grid_mapping_attr(DAS &das,
const HDFEOS2::GridDataset*gdset,
const string& cf_projection,
1615 const string & dim0name,int32 dim0size,
const string &dim1name,int32 dim1size) {
1618 const vector<HDFEOS2::Field*>gfields = gdset->getDataFields();
1620 for (
const auto &gf:gfields) {
1621 if(0 == gf->getFieldType() && gf->getRank() >1) {
1622 bool has_dim0 =
false;
1623 bool has_dim1 =
false;
1624 const vector<HDFEOS2::Dimension*>& dims= gf->getCorrectedDimensions();
1625 for (
const auto &dim:dims) {
1626 if(dim->getName()== dim0name && dim->getSize() == dim0size)
1628 else if(dim->getName()== dim1name && dim->getSize() == dim1size)
1632 if(
true == has_dim0 &&
true == has_dim1) {
1633 AttrTable *at = das.get_table(gf->getNewName());
1635 at = das.add_table(gf->getNewName(),
new AttrTable);
1638 at->append_attr(
"grid_mapping",
"String",cf_projection);
1645void HDFCFUtil::add_cf_grid_cv_attrs(DAS & das,
const HDFEOS2::GridDataset *gdset) {
1648 if(GCTP_SNSOID == gdset->getProjection().getCode()) {
1653 int32 dim0size = -1;
1654 int32 dim1size = -1;
1656 HDFCFUtil::obtain_grid_latlon_dim_info(gdset,dim0name,dim0size,dim1name,dim1size);
1659 AttrTable *at = das.get_table(dim0name);
1661 at = das.add_table(dim0name,
new AttrTable);
1662 at->append_attr(
"standard_name",
"String",
"projection_y_coordinate");
1664 string long_name=
"y coordinate of projection for grid "+ gdset->getName();
1665 at->append_attr(
"long_name",
"String",long_name);
1667 at->append_attr(
"units",
"string",
"meter");
1669 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoY");
1671 at = das.get_table(dim1name);
1673 at = das.add_table(dim1name,
new AttrTable);
1675 at->append_attr(
"standard_name",
"String",
"projection_x_coordinate");
1676 long_name=
"x coordinate of projection for grid "+ gdset->getName();
1677 at->append_attr(
"long_name",
"String",long_name);
1680 at->append_attr(
"units",
"string",
"meter");
1681 at->append_attr(
"_CoordinateAxisType",
"string",
"GeoX");
1684 string cf_projection_base =
"eos_cf_projection";
1686 at = das.get_table(cf_projection);
1688 at = das.add_table(cf_projection,
new AttrTable);
1690 at->append_attr(
"grid_mapping_name",
"String",
"sinusoidal");
1691 at->append_attr(
"longitude_of_central_meridian",
"Float64",
"0.0");
1692 at->append_attr(
"earth_radius",
"Float64",
"6371007.181");
1694 at->append_attr(
"_CoordinateAxisTypes",
"string",
"GeoX GeoY");
1698 HDFCFUtil::add_cf_grid_mapping_attr(das,gdset,cf_projection,dim0name,dim0size,dim1name,dim1size);
1707void HDFCFUtil::add_cf_grid_cvs(DDS & dds,
const HDFEOS2::GridDataset *gdset) {
1710 if(GCTP_SNSOID == gdset->getProjection().getCode()) {
1715 int32 dim0size = -1;
1716 int32 dim1size = -1;
1717 HDFCFUtil::obtain_grid_latlon_dim_info(gdset,dim0name,dim0size,dim1name,dim1size);
1722 BaseType *bt_dim0 =
nullptr;
1723 BaseType *bt_dim1 =
nullptr;
1725 HDFEOS2GeoCF1D * ar_dim0 =
nullptr;
1726 HDFEOS2GeoCF1D * ar_dim1 =
nullptr;
1728 const float64 *upleft =
nullptr;
1729 const float64 *lowright =
nullptr;
1733 bt_dim0 =
new(HDFFloat64)(dim0name,gdset->getName());
1734 bt_dim1 =
new(HDFFloat64)(dim1name,gdset->getName());
1737 upleft = gdset->getInfo().getUpLeft();
1738 lowright = gdset->getInfo().getLowRight();
1741 ar_dim0 =
new HDFEOS2GeoCF1D(GCTP_SNSOID,
1742 upleft[1],lowright[1],dim0size,dim0name,bt_dim0);
1743 ar_dim0->append_dim(dim0size,dim0name);
1745 ar_dim1 =
new HDFEOS2GeoCF1D(GCTP_SNSOID,
1746 upleft[0],lowright[0],dim1size,dim1name,bt_dim1);
1747 ar_dim1->append_dim(dim1size,dim1name);
1748 dds.add_var(ar_dim0);
1749 dds.add_var(ar_dim1);
1761 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFEOS2GeoCF1D instance.");
1774 string cf_projection_base =
"eos_cf_projection";
1779 HDFEOS2GeoCFProj * dummy_proj_cf =
new HDFEOS2GeoCFProj(cf_projection,gdset->getName());
1780 dds.add_var(dummy_proj_cf);
1782 delete dummy_proj_cf;
1791void HDFCFUtil::check_obpg_global_attrs(
HDFSP::File *f, std::string & scaling,
1792 float & slope,
bool &global_slope_flag,
1793 float & intercept,
bool & global_intercept_flag){
1795 HDFSP::SD* spsd = f->
getSD();
1806 if(attr->getName()==
"Scaling")
1808 string tmpstring(attr->getValue().begin(), attr->getValue().end());
1809 scaling = tmpstring;
1811 if(attr->getName()==
"Slope" || attr->getName()==
"slope")
1813 global_slope_flag =
true;
1815 switch(attr->getType())
1817#define GET_SLOPE(TYPE, CAST) \
1820 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
1821 slope = (float)tmpvalue; \
1824 GET_SLOPE(INT16, int16)
1825 GET_SLOPE(INT32, int32)
1826 GET_SLOPE(FLOAT32,
float)
1827 GET_SLOPE(FLOAT64,
double)
1829 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1836 if(attr->getName()==
"Intercept" || attr->getName()==
"intercept")
1838 global_intercept_flag =
true;
1839 switch(attr->getType())
1841#define GET_INTERCEPT(TYPE, CAST) \
1844 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
1845 intercept = (float)tmpvalue; \
1848 GET_INTERCEPT(INT16, int16)
1849 GET_INTERCEPT(INT32, int32)
1850 GET_INTERCEPT(FLOAT32,
float)
1851 GET_INTERCEPT(FLOAT64,
double)
1853 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1867void HDFCFUtil::add_obpg_special_attrs(
const HDFSP::File*f,DAS &das,
1869 const string& scaling,
float& slope,
1870 const bool& global_slope_flag,
1872 const bool & global_intercept_flag) {
1874 AttrTable *at = das.get_table(onespsds->
getNewName());
1876 at = das.add_table(onespsds->
getNewName(),
new AttrTable);
1880 bool scale_factor_flag =
false;
1881 bool add_offset_flag =
false;
1882 bool slope_flag =
false;
1883 bool intercept_flag =
false;
1887 for(vector<HDFSP::Attribute *>::const_iterator i=onespsds->
getAttributes().begin();
1892 if(global_slope_flag !=
true && (attr->getName()==
"Slope" || attr->getName()==
"slope"))
1896 switch(attr->getType())
1898#define GET_SLOPE(TYPE, CAST) \
1901 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
1902 slope = (float)tmpvalue; \
1906 GET_SLOPE(INT16, int16)
1907 GET_SLOPE(INT32, int32)
1908 GET_SLOPE(FLOAT32,
float)
1909 GET_SLOPE(FLOAT64,
double)
1911 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1919 if(global_intercept_flag !=
true && (attr->getName()==
"Intercept" || attr->getName()==
"intercept"))
1921 intercept_flag =
true;
1922 switch(attr->getType())
1924#define GET_INTERCEPT(TYPE, CAST) \
1927 CAST tmpvalue = *(CAST*)&(attr->getValue()[0]); \
1928 intercept = (float)tmpvalue; \
1931 GET_INTERCEPT(INT16, int16)
1932 GET_INTERCEPT(INT32, int32)
1933 GET_INTERCEPT(FLOAT32,
float)
1934 GET_INTERCEPT(FLOAT64,
double)
1936 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
1950 if((f->
getSPType()==OBPGL3 || f->
getSPType() == OBPGL2) && attr->getName()==
"scale_factor")
1951 scale_factor_flag =
true;
1953 if((f->
getSPType()==OBPGL3 || f->
getSPType() == OBPGL2) && attr->getName()==
"add_offset")
1954 add_offset_flag =
true;
1959 if((f->
getSPType() == OBPGL2 || f->
getSPType()==OBPGL3 )&& onespsds->getFieldType()==0)
1962 if((OBPGL3 == f->
getSPType() && (scaling.find(
"linear")!=string::npos)) || OBPGL2 == f->
getSPType() ) {
1964 if(
false == scale_factor_flag && (
true == slope_flag ||
true == global_slope_flag))
1970 if(
false == add_offset_flag && (
true == intercept_flag ||
true == global_intercept_flag))
1977 bool has_fill_value =
false;
1979 if (
"_FillValue" == attr->getNewName()){
1980 has_fill_value =
true;
1988 if ((
false == has_fill_value) &&(DFNT_INT16 == onespsds->
getType())) {
1989 short fill_value = -32767;
1994 if ((
false == has_fill_value) &&(DFNT_UINT16 == onespsds->
getType())) {
1995 unsigned short fill_value = 65535;
2006void HDFCFUtil::handle_otherhdf_special_attrs(
const HDFSP::File*f,DAS &das) {
2018 bool latflag =
false;
2019 bool latunitsflag =
false;
2020 bool lonflag =
false;
2021 bool lonunitsflag =
false;
2022 int llcheckoverflag = 0;
2034 for (
const auto &fd:spsds){
2042 if (OTHERHDF == f->
getSPType() &&
true == fd->IsDimNoScale())
2045 AttrTable *at = das.get_table(fd->getNewName());
2047 at = das.add_table(fd->getNewName(),
new AttrTable);
2049 for (
const auto& attr:fd->getAttributes()) {
2050 if(attr->getType()==DFNT_UCHAR || attr->getType() == DFNT_CHAR){
2052 if(attr->getName() ==
"long_name") {
2053 string tempstring2(attr->getValue().begin(),attr->getValue().end());
2054 string tempfinalstr= string(tempstring2.c_str());
2055 if(tempfinalstr==
"latitude" || tempfinalstr ==
"Latitude")
2057 if(tempfinalstr==
"longitude" || tempfinalstr ==
"Longitude")
2064 for (
const auto& attr:fd->getAttributes()) {
2065 if (attr->getName() ==
"units")
2066 latunitsflag =
true;
2071 for(
const auto& attr:fd->getAttributes()) {
2072 if(attr->getName() ==
"units")
2073 lonunitsflag =
true;
2076 if(latflag && !latunitsflag){
2077 at->append_attr(
"units",
"String",
"degrees_north");
2079 latunitsflag =
false;
2083 if(lonflag && !lonunitsflag){
2084 at->append_attr(
"units",
"String",
"degrees_east");
2086 lonunitsflag =
false;
2089 if(llcheckoverflag ==2)
break;
2099HDFCFUtil::add_missing_cf_attrs(
const HDFSP::File*f,DAS &das) {
2106 for(
const auto &fd:spsds){
2107 if(fd->getFieldType() == 0 && fd->getType()==DFNT_FLOAT32) {
2109 AttrTable *at = das.get_table(fd->getNewName());
2111 at = das.add_table(fd->getNewName(),
new AttrTable);
2112 string print_rep =
"-9999.9";
2118 for(
const auto &fd:spsds){
2119 if(fd->getFieldType() == 0 && ((fd->getType()==DFNT_INT32) || (fd->getType()==DFNT_INT16))) {
2121 AttrTable *at = das.get_table(fd->getNewName());
2123 at = das.add_table(fd->getNewName(),
new AttrTable);
2124 string print_rep =
"-9999";
2125 if(fd->getType()==DFNT_INT32)
2135 for(
const auto &fd:spsds){
2136 if(fd->getFieldType() == 6 && fd->getNewName()==
"nlayer") {
2138 AttrTable *at = das.get_table(fd->getNewName());
2140 at = das.add_table(fd->getNewName(),
new AttrTable);
2141 at->append_attr(
"units",
"String",
"km");
2144 else if(fd->getFieldType() == 4) {
2146 if (fd->getNewName()==
"nh3" ||
2147 fd->getNewName()==
"ncat3" ||
2148 fd->getNewName()==
"nthrshZO" ||
2149 fd->getNewName()==
"nthrshHB" ||
2150 fd->getNewName()==
"nthrshSRT")
2154 "http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2157 AttrTable *at = das.get_table(fd->getNewName());
2159 at = das.add_table(fd->getNewName(),
new AttrTable);
2161 if(fd->getNewName()==
"nh3") {
2162 comment=
"Index number to represent the fixed heights above the earth ellipsoid,";
2163 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
2166 else if(fd->getNewName()==
"ncat3") {
2167 comment=
"Index number to represent catgories for probability distribution functions.";
2168 comment=comment +
"Check more information from the references.";
2171 else if(fd->getNewName()==
"nthrshZO")
2172 comment=
"Q-thresholds for Zero order used for probability distribution functions.";
2174 else if(fd->getNewName()==
"nthrshHB")
2175 comment=
"Q-thresholds for HB used for probability distribution functions.";
2177 else if(fd->getNewName()==
"nthrshSRT")
2178 comment=
"Q-thresholds for SRT used for probability distribution functions.";
2180 at->append_attr(
"comment",
"String",comment);
2181 at->append_attr(
"references",
"String",references);
2192 string base_filename;
2193 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
2194 if(last_slash_pos != string::npos)
2195 base_filename = f->
getPath().substr(last_slash_pos+1);
2196 if(
""==base_filename)
2198 bool t3a26_flag = ((base_filename.find(
"3A26")!=string::npos)?
true:
false);
2200 if(
true == t3a26_flag) {
2202 for(
const auto &fd:spsds){
2204 if(fd->getFieldType() == 0 && (fd->getType()==DFNT_FLOAT32)) {
2205 AttrTable *at = das.get_table(fd->getNewName());
2207 at = das.add_table(fd->getNewName(),
new AttrTable);
2208 at->del_attr(
"_FillValue");
2209 at->append_attr(
"_FillValue",
"Float32",
"-999");
2210 at->append_attr(
"valid_min",
"Float32",
"0");
2220 for(
const auto &fd:spsds){
2222 if(fd->getFieldType() == 4 ) {
2224 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2225 if (fd->getNewName()==
"nh1") {
2227 AttrTable *at = das.get_table(fd->getNewName());
2229 at = das.add_table(fd->getNewName(),
new AttrTable);
2231 string comment=
"Number of fixed heights above the earth ellipsoid,";
2232 comment= comment +
" at 2, 4, 6, 10, and 15 km plus one for path-average.";
2234 at->append_attr(
"comment",
"String",comment);
2235 at->append_attr(
"references",
"String",references);
2238 if (fd->getNewName()==
"nh3") {
2240 AttrTable *at = das.get_table(fd->getNewName());
2242 at = das.add_table(fd->getNewName(),
new AttrTable);
2244 string comment=
"Number of fixed heights above the earth ellipsoid,";
2245 comment= comment +
" at 2, 4, 6 km plus one for path-average.";
2247 at->append_attr(
"comment",
"String",comment);
2248 at->append_attr(
"references",
"String",references);
2252 if (fd->getNewName()==
"nang") {
2254 AttrTable *at = das.get_table(fd->getNewName());
2256 at = das.add_table(fd->getNewName(),
new AttrTable);
2258 string comment=
"Number of fixed incidence angles, at 0, 5, 10 and 15 degree and all angles.";
2259 references =
"http://pps.gsfc.nasa.gov/Documents/ICSVol4.pdf";
2261 at->append_attr(
"comment",
"String",comment);
2262 at->append_attr(
"references",
"String",references);
2266 if (fd->getNewName()==
"ncat2") {
2268 AttrTable *at = das.get_table(fd->getNewName());
2270 at = das.add_table(fd->getNewName(),
new AttrTable);
2272 string comment=
"Second number of categories for histograms (30). ";
2273 comment=comment +
"Check more information from the references.";
2275 at->append_attr(
"comment",
"String",comment);
2276 at->append_attr(
"references",
"String",references);
2287 string base_filename;
2288 size_t last_slash_pos = f->
getPath().find_last_of(
"/");
2289 if(last_slash_pos != string::npos)
2290 base_filename = f->
getPath().substr(last_slash_pos+1);
2291 if(
""==base_filename)
2293 bool t2b31_flag = ((base_filename.find(
"2B31")!=string::npos)?
true:
false);
2294 bool t2a21_flag = ((base_filename.find(
"2A21")!=string::npos)?
true:
false);
2295 bool t2a12_flag = ((base_filename.find(
"2A12")!=string::npos)?
true:
false);
2298 bool t2a25_flag = ((base_filename.find(
"2A25")!=string::npos)?
true:
false);
2299 bool t1c21_flag = ((base_filename.find(
"1C21")!=string::npos)?
true:
false);
2300 bool t1b21_flag = ((base_filename.find(
"1B21")!=string::npos)?
true:
false);
2301 bool t1b11_flag = ((base_filename.find(
"1B11")!=string::npos)?
true:
false);
2302 bool t1b01_flag = ((base_filename.find(
"1B01")!=string::npos)?
true:
false);
2307 if(t2b31_flag || t2a12_flag || t2a21_flag) {
2312 for (
const auto &fd:spsds){
2314 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2316 AttrTable *at = das.get_table(fd->getNewName());
2318 at = das.add_table(fd->getNewName(),
new AttrTable);
2320 AttrTable::Attr_iter it = at->attr_begin();
2321 while (it!=at->attr_end()) {
2322 if(at->get_name(it)==
"scale_factor")
2325 string scale_factor_value=
"";
2326 string scale_factor_type;
2328 scale_factor_value = (*at->get_attr_vector(it)->begin());
2329 scale_factor_type = at->get_type(it);
2331 if(scale_factor_type ==
"Float64") {
2332 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
nullptr);
2333 at->del_attr(
"scale_factor");
2335 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2339 if(scale_factor_type ==
"Float32") {
2340 float new_scale = 1.0f/strtof(scale_factor_value.c_str(),
nullptr);
2341 at->del_attr(
"scale_factor");
2343 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2356 if (t2a12_flag==
true) {
2358 for (
const auto &fd:spsds){
2360 if (fd->getFieldType() == 6 && fd->getNewName()==
"nlayer") {
2362 AttrTable *at = das.get_table(fd->getNewName());
2364 at = das.add_table(fd->getNewName(),
new AttrTable);
2365 at->append_attr(
"units",
"String",
"km");
2370 if (fd->getFieldType() == 0 && fd->getType()==DFNT_INT8) {
2372 AttrTable *at = das.get_table(fd->getNewName());
2374 at = das.add_table(fd->getNewName(),
new AttrTable);
2375 at->append_attr(
"_FillValue",
"Int32",
"-99");
2383 for (
const auto & fd:spsds){
2384 if (fd->getFieldType() == 0 && fd->getType()==DFNT_FLOAT32) {
2386 AttrTable *at = das.get_table(fd->getNewName());
2388 at = das.add_table(fd->getNewName(),
new AttrTable);
2389 string print_rep =
"-9999.9";
2395 for (
const auto &fd:spsds){
2397 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2399 AttrTable *at = das.get_table(fd->getNewName());
2401 at = das.add_table(fd->getNewName(),
new AttrTable);
2403 string print_rep =
"-9999";
2411 else if(t2a21_flag ==
true || t2a25_flag ==
true) {
2414 if (t2a25_flag ==
true) {
2416 unsigned char handle_scale = 0;
2418 for (
const auto &fd:spsds){
2420 if (fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2421 bool has_dBZ =
false;
2422 bool has_rainrate =
false;
2423 bool has_scale =
false;
2424 string scale_factor_value;
2425 string scale_factor_type;
2427 AttrTable *at = das.get_table(fd->getNewName());
2429 at = das.add_table(fd->getNewName(),
new AttrTable);
2430 AttrTable::Attr_iter it = at->attr_begin();
2431 while (it!=at->attr_end()) {
2432 if(at->get_name(it)==
"units"){
2433 string units_value = *at->get_attr_vector(it)->begin();
2434 if(
"dBZ" == units_value) {
2438 else if(
"mm/hr" == units_value){
2439 has_rainrate =
true;
2442 if(at->get_name(it)==
"scale_factor")
2444 scale_factor_value = *at->get_attr_vector(it)->begin();
2445 scale_factor_type = at->get_type(it);
2452 if((
true == has_rainrate ||
true == has_dBZ) &&
true == has_scale) {
2455 short valid_min = 0;
2456 short valid_max = 0;
2459 if(
true == has_rainrate)
2460 valid_max = (short)(300*strtof(scale_factor_value.c_str(),
nullptr));
2461 else if(
true == has_dBZ)
2462 valid_max = (short)(80*strtof(scale_factor_value.c_str(),
nullptr));
2465 at->append_attr(
"valid_min",
"Int16",print_rep1);
2467 at->append_attr(
"valid_max",
"Int16",print_rep1);
2469 at->del_attr(
"scale_factor");
2470 if(scale_factor_type ==
"Float64") {
2471 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
nullptr);
2473 at->append_attr(
"scale_factor", scale_factor_type,print_rep2);
2477 if(scale_factor_type ==
"Float32") {
2478 float new_scale = 1.0/strtof(scale_factor_value.c_str(),
nullptr);
2480 at->append_attr(
"scale_factor", scale_factor_type,print_rep3);
2485 if(2 == handle_scale)
2494 else if (t1b21_flag || t1c21_flag || t1b11_flag) {
2497 if (t1b21_flag || t1c21_flag) {
2499 for (
const auto &fd:spsds){
2501 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2503 bool has_dBm =
false;
2504 bool has_dBZ =
false;
2506 AttrTable *at = das.get_table(fd->getNewName());
2508 at = das.add_table(fd->getNewName(),
new AttrTable);
2509 AttrTable::Attr_iter it = at->attr_begin();
2511 while (it!=at->attr_end()) {
2512 if(at->get_name(it)==
"units"){
2514 string units_value = *at->get_attr_vector(it)->begin();
2515 if(
"dBm" == units_value) {
2520 else if(
"dBZ" == units_value){
2528 if(has_dBm ==
true || has_dBZ ==
true) {
2529 it = at->attr_begin();
2530 while (it!=at->attr_end()) {
2531 if(at->get_name(it)==
"scale_factor")
2534 string scale_value = *at->get_attr_vector(it)->begin();
2536 if(
true == has_dBm) {
2537 auto valid_min = (short)(-120 *strtof(scale_value.c_str(),
nullptr));
2538 auto valid_max = (short)(-20 *strtof(scale_value.c_str(),
nullptr));
2540 at->append_attr(
"valid_min",
"Int16",print_rep);
2542 at->append_attr(
"valid_max",
"Int16",print_rep);
2547 else if(
true == has_dBZ){
2548 auto valid_min = (short)(-20 *strtof(scale_value.c_str(),
nullptr));
2549 auto valid_max = (short)(80 *strtof(scale_value.c_str(),
nullptr));
2551 at->append_attr(
"valid_min",
"Int16",print_rep);
2553 at->append_attr(
"valid_max",
"Int16",print_rep);
2569 for(
const auto &fd:spsds){
2571 if(fd->getFieldType() == 0 && fd->getType()==DFNT_INT16) {
2573 AttrTable *at = das.get_table(fd->getNewName());
2575 at = das.add_table(fd->getNewName(),
new AttrTable);
2576 AttrTable::Attr_iter it = at->attr_begin();
2578 while (it!=at->attr_end()) {
2580 if(at->get_name(it)==
"scale_factor")
2583 string scale_factor_value=
"";
2584 string scale_factor_type;
2586 scale_factor_value = (*at->get_attr_vector(it)->begin());
2587 scale_factor_type = at->get_type(it);
2589 if(scale_factor_type ==
"Float64") {
2590 double new_scale = 1.0/strtod(scale_factor_value.c_str(),
nullptr);
2591 at->del_attr(
"scale_factor");
2593 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2597 if(scale_factor_type ==
"Float32") {
2598 float new_scale = 1.0f/strtof(scale_factor_value.c_str(),
nullptr);
2599 at->del_attr(
"scale_factor");
2601 at->append_attr(
"scale_factor", scale_factor_type,print_rep);
2611 at->append_attr(
"_FillValue",
"Int16",
"-9999");
2618 else if (t1b01_flag ==
true) {
2620 for (
const auto &fd:spsds){
2622 if(fd->getFieldType() == 0 && fd->getType()==DFNT_FLOAT32) {
2624 AttrTable *at = das.get_table(fd->getNewName());
2626 at = das.add_table(fd->getNewName(),
new AttrTable);
2628 at->append_attr(
"_FillValue",
"Float32",
"-9999.9");
2633 AttrTable *at = das.get_table(
"HDF_GLOBAL");
2635 at = das.add_table(
"HDF_GLOBAL",
new AttrTable);
2636 string references =
"http://pps.gsfc.nasa.gov/Documents/filespec.TRMM.V7.pdf";
2637 string comment=
"The HDF4 OPeNDAP handler adds _FillValue, valid_min and valid_max for some TRMM level 1 and level 2 products.";
2638 comment= comment +
" It also changes scale_factor to follow CF conventions. ";
2640 at->append_attr(
"comment",
"String",comment);
2641 at->append_attr(
"references",
"String",references);
2657void HDFCFUtil::handle_merra_ceres_attrs_with_bes_keys(
const HDFSP::File *f, DAS &das,
const string& filename) {
2659 string base_filename = filename.substr(filename.find_last_of(
"/")+1);
2662 string check_ceres_merra_short_name_key=
"H4.EnableCERESMERRAShortName";
2663 bool turn_on_ceres_merra_short_name_key=
false;
2665 turn_on_ceres_merra_short_name_key = HDFCFUtil::check_beskeys(check_ceres_merra_short_name_key);
2668 bool merra_is_eos2 =
false;
2669 if (0== (base_filename.compare(0,5,
"MERRA"))) {
2673 if((fd->getName().compare(0, 14,
"StructMetadata" )== 0) ||
2674 (fd->getName().compare(0, 14,
"structmetadata" )== 0)) {
2675 merra_is_eos2 =
true;
2682 if (
true == HDF4RequestHandler::get_enable_ceres_merra_short_name() && (CER_ES4 == f->
getSPType() || CER_SRB == f->
getSPType()
2685 || CER_AVG == f->
getSPType() || (
true == merra_is_eos2))) {
2688 for (
const auto & fd:spsds){
2690 AttrTable *at = das.get_table(fd->getNewName());
2692 at = das.add_table(fd->getNewName(),
new AttrTable);
2694 at->append_attr(
"fullpath",
"String",fd->getSpecFullPath());
2702void HDFCFUtil::handle_vdata_attrs_with_desc_key(
const HDFSP::File*f,libdap::DAS &das) {
2709 string check_vdata_desc_key=
"H4.EnableVdataDescAttr";
2710 bool turn_on_vdata_desc_key=
false;
2712 turn_on_vdata_desc_key = HDFCFUtil::check_beskeys(check_vdata_desc_key);
2715 string VDdescname =
"hdf4_vd_desc";
2716 string VDdescvalue =
"This is an HDF4 Vdata.";
2717 string VDfieldprefix =
"Vdata_field_";
2718 string VDattrprefix =
"Vdata_attr_";
2719 string VDfieldattrprefix =
"Vdata_field_attr_";
2723 string check_ceres_vdata_key=
"H4.EnableCERESVdata";
2724 bool turn_on_ceres_vdata_key=
false;
2725 turn_on_ceres_vdata_key = HDFCFUtil::check_beskeys(check_ceres_vdata_key);
2728 bool output_vdata_flag =
true;
2729 if (
false == HDF4RequestHandler::get_enable_ceres_vdata() &&
2734 output_vdata_flag =
false;
2736 if (
true == output_vdata_flag) {
2740 AttrTable *at = das.get_table(vd->getNewName());
2742 at = das.add_table(vd->getNewName(),
new AttrTable);
2744 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2746 bool emptyvddasflag =
true;
2747 if (!(vd->getAttributes().empty()))
2748 emptyvddasflag =
false;
2749 if (vd->getTreatAsAttrFlag())
2750 emptyvddasflag =
false;
2752 for (
const auto &vfd:vd->getFields()) {
2753 if(!(vfd->getAttributes().empty())) {
2754 emptyvddasflag =
false;
2762 at->append_attr(VDdescname,
"String" , VDdescvalue);
2764 for(
const auto &va:vd->getAttributes()) {
2766 if(va->getType()==DFNT_UCHAR || va->getType() == DFNT_CHAR){
2768 string tempstring2(va->getValue().begin(),va->getValue().end());
2769 string tempfinalstr= string(tempstring2.c_str());
2770 at->append_attr(VDattrprefix+va->getNewName(),
"String" , tempfinalstr);
2773 for (
int loc=0; loc < va->getCount() ; loc++) {
2781 if(
false == (vd->getTreatAsAttrFlag())){
2783 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2787 for (
const auto &vdf:vd->getFields()) {
2792 if (vdf->getAttributes().empty() ==
false) {
2794 AttrTable *at_v = das.get_table(vdf->getNewName());
2796 at_v = das.add_table(vdf->getNewName(),
new AttrTable);
2798 for (
const auto &va:vdf->getAttributes()) {
2800 if(va->getType()==DFNT_UCHAR || va->getType() == DFNT_CHAR){
2802 string tempstring2(va->getValue().begin(),va->getValue().end());
2803 string tempfinalstr= string(tempstring2.c_str());
2804 at_v->append_attr(va->getNewName(),
"String" , tempfinalstr);
2807 for (
int loc=0; loc < va->getCount() ; loc++) {
2822 for(
const auto & vdf:vd->getFields()) {
2824 if(vdf->getFieldOrder() == 1) {
2825 if(vdf->getType()==DFNT_UCHAR || vdf->getType() == DFNT_CHAR){
2826 string tempfinalstr;
2827 tempfinalstr.resize(vdf->getValue().size());
2828 copy(vdf->getValue().begin(),vdf->getValue().end(),tempfinalstr.begin());
2829 at->append_attr(VDfieldprefix+vdf->getNewName(),
"String" , tempfinalstr);
2832 for (
int loc=0; loc < vdf->getNumRec(); loc++) {
2840 if (vdf->getValue().size() != (
unsigned int)(DFKNTsize(vdf->getType())*(vdf->getFieldOrder())*(vdf->getNumRec()))){
2841 throw InternalErr(__FILE__,__LINE__,
"the vdata field size doesn't match the vector value");
2844 if(vdf->getNumRec()==1){
2845 if(vdf->getType()==DFNT_UCHAR || vdf->getType() == DFNT_CHAR){
2846 string tempstring2(vdf->getValue().begin(),vdf->getValue().end());
2847 auto tempfinalstr= string(tempstring2.c_str());
2848 at->append_attr(VDfieldprefix+vdf->getNewName(),
"String",tempfinalstr);
2851 for (
int loc=0; loc < vdf->getFieldOrder(); loc++) {
2860 if(vdf->getType()==DFNT_UCHAR || vdf->getType() == DFNT_CHAR){
2862 for(
int tempcount = 0; tempcount < vdf->getNumRec()*DFKNTsize(vdf->getType());tempcount ++) {
2863 vector<char>::const_iterator tempit;
2864 tempit = vdf->getValue().begin()+tempcount*(vdf->getFieldOrder());
2865 string tempstring2(tempit,tempit+vdf->getFieldOrder());
2866 auto tempfinalstr= string(tempstring2.c_str());
2867 string tempoutstring =
"'"+tempfinalstr+
"'";
2868 at->append_attr(VDfieldprefix+vdf->getNewName(),
"String",tempoutstring);
2873 for(
int tempcount = 0; tempcount < vdf->getNumRec();tempcount ++) {
2875 for (
int loc=0; loc < vdf->getFieldOrder(); loc++) {
2876 string print_rep =
HDFCFUtil::print_attr(vdf->getType(), loc, (
void*) &(vdf->getValue()[tempcount*(vdf->getFieldOrder())]));
2886 if (
true == HDF4RequestHandler::get_enable_vdata_desc_attr()) {
2887 for(
const auto &va:vdf->getAttributes()) {
2889 if(va->getType()==DFNT_UCHAR || va->getType() == DFNT_CHAR){
2891 string tempstring2(va->getValue().begin(),va->getValue().end());
2892 auto tempfinalstr= string(tempstring2.c_str());
2893 at->append_attr(VDfieldattrprefix+va->getNewName(),
"String" , tempfinalstr);
2896 for (
int loc=0; loc < va->getCount() ; loc++) {
2898 at->append_attr(VDfieldattrprefix+va->getNewName(),
HDFCFUtil::print_type(va->getType()), print_rep);
2911void HDFCFUtil::map_eos2_objects_attrs(libdap::DAS &das,
const string &filename) {
2914 int32 status_32 = -1;
2916 int32 vgroup_id = -1;
2917 int32 num_of_lones = 0;
2918 uint16 name_len = 0;
2920 file_id = Hopen (filename.c_str(), DFACC_READ, 0);
2922 throw InternalErr(__FILE__,__LINE__,
"Hopen failed.");
2924 status_n = Vstart (file_id);
2925 if(status_n == FAIL) {
2927 throw InternalErr(__FILE__,__LINE__,
"Vstart failed.");
2931 bool unexpected_fail =
false;
2935 num_of_lones = Vlone (file_id,
nullptr, num_of_lones );
2939 if (num_of_lones > 0)
2943 vector<int32> ref_array;
2944 ref_array.resize(num_of_lones);
2950 num_of_lones = Vlone (file_id, ref_array.data(), num_of_lones);
2953 for (
int lone_vg_number = 0; lone_vg_number < num_of_lones;
2960 vgroup_id = Vattach(file_id, ref_array[lone_vg_number],
"r");
2961 if(vgroup_id == FAIL) {
2962 unexpected_fail =
true;
2963 err_msg = string(ERR_LOC) +
" Vattach failed. ";
2967 status_32 = Vgetnamelen(vgroup_id, &name_len);
2968 if(status_32 == FAIL) {
2969 unexpected_fail =
true;
2971 err_msg = string(ERR_LOC) +
" Vgetnamelen failed. ";
2975 vector<char> vgroup_name;
2976 vgroup_name.resize(name_len+1);
2977 status_32 = Vgetname (vgroup_id, vgroup_name.data());
2978 if(status_32 == FAIL) {
2979 unexpected_fail =
true;
2981 err_msg = string(ERR_LOC) +
" Vgetname failed. ";
2985 status_32 = Vgetclassnamelen(vgroup_id, &name_len);
2986 if(status_32 == FAIL) {
2987 unexpected_fail =
true;
2989 err_msg = string(ERR_LOC) +
" Vgetclassnamelen failed. ";
2993 vector<char>vgroup_class;
2994 vgroup_class.resize(name_len+1);
2995 status_32 = Vgetclass (vgroup_id, vgroup_class.data());
2996 if(status_32 == FAIL) {
2997 unexpected_fail =
true;
2999 err_msg = string(ERR_LOC) +
" Vgetclass failed. ";
3003 string vgroup_name_str(vgroup_name.begin(),vgroup_name.end());
3004 vgroup_name_str = vgroup_name_str.substr(0,vgroup_name_str.size()-1);
3006 string vgroup_class_str(vgroup_class.begin(),vgroup_class.end());
3007 vgroup_class_str = vgroup_class_str.substr(0,vgroup_class_str.size()-1);
3009 if(vgroup_class_str ==
"GRID")
3010 map_eos2_one_object_attrs_wrapper(das,file_id,vgroup_id,vgroup_name_str,
true);
3011 else if(vgroup_class_str ==
"SWATH")
3012 map_eos2_one_object_attrs_wrapper(das,file_id,vgroup_id,vgroup_name_str,
false);
3018 throw InternalErr(__FILE__,__LINE__,
"map_eos2_one_object_attrs_wrapper failed.");
3020 Vdetach (vgroup_id);
3028 if(
true == unexpected_fail)
3029 throw InternalErr(__FILE__,__LINE__,err_msg);
3035void HDFCFUtil::map_eos2_one_object_attrs_wrapper(libdap:: DAS &das,int32 file_id,int32 vgroup_id,
const string& vgroup_name,
bool is_grid) {
3037 int32 num_gobjects = Vntagrefs (vgroup_id);
3038 if(num_gobjects < 0)
3039 throw InternalErr(__FILE__,__LINE__,
"Cannot obtain the number of objects under a vgroup.");
3041 for(
int i = 0; i<num_gobjects;i++) {
3045 if (Vgettagref (vgroup_id, i, &obj_tag, &obj_ref) == FAIL)
3046 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain the tag and reference of an object under a vgroup.");
3048 if (Visvg (vgroup_id, obj_ref) == TRUE) {
3050 int32 object_attr_vgroup = Vattach(file_id,obj_ref,
"r");
3051 if(object_attr_vgroup == FAIL)
3052 throw InternalErr(__FILE__,__LINE__,
"Failed to attach an EOS2 vgroup.");
3054 uint16 name_len = 0;
3055 int32 status_32 = Vgetnamelen(object_attr_vgroup, &name_len);
3056 if(status_32 == FAIL) {
3057 Vdetach(object_attr_vgroup);
3058 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain an EOS2 vgroup name length.");
3060 vector<char> attr_vgroup_name;
3061 attr_vgroup_name.resize(name_len+1);
3062 status_32 = Vgetname (object_attr_vgroup, attr_vgroup_name.data());
3063 if(status_32 == FAIL) {
3064 Vdetach(object_attr_vgroup);
3065 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain an EOS2 vgroup name. ");
3068 string attr_vgroup_name_str(attr_vgroup_name.begin(),attr_vgroup_name.end());
3069 attr_vgroup_name_str = attr_vgroup_name_str.substr(0,attr_vgroup_name_str.size()-1);
3072 if(
true == is_grid && attr_vgroup_name_str==
"Grid Attributes"){
3073 map_eos2_one_object_attrs(das,file_id,object_attr_vgroup,vgroup_name);
3074 Vdetach(object_attr_vgroup);
3077 else if(
false == is_grid && attr_vgroup_name_str==
"Swath Attributes") {
3078 map_eos2_one_object_attrs(das,file_id,object_attr_vgroup,vgroup_name);
3079 Vdetach(object_attr_vgroup);
3084 Vdetach(object_attr_vgroup);
3085 throw InternalErr(__FILE__,__LINE__,
"Cannot map eos2 object attributes to DAP2.");
3087 Vdetach(object_attr_vgroup);
3094void HDFCFUtil::map_eos2_one_object_attrs(libdap:: DAS &das,int32 file_id, int32 obj_attr_group_id,
const string& vgroup_name) {
3096 int32 num_gobjects = Vntagrefs(obj_attr_group_id);
3097 if(num_gobjects < 0)
3098 throw InternalErr(__FILE__,__LINE__,
"Cannot obtain the number of objects under a vgroup.");
3101 AttrTable *at = das.get_table(vgroup_cf_name);
3103 at = das.add_table(vgroup_cf_name,
new AttrTable);
3105 for(
int i = 0; i<num_gobjects;i++) {
3110 if (Vgettagref(obj_attr_group_id, i, &obj_tag, &obj_ref) == FAIL)
3111 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain the tag and reference of an object under a vgroup.");
3113 if(Visvs(obj_attr_group_id,obj_ref)) {
3115 int32 vdata_id = VSattach(file_id,obj_ref,
"r");
3116 if(vdata_id == FAIL)
3117 throw InternalErr(__FILE__,__LINE__,
"Failed to attach a vdata.");
3120 if(VSisattr(vdata_id)) {
3123 int32 num_field = VFnfields(vdata_id);
3126 throw InternalErr(__FILE__,__LINE__,
"Number of vdata field for an EOS2 object must be 1.");
3128 int32 num_record = VSelts(vdata_id);
3131 throw InternalErr(__FILE__,__LINE__,
"Number of vdata record for an EOS2 object must be 1.");
3133 char vdata_name[VSNAMELENMAX];
3134 if(VSQueryname(vdata_id,vdata_name) == FAIL) {
3136 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata name.");
3138 string vdatanamestr(vdata_name);
3140 int32 fieldsize = VFfieldesize(vdata_id,0);
3141 if(fieldsize == FAIL) {
3143 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field size.");
3146 const char* fieldname = VFfieldname(vdata_id,0);
3147 if(fieldname ==
nullptr) {
3149 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field name.");
3151 int32 fieldtype = VFfieldtype(vdata_id,0);
3152 if(fieldtype == FAIL) {
3154 throw InternalErr(__FILE__,__LINE__,
"Failed to obtain EOS2 object vdata field type.");
3157 if(VSsetfields(vdata_id,fieldname) == FAIL) {
3159 throw InternalErr(__FILE__,__LINE__,
"EOS2 object vdata: VSsetfields failed.");
3162 vector<char> vdata_value;
3163 vdata_value.resize(fieldsize);
3164 if(VSread(vdata_id,(uint8*)vdata_value.data(),1,FULL_INTERLACE) == FAIL) {
3166 throw InternalErr(__FILE__,__LINE__,
"EOS2 object vdata: VSread failed.");
3170 if(fieldtype == DFNT_UCHAR || fieldtype == DFNT_CHAR){
3171 string tempstring(vdata_value.begin(),vdata_value.end());
3173 auto tempstring2 = string(tempstring.c_str());
3174 at->append_attr(vdataname_cfstr,
"String",tempstring2);
3200#define ESCAPE_STRING_ATTRIBUTES 0
3202string HDFCFUtil::escattr(
string s)
3206#if ESCAPE_STRING_ATTRIBUTES
3207 const string printable =
" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|\\:;<,>.?/'\"\n\t\r";
3208 const string ESC =
"\\";
3209 const string DOUBLE_ESC = ESC + ESC;
3210 const string QUOTE =
"\"";
3211 const string ESCQUOTE = ESC + QUOTE;
3215 while ((ind = s.find(ESC, ind)) != string::npos) {
3216 s.replace(ind, 1, DOUBLE_ESC);
3217 ind += DOUBLE_ESC.size();
3222 while ((ind = s.find(QUOTE, ind)) != string::npos) {
3224 s.replace(ind, 1, ESCQUOTE);
3225 ind += ESCQUOTE.size();
3229 while ((ind = s.find_first_not_of(printable, ind)) != string::npos) {
3230 s.replace(ind, 1, ESC + octstring(s[ind]));
3239string HDFCFUtil::escattr_fvalue(
string s)
3241 const string printable =
" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|\\:;<,>.?/'\"\n\t\r";
3242 const string ESC =
"\\";
3244 while ((ind = s.find_first_not_of(printable, ind)) != string::npos) {
3245 s.replace(ind, 1, ESC + octstring(s[ind]));
3252void HDFCFUtil::parser_trmm_v7_gridheader(
const vector<char>& value,
3253 int& latsize,
int&lonsize,
3254 float& lat_start,
float& lon_start,
3255 float& lat_res,
float& lon_res,
3256 bool check_reg_orig ){
3258 float lat_north = 0.;
3259 float lat_south = 0.;
3260 float lon_east = 0.;
3261 float lon_west = 0.;
3263 vector<string> ind_elems;
3270 if(ind_elems.size()<9)
3271 throw InternalErr(__FILE__,__LINE__,
"The number of elements in the TRMM level 3 GridHeader is not right.");
3273 if(
false == check_reg_orig) {
3274 if (0 != ind_elems[1].find(
"Registration=CENTER"))
3275 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid registration is not center.");
3278 if (0 == ind_elems[2].find(
"LatitudeResolution")){
3280 size_t equal_pos = ind_elems[2].find_first_of(
'=');
3281 if(string::npos == equal_pos)
3282 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3284 size_t scolon_pos = ind_elems[2].find_first_of(
';');
3285 if(string::npos == scolon_pos)
3286 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3287 if (equal_pos < scolon_pos){
3289 string latres_str = ind_elems[2].substr(equal_pos+1,scolon_pos-equal_pos-1);
3290 lat_res = strtof(latres_str.c_str(),
nullptr);
3293 throw InternalErr(__FILE__,__LINE__,
"latitude resolution is not right for TRMM level 3 products");
3296 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LatitudeResolution doesn't exist.");
3298 if (0 == ind_elems[3].find(
"LongitudeResolution")){
3300 size_t equal_pos = ind_elems[3].find_first_of(
'=');
3301 if(string::npos == equal_pos)
3302 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
3304 size_t scolon_pos = ind_elems[3].find_first_of(
';');
3305 if(string::npos == scolon_pos)
3306 throw InternalErr(__FILE__,__LINE__,
"Cannot find longitude resolution for TRMM level 3 products");
3307 if (equal_pos < scolon_pos){
3308 string lonres_str = ind_elems[3].substr(equal_pos+1,scolon_pos-equal_pos-1);
3309 lon_res = strtof(lonres_str.c_str(),
nullptr);
3312 throw InternalErr(__FILE__,__LINE__,
"longitude resolution is not right for TRMM level 3 products");
3315 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid LongitudeResolution doesn't exist.");
3317 if (0 == ind_elems[4].find(
"NorthBoundingCoordinate")){
3319 size_t equal_pos = ind_elems[4].find_first_of(
'=');
3320 if(string::npos == equal_pos)
3321 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3323 size_t scolon_pos = ind_elems[4].find_first_of(
';');
3324 if(string::npos == scolon_pos)
3325 throw InternalErr(__FILE__,__LINE__,
"Cannot find latitude resolution for TRMM level 3 products");
3326 if (equal_pos < scolon_pos){
3327 string north_bounding_str = ind_elems[4].substr(equal_pos+1,scolon_pos-equal_pos-1);
3328 lat_north = strtof(north_bounding_str.c_str(),
nullptr);
3331 throw InternalErr(__FILE__,__LINE__,
"NorthBoundingCoordinate is not right for TRMM level 3 products");
3335 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid NorthBoundingCoordinate doesn't exist.");
3337 if (0 == ind_elems[5].find(
"SouthBoundingCoordinate")){
3339 size_t equal_pos = ind_elems[5].find_first_of(
'=');
3340 if(string::npos == equal_pos)
3341 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3343 size_t scolon_pos = ind_elems[5].find_first_of(
';');
3344 if(string::npos == scolon_pos)
3345 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3346 if (equal_pos < scolon_pos){
3347 string lat_south_str = ind_elems[5].substr(equal_pos+1,scolon_pos-equal_pos-1);
3348 lat_south = strtof(lat_south_str.c_str(),
nullptr);
3351 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3355 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid SouthBoundingCoordinate doesn't exist.");
3357 if (0 == ind_elems[6].find(
"EastBoundingCoordinate")){
3359 size_t equal_pos = ind_elems[6].find_first_of(
'=');
3360 if(string::npos == equal_pos)
3361 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3363 size_t scolon_pos = ind_elems[6].find_first_of(
';');
3364 if(string::npos == scolon_pos)
3365 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3366 if (equal_pos < scolon_pos){
3367 string lon_east_str = ind_elems[6].substr(equal_pos+1,scolon_pos-equal_pos-1);
3368 lon_east = strtof(lon_east_str.c_str(),
nullptr);
3371 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3375 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid EastBoundingCoordinate doesn't exist.");
3377 if (0 == ind_elems[7].find(
"WestBoundingCoordinate")){
3379 size_t equal_pos = ind_elems[7].find_first_of(
'=');
3380 if(string::npos == equal_pos)
3381 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3383 size_t scolon_pos = ind_elems[7].find_first_of(
';');
3384 if(string::npos == scolon_pos)
3385 throw InternalErr(__FILE__,__LINE__,
"Cannot find south bound coordinate for TRMM level 3 products");
3386 if (equal_pos < scolon_pos){
3387 string lon_west_str = ind_elems[7].substr(equal_pos+1,scolon_pos-equal_pos-1);
3388 lon_west = strtof(lon_west_str.c_str(),
nullptr);
3391 throw InternalErr(__FILE__,__LINE__,
"south bound coordinate is not right for TRMM level 3 products");
3395 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid WestBoundingCoordinate doesn't exist.");
3397 if (
false == check_reg_orig) {
3398 if (0 != ind_elems[8].find(
"Origin=SOUTHWEST"))
3399 throw InternalErr(__FILE__,__LINE__,
"The TRMM grid origin is not SOUTHWEST.");
3404 latsize =(int)((lat_north-lat_south)/lat_res);
3405 lonsize =(int)((lon_east-lon_west)/lon_res);
3406 lat_start = lat_south;
3407 lon_start = lon_west;
3415void HDFCFUtil::rev_str(
char *str,
int len)
3433int HDFCFUtil::int_to_str(
int x,
char str[],
int d)
3438 str[i++] = (x%10) +
'0';
3453void HDFCFUtil::dtoa(
double n,
char *res,
int afterpoint)
3456 auto ipart = (int)n;
3459 double fpart = n - (double)ipart;
3462 int i = int_to_str(ipart, res, 0);
3465 if (afterpoint != 0)
3472 fpart = fpart * pow(10, afterpoint);
3476 auto final_fpart = (int)fpart;
3477 if(fpart -(
int)fpart >0.5)
3478 final_fpart = (int)fpart +1;
3479 int_to_str(final_fpart, res + i + 1, afterpoint);
3484string HDFCFUtil::get_double_str(
double x,
int total_digit,
int after_point) {
3489 res.resize(total_digit);
3490 for(
int i = 0; i<total_digit;i++)
3494 dtoa(-x,res.data(),after_point);
3495 for(
int i = 0; i<total_digit;i++) {
3497 str.push_back(res[i]);
3501 dtoa(x, res.data(), after_point);
3502 for(
int i = 0; i<total_digit;i++) {
3504 str.push_back(res[i]);
3516string HDFCFUtil::get_int_str(
int x) {
3520 str.push_back((
char)x+
'0');
3522 else if (x >10 && x<100) {
3523 str.push_back((
char)(x/10)+
'0');
3524 str.push_back((
char)(x%10)+
'0');
3528 int abs_x = (x<0)?-x:x;
3534 buf.resize(num_digit);
3535 snprintf(buf.data(),num_digit,
"%d",x);
3536 str.assign(buf.data());
3544ssize_t HDFCFUtil::read_vector_from_file(
int fd, vector<double> &val,
size_t dtypesize) {
3547 ret_val = read(fd,val.data(),val.size()*dtypesize);
3552ssize_t HDFCFUtil::read_buffer_from_file(
int fd,
void*buf,
size_t total_read) {
3555 ret_val = read(fd,buf,total_read);
3561 if(
false == pass_fileid) {
3566#ifdef USE_HDFEOS2_LIB
3579string HDFCFUtil::obtain_cache_fname(
const string & fprefix,
const string &fname,
const string &vname) {
3581 string cache_fname = fprefix;
3582 string base_file_name = basename(fname);
3584 if((base_file_name.size() >12)
3585 && (base_file_name.compare(0,4,
"AIRS") == 0)
3586 && (base_file_name.find(
".L3.")!=string::npos)
3587 && (base_file_name.find(
".v6.")!=string::npos)
3588 && ((vname ==
"Latitude") ||(vname ==
"Longitude")))
3589 cache_fname = cache_fname +
"AIRS"+
".L3."+
".v6."+vname;
3591 cache_fname = cache_fname + base_file_name +
"_"+vname;
3598size_t HDFCFUtil::obtain_dds_cache_size(
const HDFSP::File*spf) {
3600 size_t total_bytes_written = 0;
3601 const vector<HDFSP::SDField *>& spsds = spf->
getSD()->
getFields();
3602 for (
const auto &fd:spsds){
3605 if(DFNT_CHAR == fd->getType()) {
3606 total_bytes_written = 0;
3611 int temp_rank = fd->getRank();
3612 for (
const auto & dim:fd->getDimensions())
3613 total_bytes_written += (dim->getName()).size()+1;
3615 total_bytes_written +=(fd->getName()).size()+1;
3619 if((fd->getName()) != (fd->getNewName()))
3620 total_bytes_written +=(fd->getNewName()).size()+1;
3622 total_bytes_written +=1;
3625 total_bytes_written +=(temp_rank+4)*
sizeof(
int);
3629 if(total_bytes_written != 0)
3630 total_bytes_written +=1;
3632 return total_bytes_written;
3637void HDFCFUtil::write_sp_sds_dds_cache(
const HDFSP::File* spf,FILE*dds_file,
size_t total_bytes_dds_cache,
const string &dds_filename) {
3639 BESDEBUG(
"h4",
" Coming to write SDS DDS to a cache" << endl);
3640 char delimiter =
'\0';
3642 size_t total_written_bytes_count = 0;
3645 vector<char>temp_buf;
3646 temp_buf.resize(total_bytes_dds_cache);
3647 char* temp_pointer = temp_buf.data();
3649 const vector<HDFSP::SDField *>& spsds = spf->
getSD()->
getFields();
3652 for(
const auto &fd:spsds){
3655 int sds_rank = fd->getRank();
3656 int sds_ref = fd->getFieldRef();
3657 int sds_dtype = fd->getType();
3658 int sds_ftype = fd->getFieldType();
3660 vector<int32>dimsizes;
3661 dimsizes.resize(sds_rank);
3664 const vector<HDFSP::Dimension*>& dims= fd->getDimensions();
3665 for(
int i = 0; i < sds_rank; i++)
3666 dimsizes[i] = dims[i]->getSize();
3668 memcpy((
void*)temp_pointer,(
void*)&sds_rank,
sizeof(
int));
3669 temp_pointer +=
sizeof(int);
3670 memcpy((
void*)temp_pointer,(
void*)&sds_ref,
sizeof(
int));
3671 temp_pointer +=
sizeof(int);
3672 memcpy((
void*)temp_pointer,(
void*)&sds_dtype,
sizeof(
int));
3673 temp_pointer +=
sizeof(int);
3674 memcpy((
void*)temp_pointer,(
void*)&sds_ftype,
sizeof(
int));
3675 temp_pointer +=
sizeof(int);
3677 memcpy((
void*)temp_pointer,(
void*)dimsizes.data(),sds_rank*
sizeof(
int));
3678 temp_pointer +=sds_rank*
sizeof(int);
3681 total_written_bytes_count +=(sds_rank+4)*
sizeof(
int);
3685 string temp_varname = fd->getName();
3686 vector<char>temp_val1(temp_varname.begin(),temp_varname.end());
3687 memcpy((
void*)temp_pointer,(
void*)temp_val1.data(),temp_varname.size());
3688 temp_pointer +=temp_varname.size();
3689 memcpy((
void*)temp_pointer,&delimiter,1);
3692 total_written_bytes_count =total_written_bytes_count +(1+temp_varname.size());
3698 if(fd->getName() == fd->getNewName()){
3699 memcpy((
void*)temp_pointer,&delimiter,1);
3701 total_written_bytes_count +=1;
3704 string temp_varnewname = fd->getNewName();
3705 vector<char>temp_val2(temp_varnewname.begin(),temp_varnewname.end());
3706 memcpy((
void*)temp_pointer,(
void*)temp_val2.data(),temp_varnewname.size());
3707 temp_pointer +=temp_varnewname.size();
3708 memcpy((
void*)temp_pointer,&delimiter,1);
3710 total_written_bytes_count =total_written_bytes_count +(1+temp_varnewname.size());
3714 for(
int i = 0; i < sds_rank; i++) {
3715 string temp_dimname = dims[i]->getName();
3716 vector<char>temp_val3(temp_dimname.begin(),temp_dimname.end());
3717 memcpy((
void*)temp_pointer,(
void*)temp_val3.data(),temp_dimname.size());
3718 temp_pointer +=temp_dimname.size();
3719 memcpy((
void*)temp_pointer,&delimiter,1);
3721 total_written_bytes_count =total_written_bytes_count +(1+temp_dimname.size());
3725 memcpy((
void*)temp_pointer,&cend,1);
3726 total_written_bytes_count +=1;
3728 if(total_written_bytes_count != total_bytes_dds_cache) {
3729 stringstream s_total_written_count;
3730 s_total_written_count << total_written_bytes_count;
3731 stringstream s_total_bytes_dds_cache;
3732 s_total_bytes_dds_cache << total_bytes_dds_cache;
3733 string msg =
"DDs cached file "+ dds_filename +
" buffer size should be " + s_total_bytes_dds_cache.str() ;
3734 msg = msg +
". But the real size written in the buffer is " + s_total_written_count.str();
3735 throw InternalErr (__FILE__, __LINE__,msg);
3738 size_t bytes_really_written = fwrite((
const void*)temp_buf.data(),1,total_bytes_dds_cache,dds_file);
3740 if(bytes_really_written != total_bytes_dds_cache) {
3741 stringstream s_expected_bytes;
3742 s_expected_bytes << total_bytes_dds_cache;
3743 stringstream s_really_written_bytes;
3744 s_really_written_bytes << bytes_really_written;
3745 string msg =
"DDs cached file "+ dds_filename +
" size should be " + s_expected_bytes.str() ;
3746 msg +=
". But the real size written to the file is " + s_really_written_bytes.str();
3747 throw InternalErr (__FILE__, __LINE__,msg);
3753void HDFCFUtil::read_sp_sds_dds_cache(FILE* dds_file,libdap::DDS * dds_ptr,
3754 const std::string &cache_filename,
const std::string &hdf4_filename) {
3756 BESDEBUG(
"h4",
" Coming to read SDS DDS from a cache" << endl);
3760 if(stat(cache_filename.c_str(),&sb)!=0) {
3761 string err_mesg=
"The DDS cache file " + cache_filename;
3762 err_mesg = err_mesg +
" doesn't exist. ";
3763 throw InternalErr(__FILE__,__LINE__,err_mesg);
3766 auto bytes_expected_read = (size_t)sb.st_size;
3769 vector<char> temp_buf;
3770 temp_buf.resize(bytes_expected_read);
3771 size_t bytes_really_read = fread((
void*)temp_buf.data(),1,bytes_expected_read,dds_file);
3774 if(bytes_really_read != bytes_expected_read) {
3775 stringstream s_bytes_really_read;
3776 s_bytes_really_read << bytes_really_read ;
3777 stringstream s_bytes_expected_read;
3778 s_bytes_expected_read << bytes_expected_read;
3779 string msg =
"The expected bytes to read from DDS cache file " + cache_filename +
" is " + s_bytes_expected_read.str();
3780 msg = msg +
". But the real read size from the buffer is " + s_bytes_really_read.str();
3781 throw InternalErr (__FILE__, __LINE__,msg);
3783 char* temp_pointer = temp_buf.data();
3785 char delimiter =
'\0';
3788 bool end_file_flag =
false;
3792 int sds_rank = *((
int *)(temp_pointer));
3793 temp_pointer = temp_pointer +
sizeof(int);
3795 int sds_ref = *((
int *)(temp_pointer));
3796 temp_pointer = temp_pointer +
sizeof(int);
3798 int sds_dtype = *((
int *)(temp_pointer));
3799 temp_pointer = temp_pointer +
sizeof(int);
3801 int sds_ftype = *((
int *)(temp_pointer));
3802 temp_pointer = temp_pointer +
sizeof(int);
3804 vector<int32>dimsizes;
3806 throw InternalErr (__FILE__, __LINE__,
"SDS rank must be >0");
3808 dimsizes.resize(sds_rank);
3809 for (
int i = 0; i <sds_rank;i++) {
3810 dimsizes[i] = *((
int *)(temp_pointer));
3811 temp_pointer = temp_pointer +
sizeof(int);
3814 vector<string>dimnames;
3815 dimnames.resize(sds_rank);
3818 for (
int i = 0; i <sds_rank+2;i++) {
3819 vector<char> temp_vchar;
3820 char temp_char = *temp_pointer;
3823 if(temp_char == delimiter)
3824 temp_vchar.push_back(temp_char);
3825 while(temp_char !=delimiter) {
3826 temp_vchar.push_back(temp_char);
3828 temp_char = *temp_pointer;
3832 string temp_string(temp_vchar.begin(),temp_vchar.end());
3834 varname = temp_string;
3836 varnewname = temp_string;
3838 dimnames[i-2] = temp_string;
3843 if(varnewname[0] == delimiter)
3844 varnewname = varname;
3847 BaseType *bt =
nullptr;
3849#define HANDLE_CASE(tid, type) \
3851 bt = new (type)(varnewname,hdf4_filename); \
3853 HANDLE_CASE(DFNT_FLOAT32, HDFFloat32)
3854 HANDLE_CASE(DFNT_FLOAT64, HDFFloat64)
3855 HANDLE_CASE(DFNT_CHAR, HDFStr)
3856#ifndef SIGNED_BYTE_TO_INT32
3857 HANDLE_CASE(DFNT_INT8, HDFByte)
3859 HANDLE_CASE(DFNT_INT8,HDFInt32)
3861 HANDLE_CASE(DFNT_UINT8, HDFByte)
3862 HANDLE_CASE(DFNT_INT16, HDFInt16)
3863 HANDLE_CASE(DFNT_UINT16, HDFUInt16)
3864 HANDLE_CASE(DFNT_INT32, HDFInt32)
3865 HANDLE_CASE(DFNT_UINT32, HDFUInt32)
3866 HANDLE_CASE(DFNT_UCHAR8, HDFByte)
3868 throw InternalErr(__FILE__,__LINE__,
"unsupported data type.");
3873 throw InternalErr(__FILE__,__LINE__,
"Cannot create the basetype when creating DDS from a cache file.");
3875 SPType sptype = OTHERHDF;
3880 HDFSPArray_RealField *ar =
nullptr;
3883 ar =
new HDFSPArray_RealField(
3897 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFSPArray_RealField instance.");
3900 for(
int i = 0; i <sds_rank; i++)
3901 ar->append_dim(dimsizes[i],dimnames[i]);
3902 dds_ptr->add_var(ar);
3907 HDFSPArrayMissGeoField *ar =
nullptr;
3910 ar =
new HDFSPArrayMissGeoField(
3918 throw InternalErr(__FILE__,__LINE__,
"Unable to allocate the HDFSPArray_RealField instance.");
3921 ar->append_dim(dimsizes[0],dimnames[0]);
3922 dds_ptr->add_var(ar);
3927 throw InternalErr(__FILE__,__LINE__,
"SDS rank must be 1 for the missing coordinate.");
3930 if(*temp_pointer == cend)
3931 end_file_flag =
true;
3932 if((temp_pointer - temp_buf.data()) > (
int)bytes_expected_read) {
3933 string msg = cache_filename +
" doesn't have the end-line character at the end. The file may be corrupted.";
3934 throw InternalErr (__FILE__, __LINE__,msg);
3936 }
while(
false == end_file_flag);
3938 dds_ptr->set_dataset_name(basename(hdf4_filename));
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.
const std::vector< Attribute * > & getAttributes() const
Public interface to obtain the SD(file) attributes.
const std::vector< SDField * > & getFields() const
Public interface to obtain information of all SDS vectors(objects).
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 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)