25 #include "InternalErr.h"
31 HE2CF::get_vgroup_field_refids(
const string& _gname,
36 int32 vrefid = Vfind(file_id, (
char*)_gname.c_str());
40 error <<
"cannot obtain the reference number for vgroup "<<_gname;
41 throw_error(error.str());
45 int32 vgroup_id = Vattach(file_id, vrefid,
"r");
46 if (FAIL == vgroup_id) {
49 error <<
"cannot obtain the group id for vgroup "<<_gname;
50 throw_error(error.str());
54 int32 npairs = Vntagrefs(vgroup_id);
62 error <<
"Got " << npairs
63 <<
" npairs for " << _gname;
64 throw_error(error.str());
68 for (
int i = 0; i < npairs; ++i) {
72 if (Vgettagref(vgroup_id, i, &tag, &ref) < 0){
79 error <<
"failed to get tag / ref";
80 throw_error(error.str());
84 if(Visvg(vgroup_id, ref)){
85 char cvgroup_name[VGNAMELENMAX*4];
89 vgroup_cid = Vattach(file_id, ref,
"r");
91 if (FAIL == vgroup_cid) {
96 error <<
"cannot obtain the vgroup id";
97 throw_error(error.str());
102 istat = Vgetname(vgroup_cid,cvgroup_name);
109 error <<
"cannot obtain the vgroup id";
110 throw_error(error.str());
114 if(strncmp(cvgroup_name,
"Data Fields", 11) == 0){
118 if(strncmp(cvgroup_name,
"Geolocation Fields", 18) == 0){
122 if (FAIL == Vdetach(vgroup_cid)) {
126 error <<
"cannot close the vgroup "<< cvgroup_name <<
"Successfully";
127 throw_error(error.str());
136 if (FAIL == Vdetach(vgroup_id)) {
139 error <<
"cannot close the vgroup "<< _gname <<
"Successfully";
140 throw_error(error.str());
147 HE2CF::open_sd(
const string& _filename,
const int sd_id_in)
149 int32 num_datasets = -1;
152 if(SDfileinfo(sd_id, &num_datasets, &num_global_attributes)
159 error <<
"Failed to call SDfileinfo() on "
162 throw_error(error.str());
169 HE2CF::open_vgroup(
const string& _filename,
const int file_id_in)
172 file_id = file_id_in;
173 if (Vstart(file_id) < 0){
175 error <<
"Failed to call Vstart on " << _filename << endl;
176 throw_error(error.str());
205 gp.cp = (
char *) vals;
220 gp.sp = (
short *) vals;
227 gp.usp = (
unsigned short *) vals;
228 rep << *(gp.usp+loc);
234 gp.lp = (int32 *) vals;
241 gp.ui = (
unsigned int *) vals;
248 gp.fp = (
float *) vals;
250 rep << setprecision(10);
252 if (rep.str().find(
'.') == string::npos
253 && rep.str().find(
'e') == string::npos)
260 gp.dp = (
double *) vals;
261 rep << std::showpoint;
262 rep << std::setprecision(17);
264 if (rep.str().find(
'.') == string::npos
265 && rep.str().find(
'e') == string::npos)
271 return string(
"UNKNOWN");
277 HE2CF::print_type(int32 type)
281 static const char UNKNOWN[]=
"Unknown";
282 static const char BYTE[]=
"Byte";
283 static const char INT16[]=
"Int16";
284 static const char UINT16[]=
"UInt16";
285 static const char INT32[]=
"Int32";
286 static const char UINT32[]=
"UInt32";
287 static const char FLOAT32[]=
"Float32";
288 static const char FLOAT64[]=
"Float64";
289 static const char STRING[]=
"String";
339 for(
int i = 0; i < num_global_attributes; i++){
342 char temp_name[H4_MAX_NC_NAME];
344 int32 attr_count = 0;
345 if(SDattrinfo(sd_id, i, temp_name, &attr_type, &attr_count) == FAIL) {
348 error <<
"Fail to obtain SDS global attribute info." << endl;
349 throw_error(error.str());
352 string attr_namestr(temp_name);
357 if (
true == is_eosmetadata(attr_namestr))
364 if (attr_namestr.compare(0,14,
"StructMetadata" )== 0)
372 if (attr_namestr.compare(0,12,
"CoreMetadata" )== 0)
374 if (attr_namestr.compare(0,12,
"coremetadata" )== 0)
376 if (attr_namestr.compare(0,15,
"ArchiveMetadata" )== 0)
378 if (attr_namestr.compare(0,15,
"archivemetadata" )== 0)
380 if (attr_namestr.compare(0,15,
"Productmetadata" )== 0)
382 if (attr_namestr.compare(0,15,
"productmetadata" )== 0)
388 vector<char>attr_data;
389 attr_data.resize((attr_count+1) *DFKNTsize(attr_type));
391 if(attr_data ==
NULL){
394 error <<
"Fail to calloc memory" << endl;
395 throw_error(error.str());
400 if(SDreadattr(sd_id, i, &attr_data[0]) == FAIL){
404 error <<
"Fail to read SDS global attributes" << endl;
405 throw_error(error.str());
409 if (1==attr_count && DFNT_INT32==attr_type) {
410 cerr<<
"attr_name is "<< attr_namestr<<endl;
411 cerr<<
"attr value is "<<*(
int*)&attr_data[0] <<endl;
417 if (attr_type == DFNT_CHAR || attr_type == DFNT_UCHAR) {
421 attr_data[attr_count] =
'\0';
426 AttrTable *at = das->get_table(
"HDF_GLOBAL");
428 at = das->add_table(
"HDF_GLOBAL",
new AttrTable);
433 if(attr_type == DFNT_UCHAR || attr_type == DFNT_CHAR){
434 string tempstring2(attr_data);
435 string tempfinalstr= string(tempstring2.c_str());
444 for (
int loc=0; loc < attr_count ; loc++) {
463 bool HE2CF::set_metadata(
const string& metadata_basename,vector<string>& non_number_names, vector<string>& no_num_data)
465 bool suffix_is_num_or_null =
true;
469 list<string> one_dot_names;
472 list<string> two_dots_names;
479 for(
int i = 0; i < num_global_attributes; i++){
482 char temp_name[H4_MAX_NC_NAME];
484 int32 attr_count = 0;
485 if(SDattrinfo(sd_id, i, temp_name, &attr_type, &attr_count) == FAIL) {
488 error <<
"Fail to obtain SDS global attribute info." << endl;
489 throw_error(error.str());
492 string temp_name_str(temp_name);
495 if(temp_name_str.find(metadata_basename)==0) {
497 arrange_list(one_dot_names,two_dots_names,non_number_names,temp_name_str,list_flag);
501 list<string>::const_iterator lit;
508 if ( list_flag >= 0 && list_flag <=2) {
509 for (lit = one_dot_names.begin();lit!=one_dot_names.end();++lit) {
510 set_eosmetadata_namelist(*lit);
512 obtain_SD_attr_value(*lit,cur_data);
514 metadata.append(cur_data);
519 for (lit = two_dots_names.begin();lit!=two_dots_names.end();++lit){
520 set_eosmetadata_namelist(*lit);
522 obtain_SD_attr_value(*lit,cur_data);
523 metadata.append(cur_data);
527 if(non_number_names.size() >0) {
528 suffix_is_num_or_null =
false;
529 no_num_data.resize(non_number_names.size());
532 for (
unsigned int i =0; i<non_number_names.size();i++) {
533 set_eosmetadata_namelist(non_number_names[i]);
534 obtain_SD_attr_value(non_number_names[i],no_num_data[i]);
537 return suffix_is_num_or_null;
544 void HE2CF::arrange_list(list<string> & sl1, list<string>&sl2,vector<string>&v1,
string name,
int& flag) {
547 if(name.find(
".") == string::npos) {
548 sl1.push_front(name);
549 sl2.push_front(name);
552 else if (name.find_first_of(
".") == name.find_last_of(
".")) {
554 size_t dot_pos = name.find_first_of(
".");
556 if((dot_pos+1)==name.size())
557 throw InternalErr(__FILE__, __LINE__,
"Should have characters or numbers after ." );
559 string str_after_dot = name.substr(dot_pos+1);
560 stringstream sstr(str_after_dot);
561 int number_after_dot;
562 sstr >> number_after_dot;
565 else if(0 == number_after_dot) {
575 throw InternalErr(__FILE__, __LINE__,
576 "ecs metadata suffix .1 and .0.1 cannot exist at the same file" );
585 throw InternalErr(__FILE__, __LINE__,
"ecs metadata suffix .1 and .0.1 cannot exist at the same file" );
593 void HE2CF::obtain_SD_attr_value(
const string& attrname,
string &cur_data) {
595 int32 sds_index = SDfindattr(sd_id, attrname.c_str());
596 if(sds_index == FAIL){
599 error <<
"Failed to obtain the SDS global attribute" << attrname << endl;
600 throw InternalErr(__FILE__, __LINE__,error.str());
604 char temp_name[H4_MAX_NC_NAME];
608 if(SDattrinfo(sd_id, sds_index, temp_name, &type, &count) == FAIL) {
611 error <<
"Failed to obtain the SDS global attribute" << attrname <<
"information" << endl;
612 throw InternalErr(__FILE__, __LINE__,error.str());
615 vector<char> attrvalue;
616 attrvalue.resize((count+1)*DFKNTsize(type));
618 if(SDreadattr(sd_id, sds_index, &attrvalue[0]) == FAIL){
621 error <<
"Failed to read the SDS global attribute" << attrname << endl;
622 throw InternalErr(__FILE__, __LINE__,error.str());
629 if(attrvalue[count] !=
'\0')
630 throw InternalErr(__FILE__,__LINE__,
"the last character of the attribute buffer should be NULL");
633 cur_data.resize(attrvalue.size()-1);
634 copy(attrvalue.begin(),attrvalue.end()-1,cur_data.begin());
638 bool HE2CF::set_vgroup_map(int32 _refid)
645 int32 vgroup_id = Vattach(file_id, _refid,
"r");
646 if (FAIL == vgroup_id) {
649 error <<
"Fail to attach the vgroup " ;
650 throw_error(error.str());
654 int32 npairs = Vntagrefs(vgroup_id);
656 if (FAIL == npairs) {
660 error <<
"Fail to obtain the number of objects in a group " ;
661 throw_error(error.str());
665 for (
int i = 0; i < npairs; ++i) {
668 char buf[H4_MAX_NC_NAME];
670 if (Vgettagref(vgroup_id, i, &tag2, &ref2) < 0){
674 error <<
"Vgettagref failed for vgroup_id=." << vgroup_id;
675 throw_error(error.str());
679 if(tag2 == DFTAG_NDG){
681 int32 sds_index = SDreftoindex(sd_id, ref2);
682 if (FAIL == sds_index) {
686 error <<
"Cannot obtain the SDS index ";
687 throw_error(error.str());
691 int32 sds_id = SDselect(sd_id, sds_index);
692 if (FAIL == sds_id) {
697 error <<
"Cannot obtain the SDS ID ";
698 throw_error(error.str());
704 int32 dimsizes[H4_MAX_VAR_DIMS];
708 if(FAIL == SDgetinfo(sds_id, buf, &rank, dimsizes, &datatype, &num_attrs)) {
713 error <<
"Cannot obtain the SDS info.";
714 throw_error(error.str());
718 vg_sd_map[string(buf)] = sds_id;
722 if(tag2 == DFTAG_VH){
725 if ((vid = VSattach(file_id, ref2,
"r")) < 0) {
730 error <<
"VSattach failed for file_id=." << file_id;
731 throw_error(error.str());
733 if (FAIL == VSgetname(vid, buf)) {
738 error <<
"VSgetname failed for file_id=." << file_id;
739 throw_error(error.str());
741 vg_vd_map[string(buf)] = ref2;
742 if (FAIL == VSdetach(vid)) {
747 error <<
"VSdetach failed for file_id=." << file_id;
748 throw_error(error.str());
754 if (FAIL == Vdetach(vgroup_id)){
757 error <<
"VSdetach failed for file_id=." << file_id;
758 throw_error(error.str());
764 bool HE2CF::write_attr_long_name(
const string& _long_name,
765 const string& _varname,
768 AttrTable *at = das->get_table(_varname);
770 at = das->add_table(_varname,
new AttrTable);
773 at->append_attr(
"long_name",
"String", _long_name +
"(fake)");
776 at->append_attr(
"long_name",
"String", _long_name);
780 bool HE2CF::write_attr_long_name(
const string& _group_name,
781 const string& _long_name,
782 const string& _varname,
785 AttrTable *at = das->get_table(_varname);
787 at = das->add_table(_varname,
new AttrTable);
790 at->append_attr(
"long_name",
"String",
791 _group_name +
":" + _long_name +
"(fake)");
794 at->append_attr(
"long_name",
"String",
795 _group_name +
":" + _long_name);
802 HE2CF::write_attr_sd(int32 _sds_id,
const string& _newfname)
804 char buf_var[H4_MAX_NC_NAME];
805 char buf_attr[H4_MAX_NC_NAME];
807 int32 dimsizes[H4_MAX_VAR_DIMS];
813 status = SDgetinfo(_sds_id, buf_var,
814 &rank, dimsizes, &datatype, &num_attrs);
816 if (FAIL == status) {
819 SDendaccess(_sds_id);
821 error <<
"Cannot obtain the SDS info. ";
822 throw_error(error.str());
828 for (
int j=0; j < num_attrs; j++){
830 status = SDattrinfo(_sds_id, j, buf_attr, &datatype, &n_values);
835 SDendaccess(_sds_id);
838 error <<
"SDattrinfo() failed on " << buf_attr;
839 throw_error(error.str());
844 AttrTable *at = das->get_table(_newfname);
848 at = das->add_table(_newfname,
new AttrTable);
854 value.resize((n_values+1) * DFKNTsize(datatype));
856 status = SDreadattr(_sds_id, j, &value[0]);
861 SDendaccess(_sds_id);
863 error <<
"SDreadattr() failed on " << buf_attr << endl;
864 throw_error(error.str());
868 if (datatype == DFNT_CHAR || datatype == DFNT_UCHAR) {
870 value[n_values] =
'\0';
876 string attr_cf_name = string(buf_attr,strlen(buf_attr));
878 for (
int loc=0; loc < n_values ; loc++) {
885 if (attr_cf_name ==
"_FillValue") {
886 at->del_attr(attr_cf_name);
892 if (attr_cf_name ==
"long_name") {
893 at->del_attr(attr_cf_name);
900 status = SDendaccess(_sds_id);
906 bool HE2CF::write_attr_vdata(int32 _vd_id,
const string& _newfname)
908 int32 number_type, count, size;
909 char buf[H4_MAX_NC_NAME];
913 if ((vid = VSattach(file_id, _vd_id,
"r")) < 0) {
918 error <<
"VSattach failed.";
919 throw_error(error.str());
924 count = VSfnattrs(vid, _HDF_VDATA);
931 error <<
"VSfnattrs failed.";
932 throw_error(error.str());
935 AttrTable *at = das->get_table(_newfname);
937 at = das->add_table(_newfname,
new AttrTable);
940 for(
int i=0; i < count; i++){
942 if (VSattrinfo(vid, _HDF_VDATA, i, buf,
943 &number_type, &count_v, &size) < 0) {
948 error <<
"VSattrinfo failed.";
949 throw_error(error.str());
958 data.resize((count_v+1) * DFKNTsize(number_type));
959 if (VSgetattr(vid, _HDF_VDATA, i, &data[0]) < 0) {
966 error <<
"VSgetattr failed.";
967 throw_error(error.str());
970 if (number_type == DFNT_CHAR || number_type == DFNT_UCHAR8) {
977 for(
int j=0; j < count_v ; j++){
983 if(!strncmp(buf,
"_FillValue", H4_MAX_NC_NAME)){
987 if(!strncmp(buf,
"long_name", H4_MAX_NC_NAME)){
991 string vdataname(buf);
1006 throw_error(
"Cannot allocate enough memory for the data buffer");
1018 HE2CF::throw_error(
string _error)
1020 throw InternalErr(__FILE__, __LINE__,
1028 num_global_attributes = -1;
1047 int istat = Vend(file_id);
1049 ostringstream error;
1050 error <<
"Failed to call Vend in HE2CF::close.";
1051 throw_error(error.str());
1059 HE2CF::get_metadata(
const string& _name,
bool& suffix_is_number,vector<string>&meta_nonnum_names, vector<string>& meta_nonum_data)
1061 suffix_is_number = set_metadata(_name,meta_nonnum_names,meta_nonum_data);
1068 HE2CF::open(
const string& _filename,
const int sd_id,
const int file_id)
1070 if(_filename ==
""){
1071 ostringstream error;
1072 error <<
"=open(): filename is empty.";
1073 throw_error(error.str());
1077 if(!open_vgroup(_filename,file_id)){
1078 ostringstream error;
1079 error <<
"=open(): failed to open vgroup.";
1080 throw_error(error.str());
1084 if(!open_sd(_filename,sd_id)){
1085 ostringstream error;
1086 error <<
"=open(): failed to open sd.";
1087 throw_error(error.str());
1099 const string& _fname,
1100 const string& _newfname,
1106 write_attr_long_name(_gname, _fname, _newfname, _fieldtype);
1109 write_attr_long_name(_fname, _newfname, _fieldtype);
1116 if(gname != _gname){
1119 get_vgroup_field_refids(_gname, &ref_df, &ref_gf);
1122 set_vgroup_map(ref_gf);
1124 set_vgroup_map(ref_df);
1135 id = vg_sd_map[_fname];
1137 write_attr_sd(
id, _newfname);
1142 id = vg_vd_map[_fname];
1144 write_attr_vdata(
id, _newfname);
1162 uint8 val = (uint8) value;
1163 v_ptr = (
void*)&val;
1169 int8 val = (int8) value;
1170 v_ptr = (
void*)&val;
1176 int16 val = (int16) value;
1177 v_ptr = (
void*)&val;
1183 uint16 val = (uint16) value;
1184 v_ptr = (
void*)&val;
1190 int32 val = (int32) value;
1191 v_ptr = (
void*)&val;
1197 uint32 val = (uint32) value;
1198 v_ptr = (
void*)&val;
1204 v_ptr = (
void*)&value;
1209 float64 val = (float64) value;
1210 v_ptr = (
void*)&val;
1215 throw_error(
"Invalid FillValue Type - ");
1219 AttrTable *at = das->get_table(_varname);
1221 at = das->add_table(_varname,
new AttrTable);
1233 AttrTable *at = das->get_table(_varname);
1235 at = das->add_table(_varname,
new AttrTable);
1237 at->append_attr(
"coordinates",
"String", _coordinates);
1246 AttrTable *at = das->get_table(_varname);
1248 at = das->add_table(_varname,
new AttrTable);
1250 at->del_attr(
"units");
1251 at->append_attr(
"units",
"String", _units);
bool open(const string &filename, const int sd_id, const int file_id)
openes HDF4 file.
bool write_attribute_FillValue(const string &varname, int type, float val)
writes _FillValue attribute into varname attribute table.
bool set_non_ecsmetadata_attrs()
bool write_attribute_units(const string &varname, string units)
writes units attribute into varname attribute table.
static std::string print_type(int32)
Print datatype in string.
static std::string escattr(std::string s)
A customized escaping function to escape special characters following OPeNDAP's escattr function that...
bool close()
closes the opened file.
bool write_attribute_coordinates(const string &varname, string coord)
writes coordinates attribute into varname attribute table.
void set_DAS(DAS *das)
sets DAS pointer so that we can bulid attribute tables.
static std::string print_attr(int32, int, void *)
Print attribute values in string.
static std::string get_CF_string(std::string s)
Change special characters to "_".
string get_metadata(const string &metadataname, bool &suffix_is_num, vector< string > &non_num_names, vector< string > &non_num_data)
retrieves the merged metadata.
bool write_attribute(const string &gname, const string &fname, const string &newfname, int n_groups, int fieldtype)
writes attribute table into DAS given grid/swath name and its field name.
string print_attr(hid_t type, int loc, void *sm_buf)
will get the printed representation of an attribute.