openPMD-api
HDF5Auxiliary.hpp
1 /* Copyright 2017-2020 Fabian Koller
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 #pragma once
22 
23 #include "openPMD/auxiliary/StringManip.hpp"
24 #include "openPMD/backend/Attribute.hpp"
25 #include "openPMD/backend/Writable.hpp"
26 #include "openPMD/IO/HDF5/HDF5FilePosition.hpp"
27 
28 #include <hdf5.h>
29 
30 #include <stack>
31 
32 
33 namespace openPMD
34 {
35 inline hid_t
36 getH5DataType(Attribute const& att)
37 {
38  using DT = Datatype;
39  switch( att.dtype )
40  {
41  case DT::CHAR:
42  case DT::VEC_CHAR:
43  return H5Tcopy(H5T_NATIVE_CHAR);
44  case DT::UCHAR:
45  case DT::VEC_UCHAR:
46  return H5Tcopy(H5T_NATIVE_UCHAR);
47  case DT::SHORT:
48  case DT::VEC_SHORT:
49  return H5Tcopy(H5T_NATIVE_SHORT);
50  case DT::INT:
51  case DT::VEC_INT:
52  return H5Tcopy(H5T_NATIVE_INT);
53  case DT::LONG:
54  case DT::VEC_LONG:
55  return H5Tcopy(H5T_NATIVE_LONG);
56  case DT::LONGLONG:
57  case DT::VEC_LONGLONG:
58  return H5Tcopy(H5T_NATIVE_LLONG);
59  case DT::USHORT:
60  case DT::VEC_USHORT:
61  return H5Tcopy(H5T_NATIVE_USHORT);
62  case DT::UINT:
63  case DT::VEC_UINT:
64  return H5Tcopy(H5T_NATIVE_UINT);
65  case DT::ULONG:
66  case DT::VEC_ULONG:
67  return H5Tcopy(H5T_NATIVE_ULONG);
68  case DT::ULONGLONG:
69  case DT::VEC_ULONGLONG:
70  return H5Tcopy(H5T_NATIVE_ULLONG);
71  case DT::FLOAT:
72  case DT::VEC_FLOAT:
73  return H5Tcopy(H5T_NATIVE_FLOAT);
74  case DT::DOUBLE:
75  case DT::ARR_DBL_7:
76  case DT::VEC_DOUBLE:
77  return H5Tcopy(H5T_NATIVE_DOUBLE);
78  case DT::LONG_DOUBLE:
79  case DT::VEC_LONG_DOUBLE:
80  return H5Tcopy(H5T_NATIVE_LDOUBLE);
81  case DT::STRING:
82  {
83  hid_t string_t_id = H5Tcopy(H5T_C_S1);
84  H5Tset_size(string_t_id, att.get< std::string >().size());
85  return string_t_id;
86  }
87  case DT::VEC_STRING:
88  {
89  hid_t string_t_id = H5Tcopy(H5T_C_S1);
90  size_t max_len = 0;
91  for( std::string const& s : att.get< std::vector< std::string > >() )
92  max_len = std::max(max_len, s.size());
93  H5Tset_size(string_t_id, max_len);
94  return string_t_id;
95  }
96  case DT::BOOL:
97  return H5Tcopy(H5T_NATIVE_HBOOL);
98  case DT::DATATYPE:
99  throw std::runtime_error("Meta-Datatype leaked into IO");
100  case DT::UNDEFINED:
101  throw std::runtime_error("Unknown Attribute datatype (HDF5 datatype)");
102  default:
103  throw std::runtime_error("Datatype not implemented in HDF5 IO");
104  }
105 }
106 
107 inline hid_t
108 getH5DataSpace(Attribute const& att)
109 {
110  using DT = Datatype;
111  switch( att.dtype )
112  {
113  case DT::CHAR:
114  case DT::UCHAR:
115  case DT::SHORT:
116  case DT::INT:
117  case DT::LONG:
118  case DT::LONGLONG:
119  case DT::USHORT:
120  case DT::UINT:
121  case DT::ULONG:
122  case DT::ULONGLONG:
123  case DT::FLOAT:
124  case DT::DOUBLE:
125  case DT::LONG_DOUBLE:
126  case DT::STRING:
127  case DT::BOOL:
128  return H5Screate(H5S_SCALAR);
129  case DT::VEC_CHAR:
130  {
131  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
132  hsize_t dims[1] = {att.get< std::vector< char > >().size()};
133  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
134  return vec_t_id;
135  }
136  case DT::VEC_SHORT:
137  {
138  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
139  hsize_t dims[1] = {att.get< std::vector< short > >().size()};
140  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
141  return vec_t_id;
142  }
143  case DT::VEC_INT:
144  {
145  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
146  hsize_t dims[1] = {att.get< std::vector< int > >().size()};
147  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
148  return vec_t_id;
149  }
150  case DT::VEC_LONG:
151  {
152  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
153  hsize_t dims[1] = {att.get< std::vector< long > >().size()};
154  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
155  return vec_t_id;
156  }
157  case DT::VEC_LONGLONG:
158  {
159  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
160  hsize_t dims[1] = {att.get< std::vector< long long > >().size()};
161  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
162  return vec_t_id;
163  }
164  case DT::VEC_UCHAR:
165  {
166  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
167  hsize_t dims[1] = {att.get< std::vector< unsigned char > >().size()};
168  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
169  return vec_t_id;
170  }
171  case DT::VEC_USHORT:
172  {
173  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
174  hsize_t dims[1] = {att.get< std::vector< unsigned short > >().size()};
175  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
176  return vec_t_id;
177  }
178  case DT::VEC_UINT:
179  {
180  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
181  hsize_t dims[1] = {att.get< std::vector< unsigned int > >().size()};
182  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
183  return vec_t_id;
184  }
185  case DT::VEC_ULONG:
186  {
187  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
188  hsize_t dims[1] = {att.get< std::vector< unsigned long > >().size()};
189  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
190  return vec_t_id;
191  }
192  case DT::VEC_ULONGLONG:
193  {
194  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
195  hsize_t dims[1] = {att.get< std::vector< unsigned long long > >().size()};
196  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
197  return vec_t_id;
198  }
199  case DT::VEC_FLOAT:
200  {
201  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
202  hsize_t dims[1] = {att.get< std::vector< float > >().size()};
203  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
204  return vec_t_id;
205  }
206  case DT::VEC_DOUBLE:
207  {
208  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
209  hsize_t dims[1] = {att.get< std::vector< double > >().size()};
210  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
211  return vec_t_id;
212  }
213  case DT::VEC_LONG_DOUBLE:
214  {
215  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
216  hsize_t dims[1] = {att.get< std::vector< long double > >().size()};
217  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
218  return vec_t_id;
219  }
220  case DT::VEC_STRING:
221  {
222  hid_t vec_t_id = H5Screate(H5S_SIMPLE);
223  hsize_t dims[1] = {att.get< std::vector< std::string > >().size()};
224  H5Sset_extent_simple(vec_t_id, 1, dims, nullptr);
225  return vec_t_id;
226  }
227  case DT::ARR_DBL_7:
228  {
229  hid_t array_t_id = H5Screate(H5S_SIMPLE);
230  hsize_t dims[1] = {7};
231  H5Sset_extent_simple(array_t_id, 1, dims, nullptr);
232  return array_t_id;
233  }
234  case DT::UNDEFINED:
235  throw std::runtime_error("Unknown Attribute datatype (HDF5 dataspace)");
236  default:
237  throw std::runtime_error("Datatype not implemented in HDF5 IO");
238  }
239 }
240 
241 inline std::string
242 concrete_h5_file_position(Writable* w)
243 {
244  std::stack< Writable* > hierarchy;
245  if( !w->abstractFilePosition )
246  w = w->parent;
247  while( w )
248  {
249  hierarchy.push(w);
250  w = w->parent;
251  }
252 
253  std::string pos;
254  while( !hierarchy.empty() )
255  {
256  pos += std::dynamic_pointer_cast< HDF5FilePosition >(hierarchy.top()->abstractFilePosition)->location;
257  hierarchy.pop();
258  }
259 
260  return auxiliary::replace_all(pos, "//", "/");
261 }
262 } // openPMD
Datatype
Concrete datatype of an object available at runtime.
Definition: Datatype.hpp:38
Public definitions of openPMD-api.
Definition: Date.cpp:28