icedb  version 0.5.1
Snow particle scattering database API
export-hdf5.cpp
Go to the documentation of this file.
1 #include "../private/hdf5_supplemental.hpp"
2 #include "../icedb/compat/gsl/gsl_assert"
3 #include "../icedb/defs.h"
4 #include <string>
5 #include <sstream>
6 #include <utility>
7 #include <algorithm>
8 
9 namespace icedb {
10  namespace fs
11  {
12  namespace hdf5
13  {
14  namespace zlib {
15  int cval = 6;
16  }
17  int useZLIB() { return zlib::cval; }
18  void useZLIB(int val) { zlib::cval = val; }
19  //template <class DataType>
20  //MatchAttributeTypeType MatchAttributeType() {
21  // static_assert(false, "Unsupported type during attribute conversion in rtmath::plugins::hdf5::MatchAttributeType."); }
22  template<> MatchAttributeTypeType MatchAttributeType<std::string>() { return std::make_unique<H5::StrType>(0, H5T_VARIABLE); }
23  template<> MatchAttributeTypeType MatchAttributeType<const char*>() { return std::make_unique<H5::StrType>(0, H5T_VARIABLE); }
24  template<> MatchAttributeTypeType MatchAttributeType<char>() { return std::make_unique<H5::StrType>(0, 1); }
25 
26  template<> MatchAttributeTypeType MatchAttributeType<uint8_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_UINT8); }
27  template<> MatchAttributeTypeType MatchAttributeType<uint16_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_UINT16); }
28  template<> MatchAttributeTypeType MatchAttributeType<uint32_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_UINT32); }
29  template<> MatchAttributeTypeType MatchAttributeType<uint64_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_UINT64); }
30  template<> MatchAttributeTypeType MatchAttributeType<int8_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_INT8); }
31  template<> MatchAttributeTypeType MatchAttributeType<int16_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_INT16); }
32  template<> MatchAttributeTypeType MatchAttributeType<int32_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_INT32); }
33  template<> MatchAttributeTypeType MatchAttributeType<int64_t>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_INT64); }
34  //template<> MatchAttributeTypeType MatchAttributeType<char>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_CHAR)); }
35 
36  template<> MatchAttributeTypeType MatchAttributeType<float>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_FLOAT); }
37  template<> MatchAttributeTypeType MatchAttributeType<double>() { return std::make_unique<H5::IntType>(H5::PredType::NATIVE_DOUBLE); }
38  // \note bools are not recommended in HDF5. This type may be switched later on.
39  //template<> MatchAttributeTypeType MatchAttributeType<bool>() { return std::shared_ptr<H5::AtomType>(new H5::IntType(H5::PredType::NATIVE_HBOOL)); }
40 
41  template<> bool isStrType<std::string>() { return true; }
42  template<> bool isStrType<const char*>() { return true; }
43 
44  template <> void insertAttr<std::string>(const H5::Attribute &attr, gsl::not_null<H5::AtomType*> vls_type, const std::string& value)
45  {
46  attr.write(*vls_type, value);
47  }
48  template <> void loadAttr<std::string>(const H5::Attribute &attr, gsl::not_null<H5::AtomType*> vls_type, std::string& value)
49  {
50  attr.read(*vls_type, value);
51  //attr.write(*vls_type, value);
52  }
53  /*
54  template <> void insertAttr<char const*>(H5::Attribute &, std::shared_ptr<H5::AtomType>, char const * const &);
55  template <> void insertAttr<int>(H5::Attribute &, std::shared_ptr<H5::AtomType>, const int&);
56  template <> void insertAttr<unsigned __int64>(H5::Attribute &, std::shared_ptr<H5::AtomType>, const unsigned __int64&);
57  template <> void insertAttr<unsigned long long>(H5::Attribute &, std::shared_ptr<H5::AtomType>, const unsigned long long&);
58  template <> void insertAttr<float>(H5::Attribute &, std::shared_ptr<H5::AtomType>, const float&);
59  template <> void insertAttr<double>(H5::Attribute &, std::shared_ptr<H5::AtomType>, const double&);
60  */
61 
62  HDFgroup_t openOrCreateGroup(gsl::not_null<ICEDB_H5_GROUP_OWNER_PTR> base, gsl::not_null<const char*> name)
63  {
64  HDFgroup_t res;
65  try {
66  res=std::make_unique<H5::Group>( base->openGroup( name ));
67  } catch( H5::GroupIException not_found_error ) {
68  res=std::make_unique<H5::Group>(base->createGroup( name ));
69  } catch( H5::FileIException not_found_error ) {
70  res=std::make_unique<H5::Group>(base->createGroup( name ));
71  }
72  return res;
73  }
74 
75  HDFgroup_t openGroup(gsl::not_null<ICEDB_H5_GROUP_OWNER_PTR> base, gsl::not_null<const char*> name)
76  {
77  HDFgroup_t res;
78  try {
79  res=(std::make_unique<H5::Group>(base->openGroup( name )));
80  } catch( H5::GroupIException not_found_error ) {
81  return nullptr;
82  } catch( H5::FileIException not_found_error ) {
83  return nullptr;
84  }
85  return res;
86  }
87 
88  bool attrExists(gsl::not_null<H5::H5Object*> base, gsl::not_null<const char*> name)
89  {
90  try {
91  H5::Attribute(base->openAttribute(name));
92  return true;
93  }
94  catch (H5::AttributeIException not_found_error) {
95  return false;
96  }
97  catch (H5::FileIException not_found_error) {
98  return false;
99  }
100  catch (H5::GroupIException not_found_error) {
101  return false;
102  }
103  }
104 
105  bool groupExists(gsl::not_null<ICEDB_H5_GROUP_OWNER_PTR> base, gsl::not_null<const char*> name)
106  {
107  try {
108  H5::Group( base->openGroup( name ));
109  return true;
110  } catch( H5::GroupIException not_found_error ) {
111  return false;
112  }
113  catch (H5::FileIException not_found_error) {
114  return false;
115  }
116  }
117 
118  std::pair<bool,bool> symLinkExists(gsl::not_null<ICEDB_H5_GROUP_OWNER_PTR> base, gsl::not_null<const char*> name)
119  {
120  bool linkexists = false;
121  bool linkgood = false;
122  std::string lloc;
123  try {
124  H5G_stat_t stats;
125  base->getObjinfo(name, false, stats);
126  linkexists = true;
127 
128  //lloc = base->getLinkval(name);
129  base->getObjinfo(name, true, stats);
130  linkgood = true;
131  } catch( H5::GroupIException not_found_error ) {
132  } catch( H5::FileIException not_found_error) {
133  }
134  return std::pair<bool,bool>(linkexists,linkgood);
135  }
136 
137  bool datasetExists(gsl::not_null<ICEDB_H5_GROUP_OWNER_PTR> base, gsl::not_null<const char*> name)
138  {
139  try {
140  H5::DataSet(base->openDataSet(name));
141  return true;
142  }
143  catch (H5::GroupIException not_found_error) {
144  return false;
145  }
146  catch (H5::FileIException not_found_error) {
147  return false;
148  }
149  }
150 
151  std::shared_ptr<H5::DSetCreatPropList> make_plist(size_t rows, size_t cols, bool compress)
152  {
153  using namespace H5;
154  const hsize_t chunk[2] = { static_cast<hsize_t>(rows), static_cast<hsize_t>(cols) };
155  auto plist = std::make_shared<H5::DSetCreatPropList>();
156  plist->setChunk(2, chunk);
157  if (compress)
158  plist->setDeflate(6);
159  return plist;
160  }
161 
162  std::set<std::string> getGroupMembers(const ICEDB_H5_GETNUMOBJS_OWNER &base) {
163  std::set<std::string> res;
164  const hsize_t numObjs = base.getNumObjs();
165  for (hsize_t i = 0; i < numObjs; ++i)
166  {
167  std::string name = base.getObjnameByIdx(i);
168  res.insert(name);
169  }
170  return res;
171  }
172 
173  std::map<std::string, H5G_obj_t> getGroupMembersTypes(const ICEDB_H5_GETNUMOBJS_OWNER &base) {
174  std::map<std::string, H5G_obj_t> res;
175  const hsize_t numObjs = base.getNumObjs();
176  for (hsize_t i = 0; i < numObjs; ++i)
177  {
178  std::string name = base.getObjnameByIdx(i);
179  H5G_obj_t gtype = base.getObjTypeByIdx(i);
180  res[name] = gtype;
181  }
182  return res;
183  }
184 
185  std::vector<std::string> explode(std::string const & s, char delim)
186  {
187  std::vector<std::string> result;
188  std::istringstream iss(s);
189 
190  for (std::string token; std::getline(iss, token, delim); )
191  {
192  if (token.size())
193  result.push_back(std::move(token));
194  }
195 
196  return result;
197  }
198 
199  std::vector<std::string> explodeHDF5groupPath(const std::string &s) {
200  std::string mountStr = s;
201  std::replace(mountStr.begin(), mountStr.end(), '\\', '/');
202  return explode(mountStr, '/');
203  }
204 
205  H5::Group createGroupStructure(const std::string &groupName, ICEDB_H5_GROUP_OWNER &base) {
206  // Using the '/' specifier, pop off the group names and
207  // create groups if necessary in the tree. Return the final group.
208  Expects(groupName.size() > 0);
209  std::string mountStr = groupName;
210  std::replace(mountStr.begin(), mountStr.end(), '\\', '/');
211  std::vector<std::string> groups = explode(mountStr, '/');
212 
213  return std::move(createGroupStructure(groups, base));
214  }
215 
216  H5::Group createGroupStructure(const std::vector<std::string> &groups, ICEDB_H5_GROUP_OWNER &base) {
217 
222  std::shared_ptr<ICEDB_H5_GROUP_OWNER> current(&base, [](ICEDB_H5_GROUP_OWNER*) {});
223  std::vector<H5::Group> vgrps;
224  //vgrps.push_back(current);
225 
226  //H5::Group current(base);
227  for (const auto &grpname : groups) {
228  if (!grpname.size()) continue; // Skip any empty entries
229  std::set<std::string> members = getGroupMembers(*(current.get()));
230  if (!members.count(grpname)) {
231  vgrps.push_back(std::move(current->createGroup(grpname)));
232  current = std::shared_ptr<H5::Group>(&(*(vgrps.rbegin())), [](H5::Group*) {});
233  }
234  else {
235  //H5::Group newcur = current->openGroup(grpname);
236  //current = newcur;
237  vgrps.push_back(std::move(current->openGroup(grpname)));
238  current = std::shared_ptr<H5::Group>(&(*(vgrps.rbegin())), [](H5::Group*) {});
239  }
240  }
241  return std::move((*(vgrps.rbegin())));
242  }
243 
244 
246  unsigned int getHDF5IOflags(fs::IOopenFlags flags) {
247  unsigned int Hflags = 0; // HDF5 flags
248  if (flags == fs::IOopenFlags::READ_ONLY) Hflags = H5F_ACC_RDONLY;
249  else if (flags == fs::IOopenFlags::READ_WRITE) Hflags = H5F_ACC_RDWR;
250  else if (flags == fs::IOopenFlags::TRUNCATE) Hflags = H5F_ACC_TRUNC;
251  else if (flags == fs::IOopenFlags::CREATE) Hflags = H5F_ACC_CREAT;
252  return Hflags;
253  }
254 
255 
256  template<> bool isType<uint64_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_UINT64) > 0) ? true : false; }
257  template<> bool isType<int64_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_INT64) > 0) ? true : false; }
258  template<> bool isType<uint32_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_UINT32) > 0) ? true : false; }
259  template<> bool isType<int32_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_INT32) > 0) ? true : false; }
260  template<> bool isType<uint16_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_UINT16) > 0) ? true : false; }
261  template<> bool isType<int16_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_INT16) > 0) ? true : false; }
262  template<> bool isType<uint8_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_UINT8) > 0) ? true : false; }
263  template<> bool isType<int8_t>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_INT8) > 0) ? true : false; }
264  template<> bool isType<float>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_FLOAT) > 0) ? true : false; }
265  template<> bool isType<double>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_DOUBLE) > 0) ? true : false; }
266  template<> bool isType<char>(hid_t type_id) { return (H5Tequal(type_id, H5T_NATIVE_CHAR) > 0) ? true : false; }
267  template<> bool isType<std::string>(hid_t type_id) {
268  std::shared_ptr<H5::AtomType> a = std::make_shared<H5::StrType>(0, H5T_VARIABLE);
269  return (H5Tequal(type_id, a->getId()) > 0) ? true : false;
270  }
271 
272 
273  void readDatasetDimensions(gsl::not_null<H5::DataSet*> dataset, std::vector<size_t> &dims) {
274  using namespace H5;
275  const H5T_class_t type_class = dataset->getTypeClass();
276  DataSpace fspace = dataset->getSpace();
277  int rank = fspace.getSimpleExtentNdims();
278  assert(rank >= 0);
279  std::vector<hsize_t> sz(rank);
280  const int dimensionality = fspace.getSimpleExtentDims(sz.data(), NULL);
281  for (size_t i = 0; i < rank; ++i)
282  dims.push_back((size_t)sz[i]);
283  }
284 
285  size_t readDatasetNumDimensions(gsl::not_null<H5::DataSet*> dataset) {
286  using namespace H5;
287  const H5T_class_t type_class = dataset->getTypeClass();
288  DataSpace fspace = dataset->getSpace();
289  int rank = fspace.getSimpleExtentNdims();
290  assert(rank >= 0);
291  return (size_t)rank;
292  }
293 
294  }
295  }
296 }
297 
MatchAttributeTypeType MatchAttributeType< int8_t >()
Definition: export-hdf5.cpp:30
std::unique_ptr< H5::Group > HDFgroup_t
bool groupExists(gsl::not_null< ICEDB_H5_GROUP_OWNER_PTR > base, gsl::not_null< const char *> name)
Definition: Data_Types.hpp:9
MatchAttributeTypeType MatchAttributeType< char >()
Definition: export-hdf5.cpp:24
bool isType< uint8_t >(hid_t type_id)
bool attrExists(gsl::not_null< H5::H5Object *> base, gsl::not_null< const char *> name)
Definition: export-hdf5.cpp:88
bool isType< uint16_t >(hid_t type_id)
H5::Group createGroupStructure(const std::string &groupName, ICEDB_H5_GROUP_OWNER &base)
IOopenFlags
Definition: fs.hpp:16
std::shared_ptr< H5::DSetCreatPropList > make_plist(size_t rows, size_t cols, bool compress)
Creates a property list with the compression + chunking as specified.
std::set< std::string > getGroupMembers(const ICEDB_H5_GETNUMOBJS_OWNER &base)
MatchAttributeTypeType MatchAttributeType< float >()
Definition: export-hdf5.cpp:36
bool isType< uint64_t >(hid_t type_id)
MatchAttributeTypeType MatchAttributeType< uint16_t >()
Definition: export-hdf5.cpp:27
MatchAttributeTypeType MatchAttributeType< uint32_t >()
Definition: export-hdf5.cpp:28
MatchAttributeTypeType MatchAttributeType< uint64_t >()
Definition: export-hdf5.cpp:29
bool isType< int8_t >(hid_t type_id)
bool isType< int16_t >(hid_t type_id)
std::vector< std::string > explode(std::string const &s, char delim)
MatchAttributeTypeType MatchAttributeType< int64_t >()
Definition: export-hdf5.cpp:33
MatchAttributeTypeType MatchAttributeType< int32_t >()
Definition: export-hdf5.cpp:32
bool isType< int64_t >(hid_t type_id)
void readDatasetDimensions(gsl::not_null< H5::DataSet *> dataset, std::vector< size_t > &dims)
std::vector< std::string > explodeHDF5groupPath(const std::string &s)
HDFgroup_t openGroup(gsl::not_null< ICEDB_H5_GROUP_OWNER_PTR > base, gsl::not_null< const char *> name)
Definition: export-hdf5.cpp:75
bool isType< int32_t >(hid_t type_id)
bool isType< uint32_t >(hid_t type_id)
std::pair< bool, bool > symLinkExists(gsl::not_null< ICEDB_H5_GROUP_OWNER_PTR > base, gsl::not_null< const char *> name)
unsigned int getHDF5IOflags(fs::IOopenFlags flags)
bool isType< char >(hid_t type_id)
MatchAttributeTypeType MatchAttributeType< int16_t >()
Definition: export-hdf5.cpp:31
bool isType< double >(hid_t type_id)
bool datasetExists(gsl::not_null< ICEDB_H5_GROUP_OWNER_PTR > base, gsl::not_null< const char *> name)
Convenience function to check if a given dataset exists.
bool isType< float >(hid_t type_id)
size_t readDatasetNumDimensions(gsl::not_null< H5::DataSet *> dataset)
MatchAttributeTypeType MatchAttributeType< double >()
Definition: export-hdf5.cpp:37
std::map< std::string, H5G_obj_t > getGroupMembersTypes(const ICEDB_H5_GETNUMOBJS_OWNER &base)
std::unique_ptr< H5::AtomType > MatchAttributeTypeType
HDFgroup_t openOrCreateGroup(gsl::not_null< ICEDB_H5_GROUP_OWNER_PTR > base, gsl::not_null< const char *> name)
Definition: export-hdf5.cpp:62
MatchAttributeTypeType MatchAttributeType< uint8_t >()
Definition: export-hdf5.cpp:26