RMF
HDF5/types.h
Go to the documentation of this file.
1 /**
2  * \file RMF/HDF5/types.h
3  * \brief Handle read/write of Model data from/to files.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef RMF_HDF5_TYPES_H
10 #define RMF_HDF5_TYPES_H
11 
12 #include "RMF/config.h"
13 #include "handle.h"
14 #include "infrastructure_macros.h"
15 #include "RMF/internal/errors.h"
16 #include "RMF/ID.h"
17 #include "internal/types.h"
18 #include <hdf5.h>
19 #include <algorithm>
20 #include <boost/cstdint.hpp>
21 #include <limits>
22 
23 RMF_ENABLE_WARNINGS
24 namespace RMF {
25 namespace HDF5 {
26 
27 /** The type used to store integral values.*/
28 typedef int Int;
29 /** The type used to store lists of integral values.*/
30 typedef std::vector<Int> Ints;
31 /** The type used to store lists of floating point values.*/
32 typedef float Float;
33 /** The type used to store lists of floating point values.*/
34 typedef std::vector<Float> Floats;
35 /** The type used to store lists of floating point values.*/
36 typedef std::vector<Floats> FloatsList;
37 /** The type used to store lists of index values.*/
38 typedef int Index;
39 /** The type used to store lists of index values.*/
40 typedef std::vector<Index> Indexes;
41 /** The type used to store lists of indexes.*/
42 typedef std::vector<Indexes> IndexesList;
43 /** The type used to store lists of string values.*/
44 typedef std::string String;
45 /** The type used to store lists of string values.*/
46 typedef std::vector<String> Strings;
47 /** The type used to store lists of strings values.*/
48 typedef std::vector<Strings> StringsList;
49 /** The type used to store lists of lists of integers values.*/
50 typedef std::vector<Ints> IntsList;
51 /** The type used to store char values.*/
52 typedef char Char;
53 /** The type used to store lists of char values.*/
54 typedef std::string Chars;
55 
56 struct IntTraitsBase {
57  typedef int Type;
58  typedef std::vector<int> Types;
59  static const bool BatchOperations = true;
60  static int get_index() { return 0; }
61  static const Type& get_null_value() {
62  static Type null = std::numeric_limits<int>::max();
63  return null;
64  }
65  static bool get_is_null_value(Type t) { return t == get_null_value(); }
66  static hid_t get_hdf5_fill_type() { return H5T_NATIVE_INT; }
67  static hid_t get_hdf5_disk_type() { return H5T_STD_I64LE; }
68  static hid_t get_hdf5_memory_type() { return H5T_NATIVE_INT; }
69  static const Type& get_fill_value() { return get_null_value(); }
70  static std::string get_name() { return "int"; }
71 };
72 
73 struct FloatTraitsBase {
74  typedef float Type;
75  typedef std::vector<float> Types;
76  static const bool BatchOperations = true;
77  static int get_index() { return 1; }
78  static const Type& get_null_value() {
79  static Type null = std::numeric_limits<float>::max();
80  return null;
81  }
82  static bool get_is_null_value(Type t) { return t == get_null_value(); }
83  static hid_t get_hdf5_fill_type() { return H5T_NATIVE_FLOAT; }
84  static hid_t get_hdf5_disk_type() { return H5T_IEEE_F64LE; }
85  static hid_t get_hdf5_memory_type() { return H5T_NATIVE_FLOAT; }
86  static const Type& get_fill_value() { return get_null_value(); }
87  static std::string get_name() { return "float"; }
88 };
89 
90 struct IndexTraitsBase : public IntTraitsBase {
91  static int get_index() { return 2; }
92  static const Type& get_null_value() {
93  static Type null = -1;
94  return null;
95  }
96  static bool get_is_null_value(Type t) { return t == get_null_value(); }
97  static const Type& get_fill_value() { return get_null_value(); }
98  static std::string get_name() { return "index"; }
99 };
100 
101 template <class Base>
102 struct SimpleTraits : public Base {
103  static void write_value_dataset(hid_t d, hid_t iss, hid_t s,
104  typename Base::Type v) {
106  H5Dwrite(d, Base::get_hdf5_memory_type(), iss, s, H5P_DEFAULT, &v));
107  }
108  static typename Base::Type read_value_dataset(hid_t d, hid_t iss, hid_t sp) {
109  typename Base::Type ret;
111  H5Dread(d, Base::get_hdf5_memory_type(), iss, sp, H5P_DEFAULT, &ret));
112  return ret;
113  }
114  static void write_values_dataset(hid_t d, hid_t iss, hid_t s,
115  const typename Base::Types& v) {
116  if (v.empty()) return;
117  RMF_HDF5_CALL(H5Dwrite(d, Base::get_hdf5_memory_type(), iss, s, H5P_DEFAULT,
118  const_cast<typename Base::Type*>(&v[0])));
119  }
120  static typename Base::Types read_values_dataset(hid_t d, hid_t iss, hid_t sp,
121  unsigned int sz) {
122  typename Base::Types ret(sz, Base::get_null_value());
123  RMF_HDF5_CALL(H5Dread(d, Base::get_hdf5_memory_type(), iss, sp, H5P_DEFAULT,
124  &ret[0]));
125  return ret;
126  }
127  static void write_values_attribute(hid_t a, const typename Base::Types& v) {
128  if (v.empty()) return;
129  RMF_HDF5_CALL(H5Awrite(a, Base::get_hdf5_memory_type(), &v[0]));
130  }
131  static typename Base::Types read_values_attribute(hid_t a, unsigned int sz) {
132  typename Base::Types ret(sz, Base::get_null_value());
133  RMF_HDF5_CALL(H5Aread(a, Base::get_hdf5_memory_type(), &ret[0]));
134  return ret;
135  }
136 };
137 
138 struct CharTraits {
139  typedef char Type;
140  typedef std::string Types;
141  static const bool BatchOperations = false;
142  static int get_index() { return 6; }
143  static const Type& get_null_value() {
144  static char null = '\0';
145  return null;
146  }
147  static bool get_is_null_value(Type t) { return t == '\0'; }
148  static hid_t get_hdf5_fill_type() { return H5T_NATIVE_CHAR; }
149  static hid_t get_hdf5_disk_type() { return H5T_STD_I8LE; }
150  static hid_t get_hdf5_memory_type() { return H5T_NATIVE_CHAR; }
151  static const Type& get_fill_value() { return get_null_value(); }
152  static std::string get_name() { return "char"; }
153 
154  static void write_value_dataset(hid_t, hid_t, hid_t, char) {
155  RMF_NOT_IMPLEMENTED;
156  }
157  static char read_value_dataset(hid_t, hid_t, hid_t) {
158  RMF_NOT_IMPLEMENTED;
159  return '\0';
160  }
161  static void write_values_dataset(hid_t, hid_t, hid_t, const Types&) {
162  RMF_NOT_IMPLEMENTED;
163  }
164  static Types read_values_dataset(hid_t, hid_t, hid_t, unsigned int) {
165  RMF_NOT_IMPLEMENTED;
166  }
167  static void write_values_attribute(hid_t a, const Types& v) {
168  RMF_HDF5_CALL(H5Awrite(a, H5T_NATIVE_CHAR, v.c_str()));
169  }
170  static Types read_values_attribute(hid_t a, unsigned int sz) {
171  std::vector<char> v(sz);
172  RMF_HDF5_CALL(H5Aread(a, H5T_NATIVE_CHAR, &v[0]));
173  return std::string(&v[0], v.size());
174  }
175 };
176 
177 template <class Traits>
178 struct SimplePluralTraits {
179  typedef typename Traits::Types Type;
180  typedef std::vector<Type> Types;
181  static const bool BatchOperations = false;
182  static int get_index() { return 7 + Traits::get_index(); }
183  static const Type& get_null_value() {
184  static Type null;
185  return null;
186  }
187  static bool get_is_null_value(const Type& t) { return t.empty(); }
188  static hid_t get_hdf5_fill_type() { return get_hdf5_memory_type(); }
189  static hid_t get_hdf5_disk_type() {
190  static RMF_HDF5_HANDLE(
191  ints_type, H5Tvlen_create(Traits::get_hdf5_disk_type()), H5Tclose);
192  return ints_type;
193  }
194  static hid_t get_hdf5_memory_type() {
195  static RMF_HDF5_HANDLE(
196  ints_type, H5Tvlen_create(Traits::get_hdf5_memory_type()), H5Tclose);
197  return ints_type;
198  }
199  static const Type& get_fill_value() { return get_null_value(); }
200  static std::string get_name() { return Traits::get_name() + "s"; }
201 
202  static void write_value_dataset(hid_t d, hid_t iss, hid_t s, const Type& v) {
203  hvl_t data;
204  data.len = v.size();
205  if (data.len > 0) {
206  data.p = const_cast<typename Type::pointer>(&v[0]);
207  } else {
208  data.p = nullptr;
209  }
211  H5Dwrite(d, get_hdf5_memory_type(), iss, s, H5P_DEFAULT, &data));
212  }
213  static Type read_value_dataset(hid_t d, hid_t iss, hid_t sp) {
214  hvl_t data;
215  H5Dread(d, get_hdf5_memory_type(), iss, sp, H5P_DEFAULT, &data);
216  Type ret(data.len);
217  std::copy(static_cast<typename Type::pointer>(data.p),
218  static_cast<typename Type::pointer>(data.p) + data.len,
219  ret.begin());
220  free(data.p);
221  return ret;
222  }
223  static void write_values_dataset(hid_t, hid_t, hid_t, const Types&) {
224  RMF_NOT_IMPLEMENTED;
225  };
226  static Types read_values_dataset(hid_t, hid_t, hid_t, unsigned int) {
227  RMF_NOT_IMPLEMENTED;
228  }
229  static Types read_values_attribute(hid_t, unsigned int) {
230  RMF_NOT_IMPLEMENTED;
231  }
232  static void write_values_attribute(hid_t, const Types&) {
233  RMF_NOT_IMPLEMENTED;
234  }
235 };
236 
237 struct RMFEXPORT StringTraits {
238  typedef std::string Type;
239  typedef std::vector<std::string> Types;
240  static const bool BatchOperations = false;
241  static int get_index() { return 3; }
242  static const Type& get_null_value() {
243  static std::string null;
244  return null;
245  }
246  static bool get_is_null_value(Type t) { return t.empty(); }
247  static hid_t get_hdf5_fill_type() { return internal::get_string_type(); }
248  static hid_t get_hdf5_disk_type() { return internal::get_string_type(); }
249  static hid_t get_hdf5_memory_type() { return internal::get_string_type(); }
250  static const Type& get_fill_value() { return get_null_value(); }
251  static std::string get_name() { return "string"; }
252  static void write_value_dataset(hid_t d, hid_t iss, hid_t s, const Type& v);
253  static Type read_value_dataset(hid_t d, hid_t iss, hid_t sp);
254  static void write_values_dataset(hid_t, hid_t, hid_t, Types) {
255  RMF_NOT_IMPLEMENTED;
256  };
257  static Types read_values_dataset(hid_t, hid_t, hid_t, unsigned int) {
258  RMF_NOT_IMPLEMENTED;
259  }
260  static Types read_values_attribute(hid_t, unsigned int) {
261  RMF_NOT_IMPLEMENTED;
262  }
263  static void write_values_attribute(hid_t, const Types&) {
264  RMF_NOT_IMPLEMENTED;
265  }
266 };
267 
268 struct RMFEXPORT StringsTraits {
269  typedef std::vector<std::string> Type;
270  typedef std::vector<Type> Types;
271  static const bool BatchOperations = false;
272  static int get_index() { return 3 + 7; }
273  static const Type& get_null_value() {
274  static Type null;
275  return null;
276  }
277  static bool get_is_null_value(Type t) { return t.empty(); }
278  static hid_t get_hdf5_fill_type();
279  static hid_t get_hdf5_disk_type();
280  static hid_t get_hdf5_memory_type();
281  static const hvl_t& get_fill_value();
282  static std::string get_name() { return "strings"; }
283  static void write_value_dataset(hid_t d, hid_t iss, hid_t s, const Type& v);
284  static Type read_value_dataset(hid_t d, hid_t iss, hid_t sp);
285  static void write_values_dataset(hid_t, hid_t, hid_t, const Types&) {
286  RMF_NOT_IMPLEMENTED;
287  };
288  static Types read_values_dataset(hid_t, hid_t, hid_t, unsigned int) {
289  RMF_NOT_IMPLEMENTED;
290  }
291  static Types read_values_attribute(hid_t, unsigned int) {
292  RMF_NOT_IMPLEMENTED;
293  }
294  static void write_values_attribute(hid_t, const Types&) {
295  RMF_NOT_IMPLEMENTED;
296  }
297 };
298 
299 #ifndef SWIG
300 struct IntTraits : public SimpleTraits<IntTraitsBase> {};
301 struct IntsTraits : public SimplePluralTraits<IntTraits> {};
302 struct FloatTraits : public SimpleTraits<FloatTraitsBase> {};
303 struct FloatsTraits : public SimplePluralTraits<FloatTraits> {};
304 struct IndexTraits : public SimpleTraits<IndexTraitsBase> {};
305 struct IndexesTraits : public SimplePluralTraits<IndexTraits> {};
306 
307 #ifndef IMP_DOXYGEN
308 namespace {
309 template <class OutType, class InType>
310 inline void get_as_impl(InType in, OutType& out) {
311  out = OutType(in);
312 }
313 template <class Traits, class InType>
314 inline void get_as_impl(InType in, ID<Traits>& out) {
315  if (in == -1)
316  out = ID<Traits>();
317  else
318  out = ID<Traits>(in);
319 }
320 template <class OutType, class Traits>
321 inline void get_as_impl(ID<Traits> in, OutType& out) {
322  if (in == ID<Traits>())
323  out = -1;
324  else
325  out = in.get_index();
326 }
327 }
328 #endif
329 #endif
330 
331 /** Get one type as another, handling vectors or scalars.*/
332 template <class OutType, class InType>
333 inline OutType get_as(InType in) {
334  OutType ret;
335  get_as_impl(in, ret);
336  return ret;
337 }
338 
339 /** Get one type as another, handling vectors or scalars.*/
340 template <class OutType, class InType>
341 inline OutType get_as(const std::vector<InType> in) {
342  OutType ret(in.size());
343  for (unsigned int i = 0; i < ret.size(); ++i) {
344  ret[i] = get_as<typename OutType::value_type>(in[i]);
345  }
346  return ret;
347 }
348 
349 } /* namespace HDF5 */
350 } /* namespace RMF */
351 
352 RMF_DISABLE_WARNINGS
353 
354 #endif /* RMF_HDF5_TYPES_H */
char Char
Definition: HDF5/types.h:52
std::vector< String > Strings
Definition: HDF5/types.h:46
Declaration of RMF::ID.
std::string String
Definition: HDF5/types.h:44
OutType get_as(InType in)
Definition: HDF5/types.h:333
Various general useful macros for IMP.
int Index
Definition: HDF5/types.h:38
Handle read/write of Model data from/to files.
std::vector< Indexes > IndexesList
Definition: HDF5/types.h:42
std::vector< Index > Indexes
Definition: HDF5/types.h:40
std::vector< Float > Floats
Definition: HDF5/types.h:34
#define RMF_HDF5_CALL(v)
std::vector< Floats > FloatsList
Definition: HDF5/types.h:36
Include all non-deprecated headers in RMF.HDF5.
std::vector< Int > Ints
Definition: HDF5/types.h:30
std::vector< Ints > IntsList
Definition: HDF5/types.h:50
float Float
Definition: HDF5/types.h:32
std::vector< Strings > StringsList
Definition: HDF5/types.h:48
std::string Chars
Definition: HDF5/types.h:54