kspaceFirstOrder3D-OMP  1.2
The C++ implementation of the k-wave toolbox for the time-domain simulation of acoustic wave fields in 3D
Hdf5File.cpp
Go to the documentation of this file.
1 /**
2  * @file Hdf5File.cpp
3  *
4  * @author Jiri Jaros \n
5  * Faculty of Information Technology \n
6  * Brno University of Technology \n
7  * jarosjir@fit.vutbr.cz
8  *
9  * @brief The implementation file containing the HDF5 related classes.
10  *
11  * @version kspaceFirstOrder3D 2.16
12  *
13  * @date 27 July 2012, 14:14 (created) \n
14  * 04 September 2017, 10:54 (revised)
15  *
16  * @copyright Copyright (C) 2017 Jiri Jaros and Bradley Treeby.
17  *
18  * This file is part of the C++ extension of the [k-Wave Toolbox](http://www.k-wave.org).
19  *
20  * This file is part of the k-Wave. k-Wave is free software: you can redistribute it and/or modify it under the terms
21  * of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the
22  * License, or (at your option) any later version.
23  *
24  * k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
25  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
26  * more details.
27  *
28  * You should have received a copy of the GNU Lesser General Public License along with k-Wave.
29  * If not, see [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/).
30  */
31 
32 
33 #include <stdexcept>
34 
35 // Linux build
36 #ifdef __linux__
37  #include <unistd.h>
38 #endif
39 
40 //Windows 64 build
41 #ifdef _WIN64
42  #include<Winsock2.h>
43  #pragma comment(lib, "Ws2_32.lib")
44 #endif
45 
46 #include <Hdf5/Hdf5File.h>
47 #include <Parameters/Parameters.h>
48 #include <Logger/Logger.h>
49 
50 using std::ios;
51 using std::string;
52 
53 //--------------------------------------------------------------------------------------------------------------------//
54 //---------------------------------------------------- Constants -----------------------------------------------------//
55 //--------------------------------------------------------------------------------------------------------------------//
56 
57 
58 const string Hdf5File::kMatrixDomainTypeName = "domain_type";
59 const string Hdf5File::kMatrixDataTypeName = "data_type";
60 
61 const string Hdf5File::kMatrixDomainTypeNames[] = {"real", "complex"};
62 const string Hdf5File::kMatrixDataTypeNames[] = {"float", "long"};
63 
64 
65 //--------------------------------------------------------------------------------------------------------------------//
66 //------------------------------------------------- Public methods ---------------------------------------------------//
67 //--------------------------------------------------------------------------------------------------------------------//
68 
69 
70 /**
71  * Constructor.
72  */
74  : mFile(H5I_BADID), mFileName("")
75 {
76 
77 }// end of constructor
78 //----------------------------------------------------------------------------------------------------------------------
79 
80 /**
81  * Destructor.
82  */
84 {
85  if (isOpen()) close();
86 } //end of destructor
87 //----------------------------------------------------------------------------------------------------------------------
88 
89 
90 /**
91  * Create an HDF5 file.
92  */
93 void Hdf5File::create(const string& fileName,
94  unsigned int flags)
95 {
96  // file is opened
97  if (isOpen())
98  {
99  throw ios::failure(Logger::formatMessage(kErrFmtCannotRecreateFile, fileName.c_str()));
100  }
101 
102  // Create a new file using default properties.
103  mFileName = fileName;
104 
105  mFile = H5Fcreate(fileName.c_str(), flags, H5P_DEFAULT, H5P_DEFAULT);
106 
107  if (mFile < 0)
108  {
109  throw ios::failure(Logger::formatMessage(kErrFmtCannotCreateFile, fileName.c_str()));
110  }
111 }// end of create
112 //----------------------------------------------------------------------------------------------------------------------
113 
114 /**
115  * Open the HDF5 file.
116  */
117 void Hdf5File::open(const string& fileName,
118  unsigned int flags)
119 {
120  const char* cFileName = fileName.c_str();
121 
122  if (isOpen())
123  {
124  throw ios::failure(Logger::formatMessage(kErrFmtCannotReopenFile, cFileName));
125  };
126 
127  mFileName = fileName;
128 
129  if (H5Fis_hdf5(cFileName) == 0)
130  {
131  throw ios::failure(Logger::formatMessage(kErrFmtNotHdf5File, cFileName));
132  }
133 
134  mFile = H5Fopen(cFileName, flags, H5P_DEFAULT);
135 
136  if (mFile < 0)
137  {
138  throw ios::failure(Logger::formatMessage(kErrFmtFileNotOpen, cFileName));
139  }
140 }// end of open
141 //----------------------------------------------------------------------------------------------------------------------
142 
143 /**
144  * Can I access the file.
145  */
146 bool Hdf5File::canAccess(const string& fileName)
147 {
148  #ifdef __linux__
149  return (access(fileName.c_str(), F_OK) == 0);
150  #endif
151 
152  #ifdef _WIN64
153  return (_access_s(fileName.c_str(), 0) == 0 );
154  #endif
155 }// end of canAccess
156 //----------------------------------------------------------------------------------------------------------------------
157 
158 /**
159  * Close the HDF5 file.
160  */
162 {
163  // Terminate access to the file.
164  herr_t status = H5Fclose(mFile);
165  if (status < 0)
166  {
167  throw ios::failure(Logger::formatMessage(kErrFmtCannotCloseFile, mFileName.c_str()));
168  }
169 
170  mFileName = "";
171  mFile = H5I_BADID;
172 }// end of close
173 //----------------------------------------------------------------------------------------------------------------------
174 
175 /**
176  * Create a HDF5 group at a specified place in the file tree.
177  */
178 hid_t Hdf5File::createGroup(const hid_t parentGroup,
179  MatrixName& groupName)
180 {
181  hid_t group = H5Gcreate(parentGroup, groupName.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
182 
183  //if error
184  if (group == H5I_INVALID_HID)
185  {
186  throw ios::failure(Logger::formatMessage(kErrFmtCannotCreateGroup, groupName.c_str(), mFileName.c_str()));
187  }
188 
189  return group;
190 };// end of createGroup
191 //----------------------------------------------------------------------------------------------------------------------
192 
193 /**
194  * Open a HDF5 group at a specified place in the file tree.
195  */
196 hid_t Hdf5File::openGroup(const hid_t parentGroup,
197  MatrixName& groupName)
198 {
199  hid_t group = H5Gopen(parentGroup, groupName.c_str(), H5P_DEFAULT);
200 
201  //if error
202  if (group == H5I_INVALID_HID)
203  {
204  throw ios::failure(Logger::formatMessage(kErrFmtCannotOpenGroup, groupName.c_str(), mFileName.c_str()));
205  }
206 
207  return group;
208 }// end of openGroup
209 //----------------------------------------------------------------------------------------------------------------------
210 
211 /**
212  * Close a group.
213  */
214 void Hdf5File::closeGroup(const hid_t group)
215 {
216  H5Gclose(group);
217 }// end of closeGroup
218 //----------------------------------------------------------------------------------------------------------------------
219 
220 /**
221  * Open a dataset at a specified place in the file tree.
222  */
223 hid_t Hdf5File::openDataset(const hid_t parentGroup,
224  MatrixName& datasetName)
225 {
226  // Open dataset
227  hid_t dataset = H5Dopen(parentGroup, datasetName.c_str(), H5P_DEFAULT);
228 
229  if (dataset == H5I_INVALID_HID)
230  {
231  throw ios::failure(Logger::formatMessage(kErrFmtCannotOpenDataset, mFileName.c_str(), datasetName.c_str()));
232  }
233 
234  return dataset;
235 }// end of openDataset
236 //----------------------------------------------------------------------------------------------------------------------
237 
238 /**
239  * Create dataset.
240  */
241 hid_t Hdf5File::createDataset(const hid_t parentGroup,
242  MatrixName& datasetName,
243  const DimensionSizes& dimensionSizes,
244  const DimensionSizes& chunkSizes,
245  const Hdf5File::MatrixDataType matrixDataType,
246  const size_t compressionLevel)
247 {
248  const int rank = (dimensionSizes.is3D()) ? 3 : 4;
249 
250  hsize_t dims [4];
251  hsize_t chunk[4];
252 
253  // 3D dataset
254  if (dimensionSizes.is3D())
255  {
256  dims[0] = dimensionSizes.nz;
257  dims[1] = dimensionSizes.ny;
258  dims[2] = dimensionSizes.nx;
259 
260  chunk[0] = chunkSizes.nz;
261  chunk[1] = chunkSizes.ny;
262  chunk[2] = chunkSizes.nx;
263  }
264  else // 4D dataset
265  {
266  dims[0] = dimensionSizes.nt;
267  dims[1] = dimensionSizes.nz;
268  dims[2] = dimensionSizes.ny;
269  dims[3] = dimensionSizes.nx;
270 
271  chunk[0] = chunkSizes.nt;
272  chunk[1] = chunkSizes.nz;
273  chunk[2] = chunkSizes.ny;
274  chunk[3] = chunkSizes.nx;
275  }
276 
277  hid_t propertyList;
278  herr_t status;
279 
280  hid_t dataspace = H5Screate_simple(rank, dims, NULL);
281 
282  // set chunk size
283  propertyList = H5Pcreate(H5P_DATASET_CREATE);
284 
285  status = H5Pset_chunk(propertyList, rank, chunk);
286  if (status < 0)
287  {
288  throw ios::failure(Logger::formatMessage(kErrFmtCannotOpenDataset, mFileName.c_str(), datasetName.c_str()));
289  }
290 
291  // set compression level
292  status = H5Pset_deflate(propertyList, static_cast<unsigned int>(compressionLevel));
293  if (status < 0)
294  {
296  mFileName.c_str(),
297  datasetName.c_str(),
298  compressionLevel));
299  }
300 
301  const hid_t datasetType = (matrixDataType == MatrixDataType::kFloat) ? H5T_NATIVE_FLOAT : H5T_STD_U64LE;
302 
303  // create dataset
304  hid_t dataset = H5Dcreate(parentGroup,
305  datasetName.c_str(),
306  datasetType,
307  dataspace,
308  H5P_DEFAULT,
309  propertyList,
310  H5P_DEFAULT);
311 
312  if (dataset == H5I_INVALID_HID)
313  {
314  throw ios::failure(Logger::formatMessage(kErrFmtCannotOpenDataset, mFileName.c_str(), datasetName.c_str()));
315  }
316 
317  H5Pclose(propertyList);
318  return dataset;
319 }// end of createDataset
320 //----------------------------------------------------------------------------------------------------------------------
321 
322 /**
323  * Close dataset.
324  */
325 void Hdf5File::closeDataset(const hid_t dataset)
326 {
327  H5Dclose(dataset);
328 }// end of closeDataset
329 //----------------------------------------------------------------------------------------------------------------------
330 
331 /**
332  * Write a hyperslab into the dataset, float version.
333  */
334 template<class T>
335 void Hdf5File::writeHyperSlab(const hid_t dataset,
336  const DimensionSizes& position,
337  const DimensionSizes& size,
338  const T* data)
339 {
340  herr_t status;
341  hid_t filespace, memspace;
342 
343  // Get file space to find out number of dimensions
344  filespace = H5Dget_space(dataset);
345  const int rank = H5Sget_simple_extent_ndims(filespace);
346 
347  // Select sizes and positions, windows hack
348  hsize_t nElement[4];
349  hsize_t offset[4];
350 
351  // 3D dataset
352  if (rank == 3)
353  {
354  nElement[0] = size.nz;
355  nElement[1] = size.ny;
356  nElement[2] = size.nx;
357 
358  offset[0] = position.nz;
359  offset[1] = position.ny;
360  offset[2] = position.nx;
361  }
362  else // 4D dataset
363  {
364  nElement[0] = size.nt;
365  nElement[1] = size.nz;
366  nElement[2] = size.ny;
367  nElement[3] = size.nx;
368 
369  offset[0] = position.nt;
370  offset[1] = position.nz;
371  offset[2] = position.ny;
372  offset[3] = position.nx;
373  }
374 
375  // select hyperslab
376  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, nElement, NULL);
377  if (status < 0)
378  {
379  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
380  }
381 
382  // assign memspace
383  memspace = H5Screate_simple(rank, nElement, NULL);
384 
385 
386  // set status to error value to catch unknown data type.
387  status = -1;
388  // write based on datatype
389  if (std::is_same<T, size_t>())
390  {
391  status = H5Dwrite(dataset, H5T_STD_U64LE, memspace, filespace, H5P_DEFAULT, data);
392  }
393  if (std::is_same<T, float>())
394  {
395  status = H5Dwrite(dataset, H5T_NATIVE_FLOAT, memspace, filespace, H5P_DEFAULT, data);
396  }
397 
398  if (status < 0)
399  {
400  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
401  }
402 
403  H5Sclose(memspace);
404  H5Sclose(filespace);
405 }// end of writeHyperSlab
406 //----------------------------------------------------------------------------------------------------------------------
407 
408 /**
409  * Write a hyperslab into the dataset, float version explicit instance.
410  */
411 template
412 void Hdf5File::writeHyperSlab<float>(const hid_t dataset,
413  const DimensionSizes& position,
414  const DimensionSizes& size,
415  const float* data);
416 //----------------------------------------------------------------------------------------------------------------------
417 /**
418  * Write a hyperslab into the dataset, index version explicit instance.
419  */
420 template
421 void Hdf5File::writeHyperSlab<size_t>(const hid_t dataset,
422  const DimensionSizes& position,
423  const DimensionSizes& size,
424  const size_t* data);
425 //----------------------------------------------------------------------------------------------------------------------
426 
427 
428 /**
429  * Write a cuboid selected within the matrixData into a hyperslab.
430  */
431 void Hdf5File::writeCuboidToHyperSlab(const hid_t dataset,
432  const DimensionSizes & hyperslabPosition,
433  const DimensionSizes & cuboidPosition,
434  const DimensionSizes & cuboidSize,
435  const DimensionSizes & matrixDimensions,
436  const float* matrixData)
437 {
438  herr_t status;
439  hid_t filespace, memspace;
440 
441  constexpr int rank = 4;
442 
443  // Select sizes and positions
444  // The T here is always 1 (only one timestep)
445  hsize_t slabSize[rank] = {1, cuboidSize.nz, cuboidSize.ny, cuboidSize.nx};
446  hsize_t offsetInDataset[rank] = {hyperslabPosition.nt,
447  hyperslabPosition.nz,
448  hyperslabPosition.ny,
449  hyperslabPosition.nx};
450  hsize_t offsetInMatrixData[] = {cuboidPosition.nz, cuboidPosition.ny, cuboidPosition.nx};
451  hsize_t matrixSize [] = {matrixDimensions.nz, matrixDimensions.ny, matrixDimensions.nx};
452 
453 
454  // select hyperslab in the HDF5 dataset
455  filespace = H5Dget_space(dataset);
456  status = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offsetInDataset, NULL, slabSize, NULL);
457  if (status < 0)
458  {
459  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
460  }
461 
462 
463  // assign memspace and select the cuboid in the sampled matrix
464  memspace = H5Screate_simple(3, matrixSize, NULL);
465  status = H5Sselect_hyperslab(memspace,
466  H5S_SELECT_SET,
467  offsetInMatrixData,
468  NULL,
469  slabSize + 1, // Slab size has to be 3D in this case (done by skipping the T dimension)
470  NULL);
471  if (status < 0)
472  {
473  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
474  }
475 
476  // Write the data
477  status = H5Dwrite(dataset, H5T_NATIVE_FLOAT, memspace, filespace, H5P_DEFAULT, matrixData);
478  if (status < 0)
479  {
480  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
481  }
482 
483  // close memspace and filespace
484  H5Sclose(memspace);
485  H5Sclose(filespace);
486 }// end of writeCuboidToHyperSlab
487 //----------------------------------------------------------------------------------------------------------------------
488 
489 /**
490  * Write sensor data selected by the sensor mask.
491  */
492 void Hdf5File::writeSensorByMaskToHyperSlab(const hid_t dataset,
493  const DimensionSizes& hyperslabPosition,
494  const size_t indexSensorSize,
495  const size_t* indexSensorData,
496  const DimensionSizes& matrixDimensions,
497  const float* matrixData)
498 {
499  herr_t status;
500  hid_t filespace, memspace;
501 
502  constexpr int rank = 3;
503 
504  // Select sizes and positions
505  // Only one timestep
506  hsize_t slabSize[rank] = {1, 1, indexSensorSize};
507  hsize_t offsetInDataset[rank] = {hyperslabPosition.nz, hyperslabPosition.ny, hyperslabPosition.nx };
508  // treat as a 1D array
509  //hsize_t MatrixSize [] = {MatrixDimensions.Z * MatrixDimensions.Y * MatrixDimensions.X};
510  hsize_t matrixSize = matrixDimensions.nz * matrixDimensions.ny * matrixDimensions.nx;
511 
512 
513  // select hyperslab in the HDF5 dataset
514  filespace = H5Dget_space(dataset);
515  status = H5Sselect_hyperslab(filespace,
516  H5S_SELECT_SET,
517  offsetInDataset,
518  NULL,
519  slabSize,
520  NULL);
521  if (status < 0)
522  {
523  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
524  }
525 
526  // assign 1D memspace and select the elements within the array
527  memspace = H5Screate_simple(1, &matrixSize, NULL);
528  status = H5Sselect_elements(memspace,
529  H5S_SELECT_SET,
530  indexSensorSize,
531  ( hsize_t *) (indexSensorData));
532  if (status < 0)
533  {
534  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
535  }
536 
537  // Write the data
538  status = H5Dwrite(dataset,
539  H5T_NATIVE_FLOAT,
540  memspace,
541  filespace,
542  H5P_DEFAULT,
543  matrixData);
544  if (status < 0)
545  {
546  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, ""));
547  }
548 
549  // close memspace and filespace
550  H5Sclose(memspace);
551  H5Sclose(filespace);
552 }// end of writeSensorbyMaskToHyperSlab
553 //----------------------------------------------------------------------------------------------------------------------
554 
555 /**
556  * Write a scalar value at a specified place in the file tree.
557  */
558 template<class T>
559 void Hdf5File::writeScalarValue(const hid_t parentGroup,
560  MatrixName& datasetName,
561  const T value)
562 {
563  constexpr int rank = 3;
564  const hsize_t dims[] = {1, 1, 1};
565 
566  hid_t dataset = H5I_INVALID_HID;
567  hid_t dataspace = H5I_INVALID_HID;
568  hid_t datatype = H5I_INVALID_HID;
569  herr_t status;
570 
571  if (std::is_same<T, float>())
572  {
573  datatype = H5T_NATIVE_FLOAT;
574  }
575 
576  if (std::is_same<T, size_t>())
577  {
578  datatype = H5T_STD_U64LE;
579  }
580 
581  const char* cDatasetName = datasetName.c_str();
582  if (H5LTfind_dataset(parentGroup, cDatasetName) == 1)
583  { // dataset already exists (from previous simulation leg) open it
584  dataset = openDataset(parentGroup,cDatasetName);
585  }
586  else
587  { // dataset does not exist yet -> create it
588  dataspace = H5Screate_simple(rank, dims, NULL);
589  dataset = H5Dcreate(parentGroup,
590  cDatasetName,
591  datatype,
592  dataspace,
593  H5P_DEFAULT,
594  H5P_DEFAULT,
595  H5P_DEFAULT);
596  }
597 
598  // was created correctly?
599  if (dataset == H5I_INVALID_HID)
600  {
601  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, cDatasetName));
602  }
603 
604  status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, &value);
605  if (status < 0)
606  {
607  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteDataset, cDatasetName));
608  }
609 
610  if (std::is_same<T, float>())
611  {
612  writeMatrixDataType(parentGroup, datasetName, MatrixDataType::kFloat);
613  }
614  if (std::is_same<T, size_t>())
615  {
616  writeMatrixDataType(parentGroup, datasetName, MatrixDataType::kLong);
617  }
618  writeMatrixDomainType(parentGroup, datasetName, MatrixDomainType::kReal);
619 
620 } // end of writeScalarValue
621 //----------------------------------------------------------------------------------------------------------------------
622 
623 /**
624  * Write the scalar value under a specified group, float value explicit instance.
625  */
626 template
627 void Hdf5File::writeScalarValue<float>
628  (const hid_t parentGroup,
629  MatrixName& datasetName,
630  const float value);
631 //----------------------------------------------------------------------------------------------------------------------
632 /**
633  * Write the scalar value under a specified group, index value explicit instance.
634  */
635 template
636 void Hdf5File::writeScalarValue<size_t>
637  (const hid_t parentGroup,
638  MatrixName& datasetName,
639  const size_t value);
640 //----------------------------------------------------------------------------------------------------------------------
641 
642 /**
643  * Read the scalar value under a specified group.
644  */
645 template<class T>
646 void Hdf5File::readScalarValue(const hid_t parentGroup,
647  MatrixName& datasetName,
648  T& value)
649 {
650  readCompleteDataset(parentGroup, datasetName, DimensionSizes(1,1,1), &value);
651 } // end of readScalarValue
652 //----------------------------------------------------------------------------------------------------------------------
653 
654 /**
655  * Read the scalar value under a specified group, float value, explicit instance.
656  */
657 template
658 void Hdf5File::readScalarValue<float>
659  (const hid_t parentGroup,
660  MatrixName& datasetName,
661  float& value);
662 //----------------------------------------------------------------------------------------------------------------------
663 /**
664  * Read the scalar value under a specified group, float value, explicit instance
665  *
666  */
667 template
668 void Hdf5File::readScalarValue<size_t>
669  (const hid_t parentGroup,
670  MatrixName& datasetName,
671  size_t& value);
672 //----------------------------------------------------------------------------------------------------------------------
673 
674 /**
675  * Read data from the dataset at a specified place in the file tree, float version.
676  */
677 template<class T>
678 void Hdf5File::readCompleteDataset(const hid_t parentGroup,
679  MatrixName& datasetName,
680  const DimensionSizes& dimensionSizes,
681  T* data)
682 { const char* cDatasetName = datasetName.c_str();
683  // Check Dimensions sizes
684  if (getDatasetDimensionSizes(parentGroup, datasetName).nElements() != dimensionSizes.nElements())
685  {
686  throw ios::failure(Logger::formatMessage(kErrFmtBadDimensionSizes, cDatasetName));
687  }
688 
689  herr_t status = -1;
690  if (std::is_same<T, float>())
691  {
692  status = H5LTread_dataset(parentGroup, cDatasetName, H5T_NATIVE_FLOAT, data);
693  }
694  if (std::is_same<T, size_t>())
695  {
696  status = H5LTread_dataset(parentGroup, cDatasetName, H5T_STD_U64LE, data);
697  }
698 
699  if (status < 0)
700  {
701  throw ios::failure(Logger::formatMessage(kErrFmtCannotReadDataset, cDatasetName));
702  }
703 }// end of readCompleteDataset
704 //----------------------------------------------------------------------------------------------------------------------
705 
706 /**
707  * Read data from the dataset at a specified place in the file tree, float version explicit instance.
708  */
709 template
710 void Hdf5File::readCompleteDataset<float>
711  (const hid_t parentGroup,
712  MatrixName& datasetName,
713  const DimensionSizes& dimensionSizes,
714  float* data);
715 //----------------------------------------------------------------------------------------------------------------------
716 /**
717  * Read data from the dataset at a specified place in the file tree, index version explicit instance.
718  */
719 template
720 void Hdf5File::readCompleteDataset<size_t>
721  (const hid_t parentGroup,
722  MatrixName& datasetName,
723  const DimensionSizes& dimensionSizes,
724  size_t* data);
725 //----------------------------------------------------------------------------------------------------------------------
726 
727 
728  /**
729  * Get dimension sizes of the dataset at a specified place in the file tree.
730  */
732  MatrixName& datasetName)
733 {
734  const size_t ndims = getDatasetNumberOfDimensions(parentGroup, datasetName);
735  hsize_t dims[4] = { 0, 0, 0, 0};
736 
737  herr_t status = H5LTget_dataset_info(parentGroup, datasetName.c_str(), dims, NULL, NULL);
738  if (status < 0)
739  {
740  throw ios::failure(Logger::formatMessage(kErrFmtCannotReadDataset, datasetName.c_str()));
741  }
742 
743  if (ndims == 3)
744  {
745  return DimensionSizes(dims[2], dims[1], dims[0]);
746  }
747  else
748  {
749  return DimensionSizes(dims[3], dims[2], dims[1], dims[0]);
750  }
751 }// end of getDatasetDimensionSizes
752 //----------------------------------------------------------------------------------------------------------------------
753 
754 /**
755 * Get number of dimensions of the dataset under a specified group.
756  */
757 size_t Hdf5File::getDatasetNumberOfDimensions(const hid_t parentGroup,
758  MatrixName& datasetName)
759 {
760  int dims = 0;
761 
762  herr_t status = H5LTget_dataset_ndims(parentGroup, datasetName.c_str(), &dims);
763  if (status < 0)
764  {
765  throw ios::failure(Logger::formatMessage(kErrFmtCannotReadDataset, datasetName.c_str()));
766  }
767 
768  return dims;
769 }// end of getDatasetNumberOfDimensions
770 //----------------------------------------------------------------------------------------------------------------------
771 
772 /**
773  * Get dataset element count at a specified place in the file tree.
774  */
775 size_t Hdf5File::getDatasetSize(const hid_t parentGroup,
776  MatrixName& datasetName)
777 {
778  hsize_t dims[3] = {0, 0, 0};
779 
780  herr_t status = H5LTget_dataset_info(parentGroup, datasetName.c_str(), dims, NULL, NULL);
781  if (status < 0)
782  {
783  throw ios::failure(Logger::formatMessage(kErrFmtCannotReadDataset, datasetName.c_str()));
784  }
785 
786  return dims[0] * dims[1] * dims[2];
787 }// end of getDatasetSize
788 //----------------------------------------------------------------------------------------------------------------------
789 
790 /**
791  * Write matrix data type into the dataset at a specified place in the file tree.
792  */
793 void Hdf5File::writeMatrixDataType(const hid_t parentGroup,
794  MatrixName& datasetName,
795  const MatrixDataType& matrixDataType)
796 {
797  writeStringAttribute(parentGroup,
798  datasetName,
800  kMatrixDataTypeNames[static_cast<int>(matrixDataType)]);
801 }// end of writeMatrixDataType
802 //----------------------------------------------------------------------------------------------------------------------
803 
804 /**
805  * Write matrix data type into the dataset at a specified place in the file tree.
806  */
807 void Hdf5File::writeMatrixDomainType(const hid_t parentGroup,
808  MatrixName& datasetName,
809  const MatrixDomainType& matrixDomainType)
810 {
811  writeStringAttribute(parentGroup,
812  datasetName,
814  kMatrixDomainTypeNames[static_cast<int>(matrixDomainType)]);
815 }// end of writeMatrixDomainType
816 //----------------------------------------------------------------------------------------------------------------------
817 
818 /**
819  * Read matrix data type from the dataset at a specified place in the file tree.
820  */
822  MatrixName& datasetName)
823 {
824  const string paramValue = readStringAttribute(parentGroup, datasetName, kMatrixDataTypeName);
825 
826  if (paramValue == kMatrixDataTypeNames[0])
827  {
828  return static_cast<MatrixDataType>(0);
829  }
830  if (paramValue == kMatrixDataTypeNames[1])
831  {
832  return static_cast<MatrixDataType>(1);
833  }
834 
836  datasetName.c_str(),
837  kMatrixDataTypeName.c_str(),
838  paramValue.c_str()));
839 
840 // this will never be executed (just to prevent warning)
841  return static_cast<MatrixDataType> (0);
842 }// end of readMatrixDataType
843 //-----------------------------------------------------------------------------------------------------------------------
844 
845 /**
846  * Read matrix dataset domain type at a specified place in the file tree.
847  */
849  MatrixName& datasetName)
850 {
851  const string paramValue = readStringAttribute(parentGroup, datasetName, kMatrixDomainTypeName);
852 
853  if (paramValue == kMatrixDomainTypeNames[0])
854  {
855  return static_cast<MatrixDomainType> (0);
856  }
857  if (paramValue == kMatrixDomainTypeNames[1])
858  {
859  return static_cast<MatrixDomainType> (1);
860  }
861 
863  datasetName.c_str(),
864  kMatrixDomainTypeName.c_str(),
865  paramValue.c_str()));
866 
867  // This line will never be executed (just to prevent warning)
868  return static_cast<MatrixDomainType> (0);
869 }// end of readMatrixDomainType
870 //----------------------------------------------------------------------------------------------------------------------
871 
872 
873 /**
874  * Write integer attribute at a specified place in the file tree.
875  */
876 void Hdf5File::writeStringAttribute(const hid_t parentGroup,
877  MatrixName& datasetName,
878  MatrixName& attributeName,
879  const string& value)
880 {
881  herr_t status = H5LTset_attribute_string(parentGroup, datasetName.c_str(), attributeName.c_str(), value.c_str());
882  if (status < 0)
883  {
884  throw ios::failure(Logger::formatMessage(kErrFmtCannotWriteAttribute, attributeName.c_str(), datasetName.c_str()));
885  }
886 }// end of writeIntAttribute
887 //----------------------------------------------------------------------------------------------------------------------
888 
889 /**
890  * Read integer attribute at a specified place in the file tree.
891  */
892 string Hdf5File::readStringAttribute(const hid_t parentGroup,
893  MatrixName& datasetName,
894  MatrixName& attributeName)
895 {
896  char value[256] = "";
897  herr_t status = H5LTget_attribute_string(parentGroup, datasetName.c_str(), attributeName.c_str(), value);
898 
899  if (status < 0)
900  {
901  throw ios::failure(Logger::formatMessage(kErrFmtCannotReadAttribute, attributeName.c_str(), datasetName.c_str()));
902  }
903 
904  return value;
905 }// end of readIntAttribute
906 //----------------------------------------------------------------------------------------------------------------------
907 
908 
909 //--------------------------------------------------------------------------------------------------------------------//
910 //------------------------------------------------- Protected methods ------------------------------------------------//
911 //--------------------------------------------------------------------------------------------------------------------//
912 
913 
914 //--------------------------------------------------------------------------------------------------------------------//
915 //------------------------------------------------ Private methods ---------------------------------------------------//
916 //--------------------------------------------------------------------------------------------------------------------//
917 
void writeStringAttribute(const hid_t parentGroup, MatrixName &datasetName, MatrixName &attributeName, const std::string &value)
Write string attribute into the dataset under the root group.
Definition: Hdf5File.cpp:876
hid_t openDataset(const hid_t parentGroup, MatrixName &datasetName)
Open a dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:223
ErrorMessage kErrFmtCannotCloseFile
HDF5 error message.
Definition: ErrorMessages.h:73
void create(const std::string &fileName, unsigned int flags=H5F_ACC_TRUNC)
Create the HDF5 file.
Definition: Hdf5File.cpp:93
void writeScalarValue(const hid_t parentGroup, MatrixName &datasetName, const T value)
Write the scalar value under a specified group.
Definition: Hdf5File.cpp:559
static const std::string kMatrixDomainTypeName
String representation of the Domain type in the HDF5 file.
Definition: Hdf5File.h:858
ErrorMessage kErrFmtBadDimensionSizes
HDF5 error message.
Definition: ErrorMessages.h:82
size_t nz
Number of elements in the z direction.
ErrorMessage kErrFmtCannotReopenFile
HDF5 error message.
Definition: ErrorMessages.h:70
virtual ~Hdf5File()
Destructor.
Definition: Hdf5File.cpp:83
ErrorMessage kErrFmtCannotReadDataset
HDF5 error message.
Definition: ErrorMessages.h:79
hid_t openGroup(const hid_t parentGroup, MatrixName &groupName)
Open a HDF5 group at a specified place in the file tree.
Definition: Hdf5File.cpp:196
void open(const std::string &fileName, unsigned int flags=H5F_ACC_RDONLY)
Open the HDF5 file.
Definition: Hdf5File.cpp:117
The header file containing the HDF5 related classes.
void writeCuboidToHyperSlab(const hid_t dataset, const DimensionSizes &hyperslabPosition, const DimensionSizes &cuboidPosition, const DimensionSizes &cuboidSize, const DimensionSizes &matrixDimensions, const float *matrixData)
Write a cuboid selected within the matrixData into a hyperslab.
Definition: Hdf5File.cpp:431
size_t getDatasetNumberOfDimensions(const hid_t parentGroup, MatrixName &datasetName)
Get number of dimensions of the dataset under a specified group.
Definition: Hdf5File.cpp:757
ErrorMessage kErrFmtCannotCreateGroup
HDF5 error message.
DimensionSizes getDatasetDimensionSizes(const hid_t parentGroup, MatrixName &datasetName)
Get dimension sizes of the dataset under a specified group.
Definition: Hdf5File.cpp:731
std::string mFileName
File name.
Definition: Hdf5File.h:870
hid_t mFile
HDF file handle.
Definition: Hdf5File.h:868
ErrorMessage kErrFmtCannotRecreateFile
HDF5 error message.
Definition: ErrorMessages.h:67
ErrorMessage kErrFmtBadAttributeValue
HDF5 error message.
Definition: ErrorMessages.h:97
static bool canAccess(const std::string &fileName)
Can I access the file.
Definition: Hdf5File.cpp:146
void writeSensorByMaskToHyperSlab(const hid_t dataset, const DimensionSizes &hyperslabPosition, const size_t indexSensorSize, const size_t *indexSensorData, const DimensionSizes &matrixDimensions, const float *matrixData)
Write sensor data selected by the sensor mask - Occasionally very slow, do not use! ...
Definition: Hdf5File.cpp:492
The header file containing the parameters of the simulation.
void writeMatrixDomainType(const hid_t parentGroup, MatrixName &datasetName, const MatrixDomainType &matrixDomainType)
Write matrix data type into the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:807
void closeDataset(const hid_t dataset)
Close dataset.
Definition: Hdf5File.cpp:325
void readScalarValue(const hid_t parentGroup, MatrixName &datasetName, T &value)
Read the scalar value under a specified group.
Definition: Hdf5File.cpp:646
size_t nt
Number of time steps (for time series datasets).
size_t getDatasetSize(const hid_t parentGroup, MatrixName &datasetName)
Get dataset element count at a specified place in the file tree.
Definition: Hdf5File.cpp:775
void writeMatrixDataType(const hid_t parentGroup, MatrixName &datasetName, const MatrixDataType &matrixDataType)
Write matrix data type into the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:793
ErrorMessage kErrFmtCannotOpenGroup
HDF5 error message.
std::string readStringAttribute(const hid_t parentGroup, MatrixName &datasetName, MatrixName &attributeName)
Read string attribute from the dataset under the root group.
Definition: Hdf5File.cpp:892
hid_t createGroup(const hid_t parentGroup, MatrixName &groupName)
Create a HDF5 group at a specified place in the file tree.
Definition: Hdf5File.cpp:178
ErrorMessage kErrFmtCannotReadAttribute
HDF5 error message.
The header file containing a class responsible for printing out info and error messages (stdout...
bool is3D() const
Does the object include spatial dimensions only?
ErrorMessage kErrFmtCannotSetCompression
HDF5 error message.
Definition: ErrorMessages.h:94
static std::string formatMessage(const std::string &format, Args ... args)
C++-11 replacement for sprintf that works with std::string instead of char*.
Definition: Logger.h:157
void writeHyperSlab(const hid_t dataset, const DimensionSizes &position, const DimensionSizes &size, const T *data)
Write a hyperslab into the dataset.
Definition: Hdf5File.cpp:335
const std::string MatrixName
Datatype for matrix names.
Definition: MatrixNames.h:39
Structure with 4D dimension sizes (3 in space and 1 in time).
The matrix is stored in floating point 32b wide format.
ErrorMessage kErrFmtCannotWriteDataset
HDF5 error message.
Definition: ErrorMessages.h:76
MatrixDataType readMatrixDataType(const hid_t parentGroup, MatrixName &datasetName)
Read matrix data type from the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:821
The matrix is stored in fixed point point 64b wide format.
static const std::string kMatrixDataTypeNames[]
String representation of different data types.
Definition: Hdf5File.h:865
ErrorMessage kErrFmtCannotCreateFile
HDF5 error message.
Definition: ErrorMessages.h:64
size_t ny
Number of elements in the y direction.
void closeGroup(const hid_t group)
Close a group.
Definition: Hdf5File.cpp:214
size_t nElements() const
Get the number of elements, in 3D only spatial domain, in 4D with time.
void close()
Close the HDF5 file.
Definition: Hdf5File.cpp:161
MatrixDomainType
HDF5 Matrix domain type (real or complex).
Definition: Hdf5File.h:512
ErrorMessage kErrFmtFileNotOpen
HDF5 error message.
Definition: ErrorMessages.h:85
void readCompleteDataset(const hid_t parentGroup, MatrixName &datasetName, const DimensionSizes &dimensionSizes, T *data)
Read data from the dataset at a specified place in the file tree.
Definition: Hdf5File.cpp:678
static const std::string kMatrixDataTypeName
String representation of the Data type in the HDF5 file.
Definition: Hdf5File.h:860
static const std::string kMatrixDomainTypeNames[]
String representation of different domain types.
Definition: Hdf5File.h:863
MatrixDataType
HDF5 matrix data type (float or uint64).
Definition: Hdf5File.h:499
ErrorMessage kErrFmtCannotWriteAttribute
HDF5 error message.
size_t nx
Number of elements in the x direction.
Hdf5File()
Constructor of the class.
Definition: Hdf5File.cpp:73
ErrorMessage kErrFmtNotHdf5File
HDF5 error message.
Definition: ErrorMessages.h:88
ErrorMessage kErrFmtCannotOpenDataset
HDF5 error message.
Definition: ErrorMessages.h:91
hid_t createDataset(const hid_t parentGroup, MatrixName &datasetName, const DimensionSizes &dimensionSizes, const DimensionSizes &chunkSizes, const MatrixDataType matrixDataType, const size_t compressionLevel)
Create a float HDF5 dataset at a specified place in the file tree (3D/4D).
Definition: Hdf5File.cpp:241
bool isOpen() const
Is the file opened?
Definition: Hdf5File.h:560
MatrixDomainType readMatrixDomainType(const hid_t parentGroup, MatrixName &datasetName)
Read matrix dataset domain type at a specified place in the file tree.
Definition: Hdf5File.cpp:848
The matrix is defined on real domain.