40#include <libdap/InternalErr.h>
41#include <libdap/mime_util.h>
42#include <libdap/D4Maps.h>
65#include "HDF5CFProj.h"
66#include "HDF5CFProj1D.h"
67#include "HDF5MissLLArray.h"
78struct yy_buffer_state;
80yy_buffer_state *he5dds_scan_string(
const char *str);
82int he5ddslex_destroy();
84void array_add_dimensions_dimscale(
HDF5Array* ar);
86void read_objects_basetype_add_eos5_grid_mapping(
const eos5_dim_info_t &eos5_dim_info, BaseType *new_var,
const HDF5Array *ar);
87void write_dap4_attr(hid_t attr_id, libdap::D4Attribute *d4_attr, hid_t ty_id,
const DSattr_t &attr_inst);
88void write_dap4_attr_value(D4Attribute *d4_attr, hid_t ty_id, hsize_t nelmts,
char *tempvalue,
117 D4Group* par_grp,
const char *fname,
118 bool use_dimscale,
bool is_eos5,
119 vector<link_info_t> & hdf5_hls,
121 vector<string> & handled_cv_names)
124 ">breadth_first() for dmr "
126 <<
" gname: " << gname
127 <<
" fname: " << fname
136 if (H5Gget_info(pid,&g_info) < 0) {
138 "h5_dmr: counting hdf5 group elements error for ";
140 throw InternalErr(__FILE__, __LINE__, msg);
143 nelems = g_info.nlinks;
146 for (hsize_t i = 0; i < nelems; i++) {
149 obtain_hdf5_object_name(pid, i, gname, oname);
150 if (
true == check_soft_external_links(par_grp, pid, slinkindex,gname, oname,
true))
155 if (H5OGET_INFO_BY_IDX(pid,
".", H5_INDEX_NAME, H5_ITER_NATIVE,
156 i, &oinfo, H5P_DEFAULT) <0 ) {
157 string msg =
"h5_dmr handler: Error obtaining the info for the object";
158 msg += string(oname.begin(),oname.end());
159 throw InternalErr(__FILE__, __LINE__, msg);
162 H5O_type_t obj_type = oinfo.type;
164 if (H5O_TYPE_DATASET == obj_type) {
167 string full_path_name = string(gname) + string(oname.begin(),oname.end()-1);
172 bool is_pure_dim =
false;
173 get_dataset_dmr(file_id, pid, full_path_name, &dt_inst,use_dimscale,is_eos5,
174 is_pure_dim,hdf5_hls,handled_cv_names);
177 if (
false == is_pure_dim) {
178 handle_actual_dataset(par_grp, pid, full_path_name, fname, use_dimscale,
179 is_eos5, eos5_dim_info);
182 handle_pure_dimension(par_grp, pid, oname, is_eos5, full_path_name);
187 map_h5_attrs_to_dap4(pid,par_grp,
nullptr,
nullptr,0);
189 if (is_eos5 && !use_dimscale)
190 handle_eos5_datasets(par_grp, gname, eos5_dim_info);
196 map_h5_varpath_to_dap4_attr(par_grp,
nullptr,
nullptr,gname,0);
200 for (hsize_t i = 0; i < nelems; i++) {
203 obtain_hdf5_object_name(pid, i, gname, oname);
204 if (
true == check_soft_external_links(par_grp, pid, slinkindex,gname, oname,
false))
210 if (H5OGET_INFO_BY_IDX(pid,
".", H5_INDEX_NAME, H5_ITER_NATIVE,
211 i, &oinfo, H5P_DEFAULT) < 0 ) {
212 string msg =
"h5_dmr handler: Error obtaining the info for the object in the breadth_first.";
213 throw InternalErr(__FILE__, __LINE__, msg);
216 H5O_type_t obj_type = oinfo.type;
218 if (obj_type == H5O_TYPE_GROUP) {
219 handle_child_grp(file_id, pid, gname, par_grp, fname, use_dimscale, is_eos5, hdf5_hls, eos5_dim_info,
220 handled_cv_names, oname);
224 BESDEBUG(
"h5",
"<breadth_first() " << endl);
228void obtain_hdf5_object_name(hid_t pid, hsize_t obj_index,
const char *gname, vector<char> &oname) {
233 oname_size = H5Lget_name_by_idx(pid,
".",H5_INDEX_NAME,H5_ITER_NATIVE,obj_index,
235 if (oname_size <= 0) {
236 string msg =
"h5_dmr handler: Error getting the size of the hdf5 object from the group: ";
238 throw InternalErr(__FILE__, __LINE__, msg);
242 oname.resize((
size_t) oname_size + 1);
244 if (H5Lget_name_by_idx(pid,
".",H5_INDEX_NAME,H5_ITER_NATIVE,obj_index,
245 oname.data(),(
size_t)(oname_size+1), H5P_DEFAULT) < 0) {
246 string msg =
"h5_dmr handler: Error getting the hdf5 object name from the group: ";
248 throw InternalErr(__FILE__, __LINE__, msg);
252bool check_soft_external_links(D4Group *par_grp, hid_t pid,
int & slinkindex,
253 const char *gname,
const vector<char> &oname,
bool handle_softlink) {
255 bool ret_value =
false;
259 if (H5Lget_info(pid,oname.data(),&linfo,H5P_DEFAULT) < 0) {
260 string msg =
"hdf5 link name error from: ";
262 throw InternalErr(__FILE__, __LINE__, msg);
266 if (linfo.type == H5L_TYPE_SOFT) {
268 if (handle_softlink ==
false) {
271 size_t val_size = linfo.u.val_size;
272 get_softlink(par_grp, pid, oname.data(), slinkindex, val_size);
275 else if (linfo.type == H5L_TYPE_EXTERNAL)
281void handle_actual_dataset(D4Group *par_grp, hid_t pid,
const string &full_path_name,
const string &fname,
285 if ((dset_id = H5Dopen(pid,full_path_name.c_str(),H5P_DEFAULT)) < 0) {
286 string msg =
"cannot open the HDF5 dataset ";
287 msg += full_path_name;
288 throw InternalErr(__FILE__, __LINE__, msg);
292 read_objects(par_grp, pid, full_path_name, fname,dset_id,use_dimscale,is_eos5,eos5_dim_info);
298 if (H5Dclose(dset_id) < 0) {
299 string msg =
"cannot close the HDF5 dataset ";
300 msg += full_path_name;
301 throw InternalErr(__FILE__, __LINE__, msg);
306void handle_pure_dimension(D4Group *par_grp, hid_t pid,
const vector<char>& oname,
bool is_eos5,
307 const string &full_path_name) {
310 D4Dimensions *d4_dims = par_grp->dims();
313 auto tempdim_name = string(oname.begin(),oname.end()-1);
314 d4dim_name = handle_string_special_characters(tempdim_name);
317 d4dim_name = string(oname.begin(),oname.end()-1);
319 const D4Dimension *d4_dim = d4_dims->find_dim(d4dim_name);
320 if (d4_dim ==
nullptr) {
322 hsize_t nelmts = dt_inst.nelmts;
328 if (dt_inst.nelmts == 0)
329 nelmts = obtain_unlim_pure_dim_size(pid,full_path_name);
331 auto d4_dim_unique = make_unique<D4Dimension>(d4dim_name, nelmts);
332 d4_dims->add_dim_nocopy(d4_dim_unique.release());
335 BESDEBUG(
"h5",
"<h5dmr.cc: pure dimension: dataset name." << d4dim_name << endl);
337 if (H5Tclose(dt_inst.type)<0) {
338 throw InternalErr(__FILE__, __LINE__,
"Cannot close the HDF5 datatype.");
343void handle_eos5_datasets(D4Group* par_grp,
const char *gname,
eos5_dim_info_t &eos5_dim_info) {
354 add_possible_eos5_grid_vars(par_grp, eos5_dim_info);
357 unordered_map<string,vector<HE5Dim>> grppath_to_dims = eos5_dim_info.grppath_to_dims;
358 vector<string> dim_names;
359 auto par_grp_name = string(gname);
360 if (par_grp_name.size() > 1)
361 par_grp_name = par_grp_name.substr(0,par_grp_name.size()-1);
363 BESDEBUG(
"h5",
"<h5dmr.cc: eos5 handling - parent group name: " << par_grp_name << endl);
366 bool is_eos5_dims = obtain_eos5_grp_dim(par_grp_name,grppath_to_dims,dim_names);
370 vector<HE5Dim> grp_eos5_dim = grppath_to_dims[par_grp_name];
371 D4Dimensions *d4_dims = par_grp->dims();
372 for (
unsigned grp_dim_idx = 0; grp_dim_idx < dim_names.size(); grp_dim_idx++) {
374 const D4Dimension *d4_dim = d4_dims->find_dim(dim_names[grp_dim_idx]);
375 if (d4_dim ==
nullptr) {
377 make_unique<D4Dimension>(dim_names[grp_dim_idx],grp_eos5_dim[grp_dim_idx].size);
378 d4_dims->add_dim_nocopy(d4_dim_unique.release());
384void handle_child_grp(hid_t file_id, hid_t pid,
const char *gname,
385 D4Group* par_grp,
const char *fname,
386 bool use_dimscale,
bool is_eos5,
387 vector<link_info_t> & hdf5_hls,
389 vector<string> & handled_cv_names,
390 const vector<char>& oname) {
393 string full_path_name =
394 string(gname) + string(oname.begin(),oname.end()-1) +
"/";
396 BESDEBUG(
"h5",
"=breadth_first dmr ():H5G_GROUP " << full_path_name
400 t_fpn.resize(full_path_name.size() + 1);
401 copy(full_path_name.begin(),full_path_name.end(),t_fpn.begin());
402 t_fpn[full_path_name.size()] =
'\0';
404 hid_t cgroup = H5Gopen(pid, t_fpn.data(),H5P_DEFAULT);
406 throw InternalErr(__FILE__, __LINE__,
"h5_dmr handler: H5Gopen() failed.");
409 auto grp_name = string(oname.begin(),oname.end()-1);
412 string oid = get_hardlink_dmr(cgroup, full_path_name);
417 grp_name = handle_string_special_characters(grp_name);
418 auto tem_d4_cgroup_ptr = make_unique<D4Group>(grp_name);
419 auto tem_d4_cgroup = tem_d4_cgroup_ptr.release();
422 par_grp->add_group_nocopy(tem_d4_cgroup);
425 breadth_first(file_id,cgroup, t_fpn.data(), tem_d4_cgroup,fname,
426 use_dimscale,is_eos5,hdf5_hls,eos5_dim_info,handled_cv_names);
437 auto tem_d4_cgroup_unique = make_unique<D4Group>(grp_name);
438 auto tem_d4_cgroup = tem_d4_cgroup_unique.release();
441 auto d4_hlinfo_unique = make_unique<D4Attribute>(
"HDF5_HARDLINK",attr_str_c);
442 auto d4_hlinfo = d4_hlinfo_unique.release();
444 d4_hlinfo->add_value(
obj_paths.get_name(oid));
445 tem_d4_cgroup->attributes()->add_attribute_nocopy(d4_hlinfo);
446 par_grp->add_group_nocopy(tem_d4_cgroup);
449 if (H5Gclose(cgroup) < 0){
450 throw InternalErr(__FILE__, __LINE__,
"Could not close the group.");
478read_objects( D4Group * d4_grp, hid_t pid,
const string &varname,
const string &filename, hid_t dset_id,
bool use_dimscale,
482 if (dt_inst.ndims == -1 && dt_inst.nelmts == 0)
485 switch (H5Tget_class(dt_inst.type)) {
493 H5Tclose(dt_inst.type);
494 throw InternalErr(__FILE__, __LINE__,
495 "Currently don't support accessing data of Array datatype when array datatype is not inside the compound.");
502 if (H5Tclose(dt_inst.type) < 0) {
503 throw InternalErr(__FILE__, __LINE__,
"Cannot close the HDF5 datatype.");
507void array_add_dimensions_dimscale(
HDF5Array *ar){
509 if (dt_inst.dimnames.empty() ==
true) {
510 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++)
511 ar->append_dim_ll(dt_inst.size[dim_index]);
514 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++) {
515 if (dt_inst.dimnames[dim_index].empty() ==
false)
516 ar->append_dim_ll(dt_inst.size[dim_index], dt_inst.dimnames[dim_index]);
518 ar->append_dim_ll(dt_inst.size[dim_index]);
522 if (dt_inst.dimnames.empty() ==
false)
523 dt_inst.dimnames.clear();
531 vector<string> dim_names;
532 bool is_eos5_dims = obtain_eos5_dim(varname, eos5_dim_info.varpath_to_dims, dim_names);
535 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++)
536 ar->append_dim_ll(dt_inst.size[dim_index], dim_names[dim_index]);
538 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++)
539 ar->append_dim_ll(dt_inst.size[dim_index]);
544void read_objects_basetype_add_eos5_grid_mapping(
const eos5_dim_info_t &eos5_dim_info,
547 if ((eos5_dim_info.dimpath_to_cvpath.empty() ==
false) && (ar->
get_numdim() > 1))
548 add_possible_var_cv_info(new_var, eos5_dim_info);
549 if (eos5_dim_info.gridname_to_info.empty() ==
false)
550 make_attributes_to_cf(new_var, eos5_dim_info);
580 string newvarname = obtain_new_varname(varname, use_dimscale, is_eos5);
582 hid_t datatype = H5Dget_type(dset_id);
585 if (H5Tget_class(datatype) == H5T_VLEN) {
586 handle_vlen_int_float(d4_grp, pid, newvarname, varname, filename,dset_id);
593 BaseType *bt = Get_bt_enhanced(d4_grp,pid, newvarname,varname, filename, dt_inst.type);
595 throw InternalErr(__FILE__, __LINE__,
"Unable to convert hdf5 datatype to dods basetype");
598 if (dt_inst.ndims == 0) {
601 bt->set_is_dap4(
true);
602 read_objects_basetype_attr_hl(varname, bt, dset_id, is_eos5);
605 d4_grp->add_var_nocopy(bt);
611 auto ar_unique = make_unique<HDF5Array>(newvarname, filename, bt);
621 ar->set_varpath(varname);
624 int dimnames_size = 0;
625 if ((
unsigned int) ((
int) (dt_inst.dimnames.size())) != dt_inst.dimnames.size())
626 throw InternalErr(__FILE__, __LINE__,
"number of dimensions: overflow");
628 dimnames_size = (
int) (dt_inst.dimnames.size());
630 bool is_eos5_dims =
false;
631 if (dimnames_size == dt_inst.ndims)
632 array_add_dimensions_dimscale(ar);
636 is_eos5_dims = array_add_dimensions_non_dimscale(ar, varname, eos5_dim_info);
640 BaseType *new_var =
nullptr;
643 new_var = ar->h5dims_transform_to_dap4(d4_grp, eos5_dim_info.varpath_to_dims.at(varname));
645 new_var = ar->h5dims_transform_to_dap4(d4_grp, dt_inst.dimnames_path);
648 dt_inst.dimnames_path.clear();
650 read_objects_basetype_attr_hl(varname, new_var, dset_id, is_eos5);
653 if (is_eos5_dims && !use_dimscale)
654 read_objects_basetype_add_eos5_grid_mapping(eos5_dim_info, new_var, ar);
657 d4_grp->add_var_nocopy(new_var);
659 BESDEBUG(
"h5",
"<read_objects_base_type(dmr)" << endl);
663void read_objects_basetype_attr_hl(
const string &varname, BaseType *bt, hid_t dset_id,
bool is_eos5) {
666 bt->set_is_dap4(
true);
669 map_h5_attrs_to_dap4(dset_id,
nullptr,bt,
nullptr,1);
672 map_h5_dset_hardlink_to_d4(dset_id,varname,bt,
nullptr,1);
676 map_h5_varpath_to_dap4_attr(
nullptr,bt,
nullptr,varname,1);
697 const string & filename,hid_t dset_id,
bool use_dimscale,
bool is_eos5)
699 string newvarname = obtain_new_varname(varname, use_dimscale, is_eos5);
702 Structure *structure = Get_structure(newvarname, varname,filename, dt_inst.type,
true);
706 BESDEBUG(
"h5",
"=read_objects_structure(): Dimension is "
707 << dt_inst.ndims << endl);
709 if (dt_inst.ndims != 0)
710 read_objects_structure_arrays(d4_grp, structure, varname,newvarname, filename, dset_id, is_eos5);
712 read_objects_structure_scalar(d4_grp, structure, varname,dset_id, is_eos5);
720void read_objects_structure_arrays(D4Group *d4_grp, Structure *structure,
const string & varname,
721 const string &newvarname,
const string & filename, hid_t dset_id,
bool is_eos5)
723 BESDEBUG(
"h5",
"=read_objects_structure(): array of size " << dt_inst.nelmts << endl);
724 BESDEBUG(
"h5",
"=read_objects_structure(): memory needed = " << dt_inst.need << endl);
727 auto ar_unique = make_unique<HDF5Array>(newvarname, filename, structure);
729 delete structure; structure =
nullptr;
735 ar->set_length(dt_inst.nelmts);
736 ar->set_varpath(varname);
739 int dimnames_size = 0;
740 if((
unsigned int)((
int)(dt_inst.dimnames.size())) != dt_inst.dimnames.size())
742 throw InternalErr(__FILE__, __LINE__,
743 "number of dimensions: overflow");
745 dimnames_size = (
int)(dt_inst.dimnames.size());
747 if (dimnames_size ==dt_inst.ndims) {
748 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++) {
749 if (dt_inst.dimnames[dim_index].empty() ==
false)
750 ar->append_dim_ll(dt_inst.size[dim_index],dt_inst.dimnames[dim_index]);
752 ar->append_dim_ll(dt_inst.size[dim_index]);
754 dt_inst.dimnames.clear();
757 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++)
758 ar->append_dim_ll(dt_inst.size[dim_index]);
762 BaseType* new_var = ar->h5dims_transform_to_dap4(d4_grp,dt_inst.dimnames_path);
763 dt_inst.dimnames_path.clear();
766 map_h5_attrs_to_dap4(dset_id,
nullptr,new_var,
nullptr,1);
769 map_h5_dset_hardlink_to_d4(dset_id,varname,new_var,
nullptr,1);
771 map_h5_varpath_to_dap4_attr(
nullptr,new_var,
nullptr,varname,1);
775 d4_grp->add_var_nocopy(new_var);
779void read_objects_structure_scalar(D4Group *d4_grp, Structure *structure,
const string & varname,
780 hid_t dset_id,
bool is_eos5)
782 structure->set_is_dap4(
true);
783 map_h5_attrs_to_dap4(dset_id,
nullptr,
nullptr,structure,2);
784 map_h5_dset_hardlink_to_d4(dset_id,varname,
nullptr,structure,2);
786 map_h5_varpath_to_dap4_attr(
nullptr,
nullptr,structure,varname,2);
788 d4_grp->add_var_nocopy(structure);
791string obtain_new_varname(
const string &varname,
bool use_dimscale,
bool is_eos5) {
794 string newvarname = HDF5CFUtil::obtain_string_after_lastslash(varname);
796 const string nc4_non_coord=
"_nc4_non_coord_";
797 size_t nc4_non_coord_size= nc4_non_coord.size();
798 if (newvarname.find(nc4_non_coord) == 0)
799 newvarname = newvarname.substr(nc4_non_coord_size,newvarname.size()-nc4_non_coord_size);
802 newvarname = handle_string_special_characters(newvarname);
821void map_h5_attrs_to_dap4(hid_t h5_objid,D4Group* d4g,BaseType* d4b,Structure * d4s,
int flag) {
825 if (H5OGET_INFO(h5_objid, &obj_info) <0) {
826 string msg =
"Fail to obtain the HDF5 object info. .";
827 throw InternalErr(__FILE__, __LINE__, msg);
831 auto num_attrs = (
int)(obj_info.num_attrs);
832 if (num_attrs < 0 ) {
833 string msg =
"Fail to get the number of attributes for the HDF5 object. ";
834 throw InternalErr(__FILE__, __LINE__,msg);
837 bool ignore_attr =
false;
840 for (
int j = 0; j < num_attrs; j++) {
848 attr_id = get_attr_info(h5_objid, j,
true,&attr_inst, &ignore_attr);
849 if (
true == ignore_attr) {
859 hid_t ty_id = H5Aget_type(attr_id);
862 throw InternalErr(__FILE__, __LINE__,
"Cannot retrieve HDF5 attribute datatype successfully.");
865 string dap_type = get_dap_type(ty_id,
true);
868 D4AttributeType dap4_attr_type = daptype_strrep_to_dap4_attrtype(dap_type);
871 if(attr_null_c == dap4_attr_type) {
874 throw InternalErr(__FILE__, __LINE__,
"unsupported DAP4 attribute type");
877 string attr_name = attr_inst.
name;
878 BESDEBUG(
"h5",
"attr_name= " << attr_name << endl);
882 auto d4_attr_unique = make_unique<D4Attribute>(attr_name, dap4_attr_type);
883 D4Attribute *d4_attr = d4_attr_unique.release();
886 if (dap4_attr_type == attr_str_c && check_if_utf8_str(ty_id) )
887 d4_attr->set_utf8_str_flag(
true);
890 if (H5Tis_variable_str(ty_id))
891 write_vlen_str_attrs(attr_id,ty_id,&attr_inst,d4_attr,
nullptr,
true);
893 write_dap4_attr(attr_id, d4_attr, ty_id, attr_inst);
899 d4g->attributes()->add_attribute_nocopy(d4_attr);
901 d4b->attributes()->add_attribute_nocopy(d4_attr);
903 d4s->attributes()->add_attribute_nocopy(d4_attr);
907 string msg =
"The add_dap4_attr flag has to be either 0,1 or 2.";
908 msg +=
"The current flag is "+sflag.str();
910 throw InternalErr(__FILE__, __LINE__, msg);
916void write_dap4_attr(hid_t attr_id, libdap::D4Attribute *d4_attr, hid_t ty_id,
const DSattr_t &attr_inst) {
919 value.resize(attr_inst.
need);
920 BESDEBUG(
"h5",
"arttr_inst.need=" << attr_inst.
need << endl);
923 hid_t memtype = H5Tget_native_type(ty_id, H5T_DIR_ASCEND);
926 if (H5Aread(attr_id, memtype, (
void *) (value.data())) < 0) {
930 throw InternalErr(__FILE__, __LINE__,
"unable to read HDF5 attribute data");
936 char *tempvalue = value.data();
939 if (attr_inst.
ndims == 0)
940 write_dap4_attr_value(d4_attr,ty_id,1,tempvalue);
944 auto elesize = (
int) H5Tget_size(ty_id);
949 throw InternalErr(__FILE__, __LINE__,
"unable to get attibute size");
952 write_dap4_attr_value(d4_attr,ty_id,attr_inst.
nelmts,tempvalue, elesize);
956void write_dap4_attr_value(D4Attribute *d4_attr, hid_t ty_id, hsize_t nelmts,
char *tempvalue,
size_t elesize) {
961 for (hsize_t temp_index = 0; temp_index < nelmts; temp_index++) {
963 print_rep = print_attr(ty_id, 0, tempvalue);
964 if (print_rep.c_str() !=
nullptr) {
966 BESDEBUG(
"h5",
"print_rep= " << print_rep << endl);
967 d4_attr->add_value(print_rep);
968 tempvalue = tempvalue + elesize;
970 "tempvalue= " << tempvalue
971 <<
"elesize=" << elesize
976 throw InternalErr(__FILE__, __LINE__,
"unable to convert attribute value to DAP");
995void map_h5_dset_hardlink_to_d4(hid_t h5_dsetid,
const string & full_path, BaseType* d4b,Structure * d4s,
int flag) {
998 string oid = get_hardlink_dmr(h5_dsetid, full_path);
1001 if(
false == oid.empty()) {
1003 auto d4_hlinfo_unique = make_unique<D4Attribute>(
"HDF5_HARDLINK",attr_str_c);
1004 auto d4_hlinfo = d4_hlinfo_unique.release();
1005 d4_hlinfo->add_value(
obj_paths.get_name(oid));
1008 d4b->attributes()->add_attribute_nocopy(d4_hlinfo);
1009 else if ( 2 == flag)
1010 d4s->attributes()->add_attribute_nocopy(d4_hlinfo);
1033void map_h5_varpath_to_dap4_attr(D4Group* d4g,BaseType* d4b,Structure * d4s,
const string & varpath,
short flag) {
1035 auto d4_attr_unique = make_unique<D4Attribute>(
"fullnamepath",attr_str_c);
1036 auto d4_attr = d4_attr_unique.release();
1037 d4_attr->add_value(varpath);
1040 d4g->attributes()->add_attribute_nocopy(d4_attr);
1042 d4b->attributes()->add_attribute_nocopy(d4_attr);
1043 else if ( 2 == flag)
1044 d4s->attributes()->add_attribute_nocopy(d4_attr);
1048 string msg =
"The add_dap4_attr flag has to be either 0,1 or 2.";
1049 msg+=
"The current flag is "+sflag.str();
1051 throw InternalErr(__FILE__, __LINE__, msg);
1069void get_softlink(D4Group* par_grp, hid_t h5obj_id,
const string & oname,
int index,
size_t val_size)
1071 BESDEBUG(
"h5",
"dap4 get_softlink():" << oname << endl);
1074 oss << string(
"HDF5_SOFTLINK");
1077 string temp_varname = oss.str();
1079 BESDEBUG(
"h5",
"dap4->get_softlink():link name " << temp_varname << endl);
1081 auto d4_slinfo_unique = make_unique<D4Attribute>();
1082 auto d4_slinfo = d4_slinfo_unique.release();
1083 d4_slinfo->set_name(temp_varname);
1086 d4_slinfo->set_type(attr_container_c);
1088 string softlink_name =
"linkname";
1090 auto softlink_src_unique = make_unique<D4Attribute>(softlink_name, attr_str_c);
1091 auto softlink_src = softlink_src_unique.release();
1092 softlink_src->add_value(oname);
1094 d4_slinfo->attributes()->add_attribute_nocopy(softlink_src);
1095 string softlink_value_name =
"LINKTARGET";
1098 buf.resize(val_size + 1);
1101 if (H5Lget_val(h5obj_id, oname.c_str(), (
void*) buf.data(), val_size + 1, H5P_DEFAULT) < 0) {
1102 throw InternalErr(__FILE__, __LINE__,
"unable to get link value");
1104 auto softlink_tgt_unique = make_unique<D4Attribute>(softlink_value_name, attr_str_c);
1105 auto softlink_tgt = softlink_tgt_unique.release();
1107 auto link_target_name = string(buf.begin(), buf.end());
1108 softlink_tgt->add_value(link_target_name);
1110 d4_slinfo->attributes()->add_attribute_nocopy(softlink_tgt);
1111 par_grp->attributes()->add_attribute_nocopy(d4_slinfo);
1127string get_hardlink_dmr( hid_t h5obj_id,
const string & oname) {
1129 BESDEBUG(
"h5",
"dap4->get_hardlink_dmr():" << oname << endl);
1132 H5O_info_t obj_info;
1133 if (H5OGET_INFO(h5obj_id, &obj_info) <0)
1134 throw InternalErr(__FILE__, __LINE__,
"H5OGET_INFO() failed.");
1140 if (obj_info.rc >1) {
1144#if (H5_VERS_MAJOR == 1 && ((H5_VERS_MINOR == 12) || (H5_VERS_MINOR == 13) || (H5_VERS_MINOR == 14)))
1145 char *obj_tok_str =
nullptr;
1146 if(H5Otoken_to_str(h5obj_id, &(obj_info.token), &obj_tok_str) <0) {
1147 throw InternalErr(__FILE__, __LINE__,
"H5Otoken_to_str failed.");
1149 objno.assign(obj_tok_str,obj_tok_str+strlen(obj_tok_str));
1150 H5free_memory(obj_tok_str);
1154 oss << hex << obj_info.addr;
1158 BESDEBUG(
"h5",
"dap4->get_hardlink_dmr() objno=" << objno << endl);
1179 BESDEBUG(
"h5",
"Coming to read_struct_metadata() "<<endl);
1181 string total_strmeta_value;
1182 string ecs_group =
"/HDFEOS INFORMATION";
1183 hid_t ecs_grp_id = -1;
1184 if ((ecs_grp_id = H5Gopen(s_file_id, ecs_group.c_str(),H5P_DEFAULT)) < 0) {
1185 string msg =
"h5_ecs_meta: unable to open the HDF5 group ";
1187 throw InternalErr(__FILE__, __LINE__, msg);
1193 if (H5Gget_info(ecs_grp_id,&g_info) < 0) {
1194 string msg =
"h5_ecs_meta: unable to obtain the HDF5 group info. for ";
1196 H5Gclose(ecs_grp_id);
1197 throw InternalErr(__FILE__, __LINE__, msg);
1200 nelems = g_info.nlinks;
1203 int strmeta_num_total = 0;
1204 bool strmeta_no_suffix =
true;
1207 vector<string> s_oname(nelems);
1211 vector<bool> smetatype(nelems,
false);
1213 obtain_struct_metadata_info(ecs_grp_id, s_oname, smetatype,
1214 strmeta_num_total, strmeta_no_suffix, nelems);
1218 vector<string> strmeta_value;
1219 if (strmeta_num_total <= 0) {
1220 string msg =
"hdf5 object name error from: ";
1221 H5Gclose(ecs_grp_id);
1222 throw InternalErr(__FILE__, __LINE__, msg);
1225 strmeta_value.resize(strmeta_num_total);
1226 for (
int i = 0; i < strmeta_num_total; i++)
1227 strmeta_value[i]=
"";
1230 int strmeta_num = obtain_struct_metadata_value(ecs_grp_id, s_oname,smetatype, nelems,
1231 strmeta_value, total_strmeta_value);
1234 if ((strmeta_num_total > 0) && (strmeta_num != -1) ) {
1236 for (
int i = 0; i <strmeta_num_total; i++)
1237 total_strmeta_value +=strmeta_value[i];
1240 return total_strmeta_value;
1243void obtain_struct_metadata_info(hid_t ecs_grp_id, vector<string> &s_oname, vector<bool> &smetatype,
1244 int &strmeta_num_total,
bool &strmeta_no_suffix, hsize_t nelems) {
1246 string ecs_group =
"/HDFEOS INFORMATION";
1247 ssize_t oname_size = 0;
1248 for (hsize_t i = 0; i < nelems; i++) {
1251 oname_size = H5Lget_name_by_idx(ecs_grp_id,
".", H5_INDEX_NAME, H5_ITER_NATIVE,
1252 i,
nullptr,0, H5P_DEFAULT);
1253 if (oname_size <= 0) {
1254 string msg =
"hdf5 object name error from: ";
1256 H5Gclose(ecs_grp_id);
1257 throw InternalErr(__FILE__, __LINE__, msg);
1261 vector<char> oname(oname_size + 1);
1262 if (H5Lget_name_by_idx(ecs_grp_id,
".", H5_INDEX_NAME, H5_ITER_NATIVE, i,
1263 oname.data(),(
size_t) (oname_size + 1), H5P_DEFAULT) < 0) {
1264 string msg =
"hdf5 object name error from: ";
1266 H5Gclose(ecs_grp_id);
1267 throw InternalErr(__FILE__, __LINE__, msg);
1273 if (H5Lget_info(ecs_grp_id, oname.data(), &linfo, H5P_DEFAULT) < 0) {
1274 string msg =
"hdf5 link name error from: ";
1276 H5Gclose(ecs_grp_id);
1277 throw InternalErr(__FILE__, __LINE__, msg);
1281 if (linfo.type == H5L_TYPE_SOFT) {
1282 string msg =
"hdf5 link name error from: ";
1284 H5Gclose(ecs_grp_id);
1285 throw InternalErr(__FILE__, __LINE__, msg);
1290 if (H5OGET_INFO_BY_IDX(ecs_grp_id,
".", H5_INDEX_NAME, H5_ITER_NATIVE,
1291 i, &oinfo, H5P_DEFAULT) < 0) {
1292 string msg =
"Cannot obtain the object info ";
1294 H5Gclose(ecs_grp_id);
1295 throw InternalErr(__FILE__, __LINE__, msg);
1298 if (oinfo.type != H5O_TYPE_DATASET) {
1299 string msg =
"hdf5 link name error from: ";
1301 H5Gclose(ecs_grp_id);
1302 throw InternalErr(__FILE__, __LINE__, msg);
1306 string s_one_oname(oname.begin(), oname.end() - 1);
1307 s_oname[i] = s_one_oname;
1310 if (((s_one_oname.find(
"StructMetadata")) == 0) ||
1311 ((s_one_oname.find(
"structmetadata")) == 0)) {
1313 smetatype[i] =
true;
1320 if (
false == strmeta_no_suffix) {
1321 string msg =
"StructMetadata/structmetadata without suffix should only appear once. ";
1322 H5Gclose(ecs_grp_id);
1323 throw InternalErr(__FILE__, __LINE__, msg);
1324 }
else if (strmeta_num_total > 0)
1325 strmeta_num_total++;
1327 else if ((0 == s_one_oname.compare(
"StructMetadata")) ||
1328 (0 == s_one_oname.compare(
"structmetadata")))
1329 strmeta_no_suffix =
false;
1330 else strmeta_num_total++;
1333 s_one_oname.clear();
1337int obtain_struct_metadata_value(hid_t ecs_grp_id,
const vector<string> &s_oname,
const vector<bool> &smetatype,
1338 hsize_t nelems, vector<string> &strmeta_value,
string &total_strmeta_value) {
1340 int strmeta_num = -1;
1344 for (hsize_t i = 0; i < nelems; i++) {
1351 if (((s_oname[i].find(
"StructMetadata"))!=0) && ((s_oname[i].find(
"structmetadata"))!=0))
1355 hid_t s_dset_id = -1;
1356 hid_t s_space_id = -1;
1358 hssize_t s_nelms = -1;
1359 size_t dtype_size = -1;
1361 if ((s_dset_id = H5Dopen(ecs_grp_id,s_oname[i].c_str(),H5P_DEFAULT))<0){
1362 string msg =
"Cannot open HDF5 dataset ";
1364 H5Gclose(ecs_grp_id);
1365 throw InternalErr(__FILE__, __LINE__, msg);
1368 if ((s_space_id = H5Dget_space(s_dset_id))<0) {
1369 string msg =
"Cannot open the data space of HDF5 dataset ";
1371 H5Dclose(s_dset_id);
1372 H5Gclose(ecs_grp_id);
1373 throw InternalErr(__FILE__, __LINE__, msg);
1376 if ((s_ty_id = H5Dget_type(s_dset_id)) < 0) {
1377 string msg =
"Cannot get the data type of HDF5 dataset ";
1379 H5Sclose(s_space_id);
1380 H5Dclose(s_dset_id);
1381 H5Gclose(ecs_grp_id);
1382 throw InternalErr(__FILE__, __LINE__, msg);
1385 if ((s_nelms = H5Sget_simple_extent_npoints(s_space_id))<0) {
1386 string msg =
"Cannot get the number of points of HDF5 dataset ";
1389 H5Sclose(s_space_id);
1390 H5Dclose(s_dset_id);
1391 H5Gclose(ecs_grp_id);
1392 throw InternalErr(__FILE__, __LINE__, msg);
1395 if ((dtype_size = H5Tget_size(s_ty_id))==0) {
1397 string msg =
"Cannot get the data type size of HDF5 dataset ";
1400 H5Sclose(s_space_id);
1401 H5Dclose(s_dset_id);
1402 H5Gclose(ecs_grp_id);
1403 throw InternalErr(__FILE__, __LINE__, msg);
1407 vector<char> s_buf(dtype_size*s_nelms +1);
1409 if ((H5Dread(s_dset_id,s_ty_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,
1412 string msg =
"Cannot read HDF5 dataset ";
1415 H5Sclose(s_space_id);
1416 H5Dclose(s_dset_id);
1417 H5Gclose(ecs_grp_id);
1418 throw InternalErr(__FILE__, __LINE__, msg);
1423 H5Sclose(s_space_id);
1424 H5Dclose(s_dset_id);
1427 string tempstr(s_buf.begin(),s_buf.end());
1429 size_t temp_null_pos = tempstr.find_first_of(
'\0');
1434 string finstr = tempstr.substr(0,temp_null_pos);
1436 if (
true == smetatype[i]) {
1437 strmeta_num = obtain_struct_metadata_value_internal(ecs_grp_id, s_oname, strmeta_value,total_strmeta_value,
1446int obtain_struct_metadata_value_internal(hid_t ecs_grp_id,
const vector<string> &s_oname,
1447 vector<string> &strmeta_value,
string &total_strmeta_value,
1448 const string &finstr, hsize_t i)
1450 int strmeta_num = -1;
1454 strmeta_num = get_strmetadata_num(s_oname[i]);
1457 H5Gclose(ecs_grp_id);
1458 throw InternalErr(__FILE__,__LINE__,
"Obtain structmetadata suffix error.");
1465 if (-1 == strmeta_num)
1466 total_strmeta_value = finstr;
1468 else if (strmeta_value[strmeta_num].empty() ==
false) {
1469 string msg =
"The structmeta value array at this index should be empty string ";
1470 H5Gclose(ecs_grp_id);
1471 throw InternalErr(__FILE__, __LINE__, msg);
1475 strmeta_value[strmeta_num] = finstr;
1481int get_strmetadata_num(
const string & meta_str) {
1483 size_t dot_pos = meta_str.find(
".");
1484 if (dot_pos == string::npos)
1487 string num_str = meta_str.substr(dot_pos+1);
1488 stringstream ssnum(num_str);
1492 throw InternalErr(__FILE__,__LINE__,
"Suffix after dots is not a number.");
1499 unordered_map<string, vector<string>> varpath_to_dims;
1500 unordered_map<string, vector<HE5Dim>> grppath_to_dims;
1501 unordered_map<string, eos5_grid_info_t> gridname_to_info;
1508 he5dds_scan_string(st_str.c_str());
1510 he5ddslex_destroy();
1513 p.add_projparams(st_str);
1520 if (c.check_grids_unknown_parameters(&p)) {
1521 throw InternalErr(
"Unknown HDF-EOS5 grid paramters found in the file");
1524 if (c.check_grids_missing_projcode(&p)) {
1525 throw InternalErr(
"The HDF-EOS5 is missing project code ");
1529 if (c.check_grids_support_projcode(&p)) {
1530 throw InternalErr(
"The current project code is not supported");
1534 c.set_grids_missing_pixreg_orig(&p);
1536 for (
const auto &sw:p.swath_list)
1537 build_grp_dim_path(sw.name,sw.dim_list,grppath_to_dims,HE5_TYPE::SW);
1539 for (
const auto &sw:p.swath_list)
1540 build_var_dim_path(sw.name,sw.data_var_list,varpath_to_dims,HE5_TYPE::SW,
false);
1542 for (
const auto &sw:p.swath_list)
1543 build_var_dim_path(sw.name,sw.geo_var_list,varpath_to_dims,HE5_TYPE::SW,
true);
1545 for (
const auto &gd:p.grid_list)
1546 build_grp_dim_path(gd.name,gd.dim_list,grppath_to_dims,HE5_TYPE::GD);
1548 for (
const auto &gd:p.grid_list)
1549 build_var_dim_path(gd.name,gd.data_var_list,varpath_to_dims,HE5_TYPE::GD,
false);
1551 for (
const auto &gd:p.grid_list)
1552 build_gd_info(gd, gridname_to_info);
1554 for (
const auto &za:p.za_list)
1555 build_grp_dim_path(za.name,za.dim_list,grppath_to_dims,HE5_TYPE::ZA);
1557 for (
const auto &za:p.za_list)
1558 build_var_dim_path(za.name,za.data_var_list,varpath_to_dims,HE5_TYPE::ZA,
false);
1562for (
const auto& it:varpath_to_dims) {
1563 cout<<
"var path is "<<it.first <<endl;
1564 for (
const auto &sit:it.second)
1565 cout<<
"var dimension name is "<<sit <<endl;
1568for (
const auto& it:grppath_to_dims) {
1569 cout<<
"grp path is "<<it.first <<endl;
1570 for (
const auto &sit:it.second) {
1571 cout<<
"grp dimension name is "<<sit.name<<endl;
1572 cout<<
"grp dimension size is "<<sit.size<<endl;
1576for (
const auto &it:gridname_to_info) {
1577 cout<<
"grid name is "<<it.first <<endl;
1578 cout<<
"grid x dimension name is "<<it.second.xdim_fqn <<
" and the size is: "<< it.second.xdim_size << endl;
1579 cout<<
"grid y dimension name is "<<it.second.ydim_fqn <<
" and the size is: "<< it.second.ydim_size << endl;
1583 eos5_dim_info.varpath_to_dims = varpath_to_dims;
1584 eos5_dim_info.grppath_to_dims = grppath_to_dims;
1585 eos5_dim_info.gridname_to_info = gridname_to_info;
1588void build_grp_dim_path(
const string & eos5_obj_name,
const vector<HE5Dim>& dim_list, unordered_map<
string,
1589 vector<HE5Dim>>& grppath_to_dims, HE5_TYPE e5_type) {
1591 string eos_name_prefix =
"/HDFEOS/";
1592 string eos5_grp_path;
1596 eos5_grp_path = eos_name_prefix +
"SWATHS/" + eos5_obj_name;
1599 eos5_grp_path = eos_name_prefix +
"GRIDS/" + eos5_obj_name;
1602 eos5_grp_path = eos_name_prefix +
"ZAS/" + eos5_obj_name;
1609 for (
const auto & eos5dim:dim_list) {
1610 cout <<
"EOS5 Dim Name=" << eos5dim.name << endl;
1611 cout <<
"EOS5 Dim Size=" << eos5dim.size << endl;
1615 vector <HE5Dim> grp_dims;
1616 for (
const auto &eos5dim:dim_list) {
1620 if (eos5dim.name ==
"Unlimited" && eos5dim.size == -1)
1624 string new_eos5dim_name = eos5dim.name;
1626 string dim_fpath = eos5_grp_path +
"/" + handle_string_special_characters(new_eos5dim_name);
1627 eos5_dimp.name = dim_fpath;
1628 eos5_dimp.size = eos5dim.size;
1629 grp_dims.push_back(eos5_dimp);
1632 pair<string,vector<HE5Dim>> gtod = make_pair(eos5_grp_path,grp_dims);
1633 grppath_to_dims.insert(gtod);
1637void build_var_dim_path(
const string & eos5_obj_name,
const vector<HE5Var>& var_list, unordered_map<
string,
1638 vector<string>>& varpath_to_dims, HE5_TYPE e5_type,
bool is_geo) {
1640 string eos_name_prefix =
"/HDFEOS/";
1641 string eos5_data_grp_name =
"/Data Fields/";
1642 string eos5_geo_grp_name =
"/Geolocation Fields/";
1643 string eos5_dim_name_prefix;
1644 string new_eos5_obj_name = eos5_obj_name;
1648 eos5_dim_name_prefix = eos_name_prefix +
"SWATHS/"+handle_string_special_characters(new_eos5_obj_name) +
"/";
1651 eos5_dim_name_prefix = eos_name_prefix +
"GRIDS/"+handle_string_special_characters(new_eos5_obj_name) +
"/";
1654 eos5_dim_name_prefix = eos_name_prefix +
"ZAS/"+handle_string_special_characters(new_eos5_obj_name) +
"/";
1662 for (
const auto & eos5var:var_list) {
1665 vector<string> var_dim_names;
1672 var_path = eos_name_prefix +
"SWATHS/"+eos5_obj_name + eos5_geo_grp_name + eos5var.name;
1674 var_path = eos_name_prefix +
"SWATHS/"+eos5_obj_name + eos5_data_grp_name + eos5var.name;
1680 var_path = eos_name_prefix +
"GRIDS/"+eos5_obj_name + eos5_data_grp_name + eos5var.name;
1686 var_path = eos_name_prefix +
"ZAS/"+eos5_obj_name + eos5_data_grp_name + eos5var.name;
1694cout <<
"var_path is "<<var_path <<endl;
1695 for (
const auto &eos5dim:eos5var.dim_list) {
1696 cout <<
"EOS Var Dim Name=" << eos5dim.name << endl;
1699 for (
const auto &eos5dim:eos5var.dim_list) {
1700 string new_eos5dim_name = eos5dim.name;
1701 string dim_fpath = eos5_dim_name_prefix + handle_string_special_characters(new_eos5dim_name);
1702 var_dim_names.push_back(dim_fpath);
1704 pair<string,vector<string>> vtod = make_pair(var_path,var_dim_names);
1705 varpath_to_dims.insert(vtod);
1710bool obtain_eos5_dim(
const string & varname,
const unordered_map<
string, vector<string>>& varpath_to_dims,
1711 vector<string> & dimnames) {
1713 bool ret_value =
false;
1714 unordered_map<string,vector<string>>::const_iterator vit = varpath_to_dims.find(varname);
1715 if (vit != varpath_to_dims.end()){
1716 for (
const auto &sit:vit->second)
1717 dimnames.push_back(HDF5CFUtil::obtain_string_after_lastslash(sit));
1724bool obtain_eos5_grp_dim(
const string & grpname,
const unordered_map<
string, vector<HE5Dim>>& grppath_to_dims,
1725 vector<string> & dimnames) {
1727 bool ret_value =
false;
1728 unordered_map<string,vector<HE5Dim>>::const_iterator vit = grppath_to_dims.find(grpname);
1729 if (vit != grppath_to_dims.end()){
1730 for (
const auto &sit:vit->second)
1731 dimnames.push_back(HDF5CFUtil::obtain_string_after_lastslash(sit.name));
1737hsize_t obtain_unlim_pure_dim_size(hid_t pid,
const string &dname) {
1739 hsize_t ret_value = 0;
1742 if((dset_id = H5Dopen(pid,dname.c_str(),H5P_DEFAULT)) <0) {
1743 string msg =
"cannot open the HDF5 dataset ";
1745 throw InternalErr(__FILE__, __LINE__, msg);
1748 htri_t has_reference_list = -1;
1749 string reference_name=
"REFERENCE_LIST";
1750 has_reference_list = H5Aexists(dset_id,reference_name.c_str());
1752 if (has_reference_list > 0)
1753 ret_value = obtain_unlim_pure_dim_size_internal(dset_id, dname, reference_name);
1755 if (H5Dclose(dset_id) <0) {
1756 string msg =
"cannot close the HDF5 dataset ";
1758 throw InternalErr(__FILE__, __LINE__, msg);
1764hsize_t obtain_unlim_pure_dim_size_internal(hid_t dset_id,
const string &dname,
const string &reference_name) {
1766 hsize_t ret_value = 0;
1768 hid_t attr_id = H5Aopen(dset_id,reference_name.c_str(),H5P_DEFAULT);
1771 string msg =
"Cannot open the attribute " + reference_name +
" of HDF5 dataset "+ dname;
1772 throw InternalErr(__FILE__, __LINE__, msg);
1775 hid_t atype_id = H5Aget_type(attr_id);
1779 string msg =
"Cannot get the datatype of the attribute " + reference_name +
" of HDF5 dataset "+ dname;
1780 throw InternalErr(__FILE__, __LINE__, msg);
1783 if (H5T_COMPOUND == H5Tget_class(atype_id))
1784 ret_value = obtain_unlim_pure_dim_size_internal_value(dset_id, attr_id, atype_id, reference_name, dname);
1792hsize_t obtain_unlim_pure_dim_size_internal_value(hid_t dset_id, hid_t attr_id, hid_t atype_id,
1793 const string &reference_name,
const string &dname) {
1795 typedef struct s_t {
1800 hsize_t ret_value = 0;
1801 hid_t aspace_id = H5Aget_space(attr_id);
1802 if (aspace_id < 0) {
1806 string msg =
"Cannot obtain the data space ID for the attribute " + reference_name;
1807 throw InternalErr(__FILE__, __LINE__, msg);
1810 hssize_t num_ele_ref = H5Sget_simple_extent_npoints(aspace_id);
1811 if (num_ele_ref < 0) {
1815 string msg =
"Cannot obtain the number of elements for space of the attribute " + reference_name;
1816 throw InternalErr(__FILE__, __LINE__, msg);
1819 size_t ele_size = H5Tget_size(atype_id);
1820 if (ele_size == 0) {
1824 string msg =
"Cannot obtain the datatype size of the attribute " + reference_name;
1825 throw InternalErr(__FILE__, __LINE__, msg);
1828 if (
sizeof(s_t)!=ele_size) {
1832 string msg =
"The data type size is not the same as the struct. ";
1833 throw InternalErr(__FILE__, __LINE__, msg);
1835 vector<s_t> ref_list(num_ele_ref);
1837 if (H5Aread(attr_id,atype_id,ref_list.data()) <0) {
1841 string msg =
"Cannot obtain the referenced object for the variable " + dname;
1842 throw InternalErr(__FILE__, __LINE__, msg);
1848 H5O_type_t obj_type;
1849 if (H5Rget_obj_type2(dset_id, H5R_OBJECT, &((ref_list[0]).s_ref),&obj_type) <0) {
1853 string msg =
"Cannot obtain the referenced object for the variable " + dname;
1854 throw InternalErr(__FILE__, __LINE__, msg);
1857 if (obj_type == H5O_TYPE_DATASET) {
1859 hid_t did_ref = H5Rdereference2(dset_id, H5P_DEFAULT, H5R_OBJECT, &((ref_list[0]).s_ref));
1864 string msg =
"Cannot de-reference the object for the variable " + dname;
1865 throw InternalErr(__FILE__, __LINE__, msg);
1868 hid_t did_space = H5Dget_space(did_ref);
1869 if (did_space < 0) {
1874 string msg =
"Cannot open the space of the de-referenced object for the variable " + dname;
1875 throw InternalErr(__FILE__, __LINE__, msg);
1879 if (H5Sget_simple_extent_type(did_space) != H5S_SIMPLE) {
1882 H5Sclose(did_space);
1885 string msg =
"The dataspace must be a simple HDF5 dataspace for the variable " + dname;
1886 throw InternalErr(__FILE__, __LINE__, msg);
1889 int did_space_num_dims = H5Sget_simple_extent_ndims(did_space);
1890 if (did_space_num_dims <0) {
1893 H5Sclose(did_space);
1896 string msg =
"The number of dimensions must be > 0 for the variable " + dname;
1897 throw InternalErr(__FILE__, __LINE__, msg);
1899 vector<hsize_t> did_dims(did_space_num_dims);
1900 vector<hsize_t> did_max_dims(did_space_num_dims);
1902 if (H5Sget_simple_extent_dims(did_space,did_dims.data(),did_max_dims.data()) <0) {
1905 H5Sclose(did_space);
1908 string msg =
"Cannot obtain the dimension information for the variable " + dname;
1909 throw InternalErr(__FILE__, __LINE__, msg);
1912 hsize_t cur_unlimited_dim_size = 0;
1914 int num_unlimited_dims = 0;
1915 for (
unsigned i = 0; i<did_space_num_dims; i++) {
1916 if (did_max_dims[i] == H5S_UNLIMITED) {
1917 cur_unlimited_dim_size = did_dims[i];
1918 num_unlimited_dims++;
1921 if (num_unlimited_dims >1)
1922 throw InternalErr(__FILE__,__LINE__,
"This variable has more than 1 unlimited dimensions. This is not supported.");
1924 ret_value = cur_unlimited_dim_size;
1927 H5Sclose(did_space);
1930 H5Sclose(aspace_id);
1941 unordered_map<string, Array*> dsname_array_maps;
1942 obtain_ds_name_array_maps(d4_root,dsname_array_maps, handled_all_cv_names);
1946 unordered_map<string, Array*> coname_array_maps;
1948 Constructor::Vars_iter vi = d4_root->var_begin();
1949 Constructor::Vars_iter ve = d4_root->var_end();
1951 for (; vi != ve; vi++) {
1953 const BaseType *v = *vi;
1956 if (libdap::dods_array_c == v->type()) {
1958 auto t_a =
dynamic_cast<Array *
>(*vi);
1960 vector<string> coord_names;
1961 unordered_set<string> handled_dim_names;
1962 obtain_coord_names(t_a,coord_names);
1965 if (coord_names.empty()==
false) {
1966 make_coord_names_fpath(d4_root,coord_names);
1967 remove_empty_coord_names(coord_names);
1968 add_coord_maps(d4_root,t_a,coord_names,coname_array_maps,handled_dim_names);
1969 add_dimscale_maps(t_a,dsname_array_maps,handled_dim_names);
1972 add_dimscale_maps(t_a,dsname_array_maps,handled_dim_names);
1978 for (D4Group::groupsIter gi = d4_root->grp_begin(), ge = d4_root->grp_end(); gi != ge; ++gi)
1979 add_dap4_coverage_default_internal(*gi, dsname_array_maps,coname_array_maps);
1983 for (
auto &ds_map:dsname_array_maps) {
1985 D4Maps *d4_maps = (ds_map.second)->maps();
1986 size_t d4map_size = d4_maps->size();
1987 while (d4map_size != 0) {
1988 D4Map * d4_map = d4_maps->get_map(0);
1989 d4_maps->remove_map(d4_map);
1991 d4map_size = d4_maps->size();
1996 for (
auto &cv_map:coname_array_maps) {
1998 D4Maps *d4_maps = (cv_map.second)->maps();
1999 size_t d4map_size = d4_maps->size();
2000 while (d4map_size != 0) {
2001 D4Map * d4_map = d4_maps->get_map(0);
2002 d4_maps->remove_map(d4_map);
2004 d4map_size = d4_maps->size();
2011 map<string,Array*> ordered_dc_co_array_maps;
2012 map<string,Array*> ordered_coname_array_maps;
2016 for (
const auto &dsname_array_map:dsname_array_maps) {
2018 bool found_coname =
false;
2019 for (
const auto &coname_array_map:coname_array_maps) {
2020 if (coname_array_map.first == dsname_array_map.first) {
2021 found_coname =
true;
2026 if (found_coname ==
false)
2027 ordered_dc_co_array_maps.insert(dsname_array_map);
2030 for (
const auto &coname_array_map:coname_array_maps)
2031 ordered_coname_array_maps.insert(coname_array_map);
2033 reorder_vars(d4_root,ordered_coname_array_maps,ordered_dc_co_array_maps);
2037void add_dap4_coverage_default_internal(D4Group* d4_grp, unordered_map<string, Array*> &dsname_array_maps,
2038 unordered_map<string, Array*> &coname_array_maps) {
2041 Constructor::Vars_iter vi = d4_grp->var_begin();
2042 Constructor::Vars_iter ve = d4_grp->var_end();
2044 for (; vi != ve; vi++) {
2046 const BaseType *v = *vi;
2049 if (libdap::dods_array_c == v->type()) {
2051 auto t_a =
dynamic_cast<Array *
>(*vi);
2053 vector<string> coord_names;
2054 unordered_set<string> handled_dim_names;
2057 obtain_coord_names(t_a,coord_names);
2059 if (coord_names.empty()==
false) {
2062 make_coord_names_fpath(d4_grp,coord_names);
2063 remove_empty_coord_names(coord_names);
2066 add_coord_maps(d4_grp,t_a,coord_names,coname_array_maps,handled_dim_names);
2069 add_dimscale_maps(t_a,dsname_array_maps,handled_dim_names);
2072 add_dimscale_maps(t_a,dsname_array_maps,handled_dim_names);
2079 for (D4Group::groupsIter gi = d4_grp->grp_begin(), ge = d4_grp->grp_end(); gi != ge; ++gi)
2080 add_dap4_coverage_default_internal(*gi, dsname_array_maps, coname_array_maps);
2084void obtain_coord_names(Array* ar, vector<string> & coord_names) {
2086 D4Attributes *d4_attrs = ar->attributes();
2087 D4Attribute *d4_attr = d4_attrs->find(
"coordinates");
2088 if (d4_attr !=
nullptr && d4_attr->type() == attr_str_c) {
2089 if (d4_attr->num_values() == 1) {
2090 string tempstring = d4_attr->value(0);
2092 HDF5CFUtil::Split_helper(coord_names,tempstring,sep);
2097 obtain_multi_string_coord_names(d4_attr, coord_names);
2101void obtain_multi_string_coord_names(D4Attribute *d4_attr, vector<string> & coord_names) {
2103 for (D4Attribute::D4AttributeIter av_i = d4_attr->value_begin(), av_e = d4_attr->value_end(); av_i != av_e; av_i++) {
2104 vector <string> tempstr_vec;
2106 HDF5CFUtil::Split_helper(tempstr_vec,*av_i,sep);
2107 for (
const auto &tve:tempstr_vec)
2108 coord_names.push_back(tve);
2112void make_coord_names_fpath(D4Group* d4_grp, vector<string> &coord_names) {
2114 for (
auto &cname:coord_names) {
2117 if (cname.find(
'/')==string::npos) {
2118 if (
false == obtain_no_path_cv(d4_grp,cname))
2121 else if(cname[0] ==
'/')
2122 handle_absolute_path_cv(d4_grp,cname);
2124 handle_relative_path_cv(d4_grp, cname);
2132bool obtain_no_path_cv(D4Group *d4_grp,
string &coord_name) {
2134 bool found_cv =
false;
2136 Constructor::Vars_iter vi = d4_grp->var_begin();
2137 Constructor::Vars_iter ve = d4_grp->var_end();
2139 for (; vi != ve; vi++) {
2141 const BaseType *v = *vi;
2144 if (libdap::dods_array_c == v->type()) {
2146 auto t_a =
dynamic_cast<Array *
>(*vi);
2147 if (coord_name == t_a->name()) {
2149 coord_name = t_a->FQN();
2156 if (found_cv ==
false && (d4_grp->get_parent())){
2157 auto d4_grp_par =
dynamic_cast<D4Group*
>(d4_grp->get_parent());
2158 found_cv = obtain_no_path_cv(d4_grp_par,coord_name);
2163void handle_absolute_path_cv(
const D4Group *d4_grp,
string &coord_name) {
2167 string d4_grp_fqn = d4_grp->FQN();
2168 string cv_path = HDF5CFUtil::obtain_string_before_lastslash(coord_name);
2169 if (d4_grp_fqn.find(cv_path) != 0)
2175void handle_relative_path_cv(
const D4Group *d4_grp,
string &coord_name) {
2182 bool find_coord =
true;
2184 unsigned short sep_count = 0;
2185 size_t pos = coord_name.find(sep, 0);
2189 while(pos != string::npos)
2192 size_t temp_pos = pos;
2193 pos = coord_name.find(sep,pos+1);
2195 if ((pos !=string::npos) && (pos !=(temp_pos+3))) {
2204 handle_relative_path_cvname_internal(d4_grp, coord_name, sep_count);
2208void handle_relative_path_cvname_internal(
const D4Group *d4_grp,
string &coord_name,
unsigned short sep_count) {
2211 string grp_fqn = d4_grp->FQN();
2213 size_t co_path_pos = 0;
2215 size_t var_back_st_pos = grp_fqn.size()-1;
2216 if (var_back_st_pos >0)
2220 for (
size_t i =var_back_st_pos; i >=0;i--) {
2221 if (grp_fqn[i] ==
'/') {
2223 if(sep_count == 0) {
2230 if (sep_count > 0) {
2237 string the_path = grp_fqn.substr(0,co_path_pos+1);
2238 string the_name = HDF5CFUtil::obtain_string_after_lastslash(coord_name);
2239 coord_name = the_path + the_name;
2243void remove_empty_coord_names(vector<string> & coord_names) {
2245 for (
auto it = coord_names.begin(); it !=coord_names.end();) {
2247 it = coord_names.erase(it);
2256void obtain_ds_name_array_maps(D4Group *d4_grp,unordered_map<string,Array*>&dsn_array_maps,
2257 const vector<string>& handled_all_cv_names) {
2260 Constructor::Vars_iter vi = d4_grp->var_begin();
2261 Constructor::Vars_iter ve = d4_grp->var_end();
2263 for (; vi != ve; vi++) {
2264 const BaseType *v = *vi;
2267 if (libdap::dods_array_c == v->type())
2268 obtain_ds_name_array_maps_internal(*vi, dsn_array_maps, handled_all_cv_names);
2271 for (D4Group::groupsIter gi = d4_grp->grp_begin(), ge = d4_grp->grp_end(); gi != ge; ++gi) {
2272 BESDEBUG(
"h5",
"In group: " << (*gi)->name() << endl);
2273 obtain_ds_name_array_maps(*gi, dsn_array_maps, handled_all_cv_names);
2278void obtain_ds_name_array_maps_internal(BaseType *v, unordered_map<string,Array*>&dsn_array_maps,
2279 const vector<string>& handled_all_cv_names)
2281 auto t_a =
dynamic_cast<Array *
>(v);
2285 if (t_a->dimensions() == 1) {
2286 string t_a_fqn = t_a->FQN();
2287 if (find(handled_all_cv_names.begin(),handled_all_cv_names.end(),t_a_fqn) != handled_all_cv_names.end())
2288 dsn_array_maps.emplace(t_a_fqn,t_a);
2294void add_coord_maps(D4Group *d4_grp, Array *var, vector<string> &coord_names,
2295 unordered_map<string,Array*> & coname_array_maps,
2296 unordered_set<string> & handled_dim_names) {
2300 for (
auto cv_it =coord_names.begin(); cv_it != coord_names.end();) {
2302 unordered_map<string, Array*>::const_iterator it_ma = coname_array_maps.find(*cv_it);
2303 if (it_ma != coname_array_maps.end()) {
2305 auto d4_map_unique = make_unique<D4Map>(it_ma->first, it_ma->second);
2306 D4Map *d4_map = d4_map_unique.release();
2308 var->maps()->add_map(d4_map);
2312 obtain_handled_dim_names(it_ma->second,handled_dim_names);
2316 cv_it = coord_names.erase(cv_it);
2324 for (
auto cv_it =coord_names.begin(); cv_it != coord_names.end();) {
2326 bool found_cv =
false;
2327 Constructor::Vars_iter vi = d4_grp->var_begin();
2328 Constructor::Vars_iter ve = d4_grp->var_end();
2330 for (; vi != ve; vi++) {
2332 const BaseType *v = *vi;
2337 if (libdap::dods_array_c == v->type()) {
2339 auto t_a =
dynamic_cast<Array *
>(*vi);
2342 if (*cv_it == t_a->FQN()) {
2345 auto d4_map =
new D4Map(t_a->FQN(), t_a);
2346 var->maps()->add_map(d4_map);
2349 coname_array_maps.emplace(t_a->FQN(),t_a);
2353 obtain_handled_dim_names(t_a,handled_dim_names);
2363 cv_it = coord_names.erase(cv_it);
2369 if (coord_names.empty() ==
false && d4_grp->get_parent()) {
2370 auto d4_grp_par =
dynamic_cast<D4Group*
>(d4_grp->get_parent());
2371 add_coord_maps(d4_grp_par,var,coord_names,coname_array_maps,handled_dim_names);
2379void add_dimscale_maps(libdap::Array* var, std::unordered_map<std::string,libdap::Array*> & dc_array_maps,
2380 const std::unordered_set<std::string> & handled_dim_names) {
2382 BESDEBUG(
"h5",
"Coming to add_dimscale_maps() "<<endl);
2384 Array::Dim_iter di = var->dim_begin();
2385 Array::Dim_iter de = var->dim_end();
2387 for (; di != de; di++) {
2389 const D4Dimension * d4_dim = var->dimension_D4dim(di);
2395 string dim_fqn = d4_dim->fully_qualified_name();
2399 if (handled_dim_names.find(dim_fqn) == handled_dim_names.end()) {
2401 unordered_map<string, Array*>::const_iterator it_ma = dc_array_maps.find(dim_fqn);
2404 if (it_ma != dc_array_maps.end()) {
2405 auto d4_map =
new D4Map(it_ma->first, it_ma->second);
2406 var->maps()->add_map(d4_map);
2415void obtain_handled_dim_names(Array *var, unordered_set<string> & handled_dim_names) {
2417 Array::Dim_iter di = var->dim_begin();
2418 Array::Dim_iter de = var->dim_end();
2420 for (; di != de; di++) {
2421 const D4Dimension * d4_dim = var->dimension_D4dim(di);
2423 handled_dim_names.insert(d4_dim->fully_qualified_name());
2427void reorder_vars(D4Group *d4_grp,
const map<string,Array*> &coname_array_maps,
2428 const map<string,Array*> & dc_array_maps) {
2430 Constructor::Vars_iter vi = d4_grp->var_begin();
2431 Constructor::Vars_iter ve = d4_grp->var_end();
2434 vector<BaseType *> cv_obj_ptr;
2437 for (; vi != ve; vi++) {
2442 if (libdap::dods_array_c == v->type()) {
2445 for (
const auto &coname_array_map:coname_array_maps) {
2446 if (coname_array_map.first == v->FQN()) {
2447 cv_pos.push_back(v_index);
2448 cv_obj_ptr.push_back(v);
2451 for (
const auto &dc_array_map:dc_array_maps) {
2452 if (dc_array_map.first == v->FQN()) {
2453 cv_pos.push_back(v_index);
2454 cv_obj_ptr.push_back(v);
2463for (
const auto &cv_p:cv_pos)
2464cerr<<
": "<<cv_p <<endl;
2466for (
const auto &cv_obj_p:cv_obj_ptr)
2467cerr<<
"name: "<<cv_obj_p->FQN() <<endl;
2475 vector<BaseType *>front_v_ptr;
2476 auto stop_index = (
int)(cv_pos.size());
2481 reorder_vars_internal(d4_grp, cv_pos, cv_obj_ptr, stop_index);
2485 for (D4Group::groupsIter gi = d4_grp->grp_begin(), ge = d4_grp->grp_end(); gi != ge; ++gi)
2486 reorder_vars(*gi, coname_array_maps, dc_array_maps);
2490void reorder_vars_internal(D4Group* d4_grp,
const vector<int> &cv_pos,
const vector<BaseType *>& cv_obj_ptr,
int stop_index) {
2491 Constructor::Vars_iter vi = d4_grp->var_begin();
2492 Constructor::Vars_iter ve = d4_grp->var_end();
2493 vi = d4_grp->var_begin();
2494 ve = d4_grp->var_end();
2497 vector<BaseType *> front_v_ptr;
2499 for (; vi != ve; vi++) {
2501 front_v_ptr.push_back(v);
2503 if (v_index == stop_index)
2513 vector<int> overlap_cv_pos;
2514 vector<int> overlap_front_pos;
2515 for (
int i = 0; i < stop_index; i++) {
2516 for (
int j = 0; j < stop_index; j++) {
2517 if (i == cv_pos[j]) {
2518 overlap_cv_pos.push_back(cv_pos[j]);
2519 overlap_front_pos.push_back(i);
2529 vector<int> mov_cv_pos;
2530 vector<BaseType *> mov_cv_ptr;
2531 for (
int i = 0; i < stop_index; i++) {
2532 bool overlapped_cv =
false;
2533 for (
const auto &overlap_cv_p: overlap_cv_pos) {
2534 if (cv_pos[i] == overlap_cv_p) {
2535 overlapped_cv =
true;
2539 if (overlapped_cv ==
false) {
2540 mov_cv_pos.push_back(cv_pos[i]);
2541 mov_cv_ptr.push_back(cv_obj_ptr[i]);
2546 vector<int> mov_front_pos;
2547 vector<BaseType *> mov_front_v_ptr;
2548 for (
int i = 0; i < stop_index; i++) {
2549 bool overlapped_front_cv =
false;
2550 for (
const auto &overlap_front_p: overlap_front_pos) {
2551 if (i == overlap_front_p) {
2552 overlapped_front_cv =
true;
2556 if (overlapped_front_cv ==
false) {
2557 mov_front_pos.push_back(i);
2558 mov_front_v_ptr.push_back(front_v_ptr[i]);
2562 reorder_vars_internal_final_phase(d4_grp, mov_cv_pos, mov_front_pos, mov_front_v_ptr, mov_cv_ptr);
2566void reorder_vars_internal_final_phase(D4Group* d4_grp,
const vector<int> &mov_cv_pos,
2567 const vector<int> &mov_front_pos,
const vector<BaseType *> &mov_front_v_ptr,
2568 const vector<BaseType *> &mov_cv_ptr) {
2571 if (mov_cv_pos.size() != mov_front_pos.size()) {
2572 string err_msg =
"The number of moved coordinate variables is not the same as ";
2573 err_msg +=
"the number of moved non-coordinate variables";
2574 throw InternalErr(__FILE__, __LINE__, err_msg);
2579 for (
int i = 0; i <mov_cv_pos.size();i++) {
2580 cerr<<
"mov_front_pos: "<<mov_front_pos[i] <<endl;
2581 cerr<<
"mov_cv_pos: "<<mov_cv_pos[i] <<endl;
2586 for (
unsigned int i = 0; i < mov_front_pos.size(); i++) {
2587 d4_grp->set_var_index(mov_cv_ptr[i], mov_front_pos[i]);
2588 d4_grp->set_var_index(mov_front_v_ptr[i], mov_cv_pos[i]);
2594bool is_cvar(
const BaseType *v,
const unordered_map<string,Array*> &coname_array_maps,
const unordered_map<string,Array*> & dc_array_maps) {
2596 bool ret_value =
false;
2597 unordered_map<string, Array*>::const_iterator it_ma = coname_array_maps.find(v->FQN());
2598 if (it_ma != coname_array_maps.end())
2601 it_ma = dc_array_maps.find(v->FQN());
2602 if (it_ma != dc_array_maps.end())
2609void add_possible_eos5_grid_vars(D4Group* d4_grp,
eos5_dim_info_t &eos5_dim_info) {
2611 BESDEBUG(
"h5",
"coming to add_possible_eos5_grid_vars"<<endl);
2616for (
const auto & ed_info:eos5_dim_info.gridname_to_info) {
2617 cerr<<
"grid name: "<<ed_info.first <<endl;
2618 cerr<<
" projection: "<<ed_info.second.projection <<endl;
2619 cerr<<
" "<<
"xdim fqn:" << ed_info.second.xdim_fqn <<endl;
2620 cerr<<
" "<<
"ydim fqn:" << ed_info.second.ydim_fqn <<endl;
2621 cerr<<
" "<<
"xdim size:" << ed_info.second.xdim_size <<endl;
2622 cerr<<
" "<<
"ydim size:" << ed_info.second.ydim_size <<endl;
2623 cerr<<
" "<<
"xdim point_lower:" << ed_info.second.point_lower <<endl;
2624 cerr<<
" "<<
"xdim point_upper:" << ed_info.second.point_upper <<endl;
2625 cerr<<
" "<<
"xdim point_left:" << ed_info.second.point_lower <<endl;
2626 cerr<<
" "<<
"xdim point_right:" << ed_info.second.point_right <<endl;
2630for (
const auto & d_v_info:eos5_dim_info.dimpath_to_cvpath) {
2631 cerr<<
" dimension name 1" <<d_v_info.first.dpath0 <<endl;
2632 cerr<<
" dimension name 2" <<d_v_info.first.dpath1 <<endl;
2633 cerr<<
" cv name 1" <<d_v_info.second.vpath0 <<endl;
2634 cerr<<
" cv name 2" <<d_v_info.second.vpath1 <<endl;
2635 cerr<<
" cv name 3" <<d_v_info.second.cf_gmap_path <<endl;
2641 bool add_grid_var = is_eos5_grid_grp(d4_grp,eos5_dim_info,eg_info);
2643 if (add_grid_var && eg_info.projection == HE5_GCTP_GEO)
2644 add_eos5_grid_vars_geo(d4_grp, eg_info);
2645 else if (add_grid_var && (eg_info.projection == HE5_GCTP_SNSOID ||
2646 eg_info.projection == HE5_GCTP_PS ||
2647 eg_info.projection == HE5_GCTP_LAMAZ))
2648 add_eos5_grid_vars_non_geo(d4_grp, eos5_dim_info, eg_info);
2652void add_eos5_grid_vars_geo(D4Group* d4_grp,
const eos5_grid_info_t & eg_info) {
2654 BaseType *ar_bt_lat =
nullptr;
2655 BaseType *ar_bt_lon =
nullptr;
2661 auto ar_bt_lat_unique = make_unique<Float32>(
"YDim");
2662 ar_bt_lat = ar_bt_lat_unique.get();
2663 auto ar_lat_unique = make_unique<HDF5MissLLArray>(
true,
2668 ar_lat = ar_lat_unique.release();
2670 string ydimpath = d4_grp->FQN() +
"YDim";
2671 ar_lat->append_dim_ll(eg_info.ydim_size, ydimpath);
2673 auto d4_dim0_unique = make_unique<D4Dimension>(
"YDim", eg_info.ydim_size);
2674 auto d4_dim0 = d4_dim0_unique.release();
2675 (ar_lat->dim_begin())->dim = d4_dim0;
2678 D4Dimensions *dims = d4_grp->dims();
2679 dims->add_dim_nocopy(d4_dim0);
2681 auto ar_bt_lon_unique = make_unique<Float32>(
"XDim");
2683 ar_bt_lon = ar_bt_lon_unique.get();
2684 auto ar_lon_unique = make_unique<HDF5MissLLArray>(
2690 ar_lon = ar_lon_unique.release();
2692 string xdimpath = d4_grp->FQN() +
"XDim";
2693 ar_lon->append_dim_ll(eg_info.xdim_size, xdimpath);
2695 auto d4_dim1_unique = make_unique<D4Dimension>(
"XDim", eg_info.xdim_size);
2696 auto d4_dim1 = d4_dim1_unique.release();
2698 (ar_lon->dim_begin())->dim = d4_dim1;
2701 dims = d4_grp->dims();
2702 dims->add_dim_nocopy(d4_dim1);
2705 ar_lat->set_is_dap4(
true);
2706 ar_lon->set_is_dap4(
true);
2709 add_var_dap4_attr(ar_lat,
"units", attr_str_c,
"degrees_north");
2710 add_var_dap4_attr(ar_lon,
"units", attr_str_c,
"degrees_east");
2711 d4_grp->add_var_nocopy(ar_lat);
2712 d4_grp->add_var_nocopy(ar_lon);
2717 throw InternalErr(__FILE__, __LINE__,
"Unable to allocate the HDFMissLLArray instance.");
2724 BaseType *ar_bt_dim0 =
nullptr;
2725 BaseType *ar_bt_dim1 =
nullptr;
2729 BaseType *ar_bt_lat =
nullptr;
2730 BaseType *ar_bt_lon =
nullptr;
2735 string dummy_proj_cf_name =
"eos5_cf_projection";
2736 auto dummy_proj_cf_unique = make_unique<HDF5CFProj>(dummy_proj_cf_name, dummy_proj_cf_name);
2737 dummy_proj_cf = dummy_proj_cf_unique.release();
2738 dummy_proj_cf->set_is_dap4(
true);
2740 if (eg_info.projection == HE5_GCTP_SNSOID) {
2742 add_var_dap4_attr(dummy_proj_cf,
"grid_mapping_name", attr_str_c,
"sinusoidal");
2743 add_var_dap4_attr(dummy_proj_cf,
"longitude_of_central_meridian", attr_float64_c,
"0.0");
2744 add_var_dap4_attr(dummy_proj_cf,
"earth_radius", attr_float64_c,
"6371007.181");
2745 add_var_dap4_attr(dummy_proj_cf,
"_CoordinateAxisTypes", attr_str_c,
"GeoX GeoY");
2746 }
else if (eg_info.projection == HE5_GCTP_PS)
2747 add_ps_cf_grid_mapping_attrs(dummy_proj_cf, eg_info);
2748 else if (eg_info.projection == HE5_GCTP_LAMAZ)
2749 add_lamaz_cf_grid_mapping_attrs(dummy_proj_cf, eg_info);
2751 d4_grp->add_var_nocopy(dummy_proj_cf);
2753 auto ar_bt_dim1_unique = make_unique<Float64>(
"XDim");
2754 ar_bt_dim1 = ar_bt_dim1_unique.get();
2757 eg_info.xdim_size,
"XDim", ar_bt_dim1);
2758 ar_dim1 = ar_dim1_unique.release();
2761 string xdimpath = d4_grp->FQN() +
"XDim";
2762 ar_dim1->append_dim_ll(eg_info.xdim_size, xdimpath);
2765 auto d4_dim1_unique = make_unique<D4Dimension>(
"XDim", eg_info.xdim_size);
2766 auto d4_dim1 = d4_dim1_unique.release();
2768 (ar_dim1->dim_begin())->dim = d4_dim1;
2771 D4Dimensions *dims = d4_grp->dims();
2772 dims->add_dim_nocopy(d4_dim1);
2774 auto ar_bt_dim0_unique = make_unique<Float64>(
"YDim");
2775 ar_bt_dim0 = ar_bt_dim0_unique.get();
2777 auto ar_dim0_unique = make_unique<HDF5CFProj1D>
2779 ar_dim0 = ar_dim0_unique.release();
2781 string ydimpath = d4_grp->FQN() +
"YDim";
2782 ar_dim0->append_dim_ll(eg_info.ydim_size, ydimpath);
2785 auto d4_dim0_unique = make_unique<D4Dimension>(
"YDim", eg_info.ydim_size);
2786 auto d4_dim0 = d4_dim0_unique.release();
2788 (ar_dim0->dim_begin())->dim = d4_dim0;
2791 dims = d4_grp->dims();
2792 dims->add_dim_nocopy(d4_dim0);
2794 ar_dim1->set_is_dap4(
true);
2795 ar_dim0->set_is_dap4(
true);
2797 add_gm_spcvs_attrs(ar_dim0,
true);
2798 add_gm_spcvs_attrs(ar_dim1,
false);
2800 d4_grp->add_var_nocopy(ar_dim1);
2801 d4_grp->add_var_nocopy(ar_dim0);
2803 auto ar_bt_lat_unique = make_unique<Float64>(
"Latitude");
2804 ar_bt_lat = ar_bt_lat_unique.get();
2806 auto ar_lat_unique = make_unique<HDF5MissLLArray>(
true, 2, eg_info,
"Latitude", ar_bt_lat);
2807 ar_lat = ar_lat_unique.release();
2808 ar_lat->append_dim_ll(eg_info.ydim_size, ydimpath);
2809 ar_lat->append_dim_ll(eg_info.xdim_size, xdimpath);
2812 Array::Dim_iter d = ar_lat->dim_begin();
2816 add_var_dap4_attr(ar_lat,
"units", attr_str_c,
"degrees_north");
2818 auto ar_bt_lon_unique = make_unique<Float64>(
"Longitude");
2819 ar_bt_lon = ar_bt_lon_unique.get();
2821 auto ar_lon_unique = make_unique<HDF5MissLLArray>(
false,
2826 ar_lon = ar_lon_unique.release();
2827 ar_lon->append_dim_ll(eg_info.ydim_size, ydimpath);
2828 ar_lon->append_dim_ll(eg_info.xdim_size, xdimpath);
2830 add_var_dap4_attr(ar_lon,
"units", attr_str_c,
"degrees_east");
2832 d = ar_lon->dim_begin();
2837 ar_lat->set_is_dap4(
true);
2838 ar_lon->set_is_dap4(
true);
2840 d4_grp->add_var_nocopy(ar_lat);
2841 d4_grp->add_var_nocopy(ar_lon);
2846 edname_info.dpath0 = ydimpath;
2847 edname_info.dpath1 = xdimpath;
2848 ecname_info.vpath0 = d4_grp->FQN() +
"Latitude";
2849 ecname_info.vpath1 = d4_grp->FQN() +
"Longitude";
2850 ecname_info.cf_gmap_path = d4_grp->FQN() + dummy_proj_cf_name;
2852 pair<eos5_dname_info_t, eos5_cname_info_t> t_pair;
2853 t_pair = make_pair(edname_info, ecname_info);
2854 eos5_dim_info.dimpath_to_cvpath.push_back(t_pair);
2857 for (
const auto & d_v_info:eos5_dim_info.dimpath_to_cvpath) {
2858 cerr<<
" dimension name 1: " <<d_v_info.first.dpath0 <<endl;
2859 cerr<<
" dimension name 2: " <<d_v_info.first.dpath1 <<endl;
2860 cerr<<
" cv name 1: " <<d_v_info.second.vpath0 <<endl;
2861 cerr<<
" cv name 2: " <<d_v_info.second.vpath1 <<endl;
2862 cerr<<
" dummy cf projection var name: " <<d_v_info.second.cf_gmap_path <<endl;
2868 delete dummy_proj_cf;
2873 throw InternalErr(__FILE__, __LINE__,
"Unable to allocate the HDFMissLLArray instance.");
2879 bool ret_value =
false;
2880 string grp_fqn = d4_group->FQN();
2882 for (
const auto & ed_info:eos5_dim_info.gridname_to_info) {
2883 string eos_mod_path = handle_string_special_characters_in_path(ed_info.first);
2884 if (grp_fqn == (eos_mod_path +
"/")) {
2885 eg_info = ed_info.second;
2891 if (ret_value ==
true)
2892 ret_value = no_eos5_grid_vars_in_grp(d4_group, eg_info);
2897bool no_eos5_grid_vars_in_grp(D4Group *d4_group,
const eos5_grid_info_t &eg_info) {
2899 bool ret_value =
true;
2906 Constructor::Vars_iter vi = d4_group->var_begin();
2907 Constructor::Vars_iter ve = d4_group->var_end();
2909 for (; vi != ve; vi++) {
2911 const BaseType *v = *vi;
2912 string vname = v->name();
2913 if (eg_info.projection == HE5_GCTP_GEO) {
2914 if (vname ==
"YDim" || vname ==
"XDim") {
2921 if (vname ==
"YDim" || vname ==
"XDim" || vname ==
"Latitude" || vname ==
"Longitude"
2922 || vname ==
"eos5_cf_projection") {
2931void build_gd_info(
const HE5Grid &gd,unordered_map<string,eos5_grid_info_t>& gridname_to_info) {
2933 string grid_name =
"/HDFEOS/GRIDS/"+gd.name;
2935 eg_info.xdim_fqn = grid_name+
"/XDim";
2936 eg_info.ydim_fqn = grid_name+
"/YDim";
2938 bool find_xdim =
false;
2939 bool find_ydim =
false;
2948 for (
const auto &dim:gd.dim_list) {
2950 if ((dim.name ==
"XDim" || dim.name ==
"Xdim") && find_xdim ==
false) {
2951 eg_info.xdim_size = dim.size;
2954 else if ((dim.name ==
"YDim" || dim.name ==
"Ydim") && find_ydim ==
false) {
2955 eg_info.ydim_size = dim.size;
2959 if (find_xdim ==
true && find_ydim ==
true)
2964 if (find_xdim ==
true && find_ydim ==
true) {
2970 eg_info.pixelregistration = gd.pixelregistration;
2971 eg_info.gridorigin = gd.gridorigin;
2972 eg_info.projection = gd.projection;
2974 for (
int i = 0; i <13;i++)
2975 eg_info.param[i] = gd.param[i];
2977 eg_info.zone = gd.zone;
2978 eg_info.sphere = gd.sphere;
2979 gridname_to_info[grid_name] = eg_info;
2985 string dimname_list;
2986 for (
const auto &dim:gd.dim_list) {
2987 dimname_list += dim.name;
2988 dimname_list +=
" ";
2990 string err_msg =
"This HDF-EOS5 grid dimension list doesn't contain XDim, Xdim, YDim or Ydim.";
2991 err_msg +=
" The dimension names of this grid are: "+dimname_list;
2992 throw InternalErr(__FILE__,__LINE__,err_msg);
2998void add_ps_cf_grid_mapping_attrs(libdap::BaseType *var,
const eos5_grid_info_t & eg_info) {
3004 double vert_lon_pole = HE5_EHconvAng(eg_info.param[4],HE5_HDFE_DMS_DEG);
3007 double lat_true_scale = HE5_EHconvAng(eg_info.param[5],HE5_HDFE_DMS_DEG);
3010 double fe = eg_info.param[6];
3013 double fn = eg_info.param[7];
3015 add_var_dap4_attr(var,
"grid_mapping_name",attr_str_c,
"polar_stereographic");
3017 ostringstream s_vert_lon_pole;
3018 s_vert_lon_pole << vert_lon_pole;
3022 add_var_dap4_attr(var,
"straight_vertical_longitude_from_pole", attr_float64_c, s_vert_lon_pole.str());
3024 ostringstream s_lat_true_scale;
3025 s_lat_true_scale << lat_true_scale;
3026 add_var_dap4_attr(var,
"standard_parallel", attr_float64_c, s_lat_true_scale.str());
3029 add_var_dap4_attr(var,
"false_easting",attr_float64_c,
"0.0");
3033 add_var_dap4_attr(var,
"false_easting",attr_float64_c,s_fe.str());
3037 add_var_dap4_attr(var,
"false_northing",attr_float64_c,
"0.0");
3041 add_var_dap4_attr(var,
"false_northing",attr_float64_c,s_fn.str());
3044 if(lat_true_scale >0)
3045 add_var_dap4_attr(var,
"latitude_of_projection_origin",attr_float64_c,
"+90.0");
3047 add_var_dap4_attr(var,
"latitude_of_projection_origin",attr_float64_c,
"-90.0");
3049 add_var_dap4_attr(var,
"_CoordinateAxisTypes", attr_str_c,
"GeoX GeoY");
3057void add_lamaz_cf_grid_mapping_attrs(libdap::BaseType *var,
const eos5_grid_info_t & eg_info) {
3059 double lon_proj_origin = HE5_EHconvAng(eg_info.param[4],HE5_HDFE_DMS_DEG);
3060 double lat_proj_origin = HE5_EHconvAng(eg_info.param[5],HE5_HDFE_DMS_DEG);
3061 double fe = eg_info.param[6];
3062 double fn = eg_info.param[7];
3064 add_var_dap4_attr(var,
"grid_mapping_name", attr_str_c,
"lambert_azimuthal_equal_area");
3066 ostringstream s_lon_proj_origin;
3067 s_lon_proj_origin << lon_proj_origin;
3068 add_var_dap4_attr(var,
"longitude_of_projection_origin", attr_float64_c, s_lon_proj_origin.str());
3070 ostringstream s_lat_proj_origin;
3071 s_lat_proj_origin << lat_proj_origin;
3073 add_var_dap4_attr(var,
"latitude_of_projection_origin", attr_float64_c, s_lat_proj_origin.str());
3076 add_var_dap4_attr(var,
"false_easting",attr_float64_c,
"0.0");
3080 add_var_dap4_attr(var,
"false_easting",attr_float64_c,s_fe.str());
3084 add_var_dap4_attr(var,
"false_northing",attr_float64_c,
"0.0");
3088 add_var_dap4_attr(var,
"false_northing",attr_float64_c,s_fn.str());
3091 add_var_dap4_attr(var,
"_CoordinateAxisTypes", attr_str_c,
"GeoX GeoY");
3095void add_possible_var_cv_info(libdap::BaseType *var,
const eos5_dim_info_t &eos5_dim_info) {
3097 bool have_cv_dim0 =
false;
3098 bool have_cv_dim1 =
false;
3099 string dim0_cv_name1;
3100 string dim0_cv_name2;
3101 string dim0_gm_name;
3102 string dim1_cv_name1;
3103 string dim1_cv_name2;
3104 string dim1_gm_name;
3106 auto t_a =
dynamic_cast<Array*
>(var);
3108 Array::Dim_iter di = t_a->dim_begin();
3109 Array::Dim_iter de = t_a->dim_end();
3111 for (; di != de; di++) {
3113 const D4Dimension * d4_dim = t_a->dimension_D4dim(di);
3120 string dim_fqn = d4_dim->fully_qualified_name();
3122 for (
const auto &dim_to_cv:eos5_dim_info.dimpath_to_cvpath) {
3123 if (dim_fqn == dim_to_cv.first.dpath0) {
3125 dim0_cv_name1 = dim_to_cv.second.vpath0;
3126 dim0_cv_name2 = dim_to_cv.second.vpath1;
3127 dim0_gm_name = dim_to_cv.second.cf_gmap_path;
3129 have_cv_dim0 =
true;
3131 else if (dim_fqn == dim_to_cv.first.dpath1) {
3133 dim1_cv_name1 = dim_to_cv.second.vpath0;
3134 dim1_cv_name2 = dim_to_cv.second.vpath1;
3135 dim1_gm_name = dim_to_cv.second.cf_gmap_path;
3137 have_cv_dim1 =
true;
3140 if (have_cv_dim0 && have_cv_dim1)
3145 if (have_cv_dim0 && have_cv_dim1)
3151 if (have_cv_dim0 && have_cv_dim1) {
3152 if (dim0_cv_name1 != dim1_cv_name1 || dim0_cv_name2 !=dim1_cv_name2 || dim0_gm_name !=dim1_gm_name)
3153 throw InternalErr(__FILE__,__LINE__,
"Inconsistent coordinates for this EOS5 Grid");
3155 string coord_value = dim0_cv_name1 +
" "+dim0_cv_name2;
3156 add_var_dap4_attr(var,
"coordinates",attr_str_c,coord_value);
3157 add_var_dap4_attr(var,
"grid_mapping",attr_str_c,dim0_gm_name);
3163void make_attributes_to_cf(BaseType *var,
const eos5_dim_info_t &eos5_dim_info) {
3165 bool check_attr =
false;
3166 for (
const auto & ed_info:eos5_dim_info.gridname_to_info) {
3167 if (ed_info.second.projection == HE5_GCTP_GEO) {
3173 if (check_attr ==
true) {
3175 D4Attributes *d4_attrs = var->attributes();
3176 bool have_scale_factor =
false;
3177 bool have_add_offset =
false;
3178 for (
auto ii = d4_attrs->attribute_begin(), ee = d4_attrs->attribute_end(); ii != ee; ++ii) {
3179 if ((*ii)->name() ==
"ScaleFactor") {
3180 (*ii)->set_name(
"scale_factor");
3181 have_scale_factor =
true;
3183 else if ((*ii)->name() ==
"Offset") {
3184 (*ii)->set_name(
"add_offset");
3185 have_add_offset =
true;
3187 if (have_scale_factor && have_add_offset)
3193void handle_vlen_int_float(D4Group *d4_grp, hid_t pid,
const string &vname,
const string &var_path,
3194 const string &filename, hid_t dset_id) {
3196 hid_t vlen_type = H5Dget_type(dset_id);
3197 hid_t vlen_basetype = H5Tget_super(vlen_type);
3198 if (H5Tget_class(vlen_basetype) != H5T_INTEGER && H5Tget_class(vlen_basetype) != H5T_FLOAT)
3199 throw InternalErr(__FILE__, __LINE__,
"Only support float or intger variable-length datatype.");
3201 hid_t vlen_base_memtype = H5Tget_native_type(vlen_basetype, H5T_DIR_ASCEND);
3202 hid_t vlen_memtype = H5Tvlen_create(vlen_base_memtype);
3205 hid_t vlen_space = H5Dget_space(dset_id);
3206 if (H5Sget_simple_extent_type(vlen_space) != H5S_SIMPLE)
3207 throw InternalErr(__FILE__, __LINE__,
"Only support array of float or intger variable-length datatype.");
3209 hssize_t vlen_number_elements = H5Sget_simple_extent_npoints(vlen_space);
3210 vector<hvl_t> vlen_data(vlen_number_elements);
3211 if (H5Dread(dset_id, vlen_memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, vlen_data.data()) <0) {
3213 throw InternalErr(__FILE__, __LINE__,
"Cannot read variable-length datatype data.");
3216 size_t max_vlen_length = 0;
3217 for (ssize_t i = 0; i<vlen_number_elements; i++) {
3218 if (max_vlen_length<vlen_data[i].len)
3219 max_vlen_length = vlen_data[i].len;
3222 H5Dvlen_reclaim(vlen_memtype, vlen_space, H5P_DEFAULT, (
void*)(vlen_data.data()));
3223 H5Sclose(vlen_space);
3227 BaseType *bt = Get_bt_enhanced(d4_grp,pid, vname,var_path, filename, vlen_basetype);
3229 throw InternalErr(__FILE__, __LINE__,
"Unable to convert hdf5 datatype to dods basetype");
3231 H5Tclose(vlen_base_memtype);
3232 H5Tclose(vlen_basetype);
3233 H5Tclose(vlen_type);
3234 H5Tclose(vlen_memtype);
3236 auto ar_unique = make_unique<HDF5Array>(vname, filename, bt);
3241 ar->set_varpath(var_path);
3242 auto dimnames_size = (
int)(dt_inst.dimnames.size());
3243 vector<string> dimnames;
3244 if (dimnames_size == dt_inst.ndims) {
3245 for (
const auto &dimname:dt_inst.dimnames)
3246 dimnames.push_back(dimname);
3247 array_add_dimensions_dimscale(ar);
3250 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++)
3251 ar->append_dim_ll(dt_inst.size[dim_index]);
3254 string vlen_length_dimname = vname +
"_vlen";
3255 string vlen_length_dimpath = var_path +
"_vlen";
3257 if (dimnames.empty())
3258 ar->append_dim_ll(max_vlen_length);
3260 ar->append_dim_ll(max_vlen_length, vlen_length_dimname);
3263 BaseType *new_var =
nullptr;
3264 vector<string> temp_dimnames_path;
3265 if (dimnames.empty() ==
false) {
3266 for (
const auto & dimname:dt_inst.dimnames_path)
3267 temp_dimnames_path.push_back(dimname);
3268 temp_dimnames_path.push_back(vlen_length_dimpath);
3271 new_var = ar->h5dims_transform_to_dap4(d4_grp,temp_dimnames_path);
3273 read_objects_basetype_attr_hl(var_path, new_var, dset_id,
false);
3275 auto vlen_d4_attr_unique = make_unique<D4Attribute>(
"orig_datatype",attr_str_c);
3276 auto vlen_d4_attr = vlen_d4_attr_unique.get();
3277 vlen_d4_attr->add_value(
"VLEN");
3278 new_var->attributes()->add_attribute_nocopy(vlen_d4_attr_unique.release());
3280 auto vlen_d4_attr2_unique = make_unique<D4Attribute>(
"vlen_description",attr_str_c);
3281 auto vlen_d4_attr2 = vlen_d4_attr2_unique.get();
3282 string desc_str =
"The original variable-length array data is stored as the regular";
3283 desc_str +=
" array data that has an extra dimension. The data gap is filled with 0.";
3284 desc_str +=
" The actual length of each original variable-length element is stored in another array. The";
3285 desc_str +=
" variable name of this array is " + vname +
"_vlen_index" +
".";
3286 vlen_d4_attr2->add_value(desc_str);
3287 new_var->attributes()->add_attribute_nocopy(vlen_d4_attr2_unique.release());
3289 d4_grp->add_var_nocopy(new_var);
3293 string vname_idx = vname +
"_vlen_index";
3294 auto hdf5_int32 = make_unique<HDF5Int32>(vname_idx,var_path,filename);
3296 auto ar_index_unique = make_unique<HDF5Array>(vname_idx, filename, hdf5_int32.get());
3297 HDF5Array *ar_index = ar_index_unique.get();
3301 ar_index->set_varpath(var_path);
3302 if (dimnames.empty()==
false) {
3303 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++) {
3304 if (dimnames[dim_index].empty() ==
false)
3305 ar_index->append_dim_ll(dt_inst.size[dim_index], dimnames[dim_index]);
3307 ar_index->append_dim_ll(dt_inst.size[dim_index]);
3312 for (
int dim_index = 0; dim_index < dt_inst.ndims; dim_index++)
3313 ar_index->append_dim_ll(dt_inst.size[dim_index]);
3317 BaseType *new_var_index =
nullptr;
3318 new_var_index = ar_index->h5dims_transform_to_dap4(d4_grp,dt_inst.dimnames_path);
3321 dt_inst.dimnames_path.clear();
3323 auto vlen_index_d4_attr_unique = make_unique<D4Attribute>(
"orig_datatype",attr_str_c);
3324 auto vlen_index_d4_attr = vlen_index_d4_attr_unique.get();
3325 vlen_index_d4_attr->add_value(
"VLEN_INDEX");
3326 new_var_index->attributes()->add_attribute_nocopy(vlen_index_d4_attr_unique.release());
3328 d4_grp->add_var_nocopy(new_var_index);
A class for handling all types of array in HDF5 for the default option.
This file includes several helper functions for translating HDF5 to CF-compliant.
A class for mapping HDF5 32-bit float to DAP for the default option.
A class for mapping HDF5 64-bit float to DAP for the default option.
A class for HDF5 signed 16 bit integer type.
This class provides a way to map HDF5 32 bit integer to DAP Int32 for the default option.
This class converts HDF5 compound type into DAP structure for the default option.
This class provides a way to map unsigned HDF5 16 bit integer to DAP UInt16 for the default option.
This class provides a way to map unsigned HDF5 32 bit integer to DAP UInt32.
This class generates DAP URL type for the default option.
A class for parsing NASA HDF-EOS5 StructMetadata.
A class for parsing NASA HDF-EOS5 StructMetadata.
void set_numelm(hsize_t nelms)
remembers number of elements in this array.
void set_numdim(int ndims)
remembers number of dimensions of this array.
void set_memneed(size_t need)
remembers memory size needed.
int get_numdim() const
obtain the number of dimensions of this array.
void print() const
Print the information about the members of the Vector list.
Functions to generate DDS and DAS for one object(variable).
void read_objects(DAS &das, const string &varname, hid_t oid, int num_attr)
HDF5PathFinder obj_paths
A variable for remembering visited paths to break cyclic HDF5 groups.
string read_struct_metadata(hid_t s_file_id)
EOS5 handling.
bool breadth_first(hid_t file_id, hid_t pid, const char *gname, D4Group *par_grp, const char *fname, bool use_dimscale, bool is_eos5, vector< link_info_t > &hdf5_hls, eos5_dim_info_t &eos5_dim_info, vector< string > &handled_cv_names)
void read_objects_structure(D4Group *d4_grp, const string &varname, const string &filename, hid_t dset_id, bool use_dimscale, bool is_eos5)
void add_dap4_coverage_default(D4Group *d4_root, const vector< string > &handled_all_cv_names)
Add DAP4 coverage.
void get_softlink(D4Group *par_grp, hid_t h5obj_id, const string &oname, int index, size_t val_size)
void read_objects_base_type(D4Group *d4_grp, hid_t pid, const string &varname, const string &filename, hid_t dset_id, bool use_dimscale, bool is_eos5, eos5_dim_info_t &eos5_dim_info)
Data structure and retrieval processing header for the default option.
The main header of the HDF5 OPeNDAP handler.
const int DODS_NAMELEN
Maximum length of variable or attribute name(default option only).
struct DS DS_t
A structure for DDS generation.
struct DSattr DSattr_t
A structure for DAS generation.
char name[DODS_NAMELEN]
Name of HDF5 group or dataset.
int ndims
Number of dimensions.
hsize_t nelmts
Number of elements.
hsize_t need
Memory space needed to hold nelmts type.
double point_right
The rightmost coordinate value of a Grid.
double point_upper
The top coordinate value of a Grid.
double point_left
The leftmost coordinate value of a Grid.
double point_lower
The bottom coordinate value of a Grid.
double point_right
The rightmost coordinate value of a Grid.
double point_upper
The top coordinate value of a Grid.
double point_lower
The bottom coordinate value of a Grid.
double point_left
The leftmost coordinate value of a Grid.