Utopia  2
Framework for studying models of complex & adaptive systems.
hdffile.hh
Go to the documentation of this file.
1 #ifndef UTOPIA_DATAIO_HDFFILE_HH
2 #define UTOPIA_DATAIO_HDFFILE_HH
3 
4 #include <sstream>
5 #include <stdexcept>
6 #include <string>
7 #include <unordered_map>
8 
9 #include <hdf5.h>
10 #include <hdf5_hl.h>
11 
12 #include "hdfdataset.hh"
13 #include "hdfgroup.hh"
16 
17 namespace Utopia
18 {
19 namespace DataIO
20 {
21 
22 // Doxygen group for dataIO backend
23 // ++++++++++++++++++++++++++++++++++++++++++++++
61 class HDFFile final : public HDFObject< HDFCategory::file >
62 {
63  private:
68  std::shared_ptr< HDFGroup > _base_group;
69 
70  public:
76  void
77  swap(HDFFile& other)
78  {
79  using std::swap;
82  }
83 
96  void
97  open(std::string path, std::string access)
98  {
99  this->_log->info(
100  "Opening file at {} with access specifier {}", path, access);
101  if (is_valid())
102  {
103  throw std::runtime_error(
104  "File still bound to another HDF5 file when trying to call "
105  "'open'. Close first.");
106  }
107 
108  // create file access property list
109  hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);
110 
111  // set driver to stdio and close strongly, i.e., close all resources
112  // with the file
113  H5Pset_fapl_stdio(fapl);
114  H5Pset_fclose_degree(fapl, H5F_CLOSE_STRONG);
115 
116  if (access == "w")
117  {
118  bind_to(H5Fcreate(path.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, fapl),
119  &H5Fclose,
120  path);
121  }
122  else if (access == "r")
123  {
124  bind_to(
125  H5Fopen(path.c_str(), H5F_ACC_RDONLY, fapl), &H5Fclose, path);
126  }
127  else if (access == "r+")
128  {
129  bind_to(H5Fopen(path.c_str(), H5F_ACC_RDWR, fapl), &H5Fclose);
130  }
131  else if (access == "x")
132  {
133  bind_to(H5Fcreate(path.c_str(), H5F_ACC_EXCL, H5P_DEFAULT, fapl),
134  &H5Fclose,
135  path);
136  }
137  else if (access == "a")
138  {
139  hid_t file_test = H5Fopen(path.c_str(), H5F_ACC_RDWR, fapl);
140 
141  if (file_test < 0)
142  {
143  file_test =
144  H5Fcreate(path.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
145  }
146 
147  bind_to(file_test, &H5Fclose);
148  }
149  else
150  {
151  throw std::invalid_argument("wrong type of access specifier, "
152  "see documentation for allowed "
153  "values");
154  }
155 
156  _base_group = std::make_shared< HDFGroup >(*this, "/");
157  }
158 
164  std::shared_ptr< HDFGroup >
166  {
167  return _base_group;
168  }
169 
178  std::shared_ptr< HDFGroup >
179  open_group(std::string path)
180  {
181  // this removes the '/' at the beginning, because this is
182  // reserved for the basegroup
183  if (path[0] == '/')
184  {
185  path = path.substr(1, path.size() - 1);
186  }
187 
188  return _base_group->open_group(path);
189  }
190 
198  std::shared_ptr< HDFDataset >
199  open_dataset(std::string path,
200  std::vector< hsize_t > capacity = {},
201  std::vector< hsize_t > chunksizes = {},
202  std::size_t compresslevel = 0)
203  {
204  // this removes the '/' at the beginning, because this is
205  // reserved for the basegroup
206  if (path[0] == '/')
207  {
208  path = path.substr(1, path.size() - 1);
209  }
210 
211  return _base_group->open_dataset(
212  path, capacity, chunksizes, compresslevel);
213  }
214 
220  void
221  delete_group(std::string&& path)
222  {
223  _base_group->delete_group(std::forward< std::string&& >(path));
224  }
225 
229  void
231  {
232  if (is_valid())
233  {
234  H5Fflush(get_C_id(), H5F_SCOPE_GLOBAL);
235  }
236  }
237 
241  HDFFile() = default;
242 
249  HDFFile(HDFFile&& other) = default;
250 
258  HDFFile&
259  operator=(const HDFFile& other) = delete;
260 
268  HDFFile&
269  operator=(HDFFile&& other) = default;
270 
277  HDFFile(const HDFFile& other) = delete;
278 
289  HDFFile(std::string path, std::string access) : HDFFile()
290  {
291  // init the logger here because it is needed throughout the module
292  // and its existence is not guaranteed when it is initialized in `core`
293  _log = init_logger(log_data_io, spdlog::level::warn, false);
294  open(path, access);
295  }
296 
300  virtual ~HDFFile() = default;
301 };
302  // end of group HDF5 // end of group DataIO
305 
306 } // namespace DataIO
307 } // namespace Utopia
308 #endif
Class representing a HDF5 file.
Definition: hdffile.hh:62
HDFFile & operator=(HDFFile &&other)=default
Move assigment operator.
void open(std::string path, std::string access)
Open a file at location 'path' with access specifier 'access'. Keep in mind that if the object refers...
Definition: hdffile.hh:97
void flush()
Initiates an immediate write to disk of the data of the file.
Definition: hdffile.hh:230
HDFFile(HDFFile &&other)=default
Move constructor Construct a new HDFFile object via move semantics.
HDFFile(const HDFFile &other)=delete
Copy constructor. Explicitly deleted, hence cannot be used.
std::shared_ptr< HDFGroup > get_basegroup()
Get the basegroup object via shared ptr.
Definition: hdffile.hh:165
std::shared_ptr< HDFGroup > open_group(std::string path)
Open group at path 'path', creating all intermediate objects in the path. Separation character is: /.
Definition: hdffile.hh:179
HDFFile()=default
Construct a new default HDFFile object.
HDFFile(std::string path, std::string access)
Construct a new HDFFile object.
Definition: hdffile.hh:289
virtual ~HDFFile()=default
Destroy the HDFFile object.
std::shared_ptr< HDFGroup > _base_group
Pointer to base group of the file.
Definition: hdffile.hh:68
void swap(HDFFile &other)
Function for exchanging states.
Definition: hdffile.hh:77
void delete_group(std::string &&path)
deletes the group pointed to by absolute path 'path'
Definition: hdffile.hh:221
std::shared_ptr< HDFDataset > open_dataset(std::string path, std::vector< hsize_t > capacity={}, std::vector< hsize_t > chunksizes={}, std::size_t compresslevel=0)
open dataset
Definition: hdffile.hh:199
HDFFile & operator=(const HDFFile &other)=delete
Copy assignment operator, explicitly deleted, hence cannot be used.
Common base class for all HDF5 classes in the DATAIO Module i.e., for all classes that wrap HDF5-C-Li...
Definition: hdfobject.hh:37
virtual bool is_valid() const
Check if the object is still valid.
Definition: hdfobject.hh:143
std::shared_ptr< spdlog::logger > _log
pointer to the logger for dataio
Definition: hdfobject.hh:56
hid_t get_C_id() const
Get the C id object.
Definition: hdfobject.hh:120
void bind_to(hid_t id, std::function< herr_t(hid_t) > closing_func, std::string path={})
Open the object and bind it to a HDF5 object identified by 'id' with name 'path'. Object should be cr...
Definition: hdfobject.hh:186
void swap(WriteTask< BGB, DW, DB, AWG, AWD > &lhs, WriteTask< BGB, DW, DB, AWG, AWD > &rhs)
Swaps the state of lhs and rhs.
Definition: write_task.hh:240
const std::string log_data_io
Definition: logging.hh:19
std::shared_ptr< spdlog::logger > init_logger(const std::string name, const spdlog::level::level_enum level, const bool throw_on_exist=true)
Initialize a logger with a certain name and log level.
Definition: logging.hh:31
This is the central file of the HDF5 dataIO module of Utopia and provides a class for writing to,...
This file provides a class for creating and managing groups in a HDF5 file, which then can create oth...
This file provides metafunctions for automatically determining the nature of a C/C++ types at compile...
Definition: agent.hh:11